lib/storage: optimize label matching for regexp ending with literal suffix

For example, `{label=~"foo.*bar.+baz"}` contains literal suffix `baz`,
so it should work faster now.
This commit is contained in:
Aliaksandr Valialkin 2020-05-13 11:39:03 +03:00
parent 3b0f66a227
commit 8bb44a5d09
2 changed files with 10 additions and 0 deletions

View file

@ -497,7 +497,16 @@ func getOptimizedReMatchFuncExt(reMatch func(b []byte) bool, sre *syntax.Regexp)
literals = append(literals, []byte(string(sub.Rune))) literals = append(literals, []byte(string(sub.Rune)))
} }
} }
var suffix []byte
if isLiteral(sre.Sub[len(sre.Sub)-1]) {
suffix = literals[len(literals)-1]
literals = literals[:len(literals)-1]
}
return func(b []byte) bool { return func(b []byte) bool {
if len(suffix) > 0 && !bytes.HasSuffix(b, suffix) {
// Fast path - b has no the given suffix
return false
}
bOrig := b bOrig := b
for _, literal := range literals { for _, literal := range literals {
n := bytes.Index(b, literal) n := bytes.Index(b, literal)

View file

@ -68,6 +68,7 @@ func TestGetRegexpFromCache(t *testing.T) {
f(".*foo.*bar", nil, []string{"foobar", "xfoobar", "xfooxbar", "fooxbar"}, []string{"", "foobarx", "afoobarx", "aaa"}) f(".*foo.*bar", nil, []string{"foobar", "xfoobar", "xfooxbar", "fooxbar"}, []string{"", "foobarx", "afoobarx", "aaa"})
f("foo.*bar", nil, []string{"foobar", "fooxbar"}, []string{"xfoobar", "", "foobarx", "aaa"}) f("foo.*bar", nil, []string{"foobar", "fooxbar"}, []string{"xfoobar", "", "foobarx", "aaa"})
f("foo.*bar.*", nil, []string{"foobar", "fooxbar", "foobarx", "fooxbarx"}, []string{"", "afoobarx", "aaa", "afoobar"}) f("foo.*bar.*", nil, []string{"foobar", "fooxbar", "foobarx", "fooxbarx"}, []string{"", "afoobarx", "aaa", "afoobar"})
f("foo.*bar.*baz", nil, []string{"foobarbaz", "fooxbarxbaz", "foobarxbaz", "fooxbarbaz"}, []string{"", "afoobarx", "aaa", "afoobar", "foobarzaz"})
f(".+foo.+(b|c).+", nil, []string{"xfooxbar", "xfooxca"}, []string{"", "foo", "foob", "xfooc", "xfoodc"}) f(".+foo.+(b|c).+", nil, []string{"xfooxbar", "xfooxca"}, []string{"", "foo", "foob", "xfooc", "xfoodc"})
f("(?i)foo", nil, []string{"foo", "Foo", "FOO"}, []string{"xfoo", "foobar", "xFOObar"}) f("(?i)foo", nil, []string{"foo", "Foo", "FOO"}, []string{"xfoo", "foobar", "xFOObar"})