diff --git a/match/row.go b/match/row.go index 434c4ca..a079aa4 100644 --- a/match/row.go +++ b/match/row.go @@ -2,7 +2,6 @@ package match import ( "fmt" - "unicode/utf8" ) type Row struct { @@ -13,23 +12,40 @@ type Row struct { func (self Row) matchAll(s string) bool { var idx int for _, m := range self.Matchers { - l := m.Len() - if !m.Match(s[idx : idx+l]) { + length := m.Len() + + var next, i int + for next = range s[idx:] { + i++ + if i == length { + break + } + } + + if i < length || !m.Match(s[idx:idx+next+1]) { return false } - idx += l + idx += next + 1 } return true } -func (self Row) Match(s string) bool { - if utf8.RuneCountInString(s) < self.RunesLength { - return false +func (self Row) lenOk(s string) bool { + var i int + for range s { + i++ + if i >= self.RunesLength { + return true + } } - return self.matchAll(s) + return false +} + +func (self Row) Match(s string) bool { + return self.lenOk(s) && self.matchAll(s) } func (self Row) Len() (l int) { @@ -37,20 +53,20 @@ func (self Row) Len() (l int) { } func (self Row) Index(s string) (int, []int) { - l := utf8.RuneCountInString(s) - if l < self.RunesLength { + if !self.lenOk(s) { return -1, nil } for i := range s { - sub := s[i:] - if self.matchAll(sub) { - return i, []int{self.RunesLength} + // 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 { + break } - l -= 1 - if l < self.RunesLength { - return -1, nil + if self.matchAll(s[i:]) { + return i, []int{self.RunesLength} } } diff --git a/match/row_test.go b/match/row_test.go index c9422c4..4b59fe0 100644 --- a/match/row_test.go +++ b/match/row_test.go @@ -5,6 +5,20 @@ import ( "testing" ) +func BenchmarkRowIndex(b *testing.B) { + m := Row{ + Matchers: Matchers{ + NewText("abc"), + NewText("def"), + Single{}, + }, + RunesLength: 7, + } + for i := 0; i < b.N; i++ { + m.Index("abcdefghijk") + } +} + func TestRowIndex(t *testing.T) { for id, test := range []struct { matchers Matchers diff --git a/readme.md b/readme.md index f6edfba..6b26cf0 100644 --- a/readme.md +++ b/readme.md @@ -100,7 +100,7 @@ Run `go test -bench=.` from source root to see the benchmarks: Pattern | Fixture | Operations | Speed (ns/op) --------|---------|------------|-------------- -`[a-z][!a-x]*cat*[h][!b]*eyes*` | `my cat has very bright eyes` | 2000000 | 549 +`[a-z][!a-x]*cat*[h][!b]*eyes*` | `my cat has very bright eyes` | 2000000 | 527 `https://*.google.*` | `https://account.google.com` | 10000000 | 121 `{https://*.google.*,*yandex.*,*yahoo.*,*mail.ru}` | `http://yahoo.com` | 10000000 | 167 `{https://*gobwas.com,http://exclude.gobwas.com}` | `https://safe.gobwas.com` | 50000000 | 24.7