diff --git a/lib/storage/tag_filters.go b/lib/storage/tag_filters.go index f40a48e66..60e62cddd 100644 --- a/lib/storage/tag_filters.go +++ b/lib/storage/tag_filters.go @@ -497,7 +497,16 @@ func getOptimizedReMatchFuncExt(reMatch func(b []byte) bool, sre *syntax.Regexp) 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 { + if len(suffix) > 0 && !bytes.HasSuffix(b, suffix) { + // Fast path - b has no the given suffix + return false + } bOrig := b for _, literal := range literals { n := bytes.Index(b, literal) diff --git a/lib/storage/tag_filters_test.go b/lib/storage/tag_filters_test.go index a75547482..8ff934581 100644 --- a/lib/storage/tag_filters_test.go +++ b/lib/storage/tag_filters_test.go @@ -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", "fooxbar"}, []string{"xfoobar", "", "foobarx", "aaa"}) 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("(?i)foo", nil, []string{"foo", "Foo", "FOO"}, []string{"xfoo", "foobar", "xFOObar"})