Cache known snapshots instead of re-traversing the repository every time
This commit is contained in:
parent
c9b3eebc09
commit
a8cd74ba7e
1 changed files with 26 additions and 14 deletions
|
@ -75,7 +75,10 @@ func (cmd CmdMount) Execute(args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
root := fs.Tree{}
|
root := fs.Tree{}
|
||||||
root.Add("snapshots", &snapshots{repo})
|
root.Add("snapshots", &snapshots{
|
||||||
|
repo: repo,
|
||||||
|
knownSnapshots: make(map[string]*restic.Snapshot),
|
||||||
|
})
|
||||||
|
|
||||||
cmd.global.Printf("Now serving %s under %s\n", repo.Backend().Location(), mountpoint)
|
cmd.global.Printf("Now serving %s under %s\n", repo.Backend().Location(), mountpoint)
|
||||||
cmd.global.Printf("Don't forget to umount after quitting !\n")
|
cmd.global.Printf("Don't forget to umount after quitting !\n")
|
||||||
|
@ -96,6 +99,9 @@ var _ = fs.NodeStringLookuper(&snapshots{})
|
||||||
|
|
||||||
type snapshots struct {
|
type snapshots struct {
|
||||||
repo *repository.Repository
|
repo *repository.Repository
|
||||||
|
|
||||||
|
// snapshot timestamp -> snapshot
|
||||||
|
knownSnapshots map[string]*restic.Snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sn *snapshots) Attr(ctx context.Context, a *fuse.Attr) error {
|
func (sn *snapshots) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
|
@ -111,6 +117,7 @@ func (sn *snapshots) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
sn.knownSnapshots[snapshot.Time.Format(time.RFC3339)] = snapshot
|
||||||
ret = append(ret, fuse.Dirent{
|
ret = append(ret, fuse.Dirent{
|
||||||
Inode: binary.BigEndian.Uint64(id[:8]),
|
Inode: binary.BigEndian.Uint64(id[:8]),
|
||||||
Type: fuse.DT_Dir,
|
Type: fuse.DT_Dir,
|
||||||
|
@ -122,24 +129,29 @@ func (sn *snapshots) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sn *snapshots) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
func (sn *snapshots) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
||||||
// This is kind of lame: we reload each snapshot and check the name
|
if _, ok := sn.knownSnapshots[name]; !ok {
|
||||||
// (which is the timestamp)
|
// At least this snapshot is not cached. We use this opportunity to
|
||||||
for id := range sn.repo.List(backend.Snapshot, ctx.Done()) {
|
// load all missing snapshots
|
||||||
snapshot, err := restic.LoadSnapshot(sn.repo, id)
|
for id := range sn.repo.List(backend.Snapshot, ctx.Done()) {
|
||||||
if err != nil {
|
snapshot, err := restic.LoadSnapshot(sn.repo, id)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if snapshot.Time.Format(time.RFC3339) == name {
|
|
||||||
tree, err := restic.LoadTree(sn.repo, snapshot.Tree)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &dir{
|
snapshotName := snapshot.Time.Format(time.RFC3339)
|
||||||
repo: sn.repo,
|
sn.knownSnapshots[snapshotName] = snapshot
|
||||||
tree: tree,
|
break
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snapshot := sn.knownSnapshots[name]
|
||||||
|
tree, err := restic.LoadTree(sn.repo, snapshot.Tree)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &dir{
|
||||||
|
repo: sn.repo,
|
||||||
|
tree: tree,
|
||||||
|
}, nil
|
||||||
return nil, fuse.ENOENT
|
return nil, fuse.ENOENT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue