2
2
mirror of https://github.com/octoleo/restic.git synced 2024-06-04 01:50:48 +00:00

Remove combined include/exclude filters

This commit is contained in:
Alexander Neumann 2015-07-19 22:26:01 +02:00
parent b425ea19e5
commit 0d8bad273d
2 changed files with 15 additions and 198 deletions

View File

@ -106,79 +106,3 @@ func MatchList(patterns []string, str string) (matched bool, err error) {
return false, nil
}
// matchList returns true if str matches one of the patterns.
func matchList(patterns [][]string, str []string) (matched bool, err error) {
for _, pat := range patterns {
matched, err = match(pat, str)
if err != nil {
return false, err
}
if matched {
return true, nil
}
}
return false, nil
}
// Filter contains include and exclude patterns. If both lists of patterns are
// empty, all files are accepted.
type Filter struct {
include, exclude [][]string
}
// New returns a new filter with the given include/exclude lists of patterns.
func New(include, exclude []string) *Filter {
f := &Filter{}
for _, pat := range include {
f.include = append(f.include, strings.Split(pat, string(filepath.Separator)))
}
for _, pat := range exclude {
f.exclude = append(f.exclude, strings.Split(pat, string(filepath.Separator)))
}
return f
}
// Match tests a filename against the filter. If include and exclude patterns
// are both empty, true is returned.
//
// If only include patterns and no exclude patterns are configured, true is
// returned iff name matches one of the include patterns.
//
// If only exclude patterns and no include patterns are configured, true is
// returned iff name does not match all of the exclude patterns.
func (f Filter) Match(name string) (matched bool, err error) {
if name == "" {
return false, ErrBadString
}
if len(f.include) == 0 && len(f.exclude) == 0 {
return true, nil
}
names := strings.Split(name, string(filepath.Separator))
if len(f.exclude) == 0 {
return matchList(f.include, names)
}
if len(f.include) == 0 {
match, err := matchList(f.exclude, names)
return !match, err
}
excluded, err := matchList(f.exclude, names)
if err != nil {
return false, err
}
if !excluded {
return true, nil
}
return matchList(f.include, names)
}

View File

@ -222,138 +222,31 @@ func BenchmarkFilterLines(b *testing.B) {
}
}
func BenchmarkFilterSingle(b *testing.B) {
pattern := "sdk/*/cpp/*/*vars.html"
line := "/usr/share/doc/libreoffice/sdk/docs/cpp/ref/a00517.html"
func BenchmarkFilterPatterns(b *testing.B) {
patterns := []string{
"sdk/*",
"*.html",
}
lines := extractTestLines(b)
var c uint
b.ResetTimer()
for i := 0; i < b.N; i++ {
filter.Match(pattern, line)
}
}
type test struct {
path string
match bool
}
var filterTests = []struct {
include, exclude []string
tests []test
}{
{
[]string{"*.go", "/home/user"},
[]string{},
[]test{
{"/home/user/foo/test.c", true},
{"/home/user/foo/test.go", true},
{"/home/foo/test.go", true},
{"/home/foo/test.doc", false},
{"/x", false},
{"main.go", true},
},
},
{
nil,
[]string{"*.docx", "*.xlsx"},
[]test{
{"/home/user/foo/test.c", true},
{"/home/user/foo/test.docx", false},
{"/home/foo/test.xlsx", false},
{"/home/foo/test.doc", true},
{"/x", true},
{"main.go", true},
},
},
{
[]string{"accounting.*", "*Partner*"},
[]string{"*.docx", "*.xlsx"},
[]test{
{"/home/user/foo/test.c", true},
{"/home/user/Partner/test.docx", true},
{"/home/user/bar/test.docx", false},
{"/home/user/test.xlsx", false},
{"/home/foo/test.doc", true},
{"/x", true},
{"main.go", true},
{"/users/A/accounting.xlsx", true},
{"/users/A/Calculation Partner.xlsx", true},
},
},
{
[]string{"accounting.*", "*Partner*", "user/**/important*"},
[]string{"*.docx", "*.xlsx", "user/**/*hidden*"},
[]test{
{"/home/user/foo/test.c", true},
{"/home/user/Partner/test.docx", true},
{"/home/user/bar/test.docx", false},
{"/home/user/test.xlsx", false},
{"/home/foo/test.doc", true},
{"/x", true},
{"main.go", true},
{"/users/A/accounting.xlsx", true},
{"/users/A/Calculation Partner.xlsx", true},
{"/home/user/work/shared/test/important Calculations/help.txt", true},
{"/home/user/work/shared/test/important.xlsx", true},
{"/home/user/work/x/y/hidden/x", false},
},
},
}
func TestFilter(t *testing.T) {
for i, test := range filterTests {
f := filter.New(test.include, test.exclude)
for _, testfile := range test.tests {
matched, err := f.Match(testfile.path)
c = 0
for _, line := range lines {
match, err := filter.MatchList(patterns, line)
if err != nil {
t.Error(err)
b.Fatal(err)
}
if matched != testfile.match {
t.Errorf("test %d: filter.Match(%q): expected %v, got %v",
i, testfile.path, testfile.match, matched)
if match {
c++
}
}
}
}
func BenchmarkFilter(b *testing.B) {
lines := extractTestLines(b)
f := filter.New([]string{"sdk", "*.html"}, []string{"*.png"})
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, line := range lines {
f.Match(line)
}
}
}
func BenchmarkFilterInclude(b *testing.B) {
lines := extractTestLines(b)
f := filter.New([]string{"sdk", "*.html"}, nil)
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, line := range lines {
f.Match(line)
}
}
}
func BenchmarkFilterExclude(b *testing.B) {
lines := extractTestLines(b)
f := filter.New(nil, []string{"*.png"})
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, line := range lines {
f.Match(line)
if c != 22185 {
b.Fatalf("wrong number of matches: expected 22185, got %d", c)
}
}
}