Apply matchers when fetching label values

This commit is contained in:
Patrick Oyarzun 2023-04-17 19:58:56 -05:00
parent 8ef48ad9a7
commit cc9072ad64
No known key found for this signature in database
GPG key ID: 44B349E67EC0257A
2 changed files with 19 additions and 0 deletions

View file

@ -338,6 +338,24 @@ func labelValuesWithMatchers(r IndexReader, name string, matchers ...*labels.Mat
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "fetching values of label %s", name) return nil, errors.Wrapf(err, "fetching values of label %s", name)
} }
// If we have a matcher for the label name, we can filter out values that don't match
// before we fetch postings. This is especially useful for labels with many values.
// e.g. __name__ with a selector like {__name__="xyz"}
for _, m := range matchers {
if m.Name != name {
continue
}
for i := len(allValues) - 1; i >= 0; i-- {
if m.Matches(allValues[i]) {
continue
}
allValues = append(allValues[:i], allValues[i+1:]...)
}
}
valuesPostings := make([]index.Postings, len(allValues)) valuesPostings := make([]index.Postings, len(allValues))
for i, value := range allValues { for i, value := range allValues {
valuesPostings[i], err = r.Postings(name, value) valuesPostings[i], err = r.Postings(name, value)

View file

@ -182,6 +182,7 @@ func benchmarkLabelValuesWithMatchers(b *testing.B, ir IndexReader) {
labelName string labelName string
matchers []*labels.Matcher matchers []*labels.Matcher
}{ }{
{`i with i="1"`, "i", []*labels.Matcher{i1}},
// i has 100k values. // i has 100k values.
{`i with n="1"`, "i", []*labels.Matcher{n1}}, {`i with n="1"`, "i", []*labels.Matcher{n1}},
{`i with n="^.+$"`, "i", []*labels.Matcher{nPlus}}, {`i with n="^.+$"`, "i", []*labels.Matcher{nPlus}},