Skip to content

Commit

Permalink
Add a SetAndGet method to return previous value when setting a new one (
Browse files Browse the repository at this point in the history
  • Loading branch information
debspencer committed Aug 11, 2021
1 parent 6e76df7 commit 732ffc7
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
19 changes: 19 additions & 0 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,25 @@ func (cache *Cache) GetOrSet(key, value []byte, expireSeconds int) (retValue []b
return
}

// SetAndGet sets a key, value and expiration for a cache entry and stores it in the cache.
// If the key is larger than 65535 or value is larger than 1/1024 of the cache size,
// the entry will not be written to the cache. expireSeconds <= 0 means no expire,
// but it can be evicted when cache is full. Returns existing value if record exists
// with a bool value to indicate whether an existing record was found
func (cache *Cache) SetAndGet(key, value []byte, expireSeconds int) (retValue []byte, found bool, err error) {
hashVal := hashFunc(key)
segID := hashVal & segmentAndOpVal
cache.locks[segID].Lock()
defer cache.locks[segID].Unlock()

retValue, _, err = cache.segments[segID].get(key, nil, hashVal, false)
if err == nil {
found = true
}
err = cache.segments[segID].set(key, value, hashVal, expireSeconds)
return
}

// Peek returns the value or not found error, without updating access time or counters.
func (cache *Cache) Peek(key []byte) (value []byte, err error) {
hashVal := hashFunc(key)
Expand Down
20 changes: 20 additions & 0 deletions cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -824,3 +824,23 @@ func TestConcurrentGetTTL(t *testing.T) {
t.Fatalf("Failed to get the TTL with an error: %+v", err)
}
}

func TestSetAndGet(t *testing.T) {
cache := NewCache(1024)
key := []byte("abcd")
val1 := []byte("efgh")

_, found, _ := cache.SetAndGet(key, val1, 0)
if found == true {
t.Fatalf("SetAndGet unexpected found data")
}

val2 := []byte("ijkl")
rval, found, _ := cache.SetAndGet(key, val2, 0)
if found == false {
t.Fatalf("SetAndGet expected found data")
}
if string(val1) != string(rval) {
t.Fatalf("SetAndGet expected SetAndGet %s: got %s", string(val1), string(rval))
}
}

0 comments on commit 732ffc7

Please sign in to comment.