diff --git a/tools/disk_cache/api.go b/tools/disk_cache/api.go index 37faabf7a..33adc4594 100644 --- a/tools/disk_cache/api.go +++ b/tools/disk_cache/api.go @@ -43,7 +43,9 @@ func NewDiskCache(path string, max_size int64) (dc *DiskCache, err error) { if err = os.MkdirAll(path, 0o700); err != nil { return } - return &DiskCache{Path: path, MaxSize: max_size}, nil + dc = &DiskCache{Path: path, MaxSize: max_size} + err = dc.prune() + return } func KeyForPath(path string) (key string, err error) { diff --git a/tools/disk_cache/implementation.go b/tools/disk_cache/implementation.go index fd8eecb65..e989839d3 100644 --- a/tools/disk_cache/implementation.go +++ b/tools/disk_cache/implementation.go @@ -165,7 +165,7 @@ func (dc *DiskCache) remove(key string) (err error) { } func (dc *DiskCache) prune() error { - if dc.entries.TotalSize <= dc.MaxSize { + if dc.MaxSize < 1 || dc.entries.TotalSize <= dc.MaxSize { return nil } for dc.entries.TotalSize > dc.MaxSize && len(dc.entries.SortedEntries) > 0 { @@ -191,22 +191,26 @@ func (dc *DiskCache) update_timestamp(key string) { } func (dc *DiskCache) update_accounting(key string, changed int64) (err error) { - if err = dc.ensure_entries(); err == nil { - t := dc.entry_map[key] - if t == nil { - t = &Entry{Key: key} - dc.entry_map[key] = t - dc.entries.SortedEntries = append(dc.entries.SortedEntries, t) - } - old_size := t.Size - t.Size += changed - t.Size = max(0, t.Size) - dc.entries.TotalSize += t.Size - old_size - dc.update_timestamp(key) - dc.prune() - return dc.write_entries() + t := dc.entry_map[key] + if t == nil { + t = &Entry{Key: key} + dc.entry_map[key] = t + dc.entries.SortedEntries = append(dc.entries.SortedEntries, t) } - return + old_size := t.Size + t.Size += changed + t.Size = max(0, t.Size) + dc.entries.TotalSize += t.Size - old_size + dc.update_timestamp(key) + dc.prune() + return dc.write_entries() +} + +func (dc *DiskCache) keys() (ans []string, err error) { + if err = dc.ensure_entries(); err != nil { + return + } + return utils.Keys(dc.entry_map), nil } func (dc *DiskCache) add(key string, items map[string][]byte) (err error) { diff --git a/tools/disk_cache/implementation_test.go b/tools/disk_cache/implementation_test.go index ba2a68d2a..cf9ea5131 100644 --- a/tools/disk_cache/implementation_test.go +++ b/tools/disk_cache/implementation_test.go @@ -3,6 +3,8 @@ package disk_cache import ( "fmt" "os" + "slices" + "strings" "testing" "github.com/google/go-cmp/cmp" @@ -17,6 +19,11 @@ func TestDiskCache(t *testing.T) { if err != nil { t.Fatal(err) } + dc2, err := NewDiskCache(tdir, dc.MaxSize) + if err != nil { + t.Fatal(err) + } + m := dc.Get("missing", "one", "two") if diff := cmp.Diff(m, make(map[string]string)); diff != "" { t.Fatalf("Unexpected return from missing: %s", diff) @@ -24,18 +31,42 @@ func TestDiskCache(t *testing.T) { dc.Add("k1", map[string][]byte{"1": []byte("abcd"), "2": []byte("efgh")}) ad := func(key string, expected map[string]string) { - actual := dc.Get(key, utils.Keys(expected)...) + for _, x := range []*DiskCache{dc, dc2} { + actual := x.Get(key, utils.Keys(expected)...) - for k, path := range actual { - d, err := os.ReadFile(path) + for k, path := range actual { + d, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + actual[k] = string(d) + } + if diff := cmp.Diff(expected, actual); diff != "" { + t.Fatalf("Data for %s not equal: %s", key, diff) + } + } + } + ak := func(keys ...string) { + for _, x := range []*DiskCache{dc, dc2} { + kk, err := x.keys() if err != nil { t.Fatal(err) } - actual[k] = string(d) - } - if diff := cmp.Diff(expected, actual); diff != "" { - t.Fatalf("Data for %s not equal: %s", key, diff) + slices.Sort(kk) + slices.Sort(keys) + if diff := cmp.Diff(keys, kk); diff != "" { + t.Fatalf("Unexpected keys: %s", diff) + } } } ad("k1", map[string]string{"1": "abcd", "2": "efgh"}) + dc.Add("k1", map[string][]byte{"3": []byte("ijk"), "4": []byte("lmo")}) + dc2.Add("k2", map[string][]byte{"1": []byte("123456789")}) + ad("k1", map[string]string{"1": "abcd", "2": "efgh", "3": "ijk"}) + if dc.entries.TotalSize != 14+9 { + t.Fatalf("TotalSize: %d != %d", dc.entries.TotalSize, 14+9) + } + ak("k1", "k2") + dc.Add("k3", map[string][]byte{"1": []byte(strings.Repeat("a", int(dc.MaxSize)-10))}) + ak("k3", "k2") }