mirror of
https://github.com/octoleo/restic.git
synced 2025-01-11 02:08:44 +00:00
Merge pull request #2616 from greatroar/no-cache-interface
Remove practically unused cache interface
This commit is contained in:
commit
4dcd6abf37
12
internal/cache/backend.go
vendored
12
internal/cache/backend.go
vendored
@ -40,7 +40,7 @@ func (b *Backend) Remove(ctx context.Context, h restic.Handle) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.Cache.Remove(h)
|
return b.Cache.remove(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
var autoCacheTypes = map[restic.FileType]struct{}{
|
var autoCacheTypes = map[restic.FileType]struct{}{
|
||||||
@ -77,7 +77,7 @@ func (b *Backend) Save(ctx context.Context, h restic.Handle, rd restic.RewindRea
|
|||||||
err = b.Cache.Save(h, rd)
|
err = b.Cache.Save(h, rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Log("unable to save %v to cache: %v", h, err)
|
debug.Log("unable to save %v to cache: %v", h, err)
|
||||||
_ = b.Cache.Remove(h)
|
_ = b.Cache.remove(h)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ func (b *Backend) cacheFile(ctx context.Context, h restic.Handle) error {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// try to remove from the cache, ignore errors
|
// try to remove from the cache, ignore errors
|
||||||
_ = b.Cache.Remove(h)
|
_ = b.Cache.remove(h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ func (b *Backend) cacheFile(ctx context.Context, h restic.Handle) error {
|
|||||||
// loadFromCacheOrDelegate will try to load the file from the cache, and fall
|
// loadFromCacheOrDelegate will try to load the file from the cache, and fall
|
||||||
// back to the backend if that fails.
|
// back to the backend if that fails.
|
||||||
func (b *Backend) loadFromCacheOrDelegate(ctx context.Context, h restic.Handle, length int, offset int64, consumer func(rd io.Reader) error) error {
|
func (b *Backend) loadFromCacheOrDelegate(ctx context.Context, h restic.Handle, length int, offset int64, consumer func(rd io.Reader) error) error {
|
||||||
rd, err := b.Cache.Load(h, length, offset)
|
rd, err := b.Cache.load(h, length, offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Log("error caching %v: %v, falling back to backend", h, err)
|
debug.Log("error caching %v: %v, falling back to backend", h, err)
|
||||||
return b.Backend.Load(ctx, h, length, offset, consumer)
|
return b.Backend.Load(ctx, h, length, offset, consumer)
|
||||||
@ -162,7 +162,7 @@ func (b *Backend) Load(ctx context.Context, h restic.Handle, length int, offset
|
|||||||
|
|
||||||
if b.Cache.Has(h) {
|
if b.Cache.Has(h) {
|
||||||
debug.Log("Load(%v, %v, %v) from cache", h, length, offset)
|
debug.Log("Load(%v, %v, %v) from cache", h, length, offset)
|
||||||
rd, err := b.Cache.Load(h, length, offset)
|
rd, err := b.Cache.load(h, length, offset)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = consumer(rd)
|
err = consumer(rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -216,7 +216,7 @@ func (b *Backend) Stat(ctx context.Context, h restic.Handle) (restic.FileInfo, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
if b.Backend.IsNotExist(err) {
|
if b.Backend.IsNotExist(err) {
|
||||||
// try to remove from the cache, ignore errors
|
// try to remove from the cache, ignore errors
|
||||||
_ = b.Cache.Remove(h)
|
_ = b.Cache.remove(h)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fi, err
|
return fi, err
|
||||||
|
23
internal/cache/cache.go
vendored
23
internal/cache/cache.go
vendored
@ -17,7 +17,7 @@ import (
|
|||||||
|
|
||||||
// Cache manages a local cache.
|
// Cache manages a local cache.
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
Path string
|
path string
|
||||||
Base string
|
Base string
|
||||||
Created bool
|
Created bool
|
||||||
PerformReadahead func(restic.Handle) bool
|
PerformReadahead func(restic.Handle) bool
|
||||||
@ -46,9 +46,6 @@ func readVersion(dir string) (v uint, err error) {
|
|||||||
|
|
||||||
const cacheVersion = 1
|
const cacheVersion = 1
|
||||||
|
|
||||||
// ensure Cache implements restic.Cache
|
|
||||||
var _ restic.Cache = &Cache{}
|
|
||||||
|
|
||||||
var cacheLayoutPaths = map[restic.FileType]string{
|
var cacheLayoutPaths = map[restic.FileType]string{
|
||||||
restic.PackFile: "data",
|
restic.PackFile: "data",
|
||||||
restic.SnapshotFile: "snapshots",
|
restic.SnapshotFile: "snapshots",
|
||||||
@ -151,7 +148,7 @@ func New(id string, basedir string) (c *Cache, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c = &Cache{
|
c = &Cache{
|
||||||
Path: cachedir,
|
path: cachedir,
|
||||||
Base: basedir,
|
Base: basedir,
|
||||||
Created: created,
|
Created: created,
|
||||||
PerformReadahead: func(restic.Handle) bool {
|
PerformReadahead: func(restic.Handle) bool {
|
||||||
@ -253,22 +250,6 @@ func IsOld(t time.Time, maxAge time.Duration) bool {
|
|||||||
return t.Before(oldest)
|
return t.Before(oldest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// errNoSuchFile is returned when a file is not cached.
|
|
||||||
type errNoSuchFile struct {
|
|
||||||
Type string
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e errNoSuchFile) Error() string {
|
|
||||||
return fmt.Sprintf("file %v (%v) is not cached", e.Name, e.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsNotExist returns true if the error was caused by a non-existing file.
|
|
||||||
func (c *Cache) IsNotExist(err error) bool {
|
|
||||||
_, ok := errors.Cause(err).(errNoSuchFile)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap returns a backend with a cache.
|
// Wrap returns a backend with a cache.
|
||||||
func (c *Cache) Wrap(be restic.Backend) restic.Backend {
|
func (c *Cache) Wrap(be restic.Backend) restic.Backend {
|
||||||
return newBackend(be, c)
|
return newBackend(be, c)
|
||||||
|
22
internal/cache/file.go
vendored
22
internal/cache/file.go
vendored
@ -17,7 +17,7 @@ func (c *Cache) filename(h restic.Handle) string {
|
|||||||
panic("Name is empty or too short")
|
panic("Name is empty or too short")
|
||||||
}
|
}
|
||||||
subdir := h.Name[:2]
|
subdir := h.Name[:2]
|
||||||
return filepath.Join(c.Path, cacheLayoutPaths[h.Type], subdir, h.Name)
|
return filepath.Join(c.path, cacheLayoutPaths[h.Type], subdir, h.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) canBeCached(t restic.FileType) bool {
|
func (c *Cache) canBeCached(t restic.FileType) bool {
|
||||||
@ -40,7 +40,7 @@ type readCloser struct {
|
|||||||
// Load returns a reader that yields the contents of the file with the
|
// Load returns a reader that yields the contents of the file with the
|
||||||
// given handle. rd must be closed after use. If an error is returned, the
|
// given handle. rd must be closed after use. If an error is returned, the
|
||||||
// ReadCloser is nil.
|
// ReadCloser is nil.
|
||||||
func (c *Cache) Load(h restic.Handle, length int, offset int64) (io.ReadCloser, error) {
|
func (c *Cache) load(h restic.Handle, length int, offset int64) (io.ReadCloser, error) {
|
||||||
debug.Log("Load from cache: %v", h)
|
debug.Log("Load from cache: %v", h)
|
||||||
if !c.canBeCached(h.Type) {
|
if !c.canBeCached(h.Type) {
|
||||||
return nil, errors.New("cannot be cached")
|
return nil, errors.New("cannot be cached")
|
||||||
@ -59,13 +59,13 @@ func (c *Cache) Load(h restic.Handle, length int, offset int64) (io.ReadCloser,
|
|||||||
|
|
||||||
if fi.Size() <= crypto.Extension {
|
if fi.Size() <= crypto.Extension {
|
||||||
_ = f.Close()
|
_ = f.Close()
|
||||||
_ = c.Remove(h)
|
_ = c.remove(h)
|
||||||
return nil, errors.Errorf("cached file %v is truncated, removing", h)
|
return nil, errors.Errorf("cached file %v is truncated, removing", h)
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.Size() < offset+int64(length) {
|
if fi.Size() < offset+int64(length) {
|
||||||
_ = f.Close()
|
_ = f.Close()
|
||||||
_ = c.Remove(h)
|
_ = c.remove(h)
|
||||||
return nil, errors.Errorf("cached file %v is too small, removing", h)
|
return nil, errors.Errorf("cached file %v is too small, removing", h)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ func (c *Cache) Load(h restic.Handle, length int, offset int64) (io.ReadCloser,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SaveWriter returns a writer for the cache object h. It must be closed after writing is finished.
|
// SaveWriter returns a writer for the cache object h. It must be closed after writing is finished.
|
||||||
func (c *Cache) SaveWriter(h restic.Handle) (io.WriteCloser, error) {
|
func (c *Cache) saveWriter(h restic.Handle) (io.WriteCloser, error) {
|
||||||
debug.Log("Save to cache: %v", h)
|
debug.Log("Save to cache: %v", h)
|
||||||
if !c.canBeCached(h.Type) {
|
if !c.canBeCached(h.Type) {
|
||||||
return nil, errors.New("cannot be cached")
|
return nil, errors.New("cannot be cached")
|
||||||
@ -112,7 +112,7 @@ func (c *Cache) Save(h restic.Handle, rd io.Reader) error {
|
|||||||
return errors.New("Save() called with nil reader")
|
return errors.New("Save() called with nil reader")
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := c.SaveWriter(h)
|
f, err := c.saveWriter(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -120,19 +120,19 @@ func (c *Cache) Save(h restic.Handle, rd io.Reader) error {
|
|||||||
n, err := io.Copy(f, rd)
|
n, err := io.Copy(f, rd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = f.Close()
|
_ = f.Close()
|
||||||
_ = c.Remove(h)
|
_ = c.remove(h)
|
||||||
return errors.Wrap(err, "Copy")
|
return errors.Wrap(err, "Copy")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n <= crypto.Extension {
|
if n <= crypto.Extension {
|
||||||
_ = f.Close()
|
_ = f.Close()
|
||||||
_ = c.Remove(h)
|
_ = c.remove(h)
|
||||||
debug.Log("trying to cache truncated file %v, removing", h)
|
debug.Log("trying to cache truncated file %v, removing", h)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = f.Close(); err != nil {
|
if err = f.Close(); err != nil {
|
||||||
_ = c.Remove(h)
|
_ = c.remove(h)
|
||||||
return errors.Wrap(err, "Close")
|
return errors.Wrap(err, "Close")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ func (c *Cache) Save(h restic.Handle, rd io.Reader) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove deletes a file. When the file is not cache, no error is returned.
|
// Remove deletes a file. When the file is not cache, no error is returned.
|
||||||
func (c *Cache) Remove(h restic.Handle) error {
|
func (c *Cache) remove(h restic.Handle) error {
|
||||||
if !c.Has(h) {
|
if !c.Has(h) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ func (c *Cache) list(t restic.FileType) (restic.IDSet, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
list := restic.NewIDSet()
|
list := restic.NewIDSet()
|
||||||
dir := filepath.Join(c.Path, cacheLayoutPaths[t])
|
dir := filepath.Join(c.path, cacheLayoutPaths[t])
|
||||||
err := filepath.Walk(dir, func(name string, fi os.FileInfo, err error) error {
|
err := filepath.Walk(dir, func(name string, fi os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "Walk")
|
return errors.Wrap(err, "Walk")
|
||||||
|
10
internal/cache/file_test.go
vendored
10
internal/cache/file_test.go
vendored
@ -42,13 +42,13 @@ func randomID(s restic.IDSet) restic.ID {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func load(t testing.TB, c *Cache, h restic.Handle) []byte {
|
func load(t testing.TB, c *Cache, h restic.Handle) []byte {
|
||||||
rd, err := c.Load(h, 0, 0)
|
rd, err := c.load(h, 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rd == nil {
|
if rd == nil {
|
||||||
t.Fatalf("Load() returned nil reader")
|
t.Fatalf("load() returned nil reader")
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := ioutil.ReadAll(rd)
|
buf, err := ioutil.ReadAll(rd)
|
||||||
@ -148,7 +148,7 @@ func TestFileSaveWriter(t *testing.T) {
|
|||||||
Name: id.String(),
|
Name: id.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
wr, err := c.SaveWriter(h)
|
wr, err := c.saveWriter(h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ func TestFileSaveWriter(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rd, err := c.Load(h, 0, 0)
|
rd, err := c.load(h, 0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -223,7 +223,7 @@ func TestFileLoad(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(fmt.Sprintf("%v/%v", test.length, test.offset), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%v/%v", test.length, test.offset), func(t *testing.T) {
|
||||||
rd, err := c.Load(h, test.length, test.offset)
|
rd, err := c.load(h, test.length, test.offset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,8 @@ type Repository struct {
|
|||||||
key *crypto.Key
|
key *crypto.Key
|
||||||
keyName string
|
keyName string
|
||||||
idx *MasterIndex
|
idx *MasterIndex
|
||||||
restic.Cache
|
Cache *cache.Cache
|
||||||
|
|
||||||
noAutoIndexUpdate bool
|
noAutoIndexUpdate bool
|
||||||
|
|
||||||
treePM *packerManager
|
treePM *packerManager
|
||||||
@ -59,7 +60,7 @@ func (r *Repository) Config() restic.Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UseCache replaces the backend with the wrapped cache.
|
// UseCache replaces the backend with the wrapped cache.
|
||||||
func (r *Repository) UseCache(c restic.Cache) {
|
func (r *Repository) UseCache(c *cache.Cache) {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -552,7 +553,7 @@ func (r *Repository) PrepareCache(indexIDs restic.IDSet) error {
|
|||||||
|
|
||||||
// use readahead
|
// use readahead
|
||||||
debug.Log("using readahead")
|
debug.Log("using readahead")
|
||||||
cache := r.Cache.(*cache.Cache)
|
cache := r.Cache
|
||||||
cache.PerformReadahead = func(h restic.Handle) bool {
|
cache.PerformReadahead = func(h restic.Handle) bool {
|
||||||
if h.Type != restic.PackFile {
|
if h.Type != restic.PackFile {
|
||||||
debug.Log("no readahead for %v, is not a pack file", h)
|
debug.Log("no readahead for %v, is not a pack file", h)
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
package restic
|
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
// Cache manages a local cache.
|
|
||||||
type Cache interface {
|
|
||||||
// BaseDir returns the base directory of the cache.
|
|
||||||
BaseDir() string
|
|
||||||
|
|
||||||
// Wrap returns a backend with a cache.
|
|
||||||
Wrap(Backend) Backend
|
|
||||||
|
|
||||||
// IsNotExist returns true if the error was caused by a non-existing file.
|
|
||||||
IsNotExist(err error) bool
|
|
||||||
|
|
||||||
// Load returns a reader that yields the contents of the file with the
|
|
||||||
// given id if it is cached. rd must be closed after use. If an error is
|
|
||||||
// returned, the ReadCloser is nil. The files are still encrypted
|
|
||||||
Load(h Handle, length int, offset int64) (io.ReadCloser, error)
|
|
||||||
|
|
||||||
// SaveIndex saves an index in the cache.
|
|
||||||
Save(Handle, io.Reader) error
|
|
||||||
|
|
||||||
// SaveWriter returns a writer for the to be cached object h. It must be
|
|
||||||
// closed after writing is finished.
|
|
||||||
SaveWriter(Handle) (io.WriteCloser, error)
|
|
||||||
|
|
||||||
// Remove deletes a single file from the cache. If it isn't cached, this
|
|
||||||
// functions must return no error.
|
|
||||||
Remove(Handle) error
|
|
||||||
|
|
||||||
// Clear removes all files of type t from the cache that are not contained in the set.
|
|
||||||
Clear(FileType, IDSet) error
|
|
||||||
|
|
||||||
// Has returns true if the file is cached.
|
|
||||||
Has(Handle) bool
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user