Skip to content

Commit

Permalink
perf(filter): improved handling of non-strict asterisk tags (#1050)
Browse files Browse the repository at this point in the history
  • Loading branch information
almostinf authored Jul 10, 2024
1 parent 2ead98b commit c191a9b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 21 deletions.
51 changes: 30 additions & 21 deletions filter/series_by_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ func createMatchingHandlerForOneTag(
compatibility *Compatibility,
) (MatchingHandler, error) {
var matchingHandlerCondition func(string) bool
var err error
allowMatchEmpty := false

switch spec.Operator {
Expand All @@ -182,28 +183,13 @@ func createMatchingHandlerForOneTag(
matchingHandlerCondition = func(value string) bool {
return value != spec.Value
}
case MatchOperator:
case MatchOperator, NotMatchOperator:
allowMatchEmpty = compatibility.AllowRegexMatchEmpty

matchRegex, err := newMatchRegex(spec.Value, compatibility)
matchingHandlerCondition, err = handleRegexMatch(spec, compatibility)
if err != nil {
return nil, err
}

matchingHandlerCondition = func(value string) bool {
return matchRegex.MatchString(value)
}
case NotMatchOperator:
allowMatchEmpty = compatibility.AllowRegexMatchEmpty

matchRegex, err := newMatchRegex(spec.Value, compatibility)
if err != nil {
return nil, err
}

matchingHandlerCondition = func(value string) bool {
return !matchRegex.MatchString(value)
}
default:
matchingHandlerCondition = func(_ string) bool {
return false
Expand All @@ -224,14 +210,37 @@ func createMatchingHandlerForOneTag(
}, nil
}

func handleRegexMatch(
spec TagSpec,
compatibility *Compatibility,
) (func(string) bool, error) {
isMatchOperator := spec.Operator == MatchOperator

// We don't need to create a regular for the asterisk, because in such a tag
// it is the fact of the tag's presence that matters, not its value.
if spec.Value == "*" || spec.Value == ".*" {
return func(value string) bool {
return isMatchOperator
}, nil
}

matchRegex, err := newMatchRegex(spec.Value, compatibility)
if err != nil {
return nil, fmt.Errorf("failed to create new match regex: %w", err)
}

return func(value string) bool {
matchRes := matchRegex.MatchString(value)

// Invert the result depending on the match operator.
return isMatchOperator == matchRes
}, nil
}

func newMatchRegex(
tagValue string,
compatibility *Compatibility,
) (*regexp.Regexp, error) {
if tagValue == "*" {
tagValue = ".*"
}

if !compatibility.AllowRegexLooseStartMatch {
tagValue = "^" + tagValue
}
Expand Down
22 changes: 22 additions & 0 deletions filter/series_by_tag_pattern_index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,15 @@ func TestSeriesByTagPatternIndex(t *testing.T) {
"tag2=~.*": {
{"tag2", MatchOperator, ".*"},
},
"tag2!=~*": {
{"tag2", NotMatchOperator, "*"},
},
"tag2!=~.*": {
{"tag2", NotMatchOperator, ".*"},
},
"tag2!=~al2": {
{"tag2", NotMatchOperator, "al2"},
},
"tag1=val1;tag2=val2": {
{"tag1", EqualOperator, "val1"},
{"tag2", EqualOperator, "val2"},
Expand Down Expand Up @@ -293,6 +302,7 @@ func TestSeriesByTagPatternIndex(t *testing.T) {
"name=~cpu;tag1=val1",
"name=~test1",
"tag1=~al1",
"tag2!=~al2",
"tag2=~*",
"tag2=~.*",
},
Expand Down Expand Up @@ -322,6 +332,18 @@ func TestSeriesByTagPatternIndex(t *testing.T) {
"tag2=~.*",
},
},
{
"cpu.test1.test3",
map[string]string{"tag2": "val3"},
[]string{
"name=cpu.*.*",
"name=cpu.test1.*",
"name=~test1",
"tag2!=~al2",
"tag2=~*",
"tag2=~.*",
},
},
{
"cpu.test1.test2",
map[string]string{"tag1": "val1", "tag2": "val2"},
Expand Down

0 comments on commit c191a9b

Please sign in to comment.