feat: dont compile regex matcher if we know its a literal (#12434)

labels: dont compile regex matcher if we know its a literal

Signed-off-by: Michael Hoffmann <mhoffm@posteo.de>

Co-authored-by: Sharad <sharadgaur@gmail.com>
This commit is contained in:
Michael Hoffmann 2023-06-07 22:54:30 +02:00 committed by GitHub
parent 4268feb9d7
commit 344c8ff97c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 4 deletions

View File

@ -102,12 +102,12 @@ func TestInverse(t *testing.T) {
expected: &Matcher{Type: MatchEqual, Name: "name2", Value: "value2"},
},
{
matcher: &Matcher{Type: MatchRegexp, Name: "name3", Value: "value3"},
expected: &Matcher{Type: MatchNotRegexp, Name: "name3", Value: "value3"},
matcher: &Matcher{Type: MatchRegexp, Name: "name3", Value: "value3.*"},
expected: &Matcher{Type: MatchNotRegexp, Name: "name3", Value: "value3.*"},
},
{
matcher: &Matcher{Type: MatchNotRegexp, Name: "name4", Value: "value4"},
expected: &Matcher{Type: MatchRegexp, Name: "name4", Value: "value4"},
matcher: &Matcher{Type: MatchNotRegexp, Name: "name4", Value: "value4.*"},
expected: &Matcher{Type: MatchRegexp, Name: "name4", Value: "value4.*"},
},
}
@ -123,3 +123,13 @@ func BenchmarkMatchType_String(b *testing.B) {
_ = MatchType(i % int(MatchNotRegexp+1)).String()
}
}
func BenchmarkNewMatcher(b *testing.B) {
b.Run("regex matcher with literal", func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i <= b.N; i++ {
NewMatcher(MatchRegexp, "foo", "bar")
}
})
}

View File

@ -25,9 +25,16 @@ type FastRegexMatcher struct {
prefix string
suffix string
contains string
// shortcut for literals
literal bool
value string
}
func NewFastRegexMatcher(v string) (*FastRegexMatcher, error) {
if isLiteral(v) {
return &FastRegexMatcher{literal: true, value: v}, nil
}
re, err := regexp.Compile("^(?:" + v + ")$")
if err != nil {
return nil, err
@ -50,6 +57,9 @@ func NewFastRegexMatcher(v string) (*FastRegexMatcher, error) {
}
func (m *FastRegexMatcher) MatchString(s string) bool {
if m.literal {
return s == m.value
}
if m.prefix != "" && !strings.HasPrefix(s, m.prefix) {
return false
}
@ -63,9 +73,16 @@ func (m *FastRegexMatcher) MatchString(s string) bool {
}
func (m *FastRegexMatcher) GetRegexString() string {
if m.literal {
return m.value
}
return m.re.String()
}
func isLiteral(re string) bool {
return regexp.QuoteMeta(re) == re
}
// optimizeConcatRegex returns literal prefix/suffix text that can be safely
// checked against the label value before running the regexp matcher.
func optimizeConcatRegex(r *syntax.Regexp) (prefix, suffix, contains string) {