diff --git a/internal/api/thumbnail_cache.go b/internal/api/thumbnail_cache.go index 843ce9d..2d9d4ee 100644 --- a/internal/api/thumbnail_cache.go +++ b/internal/api/thumbnail_cache.go @@ -37,7 +37,7 @@ func newThumbnailCache() *thumbnailCache { items: make(map[thumbnailCacheKey]*list.Element), order: list.New(), flights: make(map[thumbnailCacheKey]*thumbnailFlight), - maxBytes: 32 << 20, + maxBytes: 8 << 20, maxItems: 64, } } @@ -53,7 +53,7 @@ func (c *thumbnailCache) Do(key thumbnailCacheKey, fn func() ([]byte, error)) ([ if f, ok := c.flights[key]; ok { c.mu.Unlock() <-f.done - return append([]byte(nil), f.data...), f.err + return f.data, f.err } f := &thumbnailFlight{done: make(chan struct{})} c.flights[key] = f @@ -63,7 +63,7 @@ func (c *thumbnailCache) Do(key thumbnailCacheKey, fn func() ([]byte, error)) ([ if err == nil && len(data) > 0 && int64(len(data)) <= c.maxBytes { c.mu.Lock() c.putLocked(key, data) - f.data = append([]byte(nil), data...) + f.data = data f.err = err delete(c.flights, key) close(f.done) @@ -82,11 +82,11 @@ func (c *thumbnailCache) putLocked(key thumbnailCacheKey, data []byte) { if e, ok := c.items[key]; ok { old := e.Value.(thumbnailCacheEntry) c.bytes -= int64(len(old.data)) - e.Value = thumbnailCacheEntry{key: key, data: append([]byte(nil), data...)} + e.Value = thumbnailCacheEntry{key: key, data: data} c.bytes += int64(len(data)) c.order.MoveToFront(e) } else { - e := c.order.PushFront(thumbnailCacheEntry{key: key, data: append([]byte(nil), data...)}) + e := c.order.PushFront(thumbnailCacheEntry{key: key, data: data}) c.items[key] = e c.bytes += int64(len(data)) } diff --git a/internal/api/thumbnail_cache_test.go b/internal/api/thumbnail_cache_test.go index 9ae0e68..aa53101 100644 --- a/internal/api/thumbnail_cache_test.go +++ b/internal/api/thumbnail_cache_test.go @@ -70,3 +70,19 @@ func TestThumbnailCacheEvictsByBound(t *testing.T) { t.Fatalf("cache size=%d/list=%d, want 2/2", len(c.items), c.order.Len()) } } + +func TestThumbnailCacheEvictsByBytes(t *testing.T) { + c := newThumbnailCache() + c.maxBytes = 3 + for i := 0; i < 2; i++ { + key := thumbnailCacheKey{Path: string(rune('x' + i))} + if _, err := c.Do(key, func() ([]byte, error) { return []byte("xx"), nil }); err != nil { + t.Fatal(err) + } + } + c.mu.Lock() + defer c.mu.Unlock() + if c.bytes > c.maxBytes || len(c.items) != 1 { + t.Fatalf("cache bytes=%d items=%d, want <=%d/1", c.bytes, len(c.items), c.maxBytes) + } +}