forked from mirror/glob
Optimize compilation
This commit is contained in:
parent
ed79d1d679
commit
b3ce5dedcb
60
compiler.go
60
compiler.go
|
@ -89,11 +89,8 @@ func glueMatchers(matchers []match.Matcher) match.Matcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
func glueAsRow(matchers []match.Matcher) match.Matcher {
|
func glueAsRow(matchers []match.Matcher) match.Matcher {
|
||||||
switch len(matchers) {
|
if len(matchers) <= 1 {
|
||||||
case 0:
|
|
||||||
return nil
|
return nil
|
||||||
case 1:
|
|
||||||
return matchers[0]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
row := match.Row{}
|
row := match.Row{}
|
||||||
|
@ -108,11 +105,8 @@ func glueAsRow(matchers []match.Matcher) match.Matcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
func glueAsEvery(matchers []match.Matcher) match.Matcher {
|
func glueAsEvery(matchers []match.Matcher) match.Matcher {
|
||||||
switch len(matchers) {
|
if len(matchers) <= 1 {
|
||||||
case 0:
|
|
||||||
return nil
|
return nil
|
||||||
case 1:
|
|
||||||
return matchers[0]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -193,25 +187,37 @@ func glueAsEvery(matchers []match.Matcher) match.Matcher {
|
||||||
return every
|
return every
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertMatchers(matchers []match.Matcher, result []match.Matcher) []match.Matcher {
|
func convertMatchers(matchers []match.Matcher) []match.Matcher {
|
||||||
var (
|
var done match.Matcher
|
||||||
buf []match.Matcher
|
var left, right, count int
|
||||||
done match.Matcher
|
|
||||||
)
|
for l := 0; l < len(matchers); l++ {
|
||||||
for idx, m := range matchers {
|
for r := len(matchers); r > l; r-- {
|
||||||
buf = append(buf, m)
|
if glued := glueMatchers(matchers[l:r]); glued != nil {
|
||||||
if g := glueMatchers(buf); g != nil {
|
if done == nil || count < r-l {
|
||||||
done = g
|
done = glued
|
||||||
} else {
|
left = l
|
||||||
return convertMatchers(matchers[idx:], append(result, done))
|
right = r
|
||||||
|
count = r - l
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if done != nil {
|
if done == nil {
|
||||||
return append(result, done)
|
return matchers
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
next := append(append([]match.Matcher{}, matchers[:left]...), done)
|
||||||
|
if right < len(matchers) {
|
||||||
|
next = append(next, matchers[right:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(next) == len(matchers) {
|
||||||
|
return next
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertMatchers(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
func compileMatchers(matchers []match.Matcher) (match.Matcher, error) {
|
func compileMatchers(matchers []match.Matcher) (match.Matcher, error) {
|
||||||
|
@ -219,6 +225,10 @@ func compileMatchers(matchers []match.Matcher) (match.Matcher, error) {
|
||||||
return nil, fmt.Errorf("compile error: need at least one matcher")
|
return nil, fmt.Errorf("compile error: need at least one matcher")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(matchers) == 1 {
|
||||||
|
return matchers[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
if m := glueMatchers(matchers); m != nil {
|
if m := glueMatchers(matchers); m != nil {
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
@ -285,7 +295,7 @@ func do(node node, s string) (m match.Matcher, err error) {
|
||||||
if _, ok := node.(*nodeAnyOf); ok {
|
if _, ok := node.(*nodeAnyOf); ok {
|
||||||
m = match.AnyOf{matchers}
|
m = match.AnyOf{matchers}
|
||||||
} else {
|
} else {
|
||||||
m, err = compileMatchers(convertMatchers(matchers, nil))
|
m, err = compileMatchers(convertMatchers(matchers))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -349,7 +359,7 @@ func do2(node node, s string) ([]match.Matcher, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, matchers := range ways {
|
for _, matchers := range ways {
|
||||||
c, err := compileMatchers(convertMatchers(matchers, nil))
|
c, err := compileMatchers(convertMatchers(matchers))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -383,7 +393,7 @@ func do2(node node, s string) ([]match.Matcher, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, matchers := range ways {
|
for _, matchers := range ways {
|
||||||
c, err := compileMatchers(convertMatchers(matchers, nil))
|
c, err := compileMatchers(convertMatchers(matchers))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,13 +162,12 @@ func TestConvertMatchers(t *testing.T) {
|
||||||
match.Range{'a', 'c', true},
|
match.Range{'a', 'c', true},
|
||||||
match.List{"zte", false},
|
match.List{"zte", false},
|
||||||
match.Raw{"c"},
|
match.Raw{"c"},
|
||||||
match.Single{},
|
|
||||||
}},
|
}},
|
||||||
match.Min{2},
|
match.Min{3},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
act := convertMatchers(test.in, nil)
|
act := convertMatchers(test.in)
|
||||||
if !reflect.DeepEqual(act, test.exp) {
|
if !reflect.DeepEqual(act, test.exp) {
|
||||||
t.Errorf("#%d unexpected convert matchers 2 result:\nact: %s;\nexp: %s", id, act, test.exp)
|
t.Errorf("#%d unexpected convert matchers 2 result:\nact: %s;\nexp: %s", id, act, test.exp)
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in New Issue