filter: Add BoundedRecursion method

This indicates that the filter set could be satisfied by a bounded
directory recursion.
This commit is contained in:
Nick Craig-Wood
2019-01-20 17:56:59 +00:00
parent bb5ac8efbe
commit 047f00a411
4 changed files with 124 additions and 8 deletions

View File

@@ -21,8 +21,9 @@ var Active = mustNewFilter(nil)
// rule is one filter rule
type rule struct {
Include bool
Regexp *regexp.Regexp
Include bool
Regexp *regexp.Regexp
boundedRecursion bool
}
// Match returns true if rule matches path
@@ -46,13 +47,14 @@ type rules struct {
}
// add adds a rule if it doesn't exist already
func (rs *rules) add(Include bool, re *regexp.Regexp) {
func (rs *rules) add(Include bool, re *regexp.Regexp, boundedRecursion bool) {
if rs.existing == nil {
rs.existing = make(map[string]struct{})
}
newRule := rule{
Include: Include,
Regexp: re,
Include: Include,
Regexp: re,
boundedRecursion: boundedRecursion,
}
newRuleString := newRule.String()
if _, ok := rs.existing[newRuleString]; ok {
@@ -73,6 +75,23 @@ func (rs *rules) len() int {
return len(rs.rules)
}
// boundedRecursion returns true if the set of filters would only
// need bounded recursion to evaluate
func (rs *rules) boundedRecursion() bool {
var (
excludeAll = false
boundedRecursion = true
)
for _, rule := range rs.rules {
if rule.Include {
boundedRecursion = boundedRecursion && rule.boundedRecursion
} else if rule.Regexp.String() == `^.*$` {
excludeAll = true
}
}
return excludeAll && boundedRecursion
}
// FilesMap describes the map of files to transfer
type FilesMap map[string]struct{}
@@ -232,7 +251,8 @@ func (f *Filter) addDirGlobs(Include bool, glob string) error {
if err != nil {
return err
}
f.dirRules.add(Include, dirRe)
boundedRecursion := globBoundedRecursion(dirGlob)
f.dirRules.add(Include, dirRe, boundedRecursion)
}
return nil
}
@@ -248,8 +268,9 @@ func (f *Filter) Add(Include bool, glob string) error {
if err != nil {
return err
}
boundedRecursion := globBoundedRecursion(glob)
if isFileRule {
f.fileRules.add(Include, re)
f.fileRules.add(Include, re, boundedRecursion)
// If include rule work out what directories are needed to scan
// if exclude rule, we can't rule anything out
// Unless it is `*` which matches everything
@@ -262,7 +283,7 @@ func (f *Filter) Add(Include bool, glob string) error {
}
}
if isDirRule {
f.dirRules.add(Include, re)
f.dirRules.add(Include, re, boundedRecursion)
}
return nil
}
@@ -343,6 +364,12 @@ func (f *Filter) InActive() bool {
len(f.Opt.ExcludeFile) == 0)
}
// BoundedRecursion returns true if the filter can be evaluated with
// bounded recursion only.
func (f *Filter) BoundedRecursion() bool {
return f.fileRules.boundedRecursion()
}
// includeRemote returns whether this remote passes the filter rules.
func (f *Filter) includeRemote(remote string) bool {
for _, rule := range f.fileRules.rules {