feat(cache): add batch eviction support
Some checks failed
CI / test (push) Failing after 3s
CI / auto-fix (push) Failing after 0s
CI / auto-merge (push) Failing after 0s

This commit is contained in:
Virgil 2026-04-01 09:46:02 +00:00
parent 248f542b08
commit 19232c5575
4 changed files with 61 additions and 0 deletions

View file

@ -200,6 +200,32 @@ func (c *Cache) Delete(key string) error {
return nil
}
// DeleteMany removes several cached items in one call.
//
// err := c.DeleteMany("github/acme/repos", "github/acme/meta")
func (c *Cache) DeleteMany(keys ...string) error {
if err := c.ensureReady("cache.DeleteMany"); err != nil {
return err
}
for _, key := range keys {
path, err := c.Path(key)
if err != nil {
return err
}
err = c.medium.Delete(path)
if core.Is(err, fs.ErrNotExist) {
continue
}
if err != nil {
return core.E("cache.DeleteMany", "failed to delete cache file", err)
}
}
return nil
}
// Clear removes all cached items under the cache base directory.
//
// err := c.Clear()

View file

@ -235,6 +235,38 @@ func TestCache_Delete_Good(t *testing.T) {
}
}
func TestCache_DeleteMany_Good(t *testing.T) {
c, _ := newTestCache(t, "/tmp/cache-delete-many", time.Minute)
data := map[string]string{"foo": "bar"}
if err := c.Set("key1", data); err != nil {
t.Fatalf("Set failed for key1: %v", err)
}
if err := c.Set("key2", data); err != nil {
t.Fatalf("Set failed for key2: %v", err)
}
if err := c.DeleteMany("key1", "missing", "key2"); err != nil {
t.Fatalf("DeleteMany failed: %v", err)
}
var retrieved map[string]string
found, err := c.Get("key1", &retrieved)
if err != nil {
t.Fatalf("Get after DeleteMany returned an unexpected error: %v", err)
}
if found {
t.Error("expected key1 to be deleted")
}
found, err = c.Get("key2", &retrieved)
if err != nil {
t.Fatalf("Get after DeleteMany returned an unexpected error: %v", err)
}
if found {
t.Error("expected key2 to be deleted")
}
}
func TestCache_Clear_Good(t *testing.T) {
c, _ := newTestCache(t, "/tmp/cache-clear", time.Minute)
data := map[string]string{"foo": "bar"}

View file

@ -22,6 +22,7 @@ own usage example in a doc comment or Go example test.
| `(*Cache).Get` | `func (c *Cache) Get(key string, dest any) (bool, error)` | `dappco.re/go/core/cache` | Retrieves a cached item if it exists and has not expired. | yes | no |
| `(*Cache).Set` | `func (c *Cache) Set(key string, data any) error` | `dappco.re/go/core/cache` | Stores an item in the cache. | yes | no |
| `(*Cache).Delete` | `func (c *Cache) Delete(key string) error` | `dappco.re/go/core/cache` | Removes an item from the cache. | yes | no |
| `(*Cache).DeleteMany` | `func (c *Cache) DeleteMany(keys ...string) error` | `dappco.re/go/core/cache` | Removes several items from the cache in one call. | yes | no |
| `(*Cache).Clear` | `func (c *Cache) Clear() error` | `dappco.re/go/core/cache` | Removes all cached items. | yes | no |
| `(*Cache).Age` | `func (c *Cache) Age(key string) time.Duration` | `dappco.re/go/core/cache` | Returns how old a cached item is, or `-1` if it is not cached. | yes | no |
| `GitHubReposKey` | `func GitHubReposKey(org string) string` | `dappco.re/go/core/cache` | Returns the cache key for an organization's repo list. | yes | no |

View file

@ -136,6 +136,8 @@ Key behaviours:
- **`Delete(key)`** removes a single entry. If the file does not exist, the
operation succeeds silently.
- **`DeleteMany(keys...)`** removes several entries in one call and ignores
missing files, using the same per-key path validation as `Delete()`.
- **`Clear()`** calls `medium.DeleteAll(baseDir)`, removing the entire cache
directory and all its contents.