diff --git a/cache.go b/cache.go index db88d2f..a98f8f9 100644 --- a/cache.go +++ b/cache.go @@ -6,6 +6,7 @@ import ( "io" "os" "runtime" + "strings" "sync" "time" ) @@ -947,6 +948,24 @@ func (c *cache) DeleteExpired() { } } +// Delete the keys with some prefix from the cache +func (c *cache) DeleteByPrefix(prefix string) { + var evictedItems []keyAndValue + c.mu.Lock() + for k := range c.items { + if strings.HasPrefix(k, prefix) { + ov, evicted := c.delete(k) + if evicted { + evictedItems = append(evictedItems, keyAndValue{k, ov}) + } + } + } + c.mu.Unlock() + for _, v := range evictedItems { + c.onEvicted(v.key, v.value) + } +} + // Sets an (optional) function that is called with the key and value when an // item is evicted from the cache. (Including when it is deleted manually, but // not when it is overwritten.) Set to nil to disable. diff --git a/cache_test.go b/cache_test.go index cb80b38..7ccde5c 100644 --- a/cache_test.go +++ b/cache_test.go @@ -1150,6 +1150,26 @@ func TestDelete(t *testing.T) { } } +func TestDeleteByPrefix(t *testing.T) { + tc := New(DefaultExpiration, 0) + keys := []string{"foo", "fooa", "foo1", "fooA"} + for _, k := range keys { + tc.Set(k, "value", DefaultExpiration) + } + tc.Set("bar", "value", DefaultExpiration) + tc.DeleteByPrefix("foo") + for _, k := range keys { + x, found := tc.Get(k) + if found || x != nil { + t.Errorf("%s was found, but it should have been deleted\n", k) + } + } + x, found := tc.Get("bar") + if !found || x == nil { + t.Error("bar was not found") + } +} + func TestItemCount(t *testing.T) { tc := New(DefaultExpiration, 0) tc.Set("foo", "1", DefaultExpiration)