Only do regex lookups when there was no equality match.

For the label matching index-based preselection phase, don't do an OR
between equality and non-equality matchers. Execute only one of the two
(with equality matchers preferred when present).

Fixes https://github.com/prometheus/prometheus/issues/924
pull/927/head
Julius Volz 9 years ago
parent a59b7ac7f8
commit 517badc21d

@ -428,11 +428,11 @@ func (s *memorySeriesStorage) MetricsForLabelMatchers(matchers ...*metric.LabelM
} }
var resFPs map[clientmodel.Fingerprint]struct{} var resFPs map[clientmodel.Fingerprint]struct{}
// If we cannot make a preselection based on equality matchers, expanding the other matchers to labels
// and intersecting their fingerprints is still likely to be the best choice.
if len(equals) > 0 { if len(equals) > 0 {
resFPs = s.fingerprintsForLabelPairs(equals...) resFPs = s.fingerprintsForLabelPairs(equals...)
} } else {
// If we cannot make a preselection based on equality matchers, expanding the other matchers to labels
// and intersecting their fingerprints is still likely to be the best choice.
var remaining metric.LabelMatchers var remaining metric.LabelMatchers
for _, matcher := range filters { for _, matcher := range filters {
// Equal matches are all empty values. // Equal matches are all empty values.
@ -461,6 +461,7 @@ func (s *memorySeriesStorage) MetricsForLabelMatchers(matchers ...*metric.LabelM
} }
// The intersected matchers no longer need to be compared against the actual metrics. // The intersected matchers no longer need to be compared against the actual metrics.
filters = remaining filters = remaining
}
result := make(map[clientmodel.Fingerprint]clientmodel.COWMetric, len(resFPs)) result := make(map[clientmodel.Fingerprint]clientmodel.COWMetric, len(resFPs))
for fp := range resFPs { for fp := range resFPs {

@ -70,7 +70,7 @@ func TestMatches(t *testing.T) {
}{ }{
{ {
matchers: metric.LabelMatchers{newMatcher(metric.Equal, "label1", "x")}, matchers: metric.LabelMatchers{newMatcher(metric.Equal, "label1", "x")},
expected: fingerprints[:0], expected: clientmodel.Fingerprints{},
}, },
{ {
matchers: metric.LabelMatchers{newMatcher(metric.Equal, "label1", "test_0")}, matchers: metric.LabelMatchers{newMatcher(metric.Equal, "label1", "test_0")},
@ -161,6 +161,20 @@ func TestMatches(t *testing.T) {
}, },
expected: append(append(clientmodel.Fingerprints{}, fingerprints[30:35]...), fingerprints[45:60]...), expected: append(append(clientmodel.Fingerprints{}, fingerprints[30:35]...), fingerprints[45:60]...),
}, },
{
matchers: metric.LabelMatchers{
newMatcher(metric.Equal, "label1", `nonexistent`),
newMatcher(metric.RegexMatch, "label2", `test`),
},
expected: clientmodel.Fingerprints{},
},
{
matchers: metric.LabelMatchers{
newMatcher(metric.Equal, "label1", `test_0`),
newMatcher(metric.RegexMatch, "label2", `nonexistent`),
},
expected: clientmodel.Fingerprints{},
},
} }
for _, mt := range matcherTests { for _, mt := range matcherTests {

Loading…
Cancel
Save