This commit is contained in:
Jaime Martinez 2020-10-16 16:55:39 +11:00 committed by GitHub
commit e37e189793
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 0 deletions

View File

@ -57,7 +57,15 @@ func (c *cache) Set(k string, x interface{}, d time.Duration) {
if d > 0 {
e = time.Now().Add(d).UnixNano()
}
var item Item
var evicted bool
c.mu.Lock()
if c.onEvicted != nil {
item, evicted = c.items[k]
}
c.items[k] = Item{
Object: x,
Expiration: e,
@ -65,6 +73,11 @@ func (c *cache) Set(k string, x interface{}, d time.Duration) {
// TODO: Calls to mu.Unlock are currently not deferred because defer
// adds ~200 ns (as of go1.)
c.mu.Unlock()
// try to call onEvicted if key existed before but the item is different
if evicted && item.Object != x {
c.onEvicted(k, item.Object)
}
}
func (c *cache) set(k string, x interface{}, d time.Duration) {

View File

@ -1247,6 +1247,37 @@ func TestOnEvicted(t *testing.T) {
}
}
func TestOnEvictedCalledBeforeSet(t *testing.T) {
tc := New(DefaultExpiration, 0)
expiry := 1 * time.Nanosecond
works := false
tc.OnEvicted(func(k string, v interface{}) {
if k == "foo" && v.(int) == 3 {
works = true
}
tc.Set("bar", 4, DefaultExpiration)
})
tc.Set("foo", 3, expiry)
if tc.onEvicted == nil {
t.Fatal("tc.onEvicted is nil")
}
// calling Set again with the same key should evict
// the item if different
tc.Set("foo", 5, DefaultExpiration)
x, _ := tc.Get("bar")
if !works {
t.Fatal("works bool not true")
}
if x.(int) != 4 {
t.Error("bar was not 4")
}
}
func TestCacheSerialization(t *testing.T) {
tc := New(DefaultExpiration, 0)
testFillAndSerialize(t, tc)