Skip to content

Commit

Permalink
items: add chain/group items
Browse files Browse the repository at this point in the history
  • Loading branch information
msaf1980 committed Mar 11, 2023
1 parent d478428 commit bcc9ff3
Show file tree
Hide file tree
Showing 16 changed files with 1,171 additions and 404 deletions.
2 changes: 1 addition & 1 deletion glob/glob.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func Parse(glob string) (g *Glob, err error) {
inners := make([]items.Item, 0, innerCount)

for glob != "" {
inner, glob, err = NextWildcardItem(glob)
inner, glob, err = items.NextWildcardItem(glob)
if err != nil {
return
}
Expand Down
178 changes: 178 additions & 0 deletions glob/glob_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package glob

import (
"testing"

"github.com/msaf1980/go-matcher/pkg/items"
"github.com/msaf1980/go-matcher/pkg/tests"
)

func TestGlob_Group(t *testing.T) {
tests := []testGlob{
{
glob: "{b*,a?cd*,cd[a-z]}bc*c*e",
want: &Glob{
Glob: "{b*,a?cd*,cd[a-z]}bc*c*e", Node: "{a?cd*,b*,cd[a-z]}bc*c*e",
Suffix: "e", MinLen: 5, MaxLen: -1,
Items: []items.Item{
&items.Group{
MinSize: 1, MaxSize: -1,
Vals: []items.Item{
&items.Chain{
Items: []items.Item{
items.Byte('a'), items.Any(1), items.NewString("cd"), items.Star(0),
},
MinSize: 4, MaxSize: -1,
},
&items.Chain{
Items: []items.Item{items.Byte('b'), items.Star(0)}, MinSize: 1, MaxSize: -1,
},
&items.Chain{
Items: []items.Item{items.NewString("cd"), items.NewRunesRanges("[a-z]")},
MinSize: 3, MaxSize: 3,
},
},
},
items.NewString("bc"), items.Star(0), items.Byte('c'), items.Star(0),
},
},
match: []string{"aZcdbcce", "aZcdQAbcZWcIe", "cdqbcZcIe", "bCDbcZIce"},
miss: []string{"", "aZcdbcc", "aZcdcce", "aZcdQAbcZWIe"},
},
{
glob: "?*{b*,a?cd*,cd[a-z]}bc*c*e",
want: &Glob{
Glob: "?*{b*,a?cd*,cd[a-z]}bc*c*e", Node: "*?{a?cd*,b*,cd[a-z]}bc*c*e",
Suffix: "e", MinLen: 6, MaxLen: -1,
Items: []items.Item{
items.Star(1),
&items.Group{
MinSize: 1, MaxSize: -1,
Vals: []items.Item{
&items.Chain{
Items: []items.Item{
items.Byte('a'), items.Any(1), items.NewString("cd"), items.Star(0),
},
MinSize: 4, MaxSize: -1,
},
&items.Chain{
Items: []items.Item{items.Byte('b'), items.Star(0)}, MinSize: 1, MaxSize: -1,
},
&items.Chain{
Items: []items.Item{items.NewString("cd"), items.NewRunesRanges("[a-z]")},
MinSize: 3, MaxSize: 3,
},
},
},
items.NewString("bc"), items.Star(0), items.Byte('c'), items.Star(0),
},
},
match: []string{"ZaZcdbcce", "ЙaЮcdQAbcZWcIe", "ЙacdqbcZcIe", "ЙabCDbcZIce"},
miss: []string{"", "aЯcdbcce", "aZcdQAbcZWcIe", "aZcdbcc", "aZcdcce", "aZcdQAbcZWIe"},
},
{
glob: "?*{b*,a?cd*,cd[a-z]}bc*c*e",
want: &Glob{
Glob: "?*{b*,a?cd*,cd[a-z]}bc*c*e", Node: "*?{a?cd*,b*,cd[a-z]}bc*c*e",
Suffix: "e", MinLen: 6, MaxLen: -1,
Items: []items.Item{
items.Star(1),
&items.Group{
MinSize: 1, MaxSize: -1,
Vals: []items.Item{
&items.Chain{
Items: []items.Item{
items.Byte('a'), items.Any(1), items.NewString("cd"), items.Star(0),
},
MinSize: 4, MaxSize: -1,
},
&items.Chain{
Items: []items.Item{items.Byte('b'), items.Star(0)}, MinSize: 1, MaxSize: -1,
},
&items.Chain{
Items: []items.Item{items.NewString("cd"), items.NewRunesRanges("[a-z]")},
MinSize: 3, MaxSize: 3,
},
},
},
items.NewString("bc"), items.Star(0), items.Byte('c'), items.Star(0),
},
},
match: []string{"ZaZcdbcce", "ЙaЮcdQAbcZWcIe", "ЙacdqbcZcIe", "ЙabCDbcZIce"},
miss: []string{"", "aЯcdbcce", "aZcdQAbcZWcIe", "aZcdbcc", "aZcdcce", "aZcdQAbcZWIe"},
},
}
for n, tt := range tests {
runTestGlob(t, n, tt)
}
}

// becnmark for group
var (
globGroup = "{b*,a?cd*,cd[a-z]}bc*c*e"
stringGroup = "cdqbcZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZcIe"
)

func Benchmark_Group(b *testing.B) {
for i := 0; i < b.N; i++ {
g := ParseMust(globGroup)
if !g.Match(stringGroup) {
b.Fatal(stringGroup)
}
}
}

func Benchmark_Group_Regex(b *testing.B) {
for i := 0; i < b.N; i++ {
w := tests.BuildGlobRegexp(globGroup)
if !w.MatchString(stringGroup) {
b.Fatal(stringGroup)
}
}
}

func Benchmark_Group_Precompiled(b *testing.B) {
g := ParseMust(globGroup)

b.ResetTimer()
for i := 0; i < b.N; i++ {
if !g.Match(stringGroup) {
b.Fatal(stringGroup)
}
}
}

// becnmark for group after star
var (
globStarGroup = "*{b*,a?cd*,cd[a-z]}bc*c*e"
stringStarGroup = "ZZZZZZZZcZZZZZZZZZZZZcdqbcZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZcIe"
)

func Benchmark_Star_Group(b *testing.B) {
for i := 0; i < b.N; i++ {
g := ParseMust(globStarGroup)
if !g.Match(stringStarGroup) {
b.Fatal(stringStarGroup)
}
}
}

func Benchmark_Star_Group_Regex(b *testing.B) {
for i := 0; i < b.N; i++ {
w := tests.BuildGlobRegexp(globStarGroup)
if !w.MatchString(stringStarGroup) {
b.Fatal(stringStarGroup)
}
}
}

func Benchmark_Star_Group_Precompiled(b *testing.B) {
g := ParseMust(globStarGroup)

b.ResetTimer()
for i := 0; i < b.N; i++ {
if !g.Match(stringStarGroup) {
b.Fatal(stringStarGroup)
}
}
}
1 change: 1 addition & 0 deletions glob/glob_stringlist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ func TestGlob_List_Broken(t *testing.T) {
// broken
{glob: "{ac", wantErr: true},
{glob: "a}c", wantErr: true},
{glob: "{b*,a?cd*,cda-z]}bc*c*e", wantErr: true},
// skip empty
{
glob: "{}a",
Expand Down
2 changes: 1 addition & 1 deletion glob/tree_batch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func TestGlobTree_Batch(t *testing.T) {
"*{b,cd}*.df", "*{b,cd}*.df", "bc.{,b,cd}*.df", "bc.{,b,cd}*.df",
"bc.*{,b,cd}", "bc.*{,b,cd}*", "bc.*{,b,cd}*",
},
"bc.": {"bc.{,b,cd}", "bc.{,b,cd}", "bc.*{,b,cd}", "bc.*{,b,cd}*"},
"bc.": {"bc.{,b,cd}", "bc.*{,b,cd}", "bc.*{,b,cd}*"},
"bcd": nil,
},
},
Expand Down
154 changes: 154 additions & 0 deletions glob/tree_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package glob

import (
"testing"
)

func TestGlobTree_Group(t *testing.T) {
tests := []testGlobTree{
{
globs: []string{
"{b*,a?cd*,cd[a-z]}bc*c*e",
"{b*,a?cd*,cd[a-z]}bc*CD*e",
},
want: &globTreeStr{
Root: &TreeItemStr{
Childs: []*TreeItemStr{
{
Node: "e", Reverse: true, Childs: []*TreeItemStr{
{
Node: "{a?cd*,b*,cd[a-z]}", Childs: []*TreeItemStr{
{
Node: "bc", Childs: []*TreeItemStr{
{
Node: "*", Childs: []*TreeItemStr{
{
Node: "c", Childs: []*TreeItemStr{
{
Node: "*", Childs: []*TreeItemStr{},
Terminated: "{a?cd*,b*,cd[a-z]}bc*c*e",
TermIndex: 0, Term: true,
},
},
},
{
Node: "CD", Childs: []*TreeItemStr{
{
Node: "*", Childs: []*TreeItemStr{},
Terminated: "{a?cd*,b*,cd[a-z]}bc*CD*e",
TermIndex: 1, Term: true,
},
},
},
},
},
},
},
},
},
},
},
},
},
Globs: map[string]int{
"{a?cd*,b*,cd[a-z]}bc*c*e": 0, "{b*,a?cd*,cd[a-z]}bc*c*e": 0,
"{a?cd*,b*,cd[a-z]}bc*CD*e": 1, "{b*,a?cd*,cd[a-z]}bc*CD*e": 1,
},
GlobsIndex: map[int]string{0: "{a?cd*,b*,cd[a-z]}bc*c*e", 1: "{a?cd*,b*,cd[a-z]}bc*CD*e"},
},
match: map[string][]string{
"aZcdbcce": {"{a?cd*,b*,cd[a-z]}bc*c*e"},
"aЯcdbcce": {"{a?cd*,b*,cd[a-z]}bc*c*e"},
"aЮcdQAbcZWcIe": {"{a?cd*,b*,cd[a-z]}bc*c*e"},
"aZcdQAbcZWcIe": {"{a?cd*,b*,cd[a-z]}bc*c*e"},
"": nil, "acdqbcZcIe": nil, "abCDbcZIce": nil,
"ЙabCDbcZIce": nil, "aZcdbcc": nil, "aZcdcce": nil, "aZcdQAbcZWIe": nil,
},
},
{
globs: []string{
"*{b*,a?cd*,cd[a-z]}bc*c*e",
"*{b*,a?cd*,cd[a-z]}bc*CD*e",
"*{b*,a?cd*,cd[a-z]}bc*cd*e",
},
want: &globTreeStr{
Root: &TreeItemStr{
Childs: []*TreeItemStr{
{
Node: "e", Reverse: true, Childs: []*TreeItemStr{
{
Node: "*", Childs: []*TreeItemStr{
{
Node: "{a?cd*,b*,cd[a-z]}", Childs: []*TreeItemStr{
{
Node: "bc", Childs: []*TreeItemStr{
{
Node: "*", Childs: []*TreeItemStr{
{
Node: "c", Childs: []*TreeItemStr{
{
Node: "*", Childs: []*TreeItemStr{},
Terminated: "*{a?cd*,b*,cd[a-z]}bc*c*e",
TermIndex: 0, Term: true,
},
},
},
{
Node: "CD", Childs: []*TreeItemStr{
{
Node: "*", Childs: []*TreeItemStr{},
Terminated: "*{a?cd*,b*,cd[a-z]}bc*CD*e",
TermIndex: 1, Term: true,
},
},
},
{
Node: "cd", Childs: []*TreeItemStr{
{
Node: "*", Childs: []*TreeItemStr{},
Terminated: "*{a?cd*,b*,cd[a-z]}bc*cd*e",
TermIndex: 2, Term: true,
},
},
},
},
},
},
},
},
},
},
},
},
},
},
},
Globs: map[string]int{
"*{a?cd*,b*,cd[a-z]}bc*c*e": 0, "*{b*,a?cd*,cd[a-z]}bc*c*e": 0,
"*{a?cd*,b*,cd[a-z]}bc*CD*e": 1, "*{b*,a?cd*,cd[a-z]}bc*CD*e": 1,
"*{a?cd*,b*,cd[a-z]}bc*cd*e": 2, "*{b*,a?cd*,cd[a-z]}bc*cd*e": 2,
},
GlobsIndex: map[int]string{
0: "*{a?cd*,b*,cd[a-z]}bc*c*e", 1: "*{a?cd*,b*,cd[a-z]}bc*CD*e",
2: "*{a?cd*,b*,cd[a-z]}bc*cd*e",
},
},
match: map[string][]string{
"aZcdbcce": {"*{a?cd*,b*,cd[a-z]}bc*c*e"},
"aЯcdbcce": {"*{a?cd*,b*,cd[a-z]}bc*c*e"},
"aЮcdQAbcZWcIe": {"*{a?cd*,b*,cd[a-z]}bc*c*e"},
"aZcdQAbcZWcIe": {"*{a?cd*,b*,cd[a-z]}bc*c*e"},
"abCDbcZIce": {"*{a?cd*,b*,cd[a-z]}bc*c*e"},
"ЙabCDbcZIce": {"*{a?cd*,b*,cd[a-z]}bc*c*e"},
"acdqbcZcIe": {"*{a?cd*,b*,cd[a-z]}bc*c*e"},
"acdqbcZCDIe": {"*{a?cd*,b*,cd[a-z]}bc*CD*e"},
"acdqbcZcdIe": {"*{a?cd*,b*,cd[a-z]}bc*c*e", "*{a?cd*,b*,cd[a-z]}bc*cd*e"},
"": nil,
"aZcdbcc": nil, "aZcdcce": nil, "aZcdQAbcZWIe": nil,
},
},
}
for n, tt := range tests {
runTestGlobTree(t, n, tt)
}
}
Loading

0 comments on commit bcc9ff3

Please sign in to comment.