From 7a468d1226cf098f273fa9d4b4a7b5f8ee77562c Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Sat, 11 Aug 2018 16:18:09 -0600 Subject: [PATCH] Speed up nonrecursive queries; include exact filter match --- cmd/restic/cmd_ls.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/cmd/restic/cmd_ls.go b/cmd/restic/cmd_ls.go index 281763433..bca2275b3 100644 --- a/cmd/restic/cmd_ls.go +++ b/cmd/restic/cmd_ls.go @@ -104,8 +104,20 @@ func runLs(opts LsOptions, gopts GlobalOptions, args []string) error { // are not in matching trees or will not lead us to matching trees var walk bool for _, dir := range dirs { - if fs.HasPathPrefix(nodepath, dir) || fs.HasPathPrefix(dir, nodepath) { - // we are either in or approaching the right tree + approachingMatchingTree := fs.HasPathPrefix(nodepath, dir) + inMatchingTree := fs.HasPathPrefix(dir, nodepath) + + // this condition is complex, but it basically requires that we + // are either approaching a matching tree (not yet deep enough) + // or: if recursive, we have entered a matching tree; if non- + // recursive, then that we are at exactly the right depth + // (we can do the walk correctly by just using the condition of + // "approachingMatchingTree || inMatchingTree", but it will be + // much slower for non-recursive queries since it will continue + // to traverse subtrees that are too deep and won't match -- this + // extra check allows us to return SkipNode if we've gone TOO deep, + // which skips all its subfolders) + if approachingMatchingTree || opts.Recursive || (inMatchingTree && dir == path.Dir(nodepath)) { walk = true break } @@ -118,6 +130,15 @@ func runLs(opts LsOptions, gopts GlobalOptions, args []string) error { // according to the filter and whether we should match subfolders var match bool for _, dir := range dirs { + if nodepath == dir { + // special case: match the directory filter exactly, + // which may or may not be desirable depending on your + // use case (for example, this is unnecessary when + // wanting to simply list the contents of a folder, + // rather than all files matching a directory prefix) + match = true + break + } if opts.Recursive && fs.HasPathPrefix(dir, nodepath) { match = true break