lib/cache: add Delete and DeletePrefix methods #4811

This commit is contained in:
Nick Craig-Wood 2020-11-30 11:46:06 +00:00
parent 657be2ace5
commit f4750928ee
2 changed files with 76 additions and 0 deletions

27
lib/cache/cache.go vendored
View File

@ -3,6 +3,7 @@
package cache package cache
import ( import (
"strings"
"sync" "sync"
"time" "time"
) )
@ -119,6 +120,32 @@ func (c *Cache) GetMaybe(key string) (value interface{}, found bool) {
return entry.value, found return entry.value, found
} }
// Delete the entry passed in
//
// Returns true if the entry was found
func (c *Cache) Delete(key string) bool {
c.mu.Lock()
_, found := c.cache[key]
delete(c.cache, key)
c.mu.Unlock()
return found
}
// DeletePrefix deletes all entries with the given prefix
//
// Returns number of entries deleted
func (c *Cache) DeletePrefix(prefix string) (deleted int) {
c.mu.Lock()
for k := range c.cache {
if strings.HasPrefix(k, prefix) {
delete(c.cache, k)
deleted++
}
}
c.mu.Unlock()
return deleted
}
// Rename renames the item at oldKey to newKey. // Rename renames the item at oldKey to newKey.
// //
// If there was an existing item at newKey then it takes precedence // If there was an existing item at newKey then it takes precedence

View File

@ -28,6 +28,8 @@ func setup(t *testing.T) (*Cache, CreateFunc) {
return "/file.txt", true, errCached return "/file.txt", true, errCached
case "/error": case "/error":
return nil, false, errSentinel return nil, false, errSentinel
case "/err":
return nil, false, errSentinel
} }
panic(fmt.Sprintf("Unknown path %q", path)) panic(fmt.Sprintf("Unknown path %q", path))
} }
@ -225,6 +227,53 @@ func TestGetMaybe(t *testing.T) {
assert.Nil(t, value) assert.Nil(t, value)
} }
func TestDelete(t *testing.T) {
c, create := setup(t)
assert.Equal(t, 0, len(c.cache))
_, err := c.Get("/", create)
require.NoError(t, err)
assert.Equal(t, 1, len(c.cache))
assert.Equal(t, false, c.Delete("notfound"))
assert.Equal(t, 1, len(c.cache))
assert.Equal(t, true, c.Delete("/"))
assert.Equal(t, 0, len(c.cache))
assert.Equal(t, false, c.Delete("/"))
assert.Equal(t, 0, len(c.cache))
}
func TestDeletePrefix(t *testing.T) {
create := func(path string) (interface{}, bool, error) {
return path, true, nil
}
c := New()
_, err := c.Get("remote:path", create)
require.NoError(t, err)
_, err = c.Get("remote:path2", create)
require.NoError(t, err)
_, err = c.Get("remote:", create)
require.NoError(t, err)
_, err = c.Get("remote", create)
require.NoError(t, err)
assert.Equal(t, 4, len(c.cache))
assert.Equal(t, 3, c.DeletePrefix("remote:"))
assert.Equal(t, 1, len(c.cache))
assert.Equal(t, 1, c.DeletePrefix(""))
assert.Equal(t, 0, len(c.cache))
assert.Equal(t, 0, c.DeletePrefix(""))
assert.Equal(t, 0, len(c.cache))
}
func TestCacheRename(t *testing.T) { func TestCacheRename(t *testing.T) {
c := New() c := New()
create := func(path string) (interface{}, bool, error) { create := func(path string) (interface{}, bool, error) {