mirror of
https://github.com/kopia/kopia.git
synced 2026-02-02 02:33:14 -05:00
* Remove remaining internal uses of Readdir * Remove old helpers and interface functions. * Update tests for updated fs.Directory interface * Fix index out of range error in snapshot walker Record one error if an error occurred and it's not limiting errors * Use helper functions more; exit loops early Follow up on reviewer comments and reduce code duplication, use more targetted functions like Directory.Child, and exit directory iteration early if possible. * Remove fs.Entries type and unused functions Leave some functions dealing with sorting and finding entries in fs package. This retains tests for those functions while still allowing mockfs to access them. * Simplify function return
83 lines
1.7 KiB
Go
83 lines
1.7 KiB
Go
// Package cachefs implements a wrapper that caches filesystem actions.
|
|
package cachefs
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/kopia/kopia/fs"
|
|
)
|
|
|
|
// DirectoryCacher reads and potentially caches directory entries for a given directory.
|
|
type DirectoryCacher interface {
|
|
IterateEntries(ctx context.Context, d fs.Directory, w EntryWrapper, callback func(context.Context, fs.Entry) error) error
|
|
}
|
|
|
|
type cacheContext struct {
|
|
cacher DirectoryCacher
|
|
}
|
|
|
|
type directory struct {
|
|
ctx *cacheContext
|
|
fs.Directory
|
|
}
|
|
|
|
func (d *directory) Child(ctx context.Context, name string) (fs.Entry, error) {
|
|
e, err := d.Directory.Child(ctx, name)
|
|
if err != nil {
|
|
// nolint:wrapcheck
|
|
return nil, err
|
|
}
|
|
|
|
return wrapWithContext(e, d.ctx), nil
|
|
}
|
|
|
|
func (d *directory) IterateEntries(ctx context.Context, callback func(context.Context, fs.Entry) error) error {
|
|
err := d.ctx.cacher.IterateEntries(
|
|
ctx,
|
|
d.Directory,
|
|
func(e fs.Entry) fs.Entry {
|
|
return wrapWithContext(e, d.ctx)
|
|
},
|
|
callback,
|
|
)
|
|
|
|
return err // nolint:wrapcheck
|
|
}
|
|
|
|
type file struct {
|
|
ctx *cacheContext
|
|
fs.File
|
|
}
|
|
|
|
type symlink struct {
|
|
ctx *cacheContext
|
|
fs.Symlink
|
|
}
|
|
|
|
// Wrap returns an Entry that wraps another Entry and caches directory reads.
|
|
func Wrap(e fs.Entry, cacher DirectoryCacher) fs.Entry {
|
|
return wrapWithContext(e, &cacheContext{cacher})
|
|
}
|
|
|
|
func wrapWithContext(e fs.Entry, opts *cacheContext) fs.Entry {
|
|
switch e := e.(type) {
|
|
case fs.Directory:
|
|
return fs.Directory(&directory{opts, e})
|
|
|
|
case fs.File:
|
|
return fs.File(&file{opts, e})
|
|
|
|
case fs.Symlink:
|
|
return fs.Symlink(&symlink{opts, e})
|
|
|
|
default:
|
|
return e
|
|
}
|
|
}
|
|
|
|
var (
|
|
_ fs.Directory = &directory{}
|
|
_ fs.File = &file{}
|
|
_ fs.Symlink = &symlink{}
|
|
)
|