Files
kopia/repo/content/content_cache_data.go
Jarek Kowalski 920341cb68 cache: prevent metadata cache thrashing if working set exceeds max defined size (#1557)
This is done by protecting newly added cache items from being swept for
X amount of time where X defaults to:

* `metadata` - 24 hours (new)
* `data` - 10 min (new)
* `indexes` - 1 hours (same as today)

Fixes #1540
2021-12-03 15:35:01 -08:00

57 lines
1.5 KiB
Go

package content
import (
"context"
"github.com/pkg/errors"
"github.com/kopia/kopia/internal/cache"
"github.com/kopia/kopia/internal/gather"
"github.com/kopia/kopia/repo/blob"
)
type contentCacheForData struct {
pc *cache.PersistentCache
st blob.Storage
}
func adjustCacheKey(cacheKey cacheKey) cacheKey {
// content IDs with odd length have a single-byte prefix.
// move the prefix to the end of cache key to make sure the top level shard is spread 256 ways.
if len(cacheKey)%2 == 1 {
return cacheKey[1:] + cacheKey[0:1]
}
return cacheKey
}
func (c *contentCacheForData) getContent(ctx context.Context, cacheKey cacheKey, blobID blob.ID, offset, length int64, output *gather.WriteBuffer) error {
cacheKey = adjustCacheKey(cacheKey)
// nolint:wrapcheck
return c.pc.GetOrLoad(ctx, string(cacheKey), func(output *gather.WriteBuffer) error {
// nolint:wrapcheck
return c.st.GetBlob(ctx, blobID, offset, length, output)
}, output)
}
func (c *contentCacheForData) close(ctx context.Context) {
c.pc.Close(ctx)
}
func newContentCacheForData(ctx context.Context, st blob.Storage, cacheStorage cache.Storage, sweep cache.SweepSettings, hmacSecret []byte) (contentCache, error) {
if cacheStorage == nil {
return passthroughContentCache{st}, nil
}
pc, err := cache.NewPersistentCache(ctx, "content cache", cacheStorage, cache.ChecksumProtection(hmacSecret), sweep)
if err != nil {
return nil, errors.Wrap(err, "unable to create base cache")
}
return &contentCacheForData{
st: st,
pc: pc,
}, nil
}