Skip to content

Commit 59cc448

Browse files
committed
Delete expired items before setting
Check if an item exists and it has expired before setting so that onEvicted is actually called. Fixes #48. Add test and split func Use nanoseconds instead
1 parent 46f4078 commit 59cc448

2 files changed

Lines changed: 48 additions & 0 deletions

File tree

cache.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ func (c *cache) Set(k string, x interface{}, d time.Duration) {
5757
if d > 0 {
5858
e = time.Now().Add(d).UnixNano()
5959
}
60+
61+
// delete before setting and call onEvicted
62+
c.deleteIfExpired(k)
63+
6064
c.mu.Lock()
6165
c.items[k] = Item{
6266
Object: x,
@@ -922,6 +926,17 @@ func (c *cache) delete(k string) (interface{}, bool) {
922926
return nil, false
923927
}
924928

929+
func (c *cache) deleteIfExpired(k string) {
930+
c.mu.Lock()
931+
i, ok := c.items[k]
932+
c.mu.Unlock()
933+
934+
if ok && i.Expired() {
935+
// delete if expired so .onEvicted is called
936+
c.Delete(k)
937+
}
938+
}
939+
925940
type keyAndValue struct {
926941
key string
927942
value interface{}

cache_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,39 @@ func TestOnEvicted(t *testing.T) {
12471247
}
12481248
}
12491249

1250+
func TestOnEvictedCalledBeforeSet(t *testing.T) {
1251+
tc := New(DefaultExpiration, 0)
1252+
expiry := 1 * time.Nanosecond
1253+
1254+
works := false
1255+
tc.OnEvicted(func(k string, v interface{}) {
1256+
if k == "foo" && v.(int) == 3 {
1257+
1258+
works = true
1259+
}
1260+
tc.Set("bar", 4, DefaultExpiration)
1261+
})
1262+
1263+
tc.Set("foo", 3, expiry)
1264+
if tc.onEvicted == nil {
1265+
t.Fatal("tc.onEvicted is nil")
1266+
}
1267+
1268+
// ensure item expires
1269+
time.Sleep(expiry)
1270+
1271+
// calling Set again should evict expired item
1272+
tc.Set("foo", 3, DefaultExpiration)
1273+
1274+
x, _ := tc.Get("bar")
1275+
if !works {
1276+
t.Fatal("works bool not true")
1277+
}
1278+
if x.(int) != 4 {
1279+
t.Error("bar was not 4")
1280+
}
1281+
}
1282+
12501283
func TestCacheSerialization(t *testing.T) {
12511284
tc := New(DefaultExpiration, 0)
12521285
testFillAndSerialize(t, tc)

0 commit comments

Comments
 (0)