Files
kopia/block/block_cache.go
2018-04-23 19:56:01 -07:00

69 lines
1.9 KiB
Go

package block
import (
"context"
"os"
"path/filepath"
"time"
"github.com/kopia/kopia/storage/filesystem"
"github.com/kopia/kopia/storage"
)
type blockCache interface {
getBlock(ctx context.Context, cacheKey string, physicalBlockID PhysicalBlockID, offset, length int64) ([]byte, error)
putBlock(ctx context.Context, blockID PhysicalBlockID, data []byte) error
listIndexBlocks(ctx context.Context, full bool, extraTime time.Duration) ([]IndexInfo, error)
close() error
}
// CachingOptions specifies configuration of local cache.
type CachingOptions struct {
CacheDirectory string `json:"cacheDirectory,omitempty"`
MaxCacheSizeBytes int64 `json:"maxCacheSize,omitempty"`
MaxListCacheDurationSec int `json:"maxListCacheDuration,omitempty"`
IgnoreListCache bool `json:"-"`
HMACSecret []byte `json:"-"`
}
func newBlockCache(ctx context.Context, st storage.Storage, caching CachingOptions) (blockCache, error) {
if caching.MaxCacheSizeBytes == 0 || caching.CacheDirectory == "" {
return nullBlockCache{st}, nil
}
blockCacheDir := filepath.Join(caching.CacheDirectory, "blocks")
if _, err := os.Stat(blockCacheDir); os.IsNotExist(err) {
if err := os.MkdirAll(blockCacheDir, 0700); err != nil {
return nil, err
}
}
cacheStorage, err := filesystem.New(context.Background(), &filesystem.Options{
Path: blockCacheDir,
})
if err != nil {
return nil, err
}
c := &localStorageCache{
st: st,
cacheStorage: cacheStorage,
maxSizeBytes: caching.MaxCacheSizeBytes,
hmacSecret: append([]byte(nil), caching.HMACSecret...),
listCacheDuration: time.Duration(caching.MaxListCacheDurationSec) * time.Second,
closed: make(chan struct{}),
}
if caching.IgnoreListCache {
c.deleteListCache(ctx)
}
if err := c.sweepDirectory(ctx); err != nil {
return nil, err
}
go c.sweepDirectoryPeriodically(ctx)
return c, nil
}