import match package

This commit is contained in:
Josh Baker 2016-08-30 07:21:50 -07:00
parent c5d75aaa71
commit 74368e4f86
2 changed files with 3 additions and 123 deletions

View File

@ -18,6 +18,7 @@ import (
"github.com/tidwall/btree"
"github.com/tidwall/gjson"
"github.com/tidwall/match"
"github.com/tidwall/rtree"
)
@ -326,7 +327,7 @@ func (db *DB) createIndex(
db.keys.Ascend(func(item btree.Item) bool {
dbi := item.(*dbItem)
if !wildcardMatch(dbi.key, idx.pattern, idx.uc) {
if !match.Match(dbi.key, idx.pattern) {
return true
}
if less != nil {
@ -341,67 +342,6 @@ func (db *DB) createIndex(
return nil
}
// wilcardMatch returns true if str matches pattern. This is a very
// simple wildcard match where '*' matches on any number characters
// and '?' matches on any one character.
func wildcardMatch(str, pattern string, uc bool) bool {
if pattern == "*" {
return true
}
if !uc {
return deepMatch(str, pattern)
}
rstr := make([]rune, 0, len(str))
rpattern := make([]rune, 0, len(pattern))
for _, r := range str {
rstr = append(rstr, r)
}
for _, r := range pattern {
rpattern = append(rpattern, r)
}
return deepMatchRune(rstr, rpattern)
}
func deepMatch(str, pattern string) bool {
for len(pattern) > 0 {
switch pattern[0] {
default:
if len(str) == 0 || str[0] != pattern[0] {
return false
}
case '?':
if len(str) == 0 {
return false
}
case '*':
return deepMatch(str, pattern[1:]) ||
(len(str) > 0 && deepMatch(str[1:], pattern))
}
str = str[1:]
pattern = pattern[1:]
}
return len(str) == 0 && len(pattern) == 0
}
func deepMatchRune(str, pattern []rune) bool {
for len(pattern) > 0 {
switch pattern[0] {
default:
if len(str) == 0 || str[0] != pattern[0] {
return false
}
case '?':
if len(str) == 0 {
return false
}
case '*':
return deepMatchRune(str, pattern[1:]) ||
(len(str) > 0 && deepMatchRune(str[1:], pattern))
}
str = str[1:]
pattern = pattern[1:]
}
return len(str) == 0 && len(pattern) == 0
}
// DropIndex removes an index.
func (db *DB) DropIndex(name string) error {
db.mu.Lock()
@ -492,7 +432,7 @@ func (db *DB) insertIntoDatabase(item *dbItem) *dbItem {
db.exps.ReplaceOrInsert(item)
}
for _, idx := range db.idxs {
if !wildcardMatch(item.key, idx.pattern, idx.uc) {
if !match.Match(item.key, idx.pattern) {
continue
}
if idx.btr != nil {

View File

@ -1107,66 +1107,6 @@ func test(t *testing.T, a, b bool) {
}
}
func TestMatch(t *testing.T) {
if !wildcardMatch("hello world", "hello world", false) {
t.Fatal("fail")
}
if wildcardMatch("hello world", "jello world", false) {
t.Fatal("fail")
}
if !wildcardMatch("hello world", "hello*", false) {
t.Fatal("fail")
}
if wildcardMatch("hello world", "jello*", false) {
t.Fatal("fail")
}
if !wildcardMatch("hello world", "hello?world", false) {
t.Fatal("fail")
}
if wildcardMatch("hello world", "jello?world", false) {
t.Fatal("fail")
}
if !wildcardMatch("hello world", "he*o?world", false) {
t.Fatal("fail")
}
if !wildcardMatch("hello world", "he*o?wor*", false) {
t.Fatal("fail")
}
if !wildcardMatch("hello world", "he*o?*r*", false) {
t.Fatal("fail")
}
if !wildcardMatch("的情况下解析一个", "*", true) {
t.Fatal("fail")
}
if !wildcardMatch("的情况下解析一个", "*况下*", true) {
t.Fatal("fail")
}
if !wildcardMatch("的情况下解析一个", "*况?*", true) {
t.Fatal("fail")
}
if !wildcardMatch("的情况下解析一个", "的情况?解析一个", true) {
t.Fatal("fail")
}
}
func TestPatternMatching(t *testing.T) {
test(t, wildcardMatch("hello", "hello", false), true)
test(t, wildcardMatch("hello", "h*", false), true)
test(t, wildcardMatch("hello", "h*o", false), true)
test(t, wildcardMatch("hello", "h*l*o", false), true)
test(t, wildcardMatch("hello", "h*z*o", false), false)
test(t, wildcardMatch("hello", "*l*o", false), true)
test(t, wildcardMatch("hello", "*l*", false), true)
test(t, wildcardMatch("hello", "*?*", false), true)
test(t, wildcardMatch("hello", "*", false), true)
test(t, wildcardMatch("hello", "h?llo", false), true)
test(t, wildcardMatch("hello", "h?l?o", false), true)
test(t, wildcardMatch("", "*", false), true)
test(t, wildcardMatch("", "", false), true)
test(t, wildcardMatch("h", "", false), false)
test(t, wildcardMatch("", "?", false), false)
}
func TestBasic(t *testing.T) {
rand.Seed(time.Now().UnixNano())
db := testOpen(t)