Skip to content

Commit

Permalink
Support cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
bajb committed Feb 25, 2021
1 parent f173a81 commit 5680146
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 6 deletions.
17 changes: 13 additions & 4 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,28 @@ func (m CacheMap) MSet(data map[string]interface{}, duration time.Duration) {
for key, value := range data {
shard := m.GetShard(key)
shard.Lock()
shard.items[key] = newItem(value, duration, time.Now().Add(m.options.maxLifetime))
shard.items[key] = newItem(value, duration, time.Now().Add(m.options.maxLifetime), nil)
shard.Unlock()
}
}

// Sets the given value under the specified key
func (m CacheMap) Set(key string, value interface{}, duration *time.Duration) {
func (m CacheMap) SetWithCleanup(key string, value interface{}, duration *time.Duration, cleanup func(*Item)) {
// Get map shard.
shard := m.GetShard(key)
shard.Lock()
if duration == nil {
duration = &m.options.defaultCacheDuration
}
shard.items[key] = newItem(value, *duration, time.Now().Add(m.options.maxLifetime))
itm := newItem(value, *duration, time.Now().Add(m.options.maxLifetime), cleanup)
shard.items[key] = itm
shard.Unlock()
}

// Sets the given value under the specified key
func (m CacheMap) Set(key string, value interface{}, duration *time.Duration) {
m.SetWithCleanup(key, value, duration, nil)
}

// Retrieves an item from the map with the given key, and optionally increase its expiry time if found
func (m CacheMap) TouchGet(key string, touch bool) (interface{}, bool) {
shard := m.GetShard(key)
Expand Down Expand Up @@ -133,6 +138,10 @@ func (ms CacheMapShared) Remove(key string) {

// Removes an element from the map
func (ms CacheMapShared) remove(key string) {
if itm, ok := ms.items[key]; ok && itm.onDelete != nil {
itm.onDelete(itm)
}

delete(ms.items, key)
}

Expand Down
29 changes: 29 additions & 0 deletions cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,32 @@ func TestItems(t *testing.T) {
t.Errorf("Expected cache to return 3 items after cache expiry")
}
}

func TestCleanup(t *testing.T) {
dur := time.Millisecond * 100

cleanup := 0

cache := ttlmap.New(ttlmap.WithCleanupDuration(time.Millisecond * 5))

cache.SetWithCleanup("item1", "one", nil, func(item *ttlmap.Item) { cleanup++ })

if cleanup != 0 {
t.Errorf("Cache item cleaned up too early")
}

cache.Remove("item1")

if cleanup != 1 {
t.Errorf("Cache item cleanup not called on Remove")
}

cache.SetWithCleanup("item2", "two", &dur, func(item *ttlmap.Item) { cleanup++ })
time.Sleep(dur)
// Wait a few more milliseconds for cleanup to run
time.Sleep(time.Millisecond * 20)

if cleanup != 2 {
t.Errorf("Cache item cleanup not called on expiry")
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/packaged/ttlmap

go 1.12
go 1.15
4 changes: 3 additions & 1 deletion item.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ type Item struct {
deadline time.Time
ttl time.Duration
expires *time.Time
onDelete func(*Item)
}

func newItem(value interface{}, duration time.Duration, deadline time.Time) *Item {
func newItem(value interface{}, duration time.Duration, deadline time.Time, onDelete func(*Item)) *Item {
i := &Item{
data: value,
ttl: duration,
deadline: deadline,
onDelete: onDelete,
}
expiry := time.Now().Add(duration)
i.expires = &expiry
Expand Down

0 comments on commit 5680146

Please sign in to comment.