mirror of
https://github.com/kopia/kopia.git
synced 2026-01-27 07:48:06 -05:00
69 lines
1.9 KiB
Go
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
|
|
}
|