Skip to content

Commit 5680146

Browse files
committed
Support cleanup
1 parent f173a81 commit 5680146

File tree

4 files changed

+46
-6
lines changed

4 files changed

+46
-6
lines changed

cache.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,28 @@ func (m CacheMap) MSet(data map[string]interface{}, duration time.Duration) {
5757
for key, value := range data {
5858
shard := m.GetShard(key)
5959
shard.Lock()
60-
shard.items[key] = newItem(value, duration, time.Now().Add(m.options.maxLifetime))
60+
shard.items[key] = newItem(value, duration, time.Now().Add(m.options.maxLifetime), nil)
6161
shard.Unlock()
6262
}
6363
}
6464

65-
// Sets the given value under the specified key
66-
func (m CacheMap) Set(key string, value interface{}, duration *time.Duration) {
65+
func (m CacheMap) SetWithCleanup(key string, value interface{}, duration *time.Duration, cleanup func(*Item)) {
6766
// Get map shard.
6867
shard := m.GetShard(key)
6968
shard.Lock()
7069
if duration == nil {
7170
duration = &m.options.defaultCacheDuration
7271
}
73-
shard.items[key] = newItem(value, *duration, time.Now().Add(m.options.maxLifetime))
72+
itm := newItem(value, *duration, time.Now().Add(m.options.maxLifetime), cleanup)
73+
shard.items[key] = itm
7474
shard.Unlock()
7575
}
7676

77+
// Sets the given value under the specified key
78+
func (m CacheMap) Set(key string, value interface{}, duration *time.Duration) {
79+
m.SetWithCleanup(key, value, duration, nil)
80+
}
81+
7782
// Retrieves an item from the map with the given key, and optionally increase its expiry time if found
7883
func (m CacheMap) TouchGet(key string, touch bool) (interface{}, bool) {
7984
shard := m.GetShard(key)
@@ -133,6 +138,10 @@ func (ms CacheMapShared) Remove(key string) {
133138

134139
// Removes an element from the map
135140
func (ms CacheMapShared) remove(key string) {
141+
if itm, ok := ms.items[key]; ok && itm.onDelete != nil {
142+
itm.onDelete(itm)
143+
}
144+
136145
delete(ms.items, key)
137146
}
138147

cache_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,32 @@ func TestItems(t *testing.T) {
9696
t.Errorf("Expected cache to return 3 items after cache expiry")
9797
}
9898
}
99+
100+
func TestCleanup(t *testing.T) {
101+
dur := time.Millisecond * 100
102+
103+
cleanup := 0
104+
105+
cache := ttlmap.New(ttlmap.WithCleanupDuration(time.Millisecond * 5))
106+
107+
cache.SetWithCleanup("item1", "one", nil, func(item *ttlmap.Item) { cleanup++ })
108+
109+
if cleanup != 0 {
110+
t.Errorf("Cache item cleaned up too early")
111+
}
112+
113+
cache.Remove("item1")
114+
115+
if cleanup != 1 {
116+
t.Errorf("Cache item cleanup not called on Remove")
117+
}
118+
119+
cache.SetWithCleanup("item2", "two", &dur, func(item *ttlmap.Item) { cleanup++ })
120+
time.Sleep(dur)
121+
// Wait a few more milliseconds for cleanup to run
122+
time.Sleep(time.Millisecond * 20)
123+
124+
if cleanup != 2 {
125+
t.Errorf("Cache item cleanup not called on expiry")
126+
}
127+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/packaged/ttlmap
22

3-
go 1.12
3+
go 1.15

item.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ type Item struct {
1212
deadline time.Time
1313
ttl time.Duration
1414
expires *time.Time
15+
onDelete func(*Item)
1516
}
1617

17-
func newItem(value interface{}, duration time.Duration, deadline time.Time) *Item {
18+
func newItem(value interface{}, duration time.Duration, deadline time.Time, onDelete func(*Item)) *Item {
1819
i := &Item{
1920
data: value,
2021
ttl: duration,
2122
deadline: deadline,
23+
onDelete: onDelete,
2224
}
2325
expiry := time.Now().Add(duration)
2426
i.expires = &expiry

0 commit comments

Comments
 (0)