mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Use Matcher.SetMatches()
Signed-off-by: Marco Pracucci <marco@pracucci.com>
This commit is contained in:
parent
a1a45990a2
commit
515890ec53
|
@ -18,7 +18,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/oklog/ulid"
|
"github.com/oklog/ulid"
|
||||||
|
@ -186,55 +185,6 @@ func (q *blockChunkQuerier) Select(ctx context.Context, sortSeries bool, hints *
|
||||||
return NewBlockChunkSeriesSet(q.blockID, q.index, q.chunks, q.tombstones, p, mint, maxt, disableTrimming)
|
return NewBlockChunkSeriesSet(q.blockID, q.index, q.chunks, q.tombstones, p, mint, maxt, disableTrimming)
|
||||||
}
|
}
|
||||||
|
|
||||||
func findSetMatches(pattern string) []string {
|
|
||||||
// Return empty matches if the wrapper from Prometheus is missing.
|
|
||||||
if len(pattern) < 6 || pattern[:4] != "^(?:" || pattern[len(pattern)-2:] != ")$" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
escaped := false
|
|
||||||
sets := []*strings.Builder{{}}
|
|
||||||
init := 4
|
|
||||||
end := len(pattern) - 2
|
|
||||||
// If the regex is wrapped in a group we can remove the first and last parentheses
|
|
||||||
if pattern[init] == '(' && pattern[end-1] == ')' {
|
|
||||||
init++
|
|
||||||
end--
|
|
||||||
}
|
|
||||||
for i := init; i < end; i++ {
|
|
||||||
if escaped {
|
|
||||||
switch {
|
|
||||||
case isRegexMetaCharacter(pattern[i]):
|
|
||||||
sets[len(sets)-1].WriteByte(pattern[i])
|
|
||||||
case pattern[i] == '\\':
|
|
||||||
sets[len(sets)-1].WriteByte('\\')
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
escaped = false
|
|
||||||
} else {
|
|
||||||
switch {
|
|
||||||
case isRegexMetaCharacter(pattern[i]):
|
|
||||||
if pattern[i] == '|' {
|
|
||||||
sets = append(sets, &strings.Builder{})
|
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
case pattern[i] == '\\':
|
|
||||||
escaped = true
|
|
||||||
default:
|
|
||||||
sets[len(sets)-1].WriteByte(pattern[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
matches := make([]string, 0, len(sets))
|
|
||||||
for _, s := range sets {
|
|
||||||
if s.Len() > 0 {
|
|
||||||
matches = append(matches, s.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matches
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostingsForMatchers assembles a single postings iterator against the index reader
|
// PostingsForMatchers assembles a single postings iterator against the index reader
|
||||||
// based on the given matchers. The resulting postings are not ordered by series.
|
// based on the given matchers. The resulting postings are not ordered by series.
|
||||||
func PostingsForMatchers(ctx context.Context, ix IndexReader, ms ...*labels.Matcher) (index.Postings, error) {
|
func PostingsForMatchers(ctx context.Context, ix IndexReader, ms ...*labels.Matcher) (index.Postings, error) {
|
||||||
|
@ -376,7 +326,7 @@ func postingsForMatcher(ctx context.Context, ix IndexReader, m *labels.Matcher)
|
||||||
|
|
||||||
// Fast-path for set matching.
|
// Fast-path for set matching.
|
||||||
if m.Type == labels.MatchRegexp {
|
if m.Type == labels.MatchRegexp {
|
||||||
setMatches := findSetMatches(m.GetRegexString())
|
setMatches := m.SetMatches()
|
||||||
if len(setMatches) > 0 {
|
if len(setMatches) > 0 {
|
||||||
return ix.Postings(ctx, m.Name, setMatches...)
|
return ix.Postings(ctx, m.Name, setMatches...)
|
||||||
}
|
}
|
||||||
|
@ -407,7 +357,7 @@ func inversePostingsForMatcher(ctx context.Context, ix IndexReader, m *labels.Ma
|
||||||
// Inverse of a MatchNotRegexp is MatchRegexp (double negation).
|
// Inverse of a MatchNotRegexp is MatchRegexp (double negation).
|
||||||
// Fast-path for set matching.
|
// Fast-path for set matching.
|
||||||
if m.Type == labels.MatchNotRegexp {
|
if m.Type == labels.MatchNotRegexp {
|
||||||
setMatches := findSetMatches(m.GetRegexString())
|
setMatches := m.SetMatches()
|
||||||
if len(setMatches) > 0 {
|
if len(setMatches) > 0 {
|
||||||
return ix.Postings(ctx, m.Name, setMatches...)
|
return ix.Postings(ctx, m.Name, setMatches...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2637,69 +2637,6 @@ func BenchmarkSetMatcher(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refer to https://github.com/prometheus/prometheus/issues/2651.
|
|
||||||
func TestFindSetMatches(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
pattern string
|
|
||||||
exp []string
|
|
||||||
}{
|
|
||||||
// Single value, coming from a `bar=~"foo"` selector.
|
|
||||||
{
|
|
||||||
pattern: "^(?:foo)$",
|
|
||||||
exp: []string{
|
|
||||||
"foo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Simple sets.
|
|
||||||
{
|
|
||||||
pattern: "^(?:foo|bar|baz)$",
|
|
||||||
exp: []string{
|
|
||||||
"foo",
|
|
||||||
"bar",
|
|
||||||
"baz",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Simple sets containing escaped characters.
|
|
||||||
{
|
|
||||||
pattern: "^(?:fo\\.o|bar\\?|\\^baz)$",
|
|
||||||
exp: []string{
|
|
||||||
"fo.o",
|
|
||||||
"bar?",
|
|
||||||
"^baz",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// Simple sets containing special characters without escaping.
|
|
||||||
{
|
|
||||||
pattern: "^(?:fo.o|bar?|^baz)$",
|
|
||||||
exp: nil,
|
|
||||||
},
|
|
||||||
// Missing wrapper.
|
|
||||||
{
|
|
||||||
pattern: "foo|bar|baz",
|
|
||||||
exp: nil,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, c := range cases {
|
|
||||||
matches := findSetMatches(c.pattern)
|
|
||||||
if len(c.exp) == 0 {
|
|
||||||
if len(matches) != 0 {
|
|
||||||
t.Errorf("Evaluating %s, unexpected result %v", c.pattern, matches)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if len(matches) != len(c.exp) {
|
|
||||||
t.Errorf("Evaluating %s, length of result not equal to exp", c.pattern)
|
|
||||||
} else {
|
|
||||||
for i := 0; i < len(c.exp); i++ {
|
|
||||||
if c.exp[i] != matches[i] {
|
|
||||||
t.Errorf("Evaluating %s, unexpected result %s", c.pattern, matches[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPostingsForMatchers(t *testing.T) {
|
func TestPostingsForMatchers(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue