remove slices

This commit is contained in:
gobwas 2016-02-05 17:29:41 +03:00
parent 462ce6e3ac
commit 4b229a908d
34 changed files with 105 additions and 138 deletions

View File

@ -13,17 +13,17 @@ func (self Any) Match(s string) bool {
return strings.IndexAnyRunes(s, self.Separators) == -1
}
func (self Any) Index(s string, segments []int) (int, []int) {
func (self Any) Index(s string) (int, []int) {
found := strings.IndexAnyRunes(s, self.Separators)
switch found {
case -1:
case 0:
segments = append(segments)
return 0, segments
return 0, []int{0}
default:
s = s[:found]
}
segments := make([]int, 0, len(s))
for i := range s {
segments = append(segments, i)
}

View File

@ -23,14 +23,13 @@ func (self AnyOf) Match(s string) bool {
return false
}
func (self AnyOf) Index(s string, segments []int) (int, []int) {
func (self AnyOf) Index(s string) (int, []int) {
index := -1
// create reusable segments
in := make([]int, 0, len(s))
segments := make([]int, 0, len(s))
for _, m := range self.Matchers {
idx, seg := m.Index(s, in[:0])
idx, seg := m.Index(s)
if idx == -1 {
continue
}

View File

@ -42,7 +42,7 @@ func TestAnyOfIndex(t *testing.T) {
},
} {
everyOf := AnyOf{test.matchers}
index, segments := everyOf.Index(test.fixture, []int{})
index, segments := everyOf.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}

View File

@ -26,7 +26,7 @@ func TestAnyIndex(t *testing.T) {
},
} {
p := Any{test.sep}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -39,19 +39,17 @@ func TestAnyIndex(t *testing.T) {
func BenchmarkIndexAny(b *testing.B) {
m := Any{bench_separators}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexAnyParallel(b *testing.B) {
m := Any{bench_separators}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -51,7 +51,7 @@ func (self BTree) Len() int {
}
// todo?
func (self BTree) Index(s string, segments []int) (int, []int) {
func (self BTree) Index(s string) (int, []int) {
return -1, nil
}
@ -65,8 +65,8 @@ func (self BTree) Match(s string) bool {
return false
}
// try to cut unnecessary parts
// by knowledge of length of right and left part
// try to cut unnecessary parts
// by knowledge of length of right and left part
var offset, limit int
if self.LeftLengthRunes >= 0 {
offset = self.LeftLengthRunes
@ -77,13 +77,9 @@ func (self BTree) Match(s string) bool {
limit = inputLen
}
// reusable segments list
// inputLen is the maximum size of output segments values
in := make([]int, 0, inputLen)
for offset < limit {
// search for matching part in substring
index, segments := self.Value.Index(s[offset:limit], in[:0])
index, segments := self.Value.Index(s[offset:limit])
if index == -1 {
return false
}

View File

@ -14,7 +14,7 @@ func (self Contains) Match(s string) bool {
return strings.Contains(s, self.Needle) != self.Not
}
func (self Contains) Index(s string, segments []int) (int, []int) {
func (self Contains) Index(s string) (int, []int) {
var offset int
idx := strings.Index(s, self.Needle)
@ -26,13 +26,14 @@ func (self Contains) Index(s string, segments []int) (int, []int) {
offset = idx + len(self.Needle)
if len(s) <= offset {
return 0, append(segments, offset)
return 0, []int{offset}
}
s = s[offset:]
} else if idx != -1 {
s = s[:idx]
}
segments := make([]int, 0, len(s)+1)
for i, _ := range s {
segments = append(segments, offset+i)
}

View File

@ -43,7 +43,7 @@ func TestContainsIndex(t *testing.T) {
},
} {
p := Contains{test.prefix, test.not}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -56,19 +56,17 @@ func TestContainsIndex(t *testing.T) {
func BenchmarkIndexContains(b *testing.B) {
m := Contains{string(bench_separators), true}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexContainsParallel(b *testing.B) {
m := Contains{string(bench_separators), true}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -25,19 +25,18 @@ func (self EveryOf) Len() (l int) {
return
}
func (self EveryOf) Index(s string, out []int) (int, []int) {
func (self EveryOf) Index(s string) (int, []int) {
var index int
var offset int
// make `in` with cap as len(s),
// cause it is the maximum size of output segments values
in := make([]int, 0, len(s))
next := make([]int, 0, len(s))
current := make([]int, 0, len(s))
sub := s
for i, m := range self.Matchers {
idx, seg := m.Index(sub, in[:0])
idx, seg := m.Index(sub)
if idx == -1 {
return -1, nil
}
@ -72,11 +71,7 @@ func (self EveryOf) Index(s string, out []int) (int, []int) {
offset += idx
}
// copy result in `out` to prevent
// allocation `current` on heap
out = append(out, current...)
return index, out
return index, current
}
func (self EveryOf) Match(s string) bool {

View File

@ -34,7 +34,7 @@ func TestEveryOfIndex(t *testing.T) {
},
} {
everyOf := EveryOf{test.matchers}
index, segments := everyOf.Index(test.fixture, []int{})
index, segments := everyOf.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}

View File

@ -25,10 +25,10 @@ func (self List) Len() int {
return lenOne
}
func (self List) Index(s string, segments []int) (int, []int) {
func (self List) Index(s string) (int, []int) {
for i, r := range s {
if self.Not == (runes.IndexRune(self.List, r) == -1) {
return i, append(segments, utf8.RuneLen(r))
return i, []int{utf8.RuneLen(r)}
}
}

View File

@ -29,7 +29,7 @@ func TestListIndex(t *testing.T) {
},
} {
p := List{test.list, test.not}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -41,20 +41,18 @@ func TestListIndex(t *testing.T) {
func BenchmarkIndexList(b *testing.B) {
m := List{[]rune("def"), false}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexListParallel(b *testing.B) {
m := List{[]rune("def"), false}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -11,7 +11,7 @@ const lenNo = -1
type Matcher interface {
Match(string) bool
Index(string, []int) (int, []int)
Index(string) (int, []int)
Len() int
String() string
}

View File

@ -21,7 +21,9 @@ func (self Max) Match(s string) bool {
return true
}
func (self Max) Index(s string, segments []int) (int, []int) {
func (self Max) Index(s string) (int, []int) {
segments := make([]int, 0, self.Limit+1)
segments = append(segments, 0)
var count int
for i, r := range s {

View File

@ -26,7 +26,7 @@ func TestMaxIndex(t *testing.T) {
},
} {
p := Max{test.limit}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -38,20 +38,18 @@ func TestMaxIndex(t *testing.T) {
func BenchmarkIndexMax(b *testing.B) {
m := Max{10}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexMaxParallel(b *testing.B) {
m := Max{10}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -21,19 +21,18 @@ func (self Min) Match(s string) bool {
return false
}
func (self Min) Index(s string, segments []int) (int, []int) {
func (self Min) Index(s string) (int, []int) {
var count int
var found bool
segments := make([]int, 0, len(s)-self.Limit+1)
for i, r := range s {
count++
if count >= self.Limit {
found = true
segments = append(segments, i+utf8.RuneLen(r))
}
}
if !found {
if len(segments) == 0 {
return -1, nil
}

View File

@ -26,7 +26,7 @@ func TestMinIndex(t *testing.T) {
},
} {
p := Min{test.limit}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -38,20 +38,18 @@ func TestMinIndex(t *testing.T) {
func BenchmarkIndexMin(b *testing.B) {
m := Min{10}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexMinParallel(b *testing.B) {
m := Min{10}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -10,8 +10,8 @@ func (self Nothing) Match(s string) bool {
return len(s) == 0
}
func (self Nothing) Index(s string, segments []int) (int, []int) {
return 0, append(segments, 0)
func (self Nothing) Index(s string) (int, []int) {
return 0, []int{0}
}
func (self Nothing) Len() int {

View File

@ -23,7 +23,7 @@ func TestNothingIndex(t *testing.T) {
},
} {
p := Nothing{}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -35,20 +35,18 @@ func TestNothingIndex(t *testing.T) {
func BenchmarkIndexNothing(b *testing.B) {
m := Nothing{}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexNothingParallel(b *testing.B) {
m := Nothing{}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -10,7 +10,7 @@ type Prefix struct {
Prefix string
}
func (self Prefix) Index(s string, segments []int) (int, []int) {
func (self Prefix) Index(s string) (int, []int) {
idx := strings.Index(s, self.Prefix)
if idx == -1 {
return -1, nil
@ -24,6 +24,7 @@ func (self Prefix) Index(s string, segments []int) (int, []int) {
sub = ""
}
segments := make([]int, 0, len(sub)+1)
segments = append(segments, length)
for i, r := range sub {
segments = append(segments, length+i+utf8.RuneLen(r))

View File

@ -9,7 +9,7 @@ type PrefixSuffix struct {
Prefix, Suffix string
}
func (self PrefixSuffix) Index(s string, segments []int) (int, []int) {
func (self PrefixSuffix) Index(s string) (int, []int) {
prefixIdx := strings.Index(s, self.Prefix)
if prefixIdx == -1 {
return -1, nil
@ -17,26 +17,27 @@ func (self PrefixSuffix) Index(s string, segments []int) (int, []int) {
suffixLen := len(self.Suffix)
if suffixLen > 0 {
for sub := s[prefixIdx:]; ; {
suffixIdx := strings.LastIndex(sub, self.Suffix)
if suffixIdx == -1 {
break
}
segments = append(segments, suffixIdx+suffixLen)
sub = sub[:suffixIdx]
}
if len(segments) == 0 {
return -1, nil
}
reverseSegments(segments)
} else {
segments = append(segments, len(s)-prefixIdx)
if suffixLen <= 0 {
return prefixIdx, []int{len(s) - prefixIdx}
}
segments := make([]int, 0, len(s)-prefixIdx)
for sub := s[prefixIdx:]; ; {
suffixIdx := strings.LastIndex(sub, self.Suffix)
if suffixIdx == -1 {
break
}
segments = append(segments, suffixIdx+suffixLen)
sub = sub[:suffixIdx]
}
if len(segments) == 0 {
return -1, nil
}
reverseSegments(segments)
return prefixIdx, segments
}

View File

@ -36,7 +36,7 @@ func TestPrefixSuffixIndex(t *testing.T) {
},
} {
p := PrefixSuffix{test.prefix, test.suffix}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -48,20 +48,18 @@ func TestPrefixSuffixIndex(t *testing.T) {
func BenchmarkIndexPrefixSuffix(b *testing.B) {
m := PrefixSuffix{"qew", "sqw"}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexPrefixSuffixParallel(b *testing.B) {
m := PrefixSuffix{"qew", "sqw"}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -26,7 +26,7 @@ func TestPrefixIndex(t *testing.T) {
},
} {
p := Prefix{test.prefix}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -38,20 +38,18 @@ func TestPrefixIndex(t *testing.T) {
func BenchmarkIndexPrefix(b *testing.B) {
m := Prefix{"qew"}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexPrefixParallel(b *testing.B) {
m := Prefix{"qew"}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -28,10 +28,10 @@ func (self Range) Match(s string) bool {
return inRange == !self.Not
}
func (self Range) Index(s string, segments []int) (int, []int) {
func (self Range) Index(s string) (int, []int) {
for i, r := range s {
if self.Not != (r >= self.Lo && r <= self.Hi) {
return i, append(segments, utf8.RuneLen(r))
return i, []int{utf8.RuneLen(r)}
}
}

View File

@ -36,7 +36,7 @@ func TestRangeIndex(t *testing.T) {
},
} {
m := Range{test.lo, test.hi, test.not}
index, segments := m.Index(test.fixture, []int{})
index, segments := m.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -48,20 +48,18 @@ func TestRangeIndex(t *testing.T) {
func BenchmarkIndexRange(b *testing.B) {
m := Range{'0', '9', false}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexRangeParallel(b *testing.B) {
m := Range{'0', '9', false}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -52,7 +52,7 @@ func (self Row) Len() (l int) {
return self.RunesLength
}
func (self Row) Index(s string, segments []int) (int, []int) {
func (self Row) Index(s string) (int, []int) {
if !self.lenOk(s) {
return -1, nil
}
@ -66,7 +66,7 @@ func (self Row) Index(s string, segments []int) (int, []int) {
}
if self.matchAll(s[i:]) {
return i, append(segments, self.RunesLength)
return i, []int{self.RunesLength}
}
}

View File

@ -40,7 +40,7 @@ func TestRowIndex(t *testing.T) {
Matchers: test.matchers,
RunesLength: test.length,
}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -59,10 +59,9 @@ func BenchmarkRowIndex(b *testing.B) {
},
RunesLength: 7,
}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
@ -75,11 +74,10 @@ func BenchmarkIndexRowParallel(b *testing.B) {
},
RunesLength: 7,
}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -24,10 +24,10 @@ func (self Single) Len() int {
return lenOne
}
func (self Single) Index(s string, segments []int) (int, []int) {
func (self Single) Index(s string) (int, []int) {
for i, r := range s {
if runes.IndexRune(self.Separators, r) == -1 {
return i, append(segments, utf8.RuneLen(r))
return i, []int{utf8.RuneLen(r)}
}
}

View File

@ -26,7 +26,7 @@ func TestSingleIndex(t *testing.T) {
},
} {
p := Single{test.separators}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -38,20 +38,18 @@ func TestSingleIndex(t *testing.T) {
func BenchmarkIndexSingle(b *testing.B) {
m := Single{bench_separators}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexSingleParallel(b *testing.B) {
m := Single{bench_separators}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -9,13 +9,13 @@ type Suffix struct {
Suffix string
}
func (self Suffix) Index(s string, segments []int) (int, []int) {
func (self Suffix) Index(s string) (int, []int) {
idx := strings.Index(s, self.Suffix)
if idx == -1 {
return -1, nil
}
return 0, append(segments, idx+len(self.Suffix))
return 0, []int{idx + len(self.Suffix)}
}
func (self Suffix) Len() int {

View File

@ -26,7 +26,7 @@ func TestSuffixIndex(t *testing.T) {
},
} {
p := Suffix{test.prefix}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -38,20 +38,18 @@ func TestSuffixIndex(t *testing.T) {
func BenchmarkIndexSuffix(b *testing.B) {
m := Suffix{"qwe"}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexSuffixParallel(b *testing.B) {
m := Suffix{"qwe"}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -14,7 +14,8 @@ func (self Super) Len() int {
return lenNo
}
func (self Super) Index(s string, segments []int) (int, []int) {
func (self Super) Index(s string) (int, []int) {
segments := make([]int, 0, len(s)+1)
for i := range s {
segments = append(segments, i)
}

View File

@ -23,7 +23,7 @@ func TestSuperIndex(t *testing.T) {
},
} {
p := Super{}
index, segments := p.Index(test.fixture, []int{})
index, segments := p.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -35,20 +35,18 @@ func TestSuperIndex(t *testing.T) {
func BenchmarkIndexSuper(b *testing.B) {
m := Super{}
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexSuperParallel(b *testing.B) {
m := Super{}
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}

View File

@ -29,13 +29,13 @@ func (self Text) Len() int {
return self.RunesLength
}
func (self Text) Index(s string, segments []int) (int, []int) {
func (self Text) Index(s string) (int, []int) {
index := strings.Index(s, self.Str)
if index == -1 {
return -1, nil
}
return index, append(segments, self.BytesLength)
return index, []int{self.BytesLength}
}
func (self Text) String() string {

View File

@ -26,7 +26,7 @@ func TestTextIndex(t *testing.T) {
},
} {
m := NewText(test.text)
index, segments := m.Index(test.fixture, []int{})
index, segments := m.Index(test.fixture)
if index != test.index {
t.Errorf("#%d unexpected index: exp: %d, act: %d", id, test.index, index)
}
@ -38,20 +38,18 @@ func TestTextIndex(t *testing.T) {
func BenchmarkIndexText(b *testing.B) {
m := NewText("foo")
in := make([]int, 0, len(bench_pattern))
for i := 0; i < b.N; i++ {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
}
func BenchmarkIndexTextParallel(b *testing.B) {
m := NewText("foo")
in := make([]int, 0, len(bench_pattern))
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m.Index(bench_pattern, in[:0])
m.Index(bench_pattern)
}
})
}