Skip to content

Commit

Permalink
perf(filter): Optimize maps read/writes in hot path
Browse files Browse the repository at this point in the history
  • Loading branch information
Tetrergeru committed Oct 28, 2024
1 parent ae27338 commit cfc2d1b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 14 deletions.
11 changes: 4 additions & 7 deletions filter/prefix_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,26 +113,23 @@ func (source *PrefixTree) Match(metric string) []string {
}

// MatchWithValue finds metric in tree and returns payloads for all matched nodes.
func (source *PrefixTree) MatchWithValue(metric string) map[string]MatchingHandler {
func (source *PrefixTree) MatchWithValue(metric string, callback func(string, MatchingHandler)) {
nodes, _ := source.findNodes(metric)
if nodes == nil {
return map[string]MatchingHandler{}
return
}

matched := make(map[string]MatchingHandler)
for _, node := range nodes {
if node.Terminal {
if node.Payload == nil {
matched[node.Prefix] = nil
callback(node.Prefix, nil)
}

for pattern, matchingHandler := range node.Payload {
matched[pattern] = matchingHandler
callback(pattern, matchingHandler)
}
}
}

return matched
}

func (source *PrefixTree) findNodes(metric string) ([]*PatternNode, int) {
Expand Down
41 changes: 36 additions & 5 deletions filter/prefix_tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ func TestPrefixTree(t *testing.T) {
})

Convey("MatchWithValue should return empty map", func() {
matchedPatterns := prefixTree.MatchWithValue("any_string")
matchedPatterns := map[string]MatchingHandler{}
prefixTree.MatchWithValue("any_string", func(s string, mh MatchingHandler) {
_, ok := matchedPatterns[s]
So(ok, ShouldBeFalse)
matchedPatterns[s] = mh
})
So(matchedPatterns, ShouldResemble, map[string]MatchingHandler{})
})
})
Expand Down Expand Up @@ -96,14 +101,28 @@ func TestPrefixTree(t *testing.T) {
"Complex.matching.pattern": nil,
"Complex.*.*": nil,
}
matchedPatterns := prefixTree.MatchWithValue(metric)

matchedPatterns := map[string]MatchingHandler{}
prefixTree.MatchWithValue(metric, func(s string, mh MatchingHandler) {
_, ok := matchedPatterns[s]
So(ok, ShouldBeFalse)
matchedPatterns[s] = mh
})

So(matchedPatterns, ShouldResemble, matchedValue)
})

Convey("For metrics not from tree", func() {
metric := "Simple.notmatching.pattern"
matchedValue := map[string]MatchingHandler{}
matchedPatterns := prefixTree.MatchWithValue(metric)

matchedPatterns := map[string]MatchingHandler{}
prefixTree.MatchWithValue(metric, func(s string, mh MatchingHandler) {
_, ok := matchedPatterns[s]
So(ok, ShouldBeFalse)
matchedPatterns[s] = mh
})

So(matchedPatterns, ShouldResemble, matchedValue)
})
})
Expand Down Expand Up @@ -143,7 +162,13 @@ func TestPrefixTree(t *testing.T) {
}},
}
for _, testCase := range testCases {
matchedPatterns := prefixTree.MatchWithValue(testCase.Metric)
matchedPatterns := map[string]MatchingHandler{}
prefixTree.MatchWithValue(testCase.Metric, func(s string, mh MatchingHandler) {
_, ok := matchedPatterns[s]
So(ok, ShouldBeFalse)
matchedPatterns[s] = mh
})

So(len(matchedPatterns), ShouldEqual, len(testCase.MatchedPatterns))
for pKey, pValue := range testCase.MatchedPatterns {
So(matchedPatterns, ShouldContainKey, pKey)
Expand All @@ -162,7 +187,13 @@ func TestPrefixTree(t *testing.T) {
"Simple.notmatching.pattern",
}
for _, testCase := range testCases {
matchedPatterns := prefixTree.MatchWithValue(testCase)
matchedPatterns := map[string]MatchingHandler{}
prefixTree.MatchWithValue(testCase, func(s string, mh MatchingHandler) {
_, ok := matchedPatterns[s]
So(ok, ShouldBeFalse)
matchedPatterns[s] = mh
})

So(matchedPatterns, ShouldResemble, map[string]MatchingHandler{})
}
})
Expand Down
4 changes: 2 additions & 2 deletions filter/series_by_tag_pattern_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ func NewSeriesByTagPatternIndex(
func (index *SeriesByTagPatternIndex) MatchPatterns(metricName string, labels map[string]string) []string {
matchedPatterns := make([]string, 0)

matchingHandlersWithCorrespondingNameTag := index.namesPrefixTree.MatchWithValue(metricName)
for pattern, matchingHandler := range matchingHandlersWithCorrespondingNameTag {
callback := func(pattern string, matchingHandler MatchingHandler) {
if matchingHandler(metricName, labels) {
matchedPatterns = append(matchedPatterns, pattern)
}
}
index.namesPrefixTree.MatchWithValue(metricName, callback)

for pattern, matchingHandler := range index.withoutStrictNameTagPatternMatchers {
if matchingHandler(metricName, labels) {
Expand Down

0 comments on commit cfc2d1b

Please sign in to comment.