Skip to content

Commit 732ffc7

Browse files
authored
Add a SetAndGet method to return previous value when setting a new one (#101)
1 parent 6e76df7 commit 732ffc7

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

cache.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,25 @@ func (cache *Cache) GetOrSet(key, value []byte, expireSeconds int) (retValue []b
117117
return
118118
}
119119

120+
// SetAndGet sets a key, value and expiration for a cache entry and stores it in the cache.
121+
// If the key is larger than 65535 or value is larger than 1/1024 of the cache size,
122+
// the entry will not be written to the cache. expireSeconds <= 0 means no expire,
123+
// but it can be evicted when cache is full. Returns existing value if record exists
124+
// with a bool value to indicate whether an existing record was found
125+
func (cache *Cache) SetAndGet(key, value []byte, expireSeconds int) (retValue []byte, found bool, err error) {
126+
hashVal := hashFunc(key)
127+
segID := hashVal & segmentAndOpVal
128+
cache.locks[segID].Lock()
129+
defer cache.locks[segID].Unlock()
130+
131+
retValue, _, err = cache.segments[segID].get(key, nil, hashVal, false)
132+
if err == nil {
133+
found = true
134+
}
135+
err = cache.segments[segID].set(key, value, hashVal, expireSeconds)
136+
return
137+
}
138+
120139
// Peek returns the value or not found error, without updating access time or counters.
121140
func (cache *Cache) Peek(key []byte) (value []byte, err error) {
122141
hashVal := hashFunc(key)

cache_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,3 +824,23 @@ func TestConcurrentGetTTL(t *testing.T) {
824824
t.Fatalf("Failed to get the TTL with an error: %+v", err)
825825
}
826826
}
827+
828+
func TestSetAndGet(t *testing.T) {
829+
cache := NewCache(1024)
830+
key := []byte("abcd")
831+
val1 := []byte("efgh")
832+
833+
_, found, _ := cache.SetAndGet(key, val1, 0)
834+
if found == true {
835+
t.Fatalf("SetAndGet unexpected found data")
836+
}
837+
838+
val2 := []byte("ijkl")
839+
rval, found, _ := cache.SetAndGet(key, val2, 0)
840+
if found == false {
841+
t.Fatalf("SetAndGet expected found data")
842+
}
843+
if string(val1) != string(rval) {
844+
t.Fatalf("SetAndGet expected SetAndGet %s: got %s", string(val1), string(rval))
845+
}
846+
}

0 commit comments

Comments
 (0)