find: Check trees only once

This commit is contained in:
Alexander Neumann 2017-06-04 11:42:40 +02:00
parent 7b5efaf7b0
commit a90e0c6595

View file

@ -173,12 +173,18 @@ func (s *statefulOutput) Finish() {
// Finder bundles information needed to find a file or directory. // Finder bundles information needed to find a file or directory.
type Finder struct { type Finder struct {
repo restic.Repository repo restic.Repository
pat findPattern pat findPattern
out statefulOutput out statefulOutput
notfound restic.IDSet
} }
func (f *Finder) findInTree(treeID restic.ID, prefix string) error { func (f *Finder) findInTree(treeID restic.ID, prefix string) error {
if f.notfound.Has(treeID) {
debug.Log("%v skipping tree %v, has already been checked", prefix, treeID.Str())
return nil
}
debug.Log("%v checking tree %v\n", prefix, treeID.Str()) debug.Log("%v checking tree %v\n", prefix, treeID.Str())
tree, err := f.repo.LoadTree(treeID) tree, err := f.repo.LoadTree(treeID)
@ -186,6 +192,7 @@ func (f *Finder) findInTree(treeID restic.ID, prefix string) error {
return err return err
} }
var found bool
for _, node := range tree.Nodes { for _, node := range tree.Nodes {
debug.Log(" testing entry %q\n", node.Name) debug.Log(" testing entry %q\n", node.Name)
@ -211,6 +218,7 @@ func (f *Finder) findInTree(treeID restic.ID, prefix string) error {
} }
debug.Log(" found match\n") debug.Log(" found match\n")
found = true
f.out.Print(prefix, node) f.out.Print(prefix, node)
} }
@ -221,6 +229,10 @@ func (f *Finder) findInTree(treeID restic.ID, prefix string) error {
} }
} }
if !found {
f.notfound.Insert(treeID)
}
return nil return nil
} }
@ -279,9 +291,10 @@ func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
defer cancel() defer cancel()
f := &Finder{ f := &Finder{
repo: repo, repo: repo,
pat: pat, pat: pat,
out: statefulOutput{ListLong: opts.ListLong, JSON: globalOptions.JSON}, out: statefulOutput{ListLong: opts.ListLong, JSON: globalOptions.JSON},
notfound: restic.NewIDSet(),
} }
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, opts.Snapshots) { for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, opts.Snapshots) {
if err = f.findInSnapshot(sn); err != nil { if err = f.findInSnapshot(sn); err != nil {