Optimize compilation

This commit is contained in:
s.kamardin 2016-01-13 20:13:11 +03:00
parent ed79d1d679
commit b3ce5dedcb
3 changed files with 41 additions and 32 deletions

View File

@ -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
} }

View File

@ -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