mirror of https://github.com/gobwas/glob.git
Use of constuctors every where, optimizations
This commit is contained in:
parent
f884dfeb2e
commit
34494ea116
60
compiler.go
60
compiler.go
|
@ -14,7 +14,7 @@ func optimize(matcher match.Matcher) match.Matcher {
|
||||||
|
|
||||||
case match.Any:
|
case match.Any:
|
||||||
if len(m.Separators) == 0 {
|
if len(m.Separators) == 0 {
|
||||||
return match.Super{}
|
return match.NewSuper()
|
||||||
}
|
}
|
||||||
|
|
||||||
case match.AnyOf:
|
case match.AnyOf:
|
||||||
|
@ -54,23 +54,23 @@ func optimize(matcher match.Matcher) match.Matcher {
|
||||||
rs, rightSuffix := m.Right.(match.Suffix)
|
rs, rightSuffix := m.Right.(match.Suffix)
|
||||||
|
|
||||||
if leftSuper && rightSuper {
|
if leftSuper && rightSuper {
|
||||||
return match.Contains{r.Str, false}
|
return match.NewContains(r.Str, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if leftSuper && rightNil {
|
if leftSuper && rightNil {
|
||||||
return match.Suffix{r.Str}
|
return match.NewSuffix(r.Str)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rightSuper && leftNil {
|
if rightSuper && leftNil {
|
||||||
return match.Prefix{r.Str}
|
return match.NewPrefix(r.Str)
|
||||||
}
|
}
|
||||||
|
|
||||||
if leftNil && rightSuffix {
|
if leftNil && rightSuffix {
|
||||||
return match.PrefixSuffix{Prefix: r.Str, Suffix: rs.Suffix}
|
return match.NewPrefixSuffix(r.Str, rs.Suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rightNil && leftPrefix {
|
if rightNil && leftPrefix {
|
||||||
return match.PrefixSuffix{Prefix: lp.Prefix, Suffix: r.Str}
|
return match.NewPrefixSuffix(lp.Prefix, r.Str)
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
@ -124,7 +124,7 @@ func glueAsRow(matchers []match.Matcher) match.Matcher {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return match.NewRow(c, l)
|
return match.NewRow(l, c...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func glueAsEvery(matchers []match.Matcher) match.Matcher {
|
func glueAsEvery(matchers []match.Matcher) match.Matcher {
|
||||||
|
@ -182,29 +182,29 @@ func glueAsEvery(matchers []match.Matcher) match.Matcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasSuper && !hasAny && !hasSingle {
|
if hasSuper && !hasAny && !hasSingle {
|
||||||
return match.Super{}
|
return match.NewSuper()
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasAny && !hasSuper && !hasSingle {
|
if hasAny && !hasSuper && !hasSingle {
|
||||||
return match.Any{separator}
|
return match.NewAny(separator)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasAny || hasSuper) && min > 0 && len(separator) == 0 {
|
if (hasAny || hasSuper) && min > 0 && len(separator) == 0 {
|
||||||
return match.Min{min}
|
return match.NewMin(min)
|
||||||
}
|
}
|
||||||
|
|
||||||
every := match.EveryOf{}
|
every := match.NewEveryOf()
|
||||||
|
|
||||||
if min > 0 {
|
if min > 0 {
|
||||||
every.Add(match.Min{min})
|
every.Add(match.NewMin(min))
|
||||||
|
|
||||||
if !hasAny && !hasSuper {
|
if !hasAny && !hasSuper {
|
||||||
every.Add(match.Max{min})
|
every.Add(match.NewMax(min))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(separator) > 0 {
|
if len(separator) > 0 {
|
||||||
every.Add(match.Contains{string(separator), true})
|
every.Add(match.NewContains(string(separator), true))
|
||||||
}
|
}
|
||||||
|
|
||||||
return every
|
return every
|
||||||
|
@ -474,7 +474,7 @@ func doAnyOf(n *nodeAnyOf, s []rune) (match.Matcher, error) {
|
||||||
var matchers []match.Matcher
|
var matchers []match.Matcher
|
||||||
for _, desc := range n.children() {
|
for _, desc := range n.children() {
|
||||||
if desc == nil {
|
if desc == nil {
|
||||||
matchers = append(matchers, match.Nothing{})
|
matchers = append(matchers, match.NewNothing())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,7 +485,7 @@ func doAnyOf(n *nodeAnyOf, s []rune) (match.Matcher, error) {
|
||||||
matchers = append(matchers, optimize(m))
|
matchers = append(matchers, optimize(m))
|
||||||
}
|
}
|
||||||
|
|
||||||
return match.AnyOf{matchers}, nil
|
return match.NewAnyOf(matchers...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func do(leaf node, s []rune) (m match.Matcher, err error) {
|
func do(leaf node, s []rune) (m match.Matcher, err error) {
|
||||||
|
@ -500,7 +500,7 @@ func do(leaf node, s []rune) (m match.Matcher, err error) {
|
||||||
var matchers []match.Matcher
|
var matchers []match.Matcher
|
||||||
for _, desc := range n.children() {
|
for _, desc := range n.children() {
|
||||||
if desc == nil {
|
if desc == nil {
|
||||||
matchers = append(matchers, match.Nothing{})
|
matchers = append(matchers, match.NewNothing())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,12 +511,12 @@ func do(leaf node, s []rune) (m match.Matcher, err error) {
|
||||||
matchers = append(matchers, optimize(m))
|
matchers = append(matchers, optimize(m))
|
||||||
}
|
}
|
||||||
|
|
||||||
return match.AnyOf{matchers}, nil
|
return match.NewAnyOf(matchers...), nil
|
||||||
|
|
||||||
case *nodePattern:
|
case *nodePattern:
|
||||||
nodes := leaf.children()
|
nodes := leaf.children()
|
||||||
if len(nodes) == 0 {
|
if len(nodes) == 0 {
|
||||||
return match.Nothing{}, nil
|
return match.NewNothing(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var matchers []match.Matcher
|
var matchers []match.Matcher
|
||||||
|
@ -534,19 +534,19 @@ func do(leaf node, s []rune) (m match.Matcher, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case *nodeList:
|
case *nodeList:
|
||||||
m = match.List{[]rune(n.chars), n.not}
|
m = match.NewList([]rune(n.chars), n.not)
|
||||||
|
|
||||||
case *nodeRange:
|
case *nodeRange:
|
||||||
m = match.Range{n.lo, n.hi, n.not}
|
m = match.NewRange(n.lo, n.hi, n.not)
|
||||||
|
|
||||||
case *nodeAny:
|
case *nodeAny:
|
||||||
m = match.Any{s}
|
m = match.NewAny(s)
|
||||||
|
|
||||||
case *nodeSuper:
|
case *nodeSuper:
|
||||||
m = match.Super{}
|
m = match.NewSuper()
|
||||||
|
|
||||||
case *nodeSingle:
|
case *nodeSingle:
|
||||||
m = match.Single{s}
|
m = match.NewSingle(s)
|
||||||
|
|
||||||
case *nodeText:
|
case *nodeText:
|
||||||
m = match.NewText(n.text)
|
m = match.NewText(n.text)
|
||||||
|
@ -633,19 +633,19 @@ func do2(node node, s []rune) ([]match.Matcher, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case *nodeList:
|
case *nodeList:
|
||||||
result = append(result, match.List{[]rune(n.chars), n.not})
|
result = append(result, match.NewList([]rune(n.chars), n.not))
|
||||||
|
|
||||||
case *nodeRange:
|
case *nodeRange:
|
||||||
result = append(result, match.Range{n.lo, n.hi, n.not})
|
result = append(result, match.NewRange(n.lo, n.hi, n.not))
|
||||||
|
|
||||||
case *nodeAny:
|
case *nodeAny:
|
||||||
result = append(result, match.Any{s})
|
result = append(result, match.NewAny(s))
|
||||||
|
|
||||||
case *nodeSuper:
|
case *nodeSuper:
|
||||||
result = append(result, match.Super{})
|
result = append(result, match.NewSuper())
|
||||||
|
|
||||||
case *nodeSingle:
|
case *nodeSingle:
|
||||||
result = append(result, match.Single{s})
|
result = append(result, match.NewSingle(s))
|
||||||
|
|
||||||
case *nodeText:
|
case *nodeText:
|
||||||
result = append(result, match.NewText(n.text))
|
result = append(result, match.NewText(n.text))
|
||||||
|
@ -669,7 +669,7 @@ func compile(ast *nodePattern, s []rune) (Glob, error) {
|
||||||
// if len(ms) == 1 {
|
// if len(ms) == 1 {
|
||||||
// return ms[0], nil
|
// return ms[0], nil
|
||||||
// } else {
|
// } else {
|
||||||
// return match.AnyOf{ms}, nil
|
// return match.NewAnyOf(ms), nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
g, err := do(ast, s)
|
g, err := do(ast, s)
|
||||||
|
|
278
compiler_test.go
278
compiler_test.go
|
@ -15,40 +15,40 @@ func TestGlueMatchers(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.Super{},
|
match.NewSuper(),
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
},
|
},
|
||||||
match.Min{1},
|
match.NewMin(1),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.Any{separators},
|
match.NewAny(separators),
|
||||||
match.Single{separators},
|
match.NewSingle(separators),
|
||||||
},
|
},
|
||||||
match.EveryOf{match.Matchers{
|
match.EveryOf{match.Matchers{
|
||||||
match.Min{1},
|
match.NewMin(1),
|
||||||
match.Contains{string(separators), true},
|
match.NewContains(string(separators), true),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
},
|
},
|
||||||
match.EveryOf{match.Matchers{
|
match.EveryOf{match.Matchers{
|
||||||
match.Min{3},
|
match.NewMin(3),
|
||||||
match.Max{3},
|
match.NewMax(3),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.List{[]rune{'a'}, true},
|
match.NewList([]rune{'a'}, true),
|
||||||
match.Any{[]rune{'a'}},
|
match.NewAny([]rune{'a'}),
|
||||||
},
|
},
|
||||||
match.EveryOf{match.Matchers{
|
match.EveryOf{match.Matchers{
|
||||||
match.Min{1},
|
match.NewMin(1),
|
||||||
match.Contains{"a", true},
|
match.NewContains("a", true),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
|
@ -59,7 +59,7 @@ func TestGlueMatchers(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(act, test.exp) {
|
if !reflect.DeepEqual(act, test.exp) {
|
||||||
t.Errorf("#%d unexpected convert matchers result:\nact: %s;\nexp: %s", id, act, test.exp)
|
t.Errorf("#%d unexpected convert matchers result:\nact: %#v;\nexp: %#v", id, act, test.exp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,15 +72,15 @@ func TestCompileMatchers(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.Super{},
|
match.NewSuper(),
|
||||||
match.Single{separators},
|
match.NewSingle(separators),
|
||||||
match.NewText("c"),
|
match.NewText("c"),
|
||||||
},
|
},
|
||||||
match.NewBTree(
|
match.NewBTree(
|
||||||
match.NewText("c"),
|
match.NewText("c"),
|
||||||
match.NewBTree(
|
match.NewBTree(
|
||||||
match.Single{separators},
|
match.NewSingle(separators),
|
||||||
match.Super{},
|
match.NewSuper(),
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
nil,
|
nil,
|
||||||
|
@ -88,32 +88,32 @@ func TestCompileMatchers(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.Any{},
|
match.NewAny(nil),
|
||||||
match.NewText("c"),
|
match.NewText("c"),
|
||||||
match.Any{},
|
match.NewAny(nil),
|
||||||
},
|
},
|
||||||
match.NewBTree(
|
match.NewBTree(
|
||||||
match.NewText("c"),
|
match.NewText("c"),
|
||||||
match.Any{},
|
match.NewAny(nil),
|
||||||
match.Any{},
|
match.NewAny(nil),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.Range{'a', 'c', true},
|
match.NewRange('a', 'c', true),
|
||||||
match.List{[]rune{'z', 't', 'e'}, false},
|
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||||
match.NewText("c"),
|
match.NewText("c"),
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
},
|
},
|
||||||
match.Row{
|
match.NewRow(
|
||||||
Matchers: match.Matchers{
|
4,
|
||||||
match.Range{'a', 'c', true},
|
match.Matchers{
|
||||||
match.List{[]rune{'z', 't', 'e'}, false},
|
match.NewRange('a', 'c', true),
|
||||||
|
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||||
match.NewText("c"),
|
match.NewText("c"),
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
},
|
}...,
|
||||||
RunesLength: 4,
|
),
|
||||||
},
|
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
act, err := compileMatchers(test.in)
|
act, err := compileMatchers(test.in)
|
||||||
|
@ -123,7 +123,7 @@ func TestCompileMatchers(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(act, test.exp) {
|
if !reflect.DeepEqual(act, test.exp) {
|
||||||
t.Errorf("#%d unexpected convert matchers result:\nact: %s;\nexp: %s", id, act, test.exp)
|
t.Errorf("#%d unexpected convert matchers result:\nact: %#v\nexp: %#v", id, act, test.exp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,52 +135,52 @@ func TestConvertMatchers(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.Range{'a', 'c', true},
|
match.NewRange('a', 'c', true),
|
||||||
match.List{[]rune{'z', 't', 'e'}, false},
|
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||||
match.NewText("c"),
|
match.NewText("c"),
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
match.Any{},
|
match.NewAny(nil),
|
||||||
},
|
},
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.Row{
|
match.NewRow(
|
||||||
Matchers: match.Matchers{
|
4,
|
||||||
match.Range{'a', 'c', true},
|
[]match.Matcher{
|
||||||
match.List{[]rune{'z', 't', 'e'}, false},
|
match.NewRange('a', 'c', true),
|
||||||
|
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||||
match.NewText("c"),
|
match.NewText("c"),
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
},
|
}...,
|
||||||
RunesLength: 4,
|
),
|
||||||
},
|
match.NewAny(nil),
|
||||||
match.Any{},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.Range{'a', 'c', true},
|
match.NewRange('a', 'c', true),
|
||||||
match.List{[]rune{'z', 't', 'e'}, false},
|
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||||
match.NewText("c"),
|
match.NewText("c"),
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
match.Any{},
|
match.NewAny(nil),
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
match.Any{},
|
match.NewAny(nil),
|
||||||
},
|
},
|
||||||
[]match.Matcher{
|
[]match.Matcher{
|
||||||
match.Row{
|
match.NewRow(
|
||||||
Matchers: match.Matchers{
|
3,
|
||||||
match.Range{'a', 'c', true},
|
match.Matchers{
|
||||||
match.List{[]rune{'z', 't', 'e'}, false},
|
match.NewRange('a', 'c', true),
|
||||||
|
match.NewList([]rune{'z', 't', 'e'}, false),
|
||||||
match.NewText("c"),
|
match.NewText("c"),
|
||||||
},
|
}...,
|
||||||
RunesLength: 3,
|
),
|
||||||
},
|
match.NewMin(3),
|
||||||
match.Min{3},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
act := minimizeMatchers(test.in)
|
act := minimizeMatchers(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: %#v\nexp: %#v", id, act, test.exp)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,20 +213,20 @@ func TestCompiler(t *testing.T) {
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeAny{}),
|
ast: pattern(&nodeAny{}),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.Any{separators},
|
result: match.NewAny(separators),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeAny{}),
|
ast: pattern(&nodeAny{}),
|
||||||
result: match.Super{},
|
result: match.NewSuper(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeSuper{}),
|
ast: pattern(&nodeSuper{}),
|
||||||
result: match.Super{},
|
result: match.NewSuper(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeSingle{}),
|
ast: pattern(&nodeSingle{}),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.Single{separators},
|
result: match.NewSingle(separators),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeRange{
|
ast: pattern(&nodeRange{
|
||||||
|
@ -234,39 +234,39 @@ func TestCompiler(t *testing.T) {
|
||||||
hi: 'z',
|
hi: 'z',
|
||||||
not: true,
|
not: true,
|
||||||
}),
|
}),
|
||||||
result: match.Range{'a', 'z', true},
|
result: match.NewRange('a', 'z', true),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeList{
|
ast: pattern(&nodeList{
|
||||||
chars: "abc",
|
chars: "abc",
|
||||||
not: true,
|
not: true,
|
||||||
}),
|
}),
|
||||||
result: match.List{[]rune{'a', 'b', 'c'}, true},
|
result: match.NewList([]rune{'a', 'b', 'c'}, true),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeAny{}, &nodeSingle{}, &nodeSingle{}, &nodeSingle{}),
|
ast: pattern(&nodeAny{}, &nodeSingle{}, &nodeSingle{}, &nodeSingle{}),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.EveryOf{Matchers: match.Matchers{
|
result: match.EveryOf{Matchers: match.Matchers{
|
||||||
match.Min{3},
|
match.NewMin(3),
|
||||||
match.Contains{string(separators), true},
|
match.NewContains(string(separators), true),
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeAny{}, &nodeSingle{}, &nodeSingle{}, &nodeSingle{}),
|
ast: pattern(&nodeAny{}, &nodeSingle{}, &nodeSingle{}, &nodeSingle{}),
|
||||||
result: match.Min{3},
|
result: match.NewMin(3),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeAny{}, &nodeText{text: "abc"}, &nodeSingle{}),
|
ast: pattern(&nodeAny{}, &nodeText{text: "abc"}, &nodeSingle{}),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
match.Row{
|
match.NewRow(
|
||||||
Matchers: match.Matchers{
|
4,
|
||||||
|
match.Matchers{
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
match.Single{separators},
|
match.NewSingle(separators),
|
||||||
},
|
}...,
|
||||||
RunesLength: 4,
|
),
|
||||||
},
|
match.NewAny(separators),
|
||||||
match.Any{separators},
|
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -274,49 +274,49 @@ func TestCompiler(t *testing.T) {
|
||||||
ast: pattern(&nodeSuper{}, &nodeSingle{}, &nodeText{text: "abc"}, &nodeSingle{}),
|
ast: pattern(&nodeSuper{}, &nodeSingle{}, &nodeText{text: "abc"}, &nodeSingle{}),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
match.Row{
|
match.NewRow(
|
||||||
Matchers: match.Matchers{
|
5,
|
||||||
match.Single{separators},
|
match.Matchers{
|
||||||
|
match.NewSingle(separators),
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
match.Single{separators},
|
match.NewSingle(separators),
|
||||||
},
|
}...,
|
||||||
RunesLength: 5,
|
),
|
||||||
},
|
match.NewSuper(),
|
||||||
match.Super{},
|
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeAny{}, &nodeText{text: "abc"}),
|
ast: pattern(&nodeAny{}, &nodeText{text: "abc"}),
|
||||||
result: match.Suffix{"abc"},
|
result: match.NewSuffix("abc"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeText{text: "abc"}, &nodeAny{}),
|
ast: pattern(&nodeText{text: "abc"}, &nodeAny{}),
|
||||||
result: match.Prefix{"abc"},
|
result: match.NewPrefix("abc"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeText{text: "abc"}, &nodeAny{}, &nodeText{text: "def"}),
|
ast: pattern(&nodeText{text: "abc"}, &nodeAny{}, &nodeText{text: "def"}),
|
||||||
result: match.PrefixSuffix{"abc", "def"},
|
result: match.NewPrefixSuffix("abc", "def"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeAny{}, &nodeAny{}, &nodeAny{}, &nodeText{text: "abc"}, &nodeAny{}, &nodeAny{}),
|
ast: pattern(&nodeAny{}, &nodeAny{}, &nodeAny{}, &nodeText{text: "abc"}, &nodeAny{}, &nodeAny{}),
|
||||||
result: match.Contains{"abc", false},
|
result: match.NewContains("abc", false),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeAny{}, &nodeAny{}, &nodeAny{}, &nodeText{text: "abc"}, &nodeAny{}, &nodeAny{}),
|
ast: pattern(&nodeAny{}, &nodeAny{}, &nodeAny{}, &nodeText{text: "abc"}, &nodeAny{}, &nodeAny{}),
|
||||||
sep: separators,
|
sep: separators,
|
||||||
result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
match.Any{separators},
|
match.NewAny(separators),
|
||||||
match.Any{separators},
|
match.NewAny(separators),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ast: pattern(&nodeSuper{}, &nodeSingle{}, &nodeText{text: "abc"}, &nodeSuper{}, &nodeSingle{}),
|
ast: pattern(&nodeSuper{}, &nodeSingle{}, &nodeText{text: "abc"}, &nodeSuper{}, &nodeSingle{}),
|
||||||
result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
match.Min{1},
|
match.NewMin(1),
|
||||||
match.Min{1},
|
match.NewMin(1),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -348,9 +348,9 @@ func TestCompiler(t *testing.T) {
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
nil,
|
nil,
|
||||||
match.AnyOf{Matchers: match.Matchers{
|
match.AnyOf{Matchers: match.Matchers{
|
||||||
match.Single{},
|
match.NewSingle(nil),
|
||||||
match.List{List: []rune{'d', 'e', 'f'}},
|
match.NewList([]rune{'d', 'e', 'f'}, false),
|
||||||
match.Nothing{},
|
match.NewNothing(),
|
||||||
}},
|
}},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -361,15 +361,15 @@ func TestCompiler(t *testing.T) {
|
||||||
&nodeAny{},
|
&nodeAny{},
|
||||||
),
|
),
|
||||||
result: match.NewBTree(
|
result: match.NewBTree(
|
||||||
match.Row{
|
match.NewRow(
|
||||||
Matchers: match.Matchers{
|
2,
|
||||||
match.Range{Lo: 'a', Hi: 'z'},
|
match.Matchers{
|
||||||
match.Range{Lo: 'a', Hi: 'x', Not: true},
|
match.NewRange('a', 'z', false),
|
||||||
},
|
match.NewRange('a', 'x', true),
|
||||||
RunesLength: 2,
|
}...,
|
||||||
},
|
),
|
||||||
nil,
|
nil,
|
||||||
match.Super{},
|
match.NewSuper(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -385,17 +385,17 @@ func TestCompiler(t *testing.T) {
|
||||||
&nodeText{text: "ghi"},
|
&nodeText{text: "ghi"},
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
result: match.Row{
|
result: match.NewRow(
|
||||||
RunesLength: 7,
|
7,
|
||||||
Matchers: match.Matchers{
|
match.Matchers{
|
||||||
match.NewText("abc"),
|
match.NewText("abc"),
|
||||||
match.AnyOf{Matchers: match.Matchers{
|
match.AnyOf{Matchers: match.Matchers{
|
||||||
match.List{List: []rune{'a', 'b', 'c'}},
|
match.NewList([]rune{'a', 'b', 'c'}, false),
|
||||||
match.List{List: []rune{'d', 'e', 'f'}},
|
match.NewList([]rune{'d', 'e', 'f'}, false),
|
||||||
}},
|
}},
|
||||||
match.NewText("ghi"),
|
match.NewText("ghi"),
|
||||||
},
|
}...,
|
||||||
},
|
),
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// ast: pattern(
|
// ast: pattern(
|
||||||
|
@ -403,21 +403,21 @@ func TestCompiler(t *testing.T) {
|
||||||
// anyOf(&nodeText{text: "c"}, &nodeText{text: "d"}),
|
// anyOf(&nodeText{text: "c"}, &nodeText{text: "d"}),
|
||||||
// ),
|
// ),
|
||||||
// result: match.AnyOf{Matchers: match.Matchers{
|
// result: match.AnyOf{Matchers: match.Matchers{
|
||||||
// match.Row{Matchers: match.Matchers{match.Raw{"a"}, match.Raw{"c", 1}}},
|
// match.NewRow(Matchers: match.Matchers{match.Raw{"a"}, match.Raw{"c", 1}}),
|
||||||
// match.Row{Matchers: match.Matchers{match.Raw{"a"}, match.Raw{"d"}}},
|
// match.NewRow(Matchers: match.Matchers{match.Raw{"a"}, match.Raw{"d"}}),
|
||||||
// match.Row{Matchers: match.Matchers{match.Raw{"b"}, match.Raw{"c", 1}}},
|
// match.NewRow(Matchers: match.Matchers{match.Raw{"b"}, match.Raw{"c", 1}}),
|
||||||
// match.Row{Matchers: match.Matchers{match.Raw{"b"}, match.Raw{"d"}}},
|
// match.NewRow(Matchers: match.Matchers{match.Raw{"b"}, match.Raw{"d"}}),
|
||||||
// }},
|
// }},
|
||||||
// },
|
// },
|
||||||
} {
|
} {
|
||||||
prog, err := compile(test.ast, test.sep)
|
m, err := compile(test.ast, test.sep)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("compilation error: %s", err)
|
t.Errorf("compilation error: %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !reflect.DeepEqual(prog, test.result) {
|
if !reflect.DeepEqual(m, test.result) {
|
||||||
t.Errorf("#%d results are not equal:\nexp: %s,\nact: %s", id, test.result, prog)
|
t.Errorf("#%d results are not equal:\nexp: %#v\nact: %#v", id, test.result, m)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -426,105 +426,105 @@ func TestCompiler(t *testing.T) {
|
||||||
const complexityString = "abcd"
|
const complexityString = "abcd"
|
||||||
|
|
||||||
//func BenchmarkComplexityAny(b *testing.B) {
|
//func BenchmarkComplexityAny(b *testing.B) {
|
||||||
// m := match.Any{}
|
// m := match.NewAny(nil)
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityContains(b *testing.B) {
|
//func BenchmarkComplexityContains(b *testing.B) {
|
||||||
// m := match.Contains{}
|
// m := match.NewContains()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityList(b *testing.B) {
|
//func BenchmarkComplexityList(b *testing.B) {
|
||||||
// m := match.List{}
|
// m := match.NewList()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityMax(b *testing.B) {
|
//func BenchmarkComplexityMax(b *testing.B) {
|
||||||
// m := match.Max{}
|
// m := match.NewMax()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityMin(b *testing.B) {
|
//func BenchmarkComplexityMin(b *testing.B) {
|
||||||
// m := match.Min{}
|
// m := match.NewMin()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityNothing(b *testing.B) {
|
//func BenchmarkComplexityNothing(b *testing.B) {
|
||||||
// m := match.Nothing{}
|
// m := match.NewNothing()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityPrefix(b *testing.B) {
|
//func BenchmarkComplexityPrefix(b *testing.B) {
|
||||||
// m := match.Prefix{}
|
// m := match.NewPrefix()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityPrefixSuffix(b *testing.B) {
|
//func BenchmarkComplexityPrefixSuffix(b *testing.B) {
|
||||||
// m := match.PrefixSuffix{}
|
// m := match.NewPrefixSuffix()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityRange(b *testing.B) {
|
//func BenchmarkComplexityRange(b *testing.B) {
|
||||||
// m := match.Range{}
|
// m := match.NewRange()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityRow(b *testing.B) {
|
//func BenchmarkComplexityRow(b *testing.B) {
|
||||||
// m := match.Row{}
|
// m := match.NewRow()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexitySingle(b *testing.B) {
|
//func BenchmarkComplexitySingle(b *testing.B) {
|
||||||
// m := match.Single{}
|
// m := match.NewSingle(nil)
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexitySuffix(b *testing.B) {
|
//func BenchmarkComplexitySuffix(b *testing.B) {
|
||||||
// m := match.Suffix{}
|
// m := match.NewSuffix()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexitySuper(b *testing.B) {
|
//func BenchmarkComplexitySuper(b *testing.B) {
|
||||||
// m := match.Super{}
|
// m := match.NewSuper()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityText(b *testing.B) {
|
//func BenchmarkComplexityText(b *testing.B) {
|
||||||
// m := match.Text{}
|
// m := match.NewText()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityAnyOf(b *testing.B) {
|
//func BenchmarkComplexityAnyOf(b *testing.B) {
|
||||||
// m := match.AnyOf{}
|
// m := match.NewAnyOf()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
|
@ -538,7 +538,7 @@ const complexityString = "abcd"
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
//func BenchmarkComplexityEveryOf(b *testing.B) {
|
//func BenchmarkComplexityEveryOf(b *testing.B) {
|
||||||
// m := match.EveryOf{}
|
// m := match.NewEveryOf()
|
||||||
// for i := 0; i < b.N; i++ {
|
// for i := 0; i < b.N; i++ {
|
||||||
// _ = m.Match(complexityString)
|
// _ = m.Match(complexityString)
|
||||||
// _, _ = m.Index(complexityString)
|
// _, _ = m.Index(complexityString)
|
||||||
|
|
|
@ -9,6 +9,10 @@ type Any struct {
|
||||||
Separators []rune
|
Separators []rune
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewAny(s []rune) Any {
|
||||||
|
return Any{s}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Any) Match(s string) bool {
|
func (self Any) Match(s string) bool {
|
||||||
return strings.IndexAnyRunes(s, self.Separators) == -1
|
return strings.IndexAnyRunes(s, self.Separators) == -1
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,10 @@ type AnyOf struct {
|
||||||
Matchers Matchers
|
Matchers Matchers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewAnyOf(m ...Matcher) AnyOf {
|
||||||
|
return AnyOf{Matchers(m)}
|
||||||
|
}
|
||||||
|
|
||||||
func (self *AnyOf) Add(m Matcher) error {
|
func (self *AnyOf) Add(m Matcher) error {
|
||||||
self.Matchers = append(self.Matchers, m)
|
self.Matchers = append(self.Matchers, m)
|
||||||
return nil
|
return nil
|
||||||
|
@ -27,7 +31,6 @@ func (self AnyOf) Index(s string) (int, []int) {
|
||||||
index := -1
|
index := -1
|
||||||
|
|
||||||
segments := acquireSegments(len(s))
|
segments := acquireSegments(len(s))
|
||||||
|
|
||||||
for _, m := range self.Matchers {
|
for _, m := range self.Matchers {
|
||||||
idx, seg := m.Index(s)
|
idx, seg := m.Index(s)
|
||||||
if idx == -1 {
|
if idx == -1 {
|
||||||
|
|
|
@ -14,7 +14,7 @@ func TestAnyOfIndex(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Matchers{
|
Matchers{
|
||||||
Any{},
|
NewAny(nil),
|
||||||
NewText("b"),
|
NewText("b"),
|
||||||
NewText("c"),
|
NewText("c"),
|
||||||
},
|
},
|
||||||
|
@ -24,8 +24,8 @@ func TestAnyOfIndex(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Matchers{
|
Matchers{
|
||||||
Prefix{"b"},
|
NewPrefix("b"),
|
||||||
Suffix{"c"},
|
NewSuffix("c"),
|
||||||
},
|
},
|
||||||
"abc",
|
"abc",
|
||||||
0,
|
0,
|
||||||
|
@ -41,7 +41,7 @@ func TestAnyOfIndex(t *testing.T) {
|
||||||
[]int{1},
|
[]int{1},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
everyOf := AnyOf{test.matchers}
|
everyOf := NewAnyOf(test.matchers...)
|
||||||
index, segments := everyOf.Index(test.fixture)
|
index, segments := everyOf.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
|
|
@ -25,7 +25,7 @@ func TestAnyIndex(t *testing.T) {
|
||||||
[]int{0, 1, 2, 3},
|
[]int{0, 1, 2, 3},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := Any{test.sep}
|
p := NewAny(test.sep)
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -37,7 +37,7 @@ func TestAnyIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexAny(b *testing.B) {
|
func BenchmarkIndexAny(b *testing.B) {
|
||||||
m := Any{bench_separators}
|
m := NewAny(bench_separators)
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, s := m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
@ -46,7 +46,7 @@ func BenchmarkIndexAny(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexAnyParallel(b *testing.B) {
|
func BenchmarkIndexAnyParallel(b *testing.B) {
|
||||||
m := Any{bench_separators}
|
m := NewAny(bench_separators)
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
|
|
|
@ -129,5 +129,18 @@ func (self BTree) Match(s string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self BTree) String() string {
|
func (self BTree) String() string {
|
||||||
return fmt.Sprintf("<btree:[%s<-%s->%s]>", self.Left, self.Value, self.Right)
|
const n string = "<nil>"
|
||||||
|
var l, r string
|
||||||
|
if self.Left == nil {
|
||||||
|
l = n
|
||||||
|
} else {
|
||||||
|
l = self.Left.String()
|
||||||
|
}
|
||||||
|
if self.Right == nil {
|
||||||
|
r = n
|
||||||
|
} else {
|
||||||
|
r = self.Right.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("<btree:[%s<-%s->%s]>", l, self.Value, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,17 +11,17 @@ func TestBTree(t *testing.T) {
|
||||||
exp bool
|
exp bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
NewBTree(NewText("abc"), Super{}, Super{}),
|
NewBTree(NewText("abc"), NewSuper(), NewSuper()),
|
||||||
"abc",
|
"abc",
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
NewBTree(NewText("a"), Single{}, Single{}),
|
NewBTree(NewText("a"), NewSingle(nil), NewSingle(nil)),
|
||||||
"aaa",
|
"aaa",
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
NewBTree(NewText("b"), Single{}, nil),
|
NewBTree(NewText("b"), NewSingle(nil), nil),
|
||||||
"bbb",
|
"bbb",
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
@ -29,8 +29,8 @@ func TestBTree(t *testing.T) {
|
||||||
NewBTree(
|
NewBTree(
|
||||||
NewText("c"),
|
NewText("c"),
|
||||||
NewBTree(
|
NewBTree(
|
||||||
Single{},
|
NewSingle(nil),
|
||||||
Super{},
|
NewSuper(),
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
nil,
|
nil,
|
||||||
|
|
|
@ -10,6 +10,10 @@ type Contains struct {
|
||||||
Not bool
|
Not bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewContains(needle string, not bool) Contains {
|
||||||
|
return Contains{needle, not}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Contains) Match(s string) bool {
|
func (self Contains) Match(s string) bool {
|
||||||
return strings.Contains(s, self.Needle) != self.Not
|
return strings.Contains(s, self.Needle) != self.Not
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ func TestContainsIndex(t *testing.T) {
|
||||||
[]int{0, 1, 2, 3},
|
[]int{0, 1, 2, 3},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := Contains{test.prefix, test.not}
|
p := NewContains(test.prefix, test.not)
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -54,7 +54,7 @@ func TestContainsIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexContains(b *testing.B) {
|
func BenchmarkIndexContains(b *testing.B) {
|
||||||
m := Contains{string(bench_separators), true}
|
m := NewContains(string(bench_separators), true)
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, s := m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
@ -63,7 +63,7 @@ func BenchmarkIndexContains(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexContainsParallel(b *testing.B) {
|
func BenchmarkIndexContainsParallel(b *testing.B) {
|
||||||
m := Contains{string(bench_separators), true}
|
m := NewContains(string(bench_separators), true)
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
|
|
|
@ -8,6 +8,10 @@ type EveryOf struct {
|
||||||
Matchers Matchers
|
Matchers Matchers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewEveryOf(m ...Matcher) EveryOf {
|
||||||
|
return EveryOf{Matchers(m)}
|
||||||
|
}
|
||||||
|
|
||||||
func (self *EveryOf) Add(m Matcher) error {
|
func (self *EveryOf) Add(m Matcher) error {
|
||||||
self.Matchers = append(self.Matchers, m)
|
self.Matchers = append(self.Matchers, m)
|
||||||
return nil
|
return nil
|
||||||
|
@ -31,7 +35,6 @@ func (self EveryOf) Index(s string) (int, []int) {
|
||||||
|
|
||||||
// make `in` with cap as len(s),
|
// make `in` with cap as len(s),
|
||||||
// cause it is the maximum size of output segments values
|
// cause it is the maximum size of output segments values
|
||||||
//todo opti!!!
|
|
||||||
next := acquireSegments(len(s))
|
next := acquireSegments(len(s))
|
||||||
current := acquireSegments(len(s))
|
current := acquireSegments(len(s))
|
||||||
|
|
||||||
|
@ -39,6 +42,8 @@ func (self EveryOf) Index(s string) (int, []int) {
|
||||||
for i, m := range self.Matchers {
|
for i, m := range self.Matchers {
|
||||||
idx, seg := m.Index(sub)
|
idx, seg := m.Index(sub)
|
||||||
if idx == -1 {
|
if idx == -1 {
|
||||||
|
releaseSegments(next)
|
||||||
|
releaseSegments(current)
|
||||||
return -1, nil
|
return -1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +66,8 @@ func (self EveryOf) Index(s string) (int, []int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(next) == 0 {
|
if len(next) == 0 {
|
||||||
|
releaseSegments(next)
|
||||||
|
releaseSegments(current)
|
||||||
return -1, nil
|
return -1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +79,8 @@ func (self EveryOf) Index(s string) (int, []int) {
|
||||||
offset += idx
|
offset += idx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
releaseSegments(next)
|
||||||
|
|
||||||
return index, current
|
return index, current
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ func TestEveryOfIndex(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Matchers{
|
Matchers{
|
||||||
Any{},
|
NewAny(nil),
|
||||||
NewText("b"),
|
NewText("b"),
|
||||||
NewText("c"),
|
NewText("c"),
|
||||||
},
|
},
|
||||||
|
@ -24,16 +24,16 @@ func TestEveryOfIndex(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Matchers{
|
Matchers{
|
||||||
Any{},
|
NewAny(nil),
|
||||||
Prefix{"b"},
|
NewPrefix("b"),
|
||||||
Suffix{"c"},
|
NewSuffix("c"),
|
||||||
},
|
},
|
||||||
"abc",
|
"abc",
|
||||||
1,
|
1,
|
||||||
[]int{2},
|
[]int{2},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
everyOf := EveryOf{test.matchers}
|
everyOf := NewEveryOf(test.matchers...)
|
||||||
index, segments := everyOf.Index(test.fixture)
|
index, segments := everyOf.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
|
|
@ -12,10 +12,7 @@ type List struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewList(list []rune, not bool) List {
|
func NewList(list []rune, not bool) List {
|
||||||
return List{
|
return List{list, not}
|
||||||
List: list,
|
|
||||||
Not: not,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self List) Match(s string) bool {
|
func (self List) Match(s string) bool {
|
||||||
|
@ -48,5 +45,5 @@ func (self List) String() string {
|
||||||
not = "!"
|
not = "!"
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("<list:%s[%s]>", not, self.List)
|
return fmt.Sprintf("<list:%s[%s]>", not, string(self.List))
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@ type Max struct {
|
||||||
Limit int
|
Limit int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewMax(l int) Max {
|
||||||
|
return Max{l}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Max) Match(s string) bool {
|
func (self Max) Match(s string) bool {
|
||||||
var l int
|
var l int
|
||||||
for range s {
|
for range s {
|
||||||
|
@ -22,8 +26,7 @@ func (self Max) Match(s string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Max) Index(s string) (int, []int) {
|
func (self Max) Index(s string) (int, []int) {
|
||||||
segments := make([]int, 0, self.Limit+1)
|
segments := acquireSegments(self.Limit + 1)
|
||||||
|
|
||||||
segments = append(segments, 0)
|
segments = append(segments, 0)
|
||||||
var count int
|
var count int
|
||||||
for i, r := range s {
|
for i, r := range s {
|
||||||
|
|
|
@ -25,7 +25,7 @@ func TestMaxIndex(t *testing.T) {
|
||||||
[]int{0, 1, 2, 3},
|
[]int{0, 1, 2, 3},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := Max{test.limit}
|
p := NewMax(test.limit)
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -37,19 +37,21 @@ func TestMaxIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexMax(b *testing.B) {
|
func BenchmarkIndexMax(b *testing.B) {
|
||||||
m := Max{10}
|
m := NewMax(10)
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
releaseSegments(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexMaxParallel(b *testing.B) {
|
func BenchmarkIndexMaxParallel(b *testing.B) {
|
||||||
m := Max{10}
|
m := NewMax(10)
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
releaseSegments(s)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
11
match/min.go
11
match/min.go
|
@ -9,6 +9,10 @@ type Min struct {
|
||||||
Limit int
|
Limit int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewMin(l int) Min {
|
||||||
|
return Min{l}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Min) Match(s string) bool {
|
func (self Min) Match(s string) bool {
|
||||||
var l int
|
var l int
|
||||||
for range s {
|
for range s {
|
||||||
|
@ -24,7 +28,12 @@ func (self Min) Match(s string) bool {
|
||||||
func (self Min) Index(s string) (int, []int) {
|
func (self Min) Index(s string) (int, []int) {
|
||||||
var count int
|
var count int
|
||||||
|
|
||||||
segments := make([]int, 0, len(s)-self.Limit+1)
|
c := len(s) - self.Limit + 1
|
||||||
|
if c <= 0 {
|
||||||
|
return -1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
segments := acquireSegments(c)
|
||||||
for i, r := range s {
|
for i, r := range s {
|
||||||
count++
|
count++
|
||||||
if count >= self.Limit {
|
if count >= self.Limit {
|
||||||
|
|
|
@ -25,7 +25,7 @@ func TestMinIndex(t *testing.T) {
|
||||||
[]int{3, 4},
|
[]int{3, 4},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := Min{test.limit}
|
p := NewMin(test.limit)
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -37,19 +37,21 @@ func TestMinIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexMin(b *testing.B) {
|
func BenchmarkIndexMin(b *testing.B) {
|
||||||
m := Min{10}
|
m := NewMin(10)
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
releaseSegments(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexMinParallel(b *testing.B) {
|
func BenchmarkIndexMinParallel(b *testing.B) {
|
||||||
m := Min{10}
|
m := NewMin(10)
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
releaseSegments(s)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,10 @@ import (
|
||||||
|
|
||||||
type Nothing struct{}
|
type Nothing struct{}
|
||||||
|
|
||||||
|
func NewNothing() Nothing {
|
||||||
|
return Nothing{}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Nothing) Match(s string) bool {
|
func (self Nothing) Match(s string) bool {
|
||||||
return len(s) == 0
|
return len(s) == 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func TestNothingIndex(t *testing.T) {
|
||||||
[]int{0},
|
[]int{0},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := Nothing{}
|
p := NewNothing()
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -34,19 +34,21 @@ func TestNothingIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexNothing(b *testing.B) {
|
func BenchmarkIndexNothing(b *testing.B) {
|
||||||
m := Nothing{}
|
m := NewNothing()
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
releaseSegments(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexNothingParallel(b *testing.B) {
|
func BenchmarkIndexNothingParallel(b *testing.B) {
|
||||||
m := Nothing{}
|
m := NewNothing()
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
releaseSegments(s)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,10 @@ type Prefix struct {
|
||||||
Prefix string
|
Prefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewPrefix(p string) Prefix {
|
||||||
|
return Prefix{p}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Prefix) Index(s string) (int, []int) {
|
func (self Prefix) Index(s string) (int, []int) {
|
||||||
idx := strings.Index(s, self.Prefix)
|
idx := strings.Index(s, self.Prefix)
|
||||||
if idx == -1 {
|
if idx == -1 {
|
||||||
|
|
|
@ -9,6 +9,10 @@ type PrefixSuffix struct {
|
||||||
Prefix, Suffix string
|
Prefix, Suffix string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewPrefixSuffix(p, s string) PrefixSuffix {
|
||||||
|
return PrefixSuffix{p, s}
|
||||||
|
}
|
||||||
|
|
||||||
func (self PrefixSuffix) Index(s string) (int, []int) {
|
func (self PrefixSuffix) Index(s string) (int, []int) {
|
||||||
prefixIdx := strings.Index(s, self.Prefix)
|
prefixIdx := strings.Index(s, self.Prefix)
|
||||||
if prefixIdx == -1 {
|
if prefixIdx == -1 {
|
||||||
|
@ -16,11 +20,14 @@ func (self PrefixSuffix) Index(s string) (int, []int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
suffixLen := len(self.Suffix)
|
suffixLen := len(self.Suffix)
|
||||||
|
|
||||||
if suffixLen <= 0 {
|
if suffixLen <= 0 {
|
||||||
return prefixIdx, []int{len(s) - prefixIdx}
|
return prefixIdx, []int{len(s) - prefixIdx}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len(s) - prefixIdx) <= 0 {
|
||||||
|
return -1, nil
|
||||||
|
}
|
||||||
|
|
||||||
segments := acquireSegments(len(s) - prefixIdx)
|
segments := acquireSegments(len(s) - prefixIdx)
|
||||||
for sub := s[prefixIdx:]; ; {
|
for sub := s[prefixIdx:]; ; {
|
||||||
suffixIdx := strings.LastIndex(sub, self.Suffix)
|
suffixIdx := strings.LastIndex(sub, self.Suffix)
|
||||||
|
@ -33,7 +40,8 @@ func (self PrefixSuffix) Index(s string) (int, []int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(segments) == 0 {
|
if len(segments) == 0 {
|
||||||
return -1, segments
|
releaseSegments(segments)
|
||||||
|
return -1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
reverseSegments(segments)
|
reverseSegments(segments)
|
||||||
|
|
|
@ -35,7 +35,7 @@ func TestPrefixSuffixIndex(t *testing.T) {
|
||||||
[]int{3},
|
[]int{3},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := PrefixSuffix{test.prefix, test.suffix}
|
p := NewPrefixSuffix(test.prefix, test.suffix)
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -47,7 +47,7 @@ func TestPrefixSuffixIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexPrefixSuffix(b *testing.B) {
|
func BenchmarkIndexPrefixSuffix(b *testing.B) {
|
||||||
m := PrefixSuffix{"qew", "sqw"}
|
m := NewPrefixSuffix("qew", "sqw")
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, s := m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
@ -56,7 +56,7 @@ func BenchmarkIndexPrefixSuffix(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexPrefixSuffixParallel(b *testing.B) {
|
func BenchmarkIndexPrefixSuffixParallel(b *testing.B) {
|
||||||
m := PrefixSuffix{"qew", "sqw"}
|
m := NewPrefixSuffix("qew", "sqw")
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
|
|
|
@ -25,7 +25,7 @@ func TestPrefixIndex(t *testing.T) {
|
||||||
[]int{2, 3, 4, 5},
|
[]int{2, 3, 4, 5},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := Prefix{test.prefix}
|
p := NewPrefix(test.prefix)
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -37,7 +37,7 @@ func TestPrefixIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexPrefix(b *testing.B) {
|
func BenchmarkIndexPrefix(b *testing.B) {
|
||||||
m := Prefix{"qew"}
|
m := NewPrefix("qew")
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, s := m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
@ -46,7 +46,7 @@ func BenchmarkIndexPrefix(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexPrefixParallel(b *testing.B) {
|
func BenchmarkIndexPrefixParallel(b *testing.B) {
|
||||||
m := Prefix{"qew"}
|
m := NewPrefix("qew")
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
|
|
|
@ -10,6 +10,10 @@ type Range struct {
|
||||||
Not bool
|
Not bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewRange(lo, hi rune, not bool) Range {
|
||||||
|
return Range{lo, hi, not}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Range) Len() int {
|
func (self Range) Len() int {
|
||||||
return lenOne
|
return lenOne
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ func TestRangeIndex(t *testing.T) {
|
||||||
[]int{1},
|
[]int{1},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
m := Range{test.lo, test.hi, test.not}
|
m := NewRange(test.lo, test.hi, test.not)
|
||||||
index, segments := m.Index(test.fixture)
|
index, segments := m.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -47,7 +47,7 @@ func TestRangeIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexRange(b *testing.B) {
|
func BenchmarkIndexRange(b *testing.B) {
|
||||||
m := Range{'0', '9', false}
|
m := NewRange('0', '9', false)
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, s := m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
@ -56,7 +56,7 @@ func BenchmarkIndexRange(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexRangeParallel(b *testing.B) {
|
func BenchmarkIndexRangeParallel(b *testing.B) {
|
||||||
m := Range{'0', '9', false}
|
m := NewRange('0', '9', false)
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
|
|
|
@ -10,9 +10,9 @@ type Row struct {
|
||||||
Segments []int
|
Segments []int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRow(m Matchers, len int) Row {
|
func NewRow(len int, m ...Matcher) Row {
|
||||||
return Row{
|
return Row{
|
||||||
Matchers: m,
|
Matchers: Matchers(m),
|
||||||
RunesLength: len,
|
RunesLength: len,
|
||||||
Segments: []int{len},
|
Segments: []int{len},
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,6 @@ func (self Row) Index(s string) (int, []int) {
|
||||||
|
|
||||||
for i := range s {
|
for i := range s {
|
||||||
// this is not strict check but useful
|
// this is not strict check but useful
|
||||||
// when glob will be refactored for usage with []rune
|
|
||||||
// it will be better
|
|
||||||
if len(s[i:]) < self.RunesLength {
|
if len(s[i:]) < self.RunesLength {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestRowIndex(t *testing.T) {
|
||||||
Matchers{
|
Matchers{
|
||||||
NewText("abc"),
|
NewText("abc"),
|
||||||
NewText("def"),
|
NewText("def"),
|
||||||
Single{},
|
NewSingle(nil),
|
||||||
},
|
},
|
||||||
7,
|
7,
|
||||||
"qweabcdefghij",
|
"qweabcdefghij",
|
||||||
|
@ -28,7 +28,7 @@ func TestRowIndex(t *testing.T) {
|
||||||
Matchers{
|
Matchers{
|
||||||
NewText("abc"),
|
NewText("abc"),
|
||||||
NewText("def"),
|
NewText("def"),
|
||||||
Single{},
|
NewSingle(nil),
|
||||||
},
|
},
|
||||||
7,
|
7,
|
||||||
"abcd",
|
"abcd",
|
||||||
|
@ -36,10 +36,7 @@ func TestRowIndex(t *testing.T) {
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := Row{
|
p := NewRow(test.length, test.matchers...)
|
||||||
Matchers: test.matchers,
|
|
||||||
RunesLength: test.length,
|
|
||||||
}
|
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -51,14 +48,14 @@ func TestRowIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkRowIndex(b *testing.B) {
|
func BenchmarkRowIndex(b *testing.B) {
|
||||||
m := Row{
|
m := NewRow(
|
||||||
Matchers: Matchers{
|
7,
|
||||||
|
Matchers{
|
||||||
NewText("abc"),
|
NewText("abc"),
|
||||||
NewText("def"),
|
NewText("def"),
|
||||||
Single{},
|
NewSingle(nil),
|
||||||
},
|
}...,
|
||||||
RunesLength: 7,
|
)
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, s := m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
@ -67,14 +64,14 @@ func BenchmarkRowIndex(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexRowParallel(b *testing.B) {
|
func BenchmarkIndexRowParallel(b *testing.B) {
|
||||||
m := Row{
|
m := NewRow(
|
||||||
Matchers: Matchers{
|
7,
|
||||||
|
Matchers{
|
||||||
NewText("abc"),
|
NewText("abc"),
|
||||||
NewText("def"),
|
NewText("def"),
|
||||||
Single{},
|
NewSingle(nil),
|
||||||
},
|
}...,
|
||||||
RunesLength: 7,
|
)
|
||||||
}
|
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
|
|
|
@ -11,6 +11,10 @@ type Single struct {
|
||||||
Separators []rune
|
Separators []rune
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSingle(s []rune) Single {
|
||||||
|
return Single{s}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Single) Match(s string) bool {
|
func (self Single) Match(s string) bool {
|
||||||
r, w := utf8.DecodeRuneInString(s)
|
r, w := utf8.DecodeRuneInString(s)
|
||||||
if len(s) > w {
|
if len(s) > w {
|
||||||
|
@ -35,5 +39,5 @@ func (self Single) Index(s string) (int, []int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Single) String() string {
|
func (self Single) String() string {
|
||||||
return fmt.Sprintf("<single:![%s]>", self.Separators)
|
return fmt.Sprintf("<single:![%s]>", string(self.Separators))
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ func TestSingleIndex(t *testing.T) {
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := Single{test.separators}
|
p := NewSingle(test.separators)
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -37,7 +37,7 @@ func TestSingleIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexSingle(b *testing.B) {
|
func BenchmarkIndexSingle(b *testing.B) {
|
||||||
m := Single{bench_separators}
|
m := NewSingle(bench_separators)
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, s := m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
@ -46,7 +46,7 @@ func BenchmarkIndexSingle(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexSingleParallel(b *testing.B) {
|
func BenchmarkIndexSingleParallel(b *testing.B) {
|
||||||
m := Single{bench_separators}
|
m := NewSingle(bench_separators)
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
|
|
|
@ -9,13 +9,8 @@ type Suffix struct {
|
||||||
Suffix string
|
Suffix string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Suffix) Index(s string) (int, []int) {
|
func NewSuffix(s string) Suffix {
|
||||||
idx := strings.Index(s, self.Suffix)
|
return Suffix{s}
|
||||||
if idx == -1 {
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, []int{idx + len(self.Suffix)}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Suffix) Len() int {
|
func (self Suffix) Len() int {
|
||||||
|
@ -26,6 +21,15 @@ func (self Suffix) Match(s string) bool {
|
||||||
return strings.HasSuffix(s, self.Suffix)
|
return strings.HasSuffix(s, self.Suffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self Suffix) Index(s string) (int, []int) {
|
||||||
|
idx := strings.Index(s, self.Suffix)
|
||||||
|
if idx == -1 {
|
||||||
|
return -1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, []int{idx + len(self.Suffix)}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Suffix) String() string {
|
func (self Suffix) String() string {
|
||||||
return fmt.Sprintf("<suffix:%s>", self.Suffix)
|
return fmt.Sprintf("<suffix:%s>", self.Suffix)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ func TestSuffixIndex(t *testing.T) {
|
||||||
[]int{5},
|
[]int{5},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := Suffix{test.prefix}
|
p := NewSuffix(test.prefix)
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -37,7 +37,7 @@ func TestSuffixIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexSuffix(b *testing.B) {
|
func BenchmarkIndexSuffix(b *testing.B) {
|
||||||
m := Suffix{"qwe"}
|
m := NewSuffix("qwe")
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, s := m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
@ -46,7 +46,7 @@ func BenchmarkIndexSuffix(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexSuffixParallel(b *testing.B) {
|
func BenchmarkIndexSuffixParallel(b *testing.B) {
|
||||||
m := Suffix{"qwe"}
|
m := NewSuffix("qwe")
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
|
|
|
@ -6,6 +6,10 @@ import (
|
||||||
|
|
||||||
type Super struct{}
|
type Super struct{}
|
||||||
|
|
||||||
|
func NewSuper() Super {
|
||||||
|
return Super{}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Super) Match(s string) bool {
|
func (self Super) Match(s string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -15,8 +19,7 @@ func (self Super) Len() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self Super) Index(s string) (int, []int) {
|
func (self Super) Index(s string) (int, []int) {
|
||||||
//todo acquire here
|
segments := acquireSegments(len(s) + 1)
|
||||||
segments := make([]int, 0, len(s)+1)
|
|
||||||
for i := range s {
|
for i := range s {
|
||||||
segments = append(segments, i)
|
segments = append(segments, i)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func TestSuperIndex(t *testing.T) {
|
||||||
[]int{0},
|
[]int{0},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
p := Super{}
|
p := NewSuper()
|
||||||
index, segments := p.Index(test.fixture)
|
index, segments := p.Index(test.fixture)
|
||||||
if index != test.index {
|
if index != test.index {
|
||||||
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
|
||||||
|
@ -34,7 +34,7 @@ func TestSuperIndex(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexSuper(b *testing.B) {
|
func BenchmarkIndexSuper(b *testing.B) {
|
||||||
m := Super{}
|
m := NewSuper()
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
_, s := m.Index(bench_pattern)
|
_, s := m.Index(bench_pattern)
|
||||||
|
@ -43,7 +43,7 @@ func BenchmarkIndexSuper(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkIndexSuperParallel(b *testing.B) {
|
func BenchmarkIndexSuperParallel(b *testing.B) {
|
||||||
m := Super{}
|
m := NewSuper()
|
||||||
|
|
||||||
b.RunParallel(func(pb *testing.PB) {
|
b.RunParallel(func(pb *testing.PB) {
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
|
|
Loading…
Reference in New Issue