mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-12 16:44:05 -08:00
Port tsdb to use pkg/labels. (#6326)
* Port tsdb to use pkg/labels. Signed-off-by: Tom Wilkie <tom.wilkie@gmail.com> * Get tests passing. Signed-off-by: Tom Wilkie <tom.wilkie@gmail.com> * Remove useless cast. Signed-off-by: Tom Wilkie <tom.wilkie@gmail.com> * Appease linters. Signed-off-by: Tom Wilkie <tom.wilkie@gmail.com> * Fix review comments Signed-off-by: Ganesh Vernekar <cs15btech11018@iith.ac.in>
This commit is contained in:
parent
23c0299d85
commit
de0a772b8e
|
@ -201,6 +201,24 @@ func (ls Labels) Has(name string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithoutEmpty returns the labelset without empty labels.
|
||||||
|
// May return the same labelset.
|
||||||
|
func (ls Labels) WithoutEmpty() Labels {
|
||||||
|
for _, v := range ls {
|
||||||
|
if v.Value != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
els := make(Labels, 0, len(ls)-1)
|
||||||
|
for _, v := range ls {
|
||||||
|
if v.Value != "" {
|
||||||
|
els = append(els, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return els
|
||||||
|
}
|
||||||
|
return ls
|
||||||
|
}
|
||||||
|
|
||||||
// Equal returns whether the two label sets are equal.
|
// Equal returns whether the two label sets are equal.
|
||||||
func Equal(ls, o Labels) bool {
|
func Equal(ls, o Labels) bool {
|
||||||
if len(ls) != len(o) {
|
if len(ls) != len(o) {
|
||||||
|
|
|
@ -68,6 +68,15 @@ func NewMatcher(t MatchType, n, v string) (*Matcher, error) {
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MustNewMatcher panics on error - only for use in tests!
|
||||||
|
func MustNewMatcher(mt MatchType, name, val string) *Matcher {
|
||||||
|
m, err := NewMatcher(mt, name, val)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Matcher) String() string {
|
func (m *Matcher) String() string {
|
||||||
return fmt.Sprintf("%s%s%q", m.Name, m.Type, m.Value)
|
return fmt.Sprintf("%s%s%q", m.Name, m.Type, m.Value)
|
||||||
}
|
}
|
||||||
|
@ -86,3 +95,18 @@ func (m *Matcher) Matches(s string) bool {
|
||||||
}
|
}
|
||||||
panic("labels.Matcher.Matches: invalid match type")
|
panic("labels.Matcher.Matches: invalid match type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inverse returns a matcher that matches the opposite.
|
||||||
|
func (m *Matcher) Inverse() (*Matcher, error) {
|
||||||
|
switch m.Type {
|
||||||
|
case MatchEqual:
|
||||||
|
return NewMatcher(MatchNotEqual, m.Name, m.Value)
|
||||||
|
case MatchNotEqual:
|
||||||
|
return NewMatcher(MatchEqual, m.Name, m.Value)
|
||||||
|
case MatchRegexp:
|
||||||
|
return NewMatcher(MatchNotRegexp, m.Name, m.Value)
|
||||||
|
case MatchNotRegexp:
|
||||||
|
return NewMatcher(MatchRegexp, m.Name, m.Value)
|
||||||
|
}
|
||||||
|
panic("labels.Matcher.Matches: invalid match type")
|
||||||
|
}
|
||||||
|
|
87
pkg/labels/test_utils.go
Normal file
87
pkg/labels/test_utils.go
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
// Copyright 2017 The Prometheus Authors
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package labels
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Slice is a sortable slice of label sets.
|
||||||
|
type Slice []Labels
|
||||||
|
|
||||||
|
func (s Slice) Len() int { return len(s) }
|
||||||
|
func (s Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||||
|
func (s Slice) Less(i, j int) bool { return Compare(s[i], s[j]) < 0 }
|
||||||
|
|
||||||
|
// Selector holds constraints for matching against a label set.
|
||||||
|
type Selector []*Matcher
|
||||||
|
|
||||||
|
// Matches returns whether the labels satisfy all matchers.
|
||||||
|
func (s Selector) Matches(labels Labels) bool {
|
||||||
|
for _, m := range s {
|
||||||
|
if v := labels.Get(m.Name); !m.Matches(v) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadLabels reads up to n label sets in a JSON formatted file fn. It is mostly useful
|
||||||
|
// to load testing data.
|
||||||
|
func ReadLabels(fn string, n int) ([]Labels, error) {
|
||||||
|
f, err := os.Open(fn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(f)
|
||||||
|
|
||||||
|
var mets []Labels
|
||||||
|
hashes := map[uint64]struct{}{}
|
||||||
|
i := 0
|
||||||
|
|
||||||
|
for scanner.Scan() && i < n {
|
||||||
|
m := make(Labels, 0, 10)
|
||||||
|
|
||||||
|
r := strings.NewReplacer("\"", "", "{", "", "}", "")
|
||||||
|
s := r.Replace(scanner.Text())
|
||||||
|
|
||||||
|
labelChunks := strings.Split(s, ",")
|
||||||
|
for _, labelChunk := range labelChunks {
|
||||||
|
split := strings.Split(labelChunk, ":")
|
||||||
|
m = append(m, Label{Name: split[0], Value: split[1]})
|
||||||
|
}
|
||||||
|
// Order of the k/v labels matters, don't assume we'll always receive them already sorted.
|
||||||
|
sort.Sort(m)
|
||||||
|
|
||||||
|
h := m.Hash()
|
||||||
|
if _, ok := hashes[h]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
mets = append(mets, m)
|
||||||
|
hashes[h] = struct{}{}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
if i != n {
|
||||||
|
return mets, errors.Errorf("requested %d metrics but found %d", n, i)
|
||||||
|
}
|
||||||
|
return mets, nil
|
||||||
|
}
|
|
@ -32,7 +32,6 @@ import (
|
||||||
"github.com/prometheus/prometheus/pkg/labels"
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/pkg/relabel"
|
"github.com/prometheus/prometheus/pkg/relabel"
|
||||||
"github.com/prometheus/prometheus/prompb"
|
"github.com/prometheus/prometheus/prompb"
|
||||||
tsdbLabels "github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/record"
|
"github.com/prometheus/prometheus/tsdb/record"
|
||||||
"github.com/prometheus/prometheus/tsdb/wal"
|
"github.com/prometheus/prometheus/tsdb/wal"
|
||||||
)
|
)
|
||||||
|
@ -443,7 +442,7 @@ func releaseLabels(ls labels.Labels) {
|
||||||
|
|
||||||
// processExternalLabels merges externalLabels into ls. If ls contains
|
// processExternalLabels merges externalLabels into ls. If ls contains
|
||||||
// a label in externalLabels, the value in ls wins.
|
// a label in externalLabels, the value in ls wins.
|
||||||
func processExternalLabels(ls tsdbLabels.Labels, externalLabels labels.Labels) labels.Labels {
|
func processExternalLabels(ls labels.Labels, externalLabels labels.Labels) labels.Labels {
|
||||||
i, j, result := 0, 0, make(labels.Labels, 0, len(ls)+len(externalLabels))
|
i, j, result := 0, 0, make(labels.Labels, 0, len(ls)+len(externalLabels))
|
||||||
for i < len(ls) && j < len(externalLabels) {
|
for i < len(ls) && j < len(externalLabels) {
|
||||||
if ls[i].Name < externalLabels[j].Name {
|
if ls[i].Name < externalLabels[j].Name {
|
||||||
|
|
|
@ -36,7 +36,6 @@ import (
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"github.com/prometheus/prometheus/pkg/labels"
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/prompb"
|
"github.com/prometheus/prometheus/prompb"
|
||||||
tsdbLabels "github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/record"
|
"github.com/prometheus/prometheus/tsdb/record"
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
@ -117,7 +116,7 @@ func TestSampleDeliveryOrder(t *testing.T) {
|
||||||
})
|
})
|
||||||
series = append(series, record.RefSeries{
|
series = append(series, record.RefSeries{
|
||||||
Ref: uint64(i),
|
Ref: uint64(i),
|
||||||
Labels: tsdbLabels.Labels{tsdbLabels.Label{Name: "__name__", Value: name}},
|
Labels: labels.Labels{labels.Label{Name: "__name__", Value: name}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +185,7 @@ func TestSeriesReset(t *testing.T) {
|
||||||
for i := 0; i < numSegments; i++ {
|
for i := 0; i < numSegments; i++ {
|
||||||
series := []record.RefSeries{}
|
series := []record.RefSeries{}
|
||||||
for j := 0; j < numSeries; j++ {
|
for j := 0; j < numSeries; j++ {
|
||||||
series = append(series, record.RefSeries{Ref: uint64((i * 100) + j), Labels: tsdbLabels.Labels{{Name: "a", Value: "a"}}})
|
series = append(series, record.RefSeries{Ref: uint64((i * 100) + j), Labels: labels.Labels{{Name: "a", Value: "a"}}})
|
||||||
}
|
}
|
||||||
m.StoreSeries(series, i)
|
m.StoreSeries(series, i)
|
||||||
}
|
}
|
||||||
|
@ -266,8 +265,8 @@ func TestReleaseNoninternedString(t *testing.T) {
|
||||||
m.StoreSeries([]record.RefSeries{
|
m.StoreSeries([]record.RefSeries{
|
||||||
{
|
{
|
||||||
Ref: uint64(i),
|
Ref: uint64(i),
|
||||||
Labels: tsdbLabels.Labels{
|
Labels: labels.Labels{
|
||||||
tsdbLabels.Label{
|
labels.Label{
|
||||||
Name: "asdf",
|
Name: "asdf",
|
||||||
Value: fmt.Sprintf("%d", i),
|
Value: fmt.Sprintf("%d", i),
|
||||||
},
|
},
|
||||||
|
@ -338,7 +337,7 @@ func createTimeseries(n int) ([]record.RefSample, []record.RefSeries) {
|
||||||
})
|
})
|
||||||
series = append(series, record.RefSeries{
|
series = append(series, record.RefSeries{
|
||||||
Ref: uint64(i),
|
Ref: uint64(i),
|
||||||
Labels: tsdbLabels.Labels{{Name: "__name__", Value: name}},
|
Labels: labels.Labels{{Name: "__name__", Value: name}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return samples, series
|
return samples, series
|
||||||
|
@ -541,27 +540,27 @@ func BenchmarkStartup(b *testing.B) {
|
||||||
|
|
||||||
func TestProcessExternalLabels(t *testing.T) {
|
func TestProcessExternalLabels(t *testing.T) {
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
labels tsdbLabels.Labels
|
labels labels.Labels
|
||||||
externalLabels labels.Labels
|
externalLabels labels.Labels
|
||||||
expected labels.Labels
|
expected labels.Labels
|
||||||
}{
|
}{
|
||||||
// Test adding labels at the end.
|
// Test adding labels at the end.
|
||||||
{
|
{
|
||||||
labels: tsdbLabels.Labels{{Name: "a", Value: "b"}},
|
labels: labels.Labels{{Name: "a", Value: "b"}},
|
||||||
externalLabels: labels.Labels{{Name: "c", Value: "d"}},
|
externalLabels: labels.Labels{{Name: "c", Value: "d"}},
|
||||||
expected: labels.Labels{{Name: "a", Value: "b"}, {Name: "c", Value: "d"}},
|
expected: labels.Labels{{Name: "a", Value: "b"}, {Name: "c", Value: "d"}},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Test adding labels at the beginning.
|
// Test adding labels at the beginning.
|
||||||
{
|
{
|
||||||
labels: tsdbLabels.Labels{{Name: "c", Value: "d"}},
|
labels: labels.Labels{{Name: "c", Value: "d"}},
|
||||||
externalLabels: labels.Labels{{Name: "a", Value: "b"}},
|
externalLabels: labels.Labels{{Name: "a", Value: "b"}},
|
||||||
expected: labels.Labels{{Name: "a", Value: "b"}, {Name: "c", Value: "d"}},
|
expected: labels.Labels{{Name: "a", Value: "b"}, {Name: "c", Value: "d"}},
|
||||||
},
|
},
|
||||||
|
|
||||||
// Test we don't override existing labels.
|
// Test we don't override existing labels.
|
||||||
{
|
{
|
||||||
labels: tsdbLabels.Labels{{Name: "a", Value: "b"}},
|
labels: labels.Labels{{Name: "a", Value: "b"}},
|
||||||
externalLabels: labels.Labels{{Name: "a", Value: "c"}},
|
externalLabels: labels.Labels{{Name: "a", Value: "c"}},
|
||||||
expected: labels.Labels{{Name: "a", Value: "b"}},
|
expected: labels.Labels{{Name: "a", Value: "b"}},
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,17 +24,9 @@ import (
|
||||||
"github.com/prometheus/prometheus/storage"
|
"github.com/prometheus/prometheus/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustNewLabelMatcher(mt labels.MatchType, name, val string) *labels.Matcher {
|
|
||||||
m, err := labels.NewMatcher(mt, name, val)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExternalLabelsQuerierSelect(t *testing.T) {
|
func TestExternalLabelsQuerierSelect(t *testing.T) {
|
||||||
matchers := []*labels.Matcher{
|
matchers := []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "job", "api-server"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "api-server"),
|
||||||
}
|
}
|
||||||
q := &externalLabelsQuerier{
|
q := &externalLabelsQuerier{
|
||||||
Querier: mockQuerier{},
|
Querier: mockQuerier{},
|
||||||
|
@ -61,10 +53,10 @@ func TestExternalLabelsQuerierAddExternalLabels(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
inMatchers: []*labels.Matcher{
|
inMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "job", "api-server"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "api-server"),
|
||||||
},
|
},
|
||||||
outMatchers: []*labels.Matcher{
|
outMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "job", "api-server"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "api-server"),
|
||||||
},
|
},
|
||||||
added: labels.Labels{},
|
added: labels.Labels{},
|
||||||
},
|
},
|
||||||
|
@ -74,12 +66,12 @@ func TestExternalLabelsQuerierAddExternalLabels(t *testing.T) {
|
||||||
{Name: "region", Value: "europe"},
|
{Name: "region", Value: "europe"},
|
||||||
},
|
},
|
||||||
inMatchers: []*labels.Matcher{
|
inMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "job", "api-server"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "api-server"),
|
||||||
},
|
},
|
||||||
outMatchers: []*labels.Matcher{
|
outMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "job", "api-server"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "api-server"),
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "region", "europe"),
|
labels.MustNewMatcher(labels.MatchEqual, "region", "europe"),
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "dc", "berlin-01"),
|
labels.MustNewMatcher(labels.MatchEqual, "dc", "berlin-01"),
|
||||||
},
|
},
|
||||||
added: labels.Labels{
|
added: labels.Labels{
|
||||||
{Name: "dc", Value: "berlin-01"},
|
{Name: "dc", Value: "berlin-01"},
|
||||||
|
@ -92,13 +84,13 @@ func TestExternalLabelsQuerierAddExternalLabels(t *testing.T) {
|
||||||
{Name: "dc", Value: "berlin-01"},
|
{Name: "dc", Value: "berlin-01"},
|
||||||
},
|
},
|
||||||
inMatchers: []*labels.Matcher{
|
inMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "job", "api-server"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "api-server"),
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "dc", "munich-02"),
|
labels.MustNewMatcher(labels.MatchEqual, "dc", "munich-02"),
|
||||||
},
|
},
|
||||||
outMatchers: []*labels.Matcher{
|
outMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "job", "api-server"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "api-server"),
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "region", "europe"),
|
labels.MustNewMatcher(labels.MatchEqual, "region", "europe"),
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "dc", "munich-02"),
|
labels.MustNewMatcher(labels.MatchEqual, "dc", "munich-02"),
|
||||||
},
|
},
|
||||||
added: labels.Labels{
|
added: labels.Labels{
|
||||||
{Name: "region", Value: "europe"},
|
{Name: "region", Value: "europe"},
|
||||||
|
@ -227,12 +219,12 @@ func TestRequiredMatchersFilter(t *testing.T) {
|
||||||
storage.QueryableFunc(func(ctx context.Context, mint, maxt int64) (storage.Querier, error) {
|
storage.QueryableFunc(func(ctx context.Context, mint, maxt int64) (storage.Querier, error) {
|
||||||
return mockQuerier{ctx: ctx, mint: mint, maxt: maxt}, nil
|
return mockQuerier{ctx: ctx, mint: mint, maxt: maxt}, nil
|
||||||
}),
|
}),
|
||||||
[]*labels.Matcher{mustNewLabelMatcher(labels.MatchEqual, "special", "label")},
|
[]*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "special", "label")},
|
||||||
)
|
)
|
||||||
|
|
||||||
want := &requiredMatchersQuerier{
|
want := &requiredMatchersQuerier{
|
||||||
Querier: mockQuerier{ctx: ctx, mint: 0, maxt: 50},
|
Querier: mockQuerier{ctx: ctx, mint: 0, maxt: 50},
|
||||||
requiredMatchers: []*labels.Matcher{mustNewLabelMatcher(labels.MatchEqual, "special", "label")},
|
requiredMatchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "special", "label")},
|
||||||
}
|
}
|
||||||
have, err := f.Querier(ctx, 0, 50)
|
have, err := f.Querier(ctx, 0, 50)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -253,66 +245,66 @@ func TestRequiredLabelsQuerierSelect(t *testing.T) {
|
||||||
{
|
{
|
||||||
requiredMatchers: []*labels.Matcher{},
|
requiredMatchers: []*labels.Matcher{},
|
||||||
matchers: []*labels.Matcher{
|
matchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
},
|
},
|
||||||
seriesSet: mockSeriesSet{},
|
seriesSet: mockSeriesSet{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
requiredMatchers: []*labels.Matcher{
|
requiredMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
},
|
},
|
||||||
matchers: []*labels.Matcher{
|
matchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
},
|
},
|
||||||
seriesSet: mockSeriesSet{},
|
seriesSet: mockSeriesSet{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
requiredMatchers: []*labels.Matcher{
|
requiredMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
},
|
},
|
||||||
matchers: []*labels.Matcher{
|
matchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchRegexp, "special", "label"),
|
labels.MustNewMatcher(labels.MatchRegexp, "special", "label"),
|
||||||
},
|
},
|
||||||
seriesSet: storage.NoopSeriesSet(),
|
seriesSet: storage.NoopSeriesSet(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
requiredMatchers: []*labels.Matcher{
|
requiredMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
},
|
},
|
||||||
matchers: []*labels.Matcher{
|
matchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "different"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "different"),
|
||||||
},
|
},
|
||||||
seriesSet: storage.NoopSeriesSet(),
|
seriesSet: storage.NoopSeriesSet(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
requiredMatchers: []*labels.Matcher{
|
requiredMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
},
|
},
|
||||||
matchers: []*labels.Matcher{
|
matchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "foo", "bar"),
|
labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"),
|
||||||
},
|
},
|
||||||
seriesSet: mockSeriesSet{},
|
seriesSet: mockSeriesSet{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
requiredMatchers: []*labels.Matcher{
|
requiredMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "foo", "bar"),
|
labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"),
|
||||||
},
|
},
|
||||||
matchers: []*labels.Matcher{
|
matchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "foo", "baz"),
|
labels.MustNewMatcher(labels.MatchEqual, "foo", "baz"),
|
||||||
},
|
},
|
||||||
seriesSet: storage.NoopSeriesSet(),
|
seriesSet: storage.NoopSeriesSet(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
requiredMatchers: []*labels.Matcher{
|
requiredMatchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "foo", "bar"),
|
labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"),
|
||||||
},
|
},
|
||||||
matchers: []*labels.Matcher{
|
matchers: []*labels.Matcher{
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "special", "label"),
|
labels.MustNewMatcher(labels.MatchEqual, "special", "label"),
|
||||||
mustNewLabelMatcher(labels.MatchEqual, "foo", "bar"),
|
labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"),
|
||||||
},
|
},
|
||||||
seriesSet: mockSeriesSet{},
|
seriesSet: mockSeriesSet{},
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,7 +17,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/alecthomas/units"
|
"github.com/alecthomas/units"
|
||||||
"github.com/go-kit/kit/log"
|
"github.com/go-kit/kit/log"
|
||||||
|
@ -27,7 +26,6 @@ import (
|
||||||
"github.com/prometheus/prometheus/pkg/labels"
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/storage"
|
"github.com/prometheus/prometheus/storage"
|
||||||
"github.com/prometheus/prometheus/tsdb"
|
"github.com/prometheus/prometheus/tsdb"
|
||||||
tsdbLabels "github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNotReady is returned if the underlying storage is not ready yet.
|
// ErrNotReady is returned if the underlying storage is not ready yet.
|
||||||
|
@ -244,12 +242,7 @@ type querier struct {
|
||||||
q tsdb.Querier
|
q tsdb.Querier
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q querier) Select(_ *storage.SelectParams, oms ...*labels.Matcher) (storage.SeriesSet, storage.Warnings, error) {
|
func (q querier) Select(_ *storage.SelectParams, ms ...*labels.Matcher) (storage.SeriesSet, storage.Warnings, error) {
|
||||||
ms := make([]tsdbLabels.Matcher, 0, len(oms))
|
|
||||||
|
|
||||||
for _, om := range oms {
|
|
||||||
ms = append(ms, convertMatcher(om))
|
|
||||||
}
|
|
||||||
set, err := q.q.Select(ms...)
|
set, err := q.q.Select(ms...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -279,15 +272,15 @@ type series struct {
|
||||||
s tsdb.Series
|
s tsdb.Series
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s series) Labels() labels.Labels { return toLabels(s.s.Labels()) }
|
func (s series) Labels() labels.Labels { return s.s.Labels() }
|
||||||
func (s series) Iterator() storage.SeriesIterator { return storage.SeriesIterator(s.s.Iterator()) }
|
func (s series) Iterator() storage.SeriesIterator { return s.s.Iterator() }
|
||||||
|
|
||||||
type appender struct {
|
type appender struct {
|
||||||
a tsdb.Appender
|
a tsdb.Appender
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a appender) Add(lset labels.Labels, t int64, v float64) (uint64, error) {
|
func (a appender) Add(lset labels.Labels, t int64, v float64) (uint64, error) {
|
||||||
ref, err := a.a.Add(toTSDBLabels(lset), t, v)
|
ref, err := a.a.Add(lset, t, v)
|
||||||
|
|
||||||
switch errors.Cause(err) {
|
switch errors.Cause(err) {
|
||||||
case tsdb.ErrNotFound:
|
case tsdb.ErrNotFound:
|
||||||
|
@ -320,36 +313,3 @@ func (a appender) AddFast(_ labels.Labels, ref uint64, t int64, v float64) error
|
||||||
|
|
||||||
func (a appender) Commit() error { return a.a.Commit() }
|
func (a appender) Commit() error { return a.a.Commit() }
|
||||||
func (a appender) Rollback() error { return a.a.Rollback() }
|
func (a appender) Rollback() error { return a.a.Rollback() }
|
||||||
|
|
||||||
func convertMatcher(m *labels.Matcher) tsdbLabels.Matcher {
|
|
||||||
switch m.Type {
|
|
||||||
case labels.MatchEqual:
|
|
||||||
return tsdbLabels.NewEqualMatcher(m.Name, m.Value)
|
|
||||||
|
|
||||||
case labels.MatchNotEqual:
|
|
||||||
return tsdbLabels.Not(tsdbLabels.NewEqualMatcher(m.Name, m.Value))
|
|
||||||
|
|
||||||
case labels.MatchRegexp:
|
|
||||||
res, err := tsdbLabels.NewRegexpMatcher(m.Name, "^(?:"+m.Value+")$")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
|
|
||||||
case labels.MatchNotRegexp:
|
|
||||||
res, err := tsdbLabels.NewRegexpMatcher(m.Name, "^(?:"+m.Value+")$")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return tsdbLabels.Not(res)
|
|
||||||
}
|
|
||||||
panic("storage.convertMatcher: invalid matcher type")
|
|
||||||
}
|
|
||||||
|
|
||||||
func toTSDBLabels(l labels.Labels) tsdbLabels.Labels {
|
|
||||||
return *(*tsdbLabels.Labels)(unsafe.Pointer(&l))
|
|
||||||
}
|
|
||||||
|
|
||||||
func toLabels(l tsdbLabels.Labels) labels.Labels {
|
|
||||||
return *(*labels.Labels)(unsafe.Pointer(&l))
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,12 +26,12 @@ import (
|
||||||
"github.com/go-kit/kit/log/level"
|
"github.com/go-kit/kit/log/level"
|
||||||
"github.com/oklog/ulid"
|
"github.com/oklog/ulid"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
||||||
"github.com/prometheus/prometheus/tsdb/fileutil"
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
||||||
"github.com/prometheus/prometheus/tsdb/index"
|
"github.com/prometheus/prometheus/tsdb/index"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -504,7 +504,7 @@ func (r blockChunkReader) Close() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete matching series between mint and maxt in the block.
|
// Delete matching series between mint and maxt in the block.
|
||||||
func (pb *Block) Delete(mint, maxt int64, ms ...labels.Matcher) error {
|
func (pb *Block) Delete(mint, maxt int64, ms ...*labels.Matcher) error {
|
||||||
pb.mtx.Lock()
|
pb.mtx.Lock()
|
||||||
defer pb.mtx.Unlock()
|
defer pb.mtx.Unlock()
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/tsdb/fileutil"
|
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
@ -28,8 +26,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-kit/kit/log"
|
"github.com/go-kit/kit/log"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
||||||
"github.com/prometheus/prometheus/tsdb/tsdbutil"
|
"github.com/prometheus/prometheus/tsdb/tsdbutil"
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
@ -184,7 +183,7 @@ func TestBlockSize(t *testing.T) {
|
||||||
|
|
||||||
// Delete some series and check the sizes again.
|
// Delete some series and check the sizes again.
|
||||||
{
|
{
|
||||||
testutil.Ok(t, blockInit.Delete(1, 10, labels.NewMustRegexpMatcher("", ".*")))
|
testutil.Ok(t, blockInit.Delete(1, 10, labels.MustNewMatcher(labels.MatchRegexp, "", ".*")))
|
||||||
expAfterDelete := blockInit.Size()
|
expAfterDelete := blockInit.Size()
|
||||||
testutil.Assert(t, expAfterDelete > expSizeInit, "after a delete the block size should be bigger as the tombstone file should grow %v > %v", expAfterDelete, expSizeInit)
|
testutil.Assert(t, expAfterDelete > expSizeInit, "after a delete the block size should be bigger as the tombstone file should grow %v > %v", expAfterDelete, expSizeInit)
|
||||||
actAfterDelete, err := fileutil.DirSize(blockDirInit)
|
actAfterDelete, err := fileutil.DirSize(blockDirInit)
|
||||||
|
|
|
@ -32,10 +32,10 @@ import (
|
||||||
|
|
||||||
"github.com/go-kit/kit/log"
|
"github.com/go-kit/kit/log"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb"
|
"github.com/prometheus/prometheus/tsdb"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
kingpin "gopkg.in/alecthomas/kingpin.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -630,7 +630,7 @@ func dumpSamples(db *tsdb.DBReadOnly, mint, maxt int64) (err error) {
|
||||||
err = merr.Err()
|
err = merr.Err()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ss, err := q.Select(labels.NewMustRegexpMatcher("", ".*"))
|
ss, err := q.Select(labels.MustNewMatcher(labels.MatchRegexp, "", ".*"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,12 @@ import (
|
||||||
"github.com/oklog/ulid"
|
"github.com/oklog/ulid"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
||||||
"github.com/prometheus/prometheus/tsdb/fileutil"
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
||||||
"github.com/prometheus/prometheus/tsdb/index"
|
"github.com/prometheus/prometheus/tsdb/index"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,9 @@ import (
|
||||||
"github.com/go-kit/kit/log"
|
"github.com/go-kit/kit/log"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
prom_testutil "github.com/prometheus/client_golang/prometheus/testutil"
|
prom_testutil "github.com/prometheus/client_golang/prometheus/testutil"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
"github.com/prometheus/prometheus/tsdb/fileutil"
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
@ -289,7 +289,7 @@ func TestLeveledCompactor_plan(t *testing.T) {
|
||||||
},
|
},
|
||||||
`Regression test: we were wrongly assuming that new block is fresh from WAL when its ULID is newest.
|
`Regression test: we were wrongly assuming that new block is fresh from WAL when its ULID is newest.
|
||||||
We need to actually look on max time instead.
|
We need to actually look on max time instead.
|
||||||
|
|
||||||
With previous, wrong approach "8" block was ignored, so we were wrongly compacting 5 and 7 and introducing
|
With previous, wrong approach "8" block was ignored, so we were wrongly compacting 5 and 7 and introducing
|
||||||
block overlaps`: {
|
block overlaps`: {
|
||||||
metas: []dirMeta{
|
metas: []dirMeta{
|
||||||
|
|
|
@ -34,11 +34,11 @@ import (
|
||||||
"github.com/oklog/ulid"
|
"github.com/oklog/ulid"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
||||||
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
||||||
"github.com/prometheus/prometheus/tsdb/fileutil"
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
||||||
_ "github.com/prometheus/prometheus/tsdb/goversion"
|
_ "github.com/prometheus/prometheus/tsdb/goversion"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/wal"
|
"github.com/prometheus/prometheus/tsdb/wal"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
@ -1247,7 +1247,7 @@ func rangeForTimestamp(t int64, width int64) (maxt int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete implements deletion of metrics. It only has atomicity guarantees on a per-block basis.
|
// Delete implements deletion of metrics. It only has atomicity guarantees on a per-block basis.
|
||||||
func (db *DB) Delete(mint, maxt int64, ms ...labels.Matcher) error {
|
func (db *DB) Delete(mint, maxt int64, ms ...*labels.Matcher) error {
|
||||||
db.cmtx.Lock()
|
db.cmtx.Lock()
|
||||||
defer db.cmtx.Unlock()
|
defer db.cmtx.Unlock()
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,9 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
prom_testutil "github.com/prometheus/client_golang/prometheus/testutil"
|
prom_testutil "github.com/prometheus/client_golang/prometheus/testutil"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
"github.com/prometheus/prometheus/tsdb/index"
|
"github.com/prometheus/prometheus/tsdb/index"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/record"
|
"github.com/prometheus/prometheus/tsdb/record"
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
"github.com/prometheus/prometheus/tsdb/tsdbutil"
|
"github.com/prometheus/prometheus/tsdb/tsdbutil"
|
||||||
|
@ -56,7 +56,7 @@ func openTestDB(t testing.TB, opts *Options) (db *DB, close func()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// query runs a matcher query against the querier and fully expands its data.
|
// query runs a matcher query against the querier and fully expands its data.
|
||||||
func query(t testing.TB, q Querier, matchers ...labels.Matcher) map[string][]tsdbutil.Sample {
|
func query(t testing.TB, q Querier, matchers ...*labels.Matcher) map[string][]tsdbutil.Sample {
|
||||||
ss, err := q.Select(matchers...)
|
ss, err := q.Select(matchers...)
|
||||||
defer func() {
|
defer func() {
|
||||||
testutil.Ok(t, q.Close())
|
testutil.Ok(t, q.Close())
|
||||||
|
@ -127,7 +127,7 @@ func TestDataAvailableOnlyAfterCommit(t *testing.T) {
|
||||||
|
|
||||||
querier, err := db.Querier(0, 1)
|
querier, err := db.Querier(0, 1)
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
seriesSet := query(t, querier, labels.NewEqualMatcher("foo", "bar"))
|
seriesSet := query(t, querier, labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"))
|
||||||
testutil.Equals(t, map[string][]tsdbutil.Sample{}, seriesSet)
|
testutil.Equals(t, map[string][]tsdbutil.Sample{}, seriesSet)
|
||||||
|
|
||||||
err = app.Commit()
|
err = app.Commit()
|
||||||
|
@ -137,7 +137,7 @@ func TestDataAvailableOnlyAfterCommit(t *testing.T) {
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
defer querier.Close()
|
defer querier.Close()
|
||||||
|
|
||||||
seriesSet = query(t, querier, labels.NewEqualMatcher("foo", "bar"))
|
seriesSet = query(t, querier, labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"))
|
||||||
|
|
||||||
testutil.Equals(t, map[string][]tsdbutil.Sample{`{foo="bar"}`: {sample{t: 0, v: 0}}}, seriesSet)
|
testutil.Equals(t, map[string][]tsdbutil.Sample{`{foo="bar"}`: {sample{t: 0, v: 0}}}, seriesSet)
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ func TestDataNotAvailableAfterRollback(t *testing.T) {
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
defer querier.Close()
|
defer querier.Close()
|
||||||
|
|
||||||
seriesSet := query(t, querier, labels.NewEqualMatcher("foo", "bar"))
|
seriesSet := query(t, querier, labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"))
|
||||||
|
|
||||||
testutil.Equals(t, map[string][]tsdbutil.Sample{}, seriesSet)
|
testutil.Equals(t, map[string][]tsdbutil.Sample{}, seriesSet)
|
||||||
}
|
}
|
||||||
|
@ -207,7 +207,7 @@ func TestDBAppenderAddRef(t *testing.T) {
|
||||||
q, err := db.Querier(0, 200)
|
q, err := db.Querier(0, 200)
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
res := query(t, q, labels.NewEqualMatcher("a", "b"))
|
res := query(t, q, labels.MustNewMatcher(labels.MatchEqual, "a", "b"))
|
||||||
|
|
||||||
testutil.Equals(t, map[string][]tsdbutil.Sample{
|
testutil.Equals(t, map[string][]tsdbutil.Sample{
|
||||||
labels.FromStrings("a", "b").String(): {
|
labels.FromStrings("a", "b").String(): {
|
||||||
|
@ -293,14 +293,14 @@ Outer:
|
||||||
// TODO(gouthamve): Reset the tombstones somehow.
|
// TODO(gouthamve): Reset the tombstones somehow.
|
||||||
// Delete the ranges.
|
// Delete the ranges.
|
||||||
for _, r := range c.Intervals {
|
for _, r := range c.Intervals {
|
||||||
testutil.Ok(t, db.Delete(r.Mint, r.Maxt, labels.NewEqualMatcher("a", "b")))
|
testutil.Ok(t, db.Delete(r.Mint, r.Maxt, labels.MustNewMatcher(labels.MatchEqual, "a", "b")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare the result.
|
// Compare the result.
|
||||||
q, err := db.Querier(0, numSamples)
|
q, err := db.Querier(0, numSamples)
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
res, err := q.Select(labels.NewEqualMatcher("a", "b"))
|
res, err := q.Select(labels.MustNewMatcher(labels.MatchEqual, "a", "b"))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
expSamples := make([]tsdbutil.Sample, 0, len(c.remaint))
|
expSamples := make([]tsdbutil.Sample, 0, len(c.remaint))
|
||||||
|
@ -419,7 +419,7 @@ func TestSkippingInvalidValuesInSameTxn(t *testing.T) {
|
||||||
q, err := db.Querier(0, 10)
|
q, err := db.Querier(0, 10)
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
ssMap := query(t, q, labels.NewEqualMatcher("a", "b"))
|
ssMap := query(t, q, labels.MustNewMatcher(labels.MatchEqual, "a", "b"))
|
||||||
|
|
||||||
testutil.Equals(t, map[string][]tsdbutil.Sample{
|
testutil.Equals(t, map[string][]tsdbutil.Sample{
|
||||||
labels.New(labels.Label{Name: "a", Value: "b"}).String(): {sample{0, 1}},
|
labels.New(labels.Label{Name: "a", Value: "b"}).String(): {sample{0, 1}},
|
||||||
|
@ -436,7 +436,7 @@ func TestSkippingInvalidValuesInSameTxn(t *testing.T) {
|
||||||
q, err = db.Querier(0, 10)
|
q, err = db.Querier(0, 10)
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
ssMap = query(t, q, labels.NewEqualMatcher("a", "b"))
|
ssMap = query(t, q, labels.MustNewMatcher(labels.MatchEqual, "a", "b"))
|
||||||
|
|
||||||
testutil.Equals(t, map[string][]tsdbutil.Sample{
|
testutil.Equals(t, map[string][]tsdbutil.Sample{
|
||||||
labels.New(labels.Label{Name: "a", Value: "b"}).String(): {sample{0, 1}, sample{10, 3}},
|
labels.New(labels.Label{Name: "a", Value: "b"}).String(): {sample{0, 1}, sample{10, 3}},
|
||||||
|
@ -477,7 +477,7 @@ func TestDB_Snapshot(t *testing.T) {
|
||||||
defer func() { testutil.Ok(t, querier.Close()) }()
|
defer func() { testutil.Ok(t, querier.Close()) }()
|
||||||
|
|
||||||
// sum values
|
// sum values
|
||||||
seriesSet, err := querier.Select(labels.NewEqualMatcher("foo", "bar"))
|
seriesSet, err := querier.Select(labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
sum := 0.0
|
sum := 0.0
|
||||||
|
@ -531,7 +531,7 @@ func TestDB_Snapshot_ChunksOutsideOfCompactedRange(t *testing.T) {
|
||||||
defer func() { testutil.Ok(t, querier.Close()) }()
|
defer func() { testutil.Ok(t, querier.Close()) }()
|
||||||
|
|
||||||
// Sum values.
|
// Sum values.
|
||||||
seriesSet, err := querier.Select(labels.NewEqualMatcher("foo", "bar"))
|
seriesSet, err := querier.Select(labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
sum := 0.0
|
sum := 0.0
|
||||||
|
@ -579,7 +579,7 @@ Outer:
|
||||||
// TODO(gouthamve): Reset the tombstones somehow.
|
// TODO(gouthamve): Reset the tombstones somehow.
|
||||||
// Delete the ranges.
|
// Delete the ranges.
|
||||||
for _, r := range c.intervals {
|
for _, r := range c.intervals {
|
||||||
testutil.Ok(t, db.Delete(r.Mint, r.Maxt, labels.NewEqualMatcher("a", "b")))
|
testutil.Ok(t, db.Delete(r.Mint, r.Maxt, labels.MustNewMatcher(labels.MatchEqual, "a", "b")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// create snapshot
|
// create snapshot
|
||||||
|
@ -602,7 +602,7 @@ Outer:
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
defer func() { testutil.Ok(t, q.Close()) }()
|
defer func() { testutil.Ok(t, q.Close()) }()
|
||||||
|
|
||||||
res, err := q.Select(labels.NewEqualMatcher("a", "b"))
|
res, err := q.Select(labels.MustNewMatcher(labels.MatchEqual, "a", "b"))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
expSamples := make([]tsdbutil.Sample, 0, len(c.remaint))
|
expSamples := make([]tsdbutil.Sample, 0, len(c.remaint))
|
||||||
|
@ -647,7 +647,7 @@ func TestDB_e2e(t *testing.T) {
|
||||||
timeInterval = int64(3)
|
timeInterval = int64(3)
|
||||||
)
|
)
|
||||||
// Create 8 series with 1000 data-points of different ranges and run queries.
|
// Create 8 series with 1000 data-points of different ranges and run queries.
|
||||||
lbls := [][]labels.Label{
|
lbls := []labels.Labels{
|
||||||
{
|
{
|
||||||
{Name: "a", Value: "b"},
|
{Name: "a", Value: "b"},
|
||||||
{Name: "instance", Value: "localhost:9090"},
|
{Name: "instance", Value: "localhost:9090"},
|
||||||
|
@ -726,22 +726,22 @@ func TestDB_e2e(t *testing.T) {
|
||||||
|
|
||||||
// Query each selector on 1000 random time-ranges.
|
// Query each selector on 1000 random time-ranges.
|
||||||
queries := []struct {
|
queries := []struct {
|
||||||
ms []labels.Matcher
|
ms []*labels.Matcher
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
ms: []labels.Matcher{labels.NewEqualMatcher("a", "b")},
|
ms: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "a", "b")},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ms: []labels.Matcher{
|
ms: []*labels.Matcher{
|
||||||
labels.NewEqualMatcher("a", "b"),
|
labels.MustNewMatcher(labels.MatchEqual, "a", "b"),
|
||||||
labels.NewEqualMatcher("job", "prom-k8s"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "prom-k8s"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ms: []labels.Matcher{
|
ms: []*labels.Matcher{
|
||||||
labels.NewEqualMatcher("a", "c"),
|
labels.MustNewMatcher(labels.MatchEqual, "a", "c"),
|
||||||
labels.NewEqualMatcher("instance", "localhost:9090"),
|
labels.MustNewMatcher(labels.MatchEqual, "instance", "localhost:9090"),
|
||||||
labels.NewEqualMatcher("job", "prometheus"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "prometheus"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// TODO: Add Regexp Matchers.
|
// TODO: Add Regexp Matchers.
|
||||||
|
@ -920,7 +920,7 @@ func TestTombstoneClean(t *testing.T) {
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
for _, r := range c.intervals {
|
for _, r := range c.intervals {
|
||||||
testutil.Ok(t, db.Delete(r.Mint, r.Maxt, labels.NewEqualMatcher("a", "b")))
|
testutil.Ok(t, db.Delete(r.Mint, r.Maxt, labels.MustNewMatcher(labels.MatchEqual, "a", "b")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// All of the setup for THIS line.
|
// All of the setup for THIS line.
|
||||||
|
@ -931,7 +931,7 @@ func TestTombstoneClean(t *testing.T) {
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
defer q.Close()
|
defer q.Close()
|
||||||
|
|
||||||
res, err := q.Select(labels.NewEqualMatcher("a", "b"))
|
res, err := q.Select(labels.MustNewMatcher(labels.MatchEqual, "a", "b"))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
expSamples := make([]tsdbutil.Sample, 0, len(c.remaint))
|
expSamples := make([]tsdbutil.Sample, 0, len(c.remaint))
|
||||||
|
@ -1232,39 +1232,39 @@ func TestNotMatcherSelectsLabelsUnsetSeries(t *testing.T) {
|
||||||
series []labels.Labels
|
series []labels.Labels
|
||||||
}{{
|
}{{
|
||||||
selector: labels.Selector{
|
selector: labels.Selector{
|
||||||
labels.Not(labels.NewEqualMatcher("lname", "lvalue")),
|
labels.MustNewMatcher(labels.MatchNotEqual, "lname", "lvalue"),
|
||||||
},
|
},
|
||||||
series: labelpairs,
|
series: labelpairs,
|
||||||
}, {
|
}, {
|
||||||
selector: labels.Selector{
|
selector: labels.Selector{
|
||||||
labels.NewEqualMatcher("a", "abcd"),
|
labels.MustNewMatcher(labels.MatchEqual, "a", "abcd"),
|
||||||
labels.Not(labels.NewEqualMatcher("b", "abcde")),
|
labels.MustNewMatcher(labels.MatchNotEqual, "b", "abcde"),
|
||||||
},
|
},
|
||||||
series: []labels.Labels{},
|
series: []labels.Labels{},
|
||||||
}, {
|
}, {
|
||||||
selector: labels.Selector{
|
selector: labels.Selector{
|
||||||
labels.NewEqualMatcher("a", "abcd"),
|
labels.MustNewMatcher(labels.MatchEqual, "a", "abcd"),
|
||||||
labels.Not(labels.NewEqualMatcher("b", "abc")),
|
labels.MustNewMatcher(labels.MatchNotEqual, "b", "abc"),
|
||||||
},
|
},
|
||||||
series: []labels.Labels{labelpairs[0]},
|
series: []labels.Labels{labelpairs[0]},
|
||||||
}, {
|
}, {
|
||||||
selector: labels.Selector{
|
selector: labels.Selector{
|
||||||
labels.Not(labels.NewMustRegexpMatcher("a", "abd.*")),
|
labels.MustNewMatcher(labels.MatchNotRegexp, "a", "abd.*"),
|
||||||
},
|
},
|
||||||
series: labelpairs,
|
series: labelpairs,
|
||||||
}, {
|
}, {
|
||||||
selector: labels.Selector{
|
selector: labels.Selector{
|
||||||
labels.Not(labels.NewMustRegexpMatcher("a", "abc.*")),
|
labels.MustNewMatcher(labels.MatchNotRegexp, "a", "abc.*"),
|
||||||
},
|
},
|
||||||
series: labelpairs[1:],
|
series: labelpairs[1:],
|
||||||
}, {
|
}, {
|
||||||
selector: labels.Selector{
|
selector: labels.Selector{
|
||||||
labels.Not(labels.NewMustRegexpMatcher("c", "abd.*")),
|
labels.MustNewMatcher(labels.MatchNotRegexp, "c", "abd.*"),
|
||||||
},
|
},
|
||||||
series: labelpairs,
|
series: labelpairs,
|
||||||
}, {
|
}, {
|
||||||
selector: labels.Selector{
|
selector: labels.Selector{
|
||||||
labels.Not(labels.NewMustRegexpMatcher("labelname", "labelvalue")),
|
labels.MustNewMatcher(labels.MatchNotRegexp, "labelname", "labelvalue"),
|
||||||
},
|
},
|
||||||
series: labelpairs[:1],
|
series: labelpairs[:1],
|
||||||
}}
|
}}
|
||||||
|
@ -1605,7 +1605,7 @@ func TestNoEmptyBlocks(t *testing.T) {
|
||||||
|
|
||||||
rangeToTriggerCompaction := db.opts.BlockRanges[0]/2*3 - 1
|
rangeToTriggerCompaction := db.opts.BlockRanges[0]/2*3 - 1
|
||||||
defaultLabel := labels.FromStrings("foo", "bar")
|
defaultLabel := labels.FromStrings("foo", "bar")
|
||||||
defaultMatcher := labels.NewMustRegexpMatcher("", ".*")
|
defaultMatcher := labels.MustNewMatcher(labels.MatchRegexp, "", ".*")
|
||||||
|
|
||||||
t.Run("Test no blocks after compact with empty head.", func(t *testing.T) {
|
t.Run("Test no blocks after compact with empty head.", func(t *testing.T) {
|
||||||
testutil.Ok(t, db.compact())
|
testutil.Ok(t, db.compact())
|
||||||
|
@ -1807,7 +1807,7 @@ func TestCorrectNumTombstones(t *testing.T) {
|
||||||
|
|
||||||
blockRange := DefaultOptions.BlockRanges[0]
|
blockRange := DefaultOptions.BlockRanges[0]
|
||||||
defaultLabel := labels.FromStrings("foo", "bar")
|
defaultLabel := labels.FromStrings("foo", "bar")
|
||||||
defaultMatcher := labels.NewEqualMatcher(defaultLabel[0].Name, defaultLabel[0].Value)
|
defaultMatcher := labels.MustNewMatcher(labels.MatchEqual, defaultLabel[0].Name, defaultLabel[0].Value)
|
||||||
|
|
||||||
app := db.Appender()
|
app := db.Appender()
|
||||||
for i := int64(0); i < 3; i++ {
|
for i := int64(0); i < 3; i++ {
|
||||||
|
@ -2152,7 +2152,7 @@ func TestVerticalCompaction(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultMatcher := labels.NewMustRegexpMatcher("__name__", ".*")
|
defaultMatcher := labels.MustNewMatcher(labels.MatchRegexp, "__name__", ".*")
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
if ok := t.Run("", func(t *testing.T) {
|
if ok := t.Run("", func(t *testing.T) {
|
||||||
|
|
||||||
|
@ -2311,7 +2311,7 @@ func TestDBReadOnly(t *testing.T) {
|
||||||
expSeries map[string][]tsdbutil.Sample
|
expSeries map[string][]tsdbutil.Sample
|
||||||
expSeriesCount int
|
expSeriesCount int
|
||||||
expDBHash []byte
|
expDBHash []byte
|
||||||
matchAll = labels.NewEqualMatcher("", "")
|
matchAll = labels.MustNewMatcher(labels.MatchEqual, "", "")
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2465,7 +2465,7 @@ func TestDBReadOnly_FlushWAL(t *testing.T) {
|
||||||
defer func() { testutil.Ok(t, querier.Close()) }()
|
defer func() { testutil.Ok(t, querier.Close()) }()
|
||||||
|
|
||||||
// Sum the values.
|
// Sum the values.
|
||||||
seriesSet, err := querier.Select(labels.NewEqualMatcher(defaultLabelName, "flush"))
|
seriesSet, err := querier.Select(labels.MustNewMatcher(labels.MatchEqual, defaultLabelName, "flush"))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
sum := 0.0
|
sum := 0.0
|
||||||
|
|
10
tsdb/head.go
10
tsdb/head.go
|
@ -28,11 +28,11 @@ import (
|
||||||
"github.com/oklog/ulid"
|
"github.com/oklog/ulid"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
"github.com/prometheus/prometheus/tsdb/encoding"
|
"github.com/prometheus/prometheus/tsdb/encoding"
|
||||||
"github.com/prometheus/prometheus/tsdb/index"
|
"github.com/prometheus/prometheus/tsdb/index"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/record"
|
"github.com/prometheus/prometheus/tsdb/record"
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
"github.com/prometheus/prometheus/tsdb/wal"
|
"github.com/prometheus/prometheus/tsdb/wal"
|
||||||
|
@ -1047,7 +1047,7 @@ func (a *headAppender) Rollback() error {
|
||||||
|
|
||||||
// Delete all samples in the range of [mint, maxt] for series that satisfy the given
|
// Delete all samples in the range of [mint, maxt] for series that satisfy the given
|
||||||
// label matchers.
|
// label matchers.
|
||||||
func (h *Head) Delete(mint, maxt int64, ms ...labels.Matcher) error {
|
func (h *Head) Delete(mint, maxt int64, ms ...*labels.Matcher) error {
|
||||||
// Do not delete anything beyond the currently valid range.
|
// Do not delete anything beyond the currently valid range.
|
||||||
mint, maxt = clampInterval(mint, maxt, h.MinTime(), h.MaxTime())
|
mint, maxt = clampInterval(mint, maxt, h.MinTime(), h.MaxTime())
|
||||||
|
|
||||||
|
@ -1516,7 +1516,7 @@ type seriesHashmap map[uint64][]*memSeries
|
||||||
|
|
||||||
func (m seriesHashmap) get(hash uint64, lset labels.Labels) *memSeries {
|
func (m seriesHashmap) get(hash uint64, lset labels.Labels) *memSeries {
|
||||||
for _, s := range m[hash] {
|
for _, s := range m[hash] {
|
||||||
if s.lset.Equals(lset) {
|
if labels.Equal(s.lset, lset) {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1526,7 +1526,7 @@ func (m seriesHashmap) get(hash uint64, lset labels.Labels) *memSeries {
|
||||||
func (m seriesHashmap) set(hash uint64, s *memSeries) {
|
func (m seriesHashmap) set(hash uint64, s *memSeries) {
|
||||||
l := m[hash]
|
l := m[hash]
|
||||||
for i, prev := range l {
|
for i, prev := range l {
|
||||||
if prev.lset.Equals(s.lset) {
|
if labels.Equal(prev.lset, s.lset) {
|
||||||
l[i] = s
|
l[i] = s
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1537,7 +1537,7 @@ func (m seriesHashmap) set(hash uint64, s *memSeries) {
|
||||||
func (m seriesHashmap) del(hash uint64, lset labels.Labels) {
|
func (m seriesHashmap) del(hash uint64, lset labels.Labels) {
|
||||||
var rem []*memSeries
|
var rem []*memSeries
|
||||||
for _, s := range m[hash] {
|
for _, s := range m[hash] {
|
||||||
if !s.lset.Equals(lset) {
|
if !labels.Equal(s.lset, lset) {
|
||||||
rem = append(rem, s)
|
rem = append(rem, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -74,39 +74,39 @@ func BenchmarkHeadPostingForMatchers(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
n1 := labels.NewEqualMatcher("n", "1")
|
n1 := labels.MustNewMatcher(labels.MatchEqual, "n", "1")
|
||||||
|
|
||||||
jFoo := labels.NewEqualMatcher("j", "foo")
|
jFoo := labels.MustNewMatcher(labels.MatchEqual, "j", "foo")
|
||||||
jNotFoo := labels.Not(jFoo)
|
jNotFoo := labels.MustNewMatcher(labels.MatchNotEqual, "j", "foo")
|
||||||
|
|
||||||
iStar := labels.NewMustRegexpMatcher("i", "^.*$")
|
iStar := labels.MustNewMatcher(labels.MatchRegexp, "i", "^.*$")
|
||||||
iPlus := labels.NewMustRegexpMatcher("i", "^.+$")
|
iPlus := labels.MustNewMatcher(labels.MatchRegexp, "i", "^.+$")
|
||||||
i1Plus := labels.NewMustRegexpMatcher("i", "^1.+$")
|
i1Plus := labels.MustNewMatcher(labels.MatchRegexp, "i", "^1.+$")
|
||||||
iEmptyRe := labels.NewMustRegexpMatcher("i", "^$")
|
iEmptyRe := labels.MustNewMatcher(labels.MatchRegexp, "i", "^$")
|
||||||
iNotEmpty := labels.Not(labels.NewEqualMatcher("i", ""))
|
iNotEmpty := labels.MustNewMatcher(labels.MatchNotEqual, "i", "")
|
||||||
iNot2 := labels.Not(labels.NewEqualMatcher("n", "2"))
|
iNot2 := labels.MustNewMatcher(labels.MatchNotEqual, "n", "2")
|
||||||
iNot2Star := labels.Not(labels.NewMustRegexpMatcher("i", "^2.*$"))
|
iNot2Star := labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^2.*$")
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
name string
|
name string
|
||||||
matchers []labels.Matcher
|
matchers []*labels.Matcher
|
||||||
}{
|
}{
|
||||||
{`n="1"`, []labels.Matcher{n1}},
|
{`n="1"`, []*labels.Matcher{n1}},
|
||||||
{`n="1",j="foo"`, []labels.Matcher{n1, jFoo}},
|
{`n="1",j="foo"`, []*labels.Matcher{n1, jFoo}},
|
||||||
{`j="foo",n="1"`, []labels.Matcher{jFoo, n1}},
|
{`j="foo",n="1"`, []*labels.Matcher{jFoo, n1}},
|
||||||
{`n="1",j!="foo"`, []labels.Matcher{n1, jNotFoo}},
|
{`n="1",j!="foo"`, []*labels.Matcher{n1, jNotFoo}},
|
||||||
{`i=~".*"`, []labels.Matcher{iStar}},
|
{`i=~".*"`, []*labels.Matcher{iStar}},
|
||||||
{`i=~".+"`, []labels.Matcher{iPlus}},
|
{`i=~".+"`, []*labels.Matcher{iPlus}},
|
||||||
{`i=~""`, []labels.Matcher{iEmptyRe}},
|
{`i=~""`, []*labels.Matcher{iEmptyRe}},
|
||||||
{`i!=""`, []labels.Matcher{iNotEmpty}},
|
{`i!=""`, []*labels.Matcher{iNotEmpty}},
|
||||||
{`n="1",i=~".*",j="foo"`, []labels.Matcher{n1, iStar, jFoo}},
|
{`n="1",i=~".*",j="foo"`, []*labels.Matcher{n1, iStar, jFoo}},
|
||||||
{`n="1",i=~".*",i!="2",j="foo"`, []labels.Matcher{n1, iStar, iNot2, jFoo}},
|
{`n="1",i=~".*",i!="2",j="foo"`, []*labels.Matcher{n1, iStar, iNot2, jFoo}},
|
||||||
{`n="1",i!=""`, []labels.Matcher{n1, iNotEmpty}},
|
{`n="1",i!=""`, []*labels.Matcher{n1, iNotEmpty}},
|
||||||
{`n="1",i!="",j="foo"`, []labels.Matcher{n1, iNotEmpty, jFoo}},
|
{`n="1",i!="",j="foo"`, []*labels.Matcher{n1, iNotEmpty, jFoo}},
|
||||||
{`n="1",i=~".+",j="foo"`, []labels.Matcher{n1, iPlus, jFoo}},
|
{`n="1",i=~".+",j="foo"`, []*labels.Matcher{n1, iPlus, jFoo}},
|
||||||
{`n="1",i=~"1.+",j="foo"`, []labels.Matcher{n1, i1Plus, jFoo}},
|
{`n="1",i=~"1.+",j="foo"`, []*labels.Matcher{n1, i1Plus, jFoo}},
|
||||||
{`n="1",i=~".+",i!="2",j="foo"`, []labels.Matcher{n1, iPlus, iNot2, jFoo}},
|
{`n="1",i=~".+",i!="2",j="foo"`, []*labels.Matcher{n1, iPlus, iNot2, jFoo}},
|
||||||
{`n="1",i=~".+",i!~"2.*",j="foo"`, []labels.Matcher{n1, iPlus, iNot2Star, jFoo}},
|
{`n="1",i=~".+",i!~"2.*",j="foo"`, []*labels.Matcher{n1, iPlus, iNot2Star, jFoo}},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
|
|
|
@ -27,10 +27,10 @@ import (
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
prom_testutil "github.com/prometheus/client_golang/prometheus/testutil"
|
prom_testutil "github.com/prometheus/client_golang/prometheus/testutil"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
"github.com/prometheus/prometheus/tsdb/index"
|
"github.com/prometheus/prometheus/tsdb/index"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/record"
|
"github.com/prometheus/prometheus/tsdb/record"
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
"github.com/prometheus/prometheus/tsdb/tsdbutil"
|
"github.com/prometheus/prometheus/tsdb/tsdbutil"
|
||||||
|
@ -290,7 +290,7 @@ func TestHead_WALMultiRef(t *testing.T) {
|
||||||
|
|
||||||
q, err := NewBlockQuerier(head, 0, 300)
|
q, err := NewBlockQuerier(head, 0, 300)
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
series := query(t, q, labels.NewEqualMatcher("foo", "bar"))
|
series := query(t, q, labels.MustNewMatcher(labels.MatchEqual, "foo", "bar"))
|
||||||
testutil.Equals(t, map[string][]tsdbutil.Sample{`{foo="bar"}`: {sample{100, 1}, sample{300, 2}}}, series)
|
testutil.Equals(t, map[string][]tsdbutil.Sample{`{foo="bar"}`: {sample{100, 1}, sample{300, 2}}}, series)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,7 +437,7 @@ func TestHeadDeleteSeriesWithoutSamples(t *testing.T) {
|
||||||
|
|
||||||
testutil.Ok(t, head.Init(math.MinInt64))
|
testutil.Ok(t, head.Init(math.MinInt64))
|
||||||
|
|
||||||
testutil.Ok(t, head.Delete(0, 100, labels.NewEqualMatcher("a", "1")))
|
testutil.Ok(t, head.Delete(0, 100, labels.MustNewMatcher(labels.MatchEqual, "a", "1")))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,7 +507,7 @@ func TestHeadDeleteSimple(t *testing.T) {
|
||||||
|
|
||||||
// Delete the ranges.
|
// Delete the ranges.
|
||||||
for _, r := range c.dranges {
|
for _, r := range c.dranges {
|
||||||
testutil.Ok(t, head.Delete(r.Mint, r.Maxt, labels.NewEqualMatcher(lblDefault.Name, lblDefault.Value)))
|
testutil.Ok(t, head.Delete(r.Mint, r.Maxt, labels.MustNewMatcher(labels.MatchEqual, lblDefault.Name, lblDefault.Value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare the samples for both heads - before and after the reload.
|
// Compare the samples for both heads - before and after the reload.
|
||||||
|
@ -522,7 +522,7 @@ func TestHeadDeleteSimple(t *testing.T) {
|
||||||
indexr, err := h.Index()
|
indexr, err := h.Index()
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
// Use an emptyTombstoneReader explicitly to get all the samples.
|
// Use an emptyTombstoneReader explicitly to get all the samples.
|
||||||
css, err := LookupChunkSeries(indexr, emptyTombstoneReader, labels.NewEqualMatcher(lblDefault.Name, lblDefault.Value))
|
css, err := LookupChunkSeries(indexr, emptyTombstoneReader, labels.MustNewMatcher(labels.MatchEqual, lblDefault.Name, lblDefault.Value))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
// Getting the actual samples.
|
// Getting the actual samples.
|
||||||
|
@ -564,7 +564,7 @@ func TestHeadDeleteSimple(t *testing.T) {
|
||||||
for _, h := range []*Head{head, reloadedHead} {
|
for _, h := range []*Head{head, reloadedHead} {
|
||||||
q, err := NewBlockQuerier(h, h.MinTime(), h.MaxTime())
|
q, err := NewBlockQuerier(h, h.MinTime(), h.MaxTime())
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
actSeriesSet, err := q.Select(labels.NewEqualMatcher(lblDefault.Name, lblDefault.Value))
|
actSeriesSet, err := q.Select(labels.MustNewMatcher(labels.MatchEqual, lblDefault.Name, lblDefault.Value))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
lns, err := q.LabelNames()
|
lns, err := q.LabelNames()
|
||||||
|
@ -623,12 +623,12 @@ func TestDeleteUntilCurMax(t *testing.T) {
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
}
|
}
|
||||||
testutil.Ok(t, app.Commit())
|
testutil.Ok(t, app.Commit())
|
||||||
testutil.Ok(t, hb.Delete(0, 10000, labels.NewEqualMatcher("a", "b")))
|
testutil.Ok(t, hb.Delete(0, 10000, labels.MustNewMatcher(labels.MatchEqual, "a", "b")))
|
||||||
|
|
||||||
// Test the series have been deleted.
|
// Test the series have been deleted.
|
||||||
q, err := NewBlockQuerier(hb, 0, 100000)
|
q, err := NewBlockQuerier(hb, 0, 100000)
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
res, err := q.Select(labels.NewEqualMatcher("a", "b"))
|
res, err := q.Select(labels.MustNewMatcher(labels.MatchEqual, "a", "b"))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
testutil.Assert(t, !res.Next(), "series didn't get deleted")
|
testutil.Assert(t, !res.Next(), "series didn't get deleted")
|
||||||
|
|
||||||
|
@ -639,7 +639,7 @@ func TestDeleteUntilCurMax(t *testing.T) {
|
||||||
testutil.Ok(t, app.Commit())
|
testutil.Ok(t, app.Commit())
|
||||||
q, err = NewBlockQuerier(hb, 0, 100000)
|
q, err = NewBlockQuerier(hb, 0, 100000)
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
res, err = q.Select(labels.NewEqualMatcher("a", "b"))
|
res, err = q.Select(labels.MustNewMatcher(labels.MatchEqual, "a", "b"))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
testutil.Assert(t, res.Next(), "series don't exist")
|
testutil.Assert(t, res.Next(), "series don't exist")
|
||||||
exps := res.At()
|
exps := res.At()
|
||||||
|
@ -669,7 +669,7 @@ func TestDeletedSamplesAndSeriesStillInWALAfterCheckpoint(t *testing.T) {
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
testutil.Ok(t, app.Commit())
|
testutil.Ok(t, app.Commit())
|
||||||
}
|
}
|
||||||
testutil.Ok(t, hb.Delete(0, int64(numSamples), labels.NewEqualMatcher("a", "b")))
|
testutil.Ok(t, hb.Delete(0, int64(numSamples), labels.MustNewMatcher(labels.MatchEqual, "a", "b")))
|
||||||
testutil.Ok(t, hb.Truncate(1))
|
testutil.Ok(t, hb.Truncate(1))
|
||||||
testutil.Ok(t, hb.Close())
|
testutil.Ok(t, hb.Close())
|
||||||
|
|
||||||
|
@ -774,25 +774,25 @@ func TestDelete_e2e(t *testing.T) {
|
||||||
testutil.Ok(t, app.Commit())
|
testutil.Ok(t, app.Commit())
|
||||||
// Delete a time-range from each-selector.
|
// Delete a time-range from each-selector.
|
||||||
dels := []struct {
|
dels := []struct {
|
||||||
ms []labels.Matcher
|
ms []*labels.Matcher
|
||||||
drange tombstones.Intervals
|
drange tombstones.Intervals
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
ms: []labels.Matcher{labels.NewEqualMatcher("a", "b")},
|
ms: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "a", "b")},
|
||||||
drange: tombstones.Intervals{{Mint: 300, Maxt: 500}, {Mint: 600, Maxt: 670}},
|
drange: tombstones.Intervals{{Mint: 300, Maxt: 500}, {Mint: 600, Maxt: 670}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ms: []labels.Matcher{
|
ms: []*labels.Matcher{
|
||||||
labels.NewEqualMatcher("a", "b"),
|
labels.MustNewMatcher(labels.MatchEqual, "a", "b"),
|
||||||
labels.NewEqualMatcher("job", "prom-k8s"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "prom-k8s"),
|
||||||
},
|
},
|
||||||
drange: tombstones.Intervals{{Mint: 300, Maxt: 500}, {Mint: 100, Maxt: 670}},
|
drange: tombstones.Intervals{{Mint: 300, Maxt: 500}, {Mint: 100, Maxt: 670}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ms: []labels.Matcher{
|
ms: []*labels.Matcher{
|
||||||
labels.NewEqualMatcher("a", "c"),
|
labels.MustNewMatcher(labels.MatchEqual, "a", "c"),
|
||||||
labels.NewEqualMatcher("instance", "localhost:9090"),
|
labels.MustNewMatcher(labels.MatchEqual, "instance", "localhost:9090"),
|
||||||
labels.NewEqualMatcher("job", "prometheus"),
|
labels.MustNewMatcher(labels.MatchEqual, "job", "prometheus"),
|
||||||
},
|
},
|
||||||
drange: tombstones.Intervals{{Mint: 300, Maxt: 400}, {Mint: 100, Maxt: 6700}},
|
drange: tombstones.Intervals{{Mint: 300, Maxt: 400}, {Mint: 100, Maxt: 6700}},
|
||||||
},
|
},
|
||||||
|
@ -1077,7 +1077,7 @@ func TestUncommittedSamplesNotLostOnTruncate(t *testing.T) {
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
defer q.Close()
|
defer q.Close()
|
||||||
|
|
||||||
ss, err := q.Select(labels.NewEqualMatcher("a", "1"))
|
ss, err := q.Select(labels.MustNewMatcher(labels.MatchEqual, "a", "1"))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
testutil.Equals(t, true, ss.Next())
|
testutil.Equals(t, true, ss.Next())
|
||||||
|
@ -1104,7 +1104,7 @@ func TestRemoveSeriesAfterRollbackAndTruncate(t *testing.T) {
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
defer q.Close()
|
defer q.Close()
|
||||||
|
|
||||||
ss, err := q.Select(labels.NewEqualMatcher("a", "1"))
|
ss, err := q.Select(labels.MustNewMatcher(labels.MatchEqual, "a", "1"))
|
||||||
testutil.Ok(t, err)
|
testutil.Ok(t, err)
|
||||||
|
|
||||||
testutil.Equals(t, false, ss.Next())
|
testutil.Equals(t, false, ss.Next())
|
||||||
|
|
|
@ -27,11 +27,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
"github.com/prometheus/prometheus/tsdb/encoding"
|
"github.com/prometheus/prometheus/tsdb/encoding"
|
||||||
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
||||||
"github.com/prometheus/prometheus/tsdb/fileutil"
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -22,10 +22,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
"github.com/prometheus/prometheus/tsdb/encoding"
|
"github.com/prometheus/prometheus/tsdb/encoding"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
)
|
)
|
||||||
|
|
||||||
var allPostingsKey = labels.Label{}
|
var allPostingsKey = labels.Label{}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,233 +0,0 @@
|
||||||
// Copyright 2017 The Prometheus Authors
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package labels
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"os"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/cespare/xxhash"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
const sep = '\xff'
|
|
||||||
|
|
||||||
// Label is a key/value pair of strings.
|
|
||||||
type Label struct {
|
|
||||||
Name, Value string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Labels is a sorted set of labels. Order has to be guaranteed upon
|
|
||||||
// instantiation.
|
|
||||||
type Labels []Label
|
|
||||||
|
|
||||||
func (ls Labels) Len() int { return len(ls) }
|
|
||||||
func (ls Labels) Swap(i, j int) { ls[i], ls[j] = ls[j], ls[i] }
|
|
||||||
func (ls Labels) Less(i, j int) bool { return ls[i].Name < ls[j].Name }
|
|
||||||
|
|
||||||
func (ls Labels) String() string {
|
|
||||||
var b bytes.Buffer
|
|
||||||
|
|
||||||
b.WriteByte('{')
|
|
||||||
for i, l := range ls {
|
|
||||||
if i > 0 {
|
|
||||||
b.WriteByte(',')
|
|
||||||
}
|
|
||||||
b.WriteString(l.Name)
|
|
||||||
b.WriteByte('=')
|
|
||||||
b.WriteString(strconv.Quote(l.Value))
|
|
||||||
}
|
|
||||||
b.WriteByte('}')
|
|
||||||
|
|
||||||
return b.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash returns a hash value for the label set.
|
|
||||||
func (ls Labels) Hash() uint64 {
|
|
||||||
b := make([]byte, 0, 1024)
|
|
||||||
|
|
||||||
for _, v := range ls {
|
|
||||||
b = append(b, v.Name...)
|
|
||||||
b = append(b, sep)
|
|
||||||
b = append(b, v.Value...)
|
|
||||||
b = append(b, sep)
|
|
||||||
}
|
|
||||||
return xxhash.Sum64(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the value for the label with the given name.
|
|
||||||
// Returns an empty string if the label doesn't exist.
|
|
||||||
func (ls Labels) Get(name string) string {
|
|
||||||
for _, l := range ls {
|
|
||||||
if l.Name == name {
|
|
||||||
return l.Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equals returns whether the two label sets are equal.
|
|
||||||
func (ls Labels) Equals(o Labels) bool {
|
|
||||||
if len(ls) != len(o) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i, l := range ls {
|
|
||||||
if o[i] != l {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map returns a string map of the labels.
|
|
||||||
func (ls Labels) Map() map[string]string {
|
|
||||||
m := make(map[string]string, len(ls))
|
|
||||||
for _, l := range ls {
|
|
||||||
m[l.Name] = l.Value
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithoutEmpty returns the labelset without empty labels.
|
|
||||||
// May return the same labelset.
|
|
||||||
func (ls Labels) WithoutEmpty() Labels {
|
|
||||||
for _, v := range ls {
|
|
||||||
if v.Value == "" {
|
|
||||||
els := make(Labels, 0, len(ls)-1)
|
|
||||||
for _, v := range ls {
|
|
||||||
if v.Value != "" {
|
|
||||||
els = append(els, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return els
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ls
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a sorted Labels from the given labels.
|
|
||||||
// The caller has to guarantee that all label names are unique.
|
|
||||||
func New(ls ...Label) Labels {
|
|
||||||
set := make(Labels, 0, len(ls))
|
|
||||||
for _, l := range ls {
|
|
||||||
set = append(set, l)
|
|
||||||
}
|
|
||||||
sort.Sort(set)
|
|
||||||
|
|
||||||
return set
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromMap returns new sorted Labels from the given map.
|
|
||||||
func FromMap(m map[string]string) Labels {
|
|
||||||
l := make(Labels, 0, len(m))
|
|
||||||
for k, v := range m {
|
|
||||||
if v != "" {
|
|
||||||
l = append(l, Label{Name: k, Value: v})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sort.Sort(l)
|
|
||||||
|
|
||||||
return l
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromStrings creates new labels from pairs of strings.
|
|
||||||
func FromStrings(ss ...string) Labels {
|
|
||||||
if len(ss)%2 != 0 {
|
|
||||||
panic("invalid number of strings")
|
|
||||||
}
|
|
||||||
var res Labels
|
|
||||||
for i := 0; i < len(ss); i += 2 {
|
|
||||||
if ss[i+1] != "" {
|
|
||||||
res = append(res, Label{Name: ss[i], Value: ss[i+1]})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Sort(res)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare compares the two label sets.
|
|
||||||
// The result will be 0 if a==b, <0 if a < b, and >0 if a > b.
|
|
||||||
func Compare(a, b Labels) int {
|
|
||||||
l := len(a)
|
|
||||||
if len(b) < l {
|
|
||||||
l = len(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < l; i++ {
|
|
||||||
if d := strings.Compare(a[i].Name, b[i].Name); d != 0 {
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
if d := strings.Compare(a[i].Value, b[i].Value); d != 0 {
|
|
||||||
return d
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If all labels so far were in common, the set with fewer labels comes first.
|
|
||||||
return len(a) - len(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Slice is a sortable slice of label sets.
|
|
||||||
type Slice []Labels
|
|
||||||
|
|
||||||
func (s Slice) Len() int { return len(s) }
|
|
||||||
func (s Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
||||||
func (s Slice) Less(i, j int) bool { return Compare(s[i], s[j]) < 0 }
|
|
||||||
|
|
||||||
// ReadLabels reads up to n label sets in a JSON formatted file fn. It is mostly useful
|
|
||||||
// to load testing data.
|
|
||||||
func ReadLabels(fn string, n int) ([]Labels, error) {
|
|
||||||
f, err := os.Open(fn)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(f)
|
|
||||||
|
|
||||||
var mets []Labels
|
|
||||||
hashes := map[uint64]struct{}{}
|
|
||||||
i := 0
|
|
||||||
|
|
||||||
for scanner.Scan() && i < n {
|
|
||||||
m := make(Labels, 0, 10)
|
|
||||||
|
|
||||||
r := strings.NewReplacer("\"", "", "{", "", "}", "")
|
|
||||||
s := r.Replace(scanner.Text())
|
|
||||||
|
|
||||||
labelChunks := strings.Split(s, ",")
|
|
||||||
for _, labelChunk := range labelChunks {
|
|
||||||
split := strings.Split(labelChunk, ":")
|
|
||||||
m = append(m, Label{Name: split[0], Value: split[1]})
|
|
||||||
}
|
|
||||||
// Order of the k/v labels matters, don't assume we'll always receive them already sorted.
|
|
||||||
sort.Sort(m)
|
|
||||||
|
|
||||||
h := m.Hash()
|
|
||||||
if _, ok := hashes[h]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
mets = append(mets, m)
|
|
||||||
hashes[h] = struct{}{}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
if i != n {
|
|
||||||
return mets, errors.Errorf("requested %d metrics but found %d", n, i)
|
|
||||||
}
|
|
||||||
return mets, nil
|
|
||||||
}
|
|
|
@ -1,199 +0,0 @@
|
||||||
// Copyright 2017 The Prometheus Authors
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package labels
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"math/rand"
|
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCompareAndEquals(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
a, b []Label
|
|
||||||
res int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
a: []Label{},
|
|
||||||
b: []Label{},
|
|
||||||
res: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a: []Label{{"a", ""}},
|
|
||||||
b: []Label{{"a", ""}, {"b", ""}},
|
|
||||||
res: -1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a: []Label{{"a", ""}},
|
|
||||||
b: []Label{{"a", ""}},
|
|
||||||
res: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a: []Label{{"aa", ""}, {"aa", ""}},
|
|
||||||
b: []Label{{"aa", ""}, {"ab", ""}},
|
|
||||||
res: -1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a: []Label{{"aa", ""}, {"abb", ""}},
|
|
||||||
b: []Label{{"aa", ""}, {"ab", ""}},
|
|
||||||
res: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a: []Label{
|
|
||||||
{"__name__", "go_gc_duration_seconds"},
|
|
||||||
{"job", "prometheus"},
|
|
||||||
{"quantile", "0.75"},
|
|
||||||
},
|
|
||||||
b: []Label{
|
|
||||||
{"__name__", "go_gc_duration_seconds"},
|
|
||||||
{"job", "prometheus"},
|
|
||||||
{"quantile", "1"},
|
|
||||||
},
|
|
||||||
res: -1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a: []Label{
|
|
||||||
{"handler", "prometheus"},
|
|
||||||
{"instance", "localhost:9090"},
|
|
||||||
},
|
|
||||||
b: []Label{
|
|
||||||
{"handler", "query"},
|
|
||||||
{"instance", "localhost:9090"},
|
|
||||||
},
|
|
||||||
res: -1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, c := range cases {
|
|
||||||
// Use constructor to ensure sortedness.
|
|
||||||
a, b := New(c.a...), New(c.b...)
|
|
||||||
|
|
||||||
testutil.Equals(t, c.res, Compare(a, b))
|
|
||||||
testutil.Equals(t, c.res == 0, a.Equals(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkSliceSort(b *testing.B) {
|
|
||||||
lbls, err := ReadLabels(filepath.Join("..", "testdata", "20kseries.json"), 20000)
|
|
||||||
testutil.Ok(b, err)
|
|
||||||
|
|
||||||
for len(lbls) < 20e6 {
|
|
||||||
lbls = append(lbls, lbls...)
|
|
||||||
}
|
|
||||||
for i := range lbls {
|
|
||||||
j := rand.Intn(i + 1)
|
|
||||||
lbls[i], lbls[j] = lbls[j], lbls[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, k := range []int{
|
|
||||||
100, 5000, 50000, 300000, 900000, 5e6, 20e6,
|
|
||||||
} {
|
|
||||||
b.Run(fmt.Sprintf("%d", k), func(b *testing.B) {
|
|
||||||
b.ReportAllocs()
|
|
||||||
|
|
||||||
for a := 0; a < b.N; a++ {
|
|
||||||
b.StopTimer()
|
|
||||||
cl := make(Slice, k)
|
|
||||||
copy(cl, Slice(lbls[:k]))
|
|
||||||
b.StartTimer()
|
|
||||||
|
|
||||||
sort.Sort(cl)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkLabelSetFromMap(b *testing.B) {
|
|
||||||
m := map[string]string{
|
|
||||||
"job": "node",
|
|
||||||
"instance": "123.123.1.211:9090",
|
|
||||||
"path": "/api/v1/namespaces/<namespace>/deployments/<name>",
|
|
||||||
"method": "GET",
|
|
||||||
"namespace": "system",
|
|
||||||
"status": "500",
|
|
||||||
}
|
|
||||||
var ls Labels
|
|
||||||
b.ReportAllocs()
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
ls = FromMap(m)
|
|
||||||
}
|
|
||||||
_ = ls
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkMapFromLabels(b *testing.B) {
|
|
||||||
m := map[string]string{
|
|
||||||
"job": "node",
|
|
||||||
"instance": "123.123.1.211:9090",
|
|
||||||
"path": "/api/v1/namespaces/<namespace>/deployments/<name>",
|
|
||||||
"method": "GET",
|
|
||||||
"namespace": "system",
|
|
||||||
"status": "500",
|
|
||||||
}
|
|
||||||
ls := FromMap(m)
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
b.ReportAllocs()
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_ = ls.Map()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkLabelSetEquals(b *testing.B) {
|
|
||||||
// The vast majority of comparisons will be against a matching label set.
|
|
||||||
m := map[string]string{
|
|
||||||
"job": "node",
|
|
||||||
"instance": "123.123.1.211:9090",
|
|
||||||
"path": "/api/v1/namespaces/<namespace>/deployments/<name>",
|
|
||||||
"method": "GET",
|
|
||||||
"namespace": "system",
|
|
||||||
"status": "500",
|
|
||||||
}
|
|
||||||
ls := FromMap(m)
|
|
||||||
var res bool
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
b.ReportAllocs()
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
res = ls.Equals(ls)
|
|
||||||
}
|
|
||||||
_ = res
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkLabelSetHash(b *testing.B) {
|
|
||||||
// The vast majority of comparisons will be against a matching label set.
|
|
||||||
m := map[string]string{
|
|
||||||
"job": "node",
|
|
||||||
"instance": "123.123.1.211:9090",
|
|
||||||
"path": "/api/v1/namespaces/<namespace>/deployments/<name>",
|
|
||||||
"method": "GET",
|
|
||||||
"namespace": "system",
|
|
||||||
"status": "500",
|
|
||||||
}
|
|
||||||
ls := FromMap(m)
|
|
||||||
var res uint64
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
b.ReportAllocs()
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
res += ls.Hash()
|
|
||||||
}
|
|
||||||
fmt.Println(res)
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
// Copyright 2017 The Prometheus Authors
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package labels
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Selector holds constraints for matching against a label set.
|
|
||||||
type Selector []Matcher
|
|
||||||
|
|
||||||
// Matches returns whether the labels satisfy all matchers.
|
|
||||||
func (s Selector) Matches(labels Labels) bool {
|
|
||||||
for _, m := range s {
|
|
||||||
if v := labels.Get(m.Name()); !m.Matches(v) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Matcher specifies a constraint for the value of a label.
|
|
||||||
type Matcher interface {
|
|
||||||
// Name returns the label name the matcher should apply to.
|
|
||||||
Name() string
|
|
||||||
// Matches checks whether a value fulfills the constraints.
|
|
||||||
Matches(v string) bool
|
|
||||||
// String returns a human readable matcher.
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
// EqualMatcher matches on equality.
|
|
||||||
type EqualMatcher struct {
|
|
||||||
name, value string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name implements Matcher interface.
|
|
||||||
func (m EqualMatcher) Name() string { return m.name }
|
|
||||||
|
|
||||||
// Matches implements Matcher interface.
|
|
||||||
func (m EqualMatcher) Matches(v string) bool { return v == m.value }
|
|
||||||
|
|
||||||
// String implements Matcher interface.
|
|
||||||
func (m EqualMatcher) String() string { return fmt.Sprintf("%s=%q", m.name, m.value) }
|
|
||||||
|
|
||||||
// Value returns the matched value.
|
|
||||||
func (m EqualMatcher) Value() string { return m.value }
|
|
||||||
|
|
||||||
// NewEqualMatcher returns a new matcher matching an exact label value.
|
|
||||||
func NewEqualMatcher(name, value string) Matcher {
|
|
||||||
return &EqualMatcher{name: name, value: value}
|
|
||||||
}
|
|
||||||
|
|
||||||
type RegexpMatcher struct {
|
|
||||||
name string
|
|
||||||
re *regexp.Regexp
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m RegexpMatcher) Name() string { return m.name }
|
|
||||||
func (m RegexpMatcher) Matches(v string) bool { return m.re.MatchString(v) }
|
|
||||||
func (m RegexpMatcher) String() string { return fmt.Sprintf("%s=~%q", m.name, m.re.String()) }
|
|
||||||
func (m RegexpMatcher) Value() string { return m.re.String() }
|
|
||||||
|
|
||||||
// NewRegexpMatcher returns a new matcher verifying that a value matches
|
|
||||||
// the regular expression pattern.
|
|
||||||
func NewRegexpMatcher(name, pattern string) (Matcher, error) {
|
|
||||||
re, err := regexp.Compile(pattern)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &RegexpMatcher{name: name, re: re}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMustRegexpMatcher returns a new matcher verifying that a value matches
|
|
||||||
// the regular expression pattern. Will panic if the pattern is not a valid
|
|
||||||
// regular expression.
|
|
||||||
func NewMustRegexpMatcher(name, pattern string) Matcher {
|
|
||||||
re, err := regexp.Compile(pattern)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return &RegexpMatcher{name: name, re: re}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// NotMatcher inverts the matching result for a matcher.
|
|
||||||
type NotMatcher struct {
|
|
||||||
Matcher
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m NotMatcher) Matches(v string) bool { return !m.Matcher.Matches(v) }
|
|
||||||
func (m NotMatcher) String() string { return fmt.Sprintf("not(%s)", m.Matcher.String()) }
|
|
||||||
|
|
||||||
// Not inverts the matcher's matching result.
|
|
||||||
func Not(m Matcher) Matcher {
|
|
||||||
return &NotMatcher{m}
|
|
||||||
}
|
|
|
@ -14,10 +14,10 @@
|
||||||
package tsdb
|
package tsdb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
"github.com/prometheus/prometheus/tsdb/index"
|
"github.com/prometheus/prometheus/tsdb/index"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ func (mockIndexWriter) AddSymbols(sym map[string]struct{}) error { return nil }
|
||||||
func (m *mockIndexWriter) AddSeries(ref uint64, l labels.Labels, chunks ...chunks.Meta) error {
|
func (m *mockIndexWriter) AddSeries(ref uint64, l labels.Labels, chunks ...chunks.Meta) error {
|
||||||
i := -1
|
i := -1
|
||||||
for j, s := range m.series {
|
for j, s := range m.series {
|
||||||
if !labels.FromMap(s.lset).Equals(l) {
|
if !labels.Equal(labels.FromMap(s.lset), l) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
i = j
|
i = j
|
||||||
|
|
|
@ -20,11 +20,11 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
||||||
"github.com/prometheus/prometheus/tsdb/index"
|
"github.com/prometheus/prometheus/tsdb/index"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ import (
|
||||||
// time range.
|
// time range.
|
||||||
type Querier interface {
|
type Querier interface {
|
||||||
// Select returns a set of series that matches the given label matchers.
|
// Select returns a set of series that matches the given label matchers.
|
||||||
Select(...labels.Matcher) (SeriesSet, error)
|
Select(...*labels.Matcher) (SeriesSet, error)
|
||||||
|
|
||||||
// LabelValues returns all potential values for a label name.
|
// LabelValues returns all potential values for a label name.
|
||||||
LabelValues(string) ([]string, error)
|
LabelValues(string) ([]string, error)
|
||||||
|
@ -112,7 +112,7 @@ func (q *querier) LabelValuesFor(string, labels.Label) ([]string, error) {
|
||||||
return nil, fmt.Errorf("not implemented")
|
return nil, fmt.Errorf("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *querier) Select(ms ...labels.Matcher) (SeriesSet, error) {
|
func (q *querier) Select(ms ...*labels.Matcher) (SeriesSet, error) {
|
||||||
if len(q.blocks) == 0 {
|
if len(q.blocks) == 0 {
|
||||||
return EmptySeriesSet(), nil
|
return EmptySeriesSet(), nil
|
||||||
}
|
}
|
||||||
|
@ -145,11 +145,11 @@ type verticalQuerier struct {
|
||||||
querier
|
querier
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *verticalQuerier) Select(ms ...labels.Matcher) (SeriesSet, error) {
|
func (q *verticalQuerier) Select(ms ...*labels.Matcher) (SeriesSet, error) {
|
||||||
return q.sel(q.blocks, ms)
|
return q.sel(q.blocks, ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *verticalQuerier) sel(qs []Querier, ms []labels.Matcher) (SeriesSet, error) {
|
func (q *verticalQuerier) sel(qs []Querier, ms []*labels.Matcher) (SeriesSet, error) {
|
||||||
if len(qs) == 0 {
|
if len(qs) == 0 {
|
||||||
return EmptySeriesSet(), nil
|
return EmptySeriesSet(), nil
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ type blockQuerier struct {
|
||||||
mint, maxt int64
|
mint, maxt int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *blockQuerier) Select(ms ...labels.Matcher) (SeriesSet, error) {
|
func (q *blockQuerier) Select(ms ...*labels.Matcher) (SeriesSet, error) {
|
||||||
base, err := LookupChunkSeries(q.index, q.tombstones, ms...)
|
base, err := LookupChunkSeries(q.index, q.tombstones, ms...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -320,26 +320,31 @@ func findSetMatches(pattern string) []string {
|
||||||
|
|
||||||
// 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.
|
// based on the given matchers.
|
||||||
func PostingsForMatchers(ix IndexReader, ms ...labels.Matcher) (index.Postings, error) {
|
func PostingsForMatchers(ix IndexReader, ms ...*labels.Matcher) (index.Postings, error) {
|
||||||
var its, notIts []index.Postings
|
var its, notIts []index.Postings
|
||||||
// See which label must be non-empty.
|
// See which label must be non-empty.
|
||||||
// Optimization for case like {l=~".", l!="1"}.
|
// Optimization for case like {l=~".", l!="1"}.
|
||||||
labelMustBeSet := make(map[string]bool, len(ms))
|
labelMustBeSet := make(map[string]bool, len(ms))
|
||||||
for _, m := range ms {
|
for _, m := range ms {
|
||||||
if !m.Matches("") {
|
if !m.Matches("") {
|
||||||
labelMustBeSet[m.Name()] = true
|
labelMustBeSet[m.Name] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, m := range ms {
|
for _, m := range ms {
|
||||||
if labelMustBeSet[m.Name()] {
|
if labelMustBeSet[m.Name] {
|
||||||
// If this matcher must be non-empty, we can be smarter.
|
// If this matcher must be non-empty, we can be smarter.
|
||||||
matchesEmpty := m.Matches("")
|
matchesEmpty := m.Matches("")
|
||||||
nm, isNot := m.(*labels.NotMatcher)
|
isNot := m.Type == labels.MatchNotEqual || m.Type == labels.MatchNotRegexp
|
||||||
if isNot && matchesEmpty { // l!="foo"
|
if isNot && matchesEmpty { // l!="foo"
|
||||||
// If the label can't be empty and is a Not and the inner matcher
|
// If the label can't be empty and is a Not and the inner matcher
|
||||||
// doesn't match empty, then subtract it out at the end.
|
// doesn't match empty, then subtract it out at the end.
|
||||||
it, err := postingsForMatcher(ix, nm.Matcher)
|
inverse, err := m.Inverse()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
it, err := postingsForMatcher(ix, inverse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -347,7 +352,12 @@ func PostingsForMatchers(ix IndexReader, ms ...labels.Matcher) (index.Postings,
|
||||||
} else if isNot && !matchesEmpty { // l!=""
|
} else if isNot && !matchesEmpty { // l!=""
|
||||||
// If the label can't be empty and is a Not, but the inner matcher can
|
// If the label can't be empty and is a Not, but the inner matcher can
|
||||||
// be empty we need to use inversePostingsForMatcher.
|
// be empty we need to use inversePostingsForMatcher.
|
||||||
it, err := inversePostingsForMatcher(ix, nm.Matcher)
|
inverse, err := m.Inverse()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
it, err := inversePostingsForMatcher(ix, inverse)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -391,23 +401,23 @@ func PostingsForMatchers(ix IndexReader, ms ...labels.Matcher) (index.Postings,
|
||||||
return ix.SortedPostings(it), nil
|
return ix.SortedPostings(it), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func postingsForMatcher(ix IndexReader, m labels.Matcher) (index.Postings, error) {
|
func postingsForMatcher(ix IndexReader, m *labels.Matcher) (index.Postings, error) {
|
||||||
// This method will not return postings for missing labels.
|
// This method will not return postings for missing labels.
|
||||||
|
|
||||||
// Fast-path for equal matching.
|
// Fast-path for equal matching.
|
||||||
if em, ok := m.(*labels.EqualMatcher); ok {
|
if m.Type == labels.MatchEqual {
|
||||||
return ix.Postings(em.Name(), em.Value())
|
return ix.Postings(m.Name, m.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fast-path for set matching.
|
// Fast-path for set matching.
|
||||||
if em, ok := m.(*labels.RegexpMatcher); ok {
|
if m.Type == labels.MatchRegexp {
|
||||||
setMatches := findSetMatches(em.Value())
|
setMatches := findSetMatches(m.Value)
|
||||||
if len(setMatches) > 0 {
|
if len(setMatches) > 0 {
|
||||||
return postingsForSetMatcher(ix, em.Name(), setMatches)
|
return postingsForSetMatcher(ix, m.Name, setMatches)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tpls, err := ix.LabelValues(m.Name())
|
tpls, err := ix.LabelValues(m.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -430,7 +440,7 @@ func postingsForMatcher(ix IndexReader, m labels.Matcher) (index.Postings, error
|
||||||
var rit []index.Postings
|
var rit []index.Postings
|
||||||
|
|
||||||
for _, v := range res {
|
for _, v := range res {
|
||||||
it, err := ix.Postings(m.Name(), v)
|
it, err := ix.Postings(m.Name, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -441,8 +451,8 @@ func postingsForMatcher(ix IndexReader, m labels.Matcher) (index.Postings, error
|
||||||
}
|
}
|
||||||
|
|
||||||
// inversePostingsForMatcher returns the postings for the series with the label name set but not matching the matcher.
|
// inversePostingsForMatcher returns the postings for the series with the label name set but not matching the matcher.
|
||||||
func inversePostingsForMatcher(ix IndexReader, m labels.Matcher) (index.Postings, error) {
|
func inversePostingsForMatcher(ix IndexReader, m *labels.Matcher) (index.Postings, error) {
|
||||||
tpls, err := ix.LabelValues(m.Name())
|
tpls, err := ix.LabelValues(m.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -461,7 +471,7 @@ func inversePostingsForMatcher(ix IndexReader, m labels.Matcher) (index.Postings
|
||||||
|
|
||||||
var rit []index.Postings
|
var rit []index.Postings
|
||||||
for _, v := range res {
|
for _, v := range res {
|
||||||
it, err := ix.Postings(m.Name(), v)
|
it, err := ix.Postings(m.Name, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -737,7 +747,7 @@ type baseChunkSeries struct {
|
||||||
|
|
||||||
// LookupChunkSeries retrieves all series for the given matchers and returns a ChunkSeriesSet
|
// LookupChunkSeries retrieves all series for the given matchers and returns a ChunkSeriesSet
|
||||||
// over them. It drops chunks based on tombstones in the given reader.
|
// over them. It drops chunks based on tombstones in the given reader.
|
||||||
func LookupChunkSeries(ir IndexReader, tr tombstones.Reader, ms ...labels.Matcher) (ChunkSeriesSet, error) {
|
func LookupChunkSeries(ir IndexReader, tr tombstones.Reader, ms ...*labels.Matcher) (ChunkSeriesSet, error) {
|
||||||
if tr == nil {
|
if tr == nil {
|
||||||
tr = tombstones.NewMemTombstones()
|
tr = tombstones.NewMemTombstones()
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,10 +25,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
"github.com/prometheus/prometheus/tsdb/chunkenc"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
"github.com/prometheus/prometheus/tsdb/index"
|
"github.com/prometheus/prometheus/tsdb/index"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
"github.com/prometheus/prometheus/tsdb/tsdbutil"
|
"github.com/prometheus/prometheus/tsdb/tsdbutil"
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
|
@ -271,7 +271,7 @@ func TestBlockQuerier(t *testing.T) {
|
||||||
|
|
||||||
type query struct {
|
type query struct {
|
||||||
mint, maxt int64
|
mint, maxt int64
|
||||||
ms []labels.Matcher
|
ms []*labels.Matcher
|
||||||
exp SeriesSet
|
exp SeriesSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,25 +327,25 @@ func TestBlockQuerier(t *testing.T) {
|
||||||
{
|
{
|
||||||
mint: 0,
|
mint: 0,
|
||||||
maxt: 0,
|
maxt: 0,
|
||||||
ms: []labels.Matcher{},
|
ms: []*labels.Matcher{},
|
||||||
exp: newMockSeriesSet([]Series{}),
|
exp: newMockSeriesSet([]Series{}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mint: 0,
|
mint: 0,
|
||||||
maxt: 0,
|
maxt: 0,
|
||||||
ms: []labels.Matcher{labels.NewEqualMatcher("a", "a")},
|
ms: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "a", "a")},
|
||||||
exp: newMockSeriesSet([]Series{}),
|
exp: newMockSeriesSet([]Series{}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mint: 1,
|
mint: 1,
|
||||||
maxt: 0,
|
maxt: 0,
|
||||||
ms: []labels.Matcher{labels.NewEqualMatcher("a", "a")},
|
ms: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "a", "a")},
|
||||||
exp: newMockSeriesSet([]Series{}),
|
exp: newMockSeriesSet([]Series{}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
mint: 2,
|
mint: 2,
|
||||||
maxt: 6,
|
maxt: 6,
|
||||||
ms: []labels.Matcher{labels.NewEqualMatcher("a", "a")},
|
ms: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "a", "a")},
|
||||||
exp: newMockSeriesSet([]Series{
|
exp: newMockSeriesSet([]Series{
|
||||||
newSeries(map[string]string{
|
newSeries(map[string]string{
|
||||||
"a": "a",
|
"a": "a",
|
||||||
|
@ -409,7 +409,7 @@ func TestBlockQuerierDelete(t *testing.T) {
|
||||||
|
|
||||||
type query struct {
|
type query struct {
|
||||||
mint, maxt int64
|
mint, maxt int64
|
||||||
ms []labels.Matcher
|
ms []*labels.Matcher
|
||||||
exp SeriesSet
|
exp SeriesSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +470,7 @@ func TestBlockQuerierDelete(t *testing.T) {
|
||||||
{
|
{
|
||||||
mint: 2,
|
mint: 2,
|
||||||
maxt: 7,
|
maxt: 7,
|
||||||
ms: []labels.Matcher{labels.NewEqualMatcher("a", "a")},
|
ms: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "a", "a")},
|
||||||
exp: newMockSeriesSet([]Series{
|
exp: newMockSeriesSet([]Series{
|
||||||
newSeries(map[string]string{
|
newSeries(map[string]string{
|
||||||
"a": "a",
|
"a": "a",
|
||||||
|
@ -488,7 +488,7 @@ func TestBlockQuerierDelete(t *testing.T) {
|
||||||
{
|
{
|
||||||
mint: 2,
|
mint: 2,
|
||||||
maxt: 7,
|
maxt: 7,
|
||||||
ms: []labels.Matcher{labels.NewEqualMatcher("b", "b")},
|
ms: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "b", "b")},
|
||||||
exp: newMockSeriesSet([]Series{
|
exp: newMockSeriesSet([]Series{
|
||||||
newSeries(map[string]string{
|
newSeries(map[string]string{
|
||||||
"a": "a",
|
"a": "a",
|
||||||
|
@ -506,7 +506,7 @@ func TestBlockQuerierDelete(t *testing.T) {
|
||||||
{
|
{
|
||||||
mint: 1,
|
mint: 1,
|
||||||
maxt: 4,
|
maxt: 4,
|
||||||
ms: []labels.Matcher{labels.NewEqualMatcher("a", "a")},
|
ms: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "a", "a")},
|
||||||
exp: newMockSeriesSet([]Series{
|
exp: newMockSeriesSet([]Series{
|
||||||
newSeries(map[string]string{
|
newSeries(map[string]string{
|
||||||
"a": "a",
|
"a": "a",
|
||||||
|
@ -519,7 +519,7 @@ func TestBlockQuerierDelete(t *testing.T) {
|
||||||
{
|
{
|
||||||
mint: 1,
|
mint: 1,
|
||||||
maxt: 3,
|
maxt: 3,
|
||||||
ms: []labels.Matcher{labels.NewEqualMatcher("a", "a")},
|
ms: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "a", "a")},
|
||||||
exp: newMockSeriesSet([]Series{}),
|
exp: newMockSeriesSet([]Series{}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1539,7 +1539,7 @@ func BenchmarkQueryIterator(b *testing.B) {
|
||||||
}
|
}
|
||||||
defer sq.Close()
|
defer sq.Close()
|
||||||
|
|
||||||
benchQuery(b, c.numSeries, sq, labels.Selector{labels.NewMustRegexpMatcher("__name__", ".*")})
|
benchQuery(b, c.numSeries, sq, labels.Selector{labels.MustNewMatcher(labels.MatchRegexp, "__name__", ".*")})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1619,7 +1619,7 @@ func BenchmarkQuerySeek(b *testing.B) {
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
|
||||||
ss, err := sq.Select(labels.NewMustRegexpMatcher("__name__", ".*"))
|
ss, err := sq.Select(labels.MustNewMatcher(labels.MatchRegexp, "__name__", ".*"))
|
||||||
for ss.Next() {
|
for ss.Next() {
|
||||||
it := ss.At().Iterator()
|
it := ss.At().Iterator()
|
||||||
for t := mint; t <= maxt; t++ {
|
for t := mint; t <= maxt; t++ {
|
||||||
|
@ -1756,7 +1756,7 @@ func BenchmarkSetMatcher(b *testing.B) {
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
_, err := que.Select(labels.NewMustRegexpMatcher("test", c.pattern))
|
_, err := que.Select(labels.MustNewMatcher(labels.MatchRegexp, "test", c.pattern))
|
||||||
testutil.Ok(b, err)
|
testutil.Ok(b, err)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1836,12 +1836,12 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
testutil.Ok(t, app.Commit())
|
testutil.Ok(t, app.Commit())
|
||||||
|
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
matchers []labels.Matcher
|
matchers []*labels.Matcher
|
||||||
exp []labels.Labels
|
exp []labels.Labels
|
||||||
}{
|
}{
|
||||||
// Simple equals.
|
// Simple equals.
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
|
@ -1849,17 +1849,17 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.NewEqualMatcher("i", "a")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchEqual, "i", "a")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.NewEqualMatcher("i", "missing")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchEqual, "i", "missing")},
|
||||||
exp: []labels.Labels{},
|
exp: []labels.Labels{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("missing", "")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "missing", "")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
|
@ -1870,32 +1870,32 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
},
|
},
|
||||||
// Not equals.
|
// Not equals.
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.Not(labels.NewEqualMatcher("n", "1"))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchNotEqual, "n", "1")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "2"),
|
labels.FromStrings("n", "2"),
|
||||||
labels.FromStrings("n", "2.5"),
|
labels.FromStrings("n", "2.5"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.Not(labels.NewEqualMatcher("i", ""))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchNotEqual, "i", "")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
labels.FromStrings("n", "1", "i", "b"),
|
labels.FromStrings("n", "1", "i", "b"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.Not(labels.NewEqualMatcher("missing", ""))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchNotEqual, "missing", "")},
|
||||||
exp: []labels.Labels{},
|
exp: []labels.Labels{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.Not(labels.NewEqualMatcher("i", "a"))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchNotEqual, "i", "a")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
labels.FromStrings("n", "1", "i", "b"),
|
labels.FromStrings("n", "1", "i", "b"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.Not(labels.NewEqualMatcher("i", ""))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchNotEqual, "i", "")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
labels.FromStrings("n", "1", "i", "b"),
|
labels.FromStrings("n", "1", "i", "b"),
|
||||||
|
@ -1903,7 +1903,7 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
},
|
},
|
||||||
// Regex.
|
// Regex.
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewMustRegexpMatcher("n", "^1$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchRegexp, "n", "^1$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
|
@ -1911,20 +1911,20 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.NewMustRegexpMatcher("i", "^a$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchRegexp, "i", "^a$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.NewMustRegexpMatcher("i", "^a?$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchRegexp, "i", "^a?$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewMustRegexpMatcher("i", "^$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchRegexp, "i", "^$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
labels.FromStrings("n", "2"),
|
labels.FromStrings("n", "2"),
|
||||||
|
@ -1932,13 +1932,13 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.NewMustRegexpMatcher("i", "^$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchRegexp, "i", "^$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.NewMustRegexpMatcher("i", "^.*$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchRegexp, "i", "^.*$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
|
@ -1946,7 +1946,7 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.NewMustRegexpMatcher("i", "^.+$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchRegexp, "i", "^.+$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
labels.FromStrings("n", "1", "i", "b"),
|
labels.FromStrings("n", "1", "i", "b"),
|
||||||
|
@ -1954,51 +1954,51 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
},
|
},
|
||||||
// Not regex.
|
// Not regex.
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.Not(labels.NewMustRegexpMatcher("n", "^1$"))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchNotRegexp, "n", "^1$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "2"),
|
labels.FromStrings("n", "2"),
|
||||||
labels.FromStrings("n", "2.5"),
|
labels.FromStrings("n", "2.5"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.Not(labels.NewMustRegexpMatcher("i", "^a$"))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^a$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
labels.FromStrings("n", "1", "i", "b"),
|
labels.FromStrings("n", "1", "i", "b"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.Not(labels.NewMustRegexpMatcher("i", "^a?$"))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^a?$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1", "i", "b"),
|
labels.FromStrings("n", "1", "i", "b"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.Not(labels.NewMustRegexpMatcher("i", "^$"))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
labels.FromStrings("n", "1", "i", "b"),
|
labels.FromStrings("n", "1", "i", "b"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.Not(labels.NewMustRegexpMatcher("i", "^.*$"))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^.*$")},
|
||||||
exp: []labels.Labels{},
|
exp: []labels.Labels{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.Not(labels.NewMustRegexpMatcher("i", "^.+$"))},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchNotRegexp, "i", "^.+$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Combinations.
|
// Combinations.
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.Not(labels.NewEqualMatcher("i", "")), labels.NewEqualMatcher("i", "a")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchNotEqual, "i", ""), labels.MustNewMatcher(labels.MatchEqual, "i", "a")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewEqualMatcher("n", "1"), labels.Not(labels.NewEqualMatcher("i", "b")), labels.NewMustRegexpMatcher("i", "^(b|a).*$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchEqual, "n", "1"), labels.MustNewMatcher(labels.MatchNotEqual, "i", "b"), labels.MustNewMatcher(labels.MatchRegexp, "i", "^(b|a).*$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
},
|
},
|
||||||
|
@ -2006,7 +2006,7 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
// Set optimization for Regex.
|
// Set optimization for Regex.
|
||||||
// Refer to https://github.com/prometheus/prometheus/issues/2651.
|
// Refer to https://github.com/prometheus/prometheus/issues/2651.
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewMustRegexpMatcher("n", "^(?:1|2)$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchRegexp, "n", "^(?:1|2)$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
|
@ -2015,20 +2015,20 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewMustRegexpMatcher("i", "^(?:a|b)$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchRegexp, "i", "^(?:a|b)$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1", "i", "a"),
|
labels.FromStrings("n", "1", "i", "a"),
|
||||||
labels.FromStrings("n", "1", "i", "b"),
|
labels.FromStrings("n", "1", "i", "b"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewMustRegexpMatcher("n", "^(?:x1|2)$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchRegexp, "n", "^(?:x1|2)$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "2"),
|
labels.FromStrings("n", "2"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewMustRegexpMatcher("n", "^(?:2|2\\.5)$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchRegexp, "n", "^(?:2|2\\.5)$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "2"),
|
labels.FromStrings("n", "2"),
|
||||||
labels.FromStrings("n", "2.5"),
|
labels.FromStrings("n", "2.5"),
|
||||||
|
@ -2036,7 +2036,7 @@ func TestPostingsForMatchers(t *testing.T) {
|
||||||
},
|
},
|
||||||
// Empty value.
|
// Empty value.
|
||||||
{
|
{
|
||||||
matchers: []labels.Matcher{labels.NewMustRegexpMatcher("i", "^(?:c||d)$")},
|
matchers: []*labels.Matcher{labels.MustNewMatcher(labels.MatchRegexp, "i", "^(?:c||d)$")},
|
||||||
exp: []labels.Labels{
|
exp: []labels.Labels{
|
||||||
labels.FromStrings("n", "1"),
|
labels.FromStrings("n", "1"),
|
||||||
labels.FromStrings("n", "2"),
|
labels.FromStrings("n", "2"),
|
||||||
|
@ -2103,29 +2103,29 @@ func TestClose(t *testing.T) {
|
||||||
func BenchmarkQueries(b *testing.B) {
|
func BenchmarkQueries(b *testing.B) {
|
||||||
cases := map[string]labels.Selector{
|
cases := map[string]labels.Selector{
|
||||||
"Eq Matcher: Expansion - 1": {
|
"Eq Matcher: Expansion - 1": {
|
||||||
labels.NewEqualMatcher("la", "va"),
|
labels.MustNewMatcher(labels.MatchEqual, "la", "va"),
|
||||||
},
|
},
|
||||||
"Eq Matcher: Expansion - 2": {
|
"Eq Matcher: Expansion - 2": {
|
||||||
labels.NewEqualMatcher("la", "va"),
|
labels.MustNewMatcher(labels.MatchEqual, "la", "va"),
|
||||||
labels.NewEqualMatcher("lb", "vb"),
|
labels.MustNewMatcher(labels.MatchEqual, "lb", "vb"),
|
||||||
},
|
},
|
||||||
|
|
||||||
"Eq Matcher: Expansion - 3": {
|
"Eq Matcher: Expansion - 3": {
|
||||||
labels.NewEqualMatcher("la", "va"),
|
labels.MustNewMatcher(labels.MatchEqual, "la", "va"),
|
||||||
labels.NewEqualMatcher("lb", "vb"),
|
labels.MustNewMatcher(labels.MatchEqual, "lb", "vb"),
|
||||||
labels.NewEqualMatcher("lc", "vc"),
|
labels.MustNewMatcher(labels.MatchEqual, "lc", "vc"),
|
||||||
},
|
},
|
||||||
"Regex Matcher: Expansion - 1": {
|
"Regex Matcher: Expansion - 1": {
|
||||||
labels.NewMustRegexpMatcher("la", ".*va"),
|
labels.MustNewMatcher(labels.MatchRegexp, "la", ".*va"),
|
||||||
},
|
},
|
||||||
"Regex Matcher: Expansion - 2": {
|
"Regex Matcher: Expansion - 2": {
|
||||||
labels.NewMustRegexpMatcher("la", ".*va"),
|
labels.MustNewMatcher(labels.MatchRegexp, "la", ".*va"),
|
||||||
labels.NewMustRegexpMatcher("lb", ".*vb"),
|
labels.MustNewMatcher(labels.MatchRegexp, "lb", ".*vb"),
|
||||||
},
|
},
|
||||||
"Regex Matcher: Expansion - 3": {
|
"Regex Matcher: Expansion - 3": {
|
||||||
labels.NewMustRegexpMatcher("la", ".*va"),
|
labels.MustNewMatcher(labels.MatchRegexp, "la", ".*va"),
|
||||||
labels.NewMustRegexpMatcher("lb", ".*vb"),
|
labels.MustNewMatcher(labels.MatchRegexp, "lb", ".*vb"),
|
||||||
labels.NewMustRegexpMatcher("lc", ".*vc"),
|
labels.MustNewMatcher(labels.MatchRegexp, "lc", ".*vc"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2154,11 +2154,11 @@ func BenchmarkQueries(b *testing.B) {
|
||||||
{
|
{
|
||||||
var commonLbls labels.Labels
|
var commonLbls labels.Labels
|
||||||
for _, selector := range selectors {
|
for _, selector := range selectors {
|
||||||
switch sel := selector.(type) {
|
switch selector.Type {
|
||||||
case *labels.EqualMatcher:
|
case labels.MatchEqual:
|
||||||
commonLbls = append(commonLbls, labels.Label{Name: sel.Name(), Value: sel.Value()})
|
commonLbls = append(commonLbls, labels.Label{Name: selector.Name, Value: selector.Value})
|
||||||
case *labels.RegexpMatcher:
|
case labels.MatchRegexp:
|
||||||
commonLbls = append(commonLbls, labels.Label{Name: sel.Name(), Value: sel.Value()})
|
commonLbls = append(commonLbls, labels.Label{Name: selector.Name, Value: selector.Value})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i := range commonLbls {
|
for i := range commonLbls {
|
||||||
|
|
|
@ -19,8 +19,8 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/encoding"
|
"github.com/prometheus/prometheus/tsdb/encoding"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/encoding"
|
"github.com/prometheus/prometheus/tsdb/encoding"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
|
|
@ -18,10 +18,10 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/chunks"
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
||||||
"github.com/prometheus/prometheus/tsdb/fileutil"
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
||||||
"github.com/prometheus/prometheus/tsdb/index"
|
"github.com/prometheus/prometheus/tsdb/index"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkMapClone(b *testing.B) {
|
func BenchmarkMapClone(b *testing.B) {
|
||||||
|
|
|
@ -31,9 +31,9 @@ import (
|
||||||
"github.com/go-kit/kit/log/level"
|
"github.com/go-kit/kit/log/level"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/encoding"
|
"github.com/prometheus/prometheus/tsdb/encoding"
|
||||||
"github.com/prometheus/prometheus/tsdb/fileutil"
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/record"
|
"github.com/prometheus/prometheus/tsdb/record"
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
"github.com/prometheus/prometheus/tsdb/wal"
|
"github.com/prometheus/prometheus/tsdb/wal"
|
||||||
|
|
|
@ -23,8 +23,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/fileutil"
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/record"
|
"github.com/prometheus/prometheus/tsdb/record"
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/record"
|
"github.com/prometheus/prometheus/tsdb/record"
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
|
|
@ -27,8 +27,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-kit/kit/log"
|
"github.com/go-kit/kit/log"
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/tsdb/fileutil"
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
||||||
"github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/record"
|
"github.com/prometheus/prometheus/tsdb/record"
|
||||||
"github.com/prometheus/prometheus/tsdb/tombstones"
|
"github.com/prometheus/prometheus/tsdb/tombstones"
|
||||||
"github.com/prometheus/prometheus/tsdb/wal"
|
"github.com/prometheus/prometheus/tsdb/wal"
|
||||||
|
|
|
@ -36,9 +36,6 @@ import (
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
"github.com/prometheus/common/route"
|
"github.com/prometheus/common/route"
|
||||||
"github.com/prometheus/prometheus/tsdb"
|
|
||||||
"github.com/prometheus/prometheus/tsdb/index"
|
|
||||||
tsdbLabels "github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"github.com/prometheus/prometheus/pkg/gate"
|
"github.com/prometheus/prometheus/pkg/gate"
|
||||||
|
@ -51,6 +48,8 @@ import (
|
||||||
"github.com/prometheus/prometheus/scrape"
|
"github.com/prometheus/prometheus/scrape"
|
||||||
"github.com/prometheus/prometheus/storage"
|
"github.com/prometheus/prometheus/storage"
|
||||||
"github.com/prometheus/prometheus/storage/remote"
|
"github.com/prometheus/prometheus/storage/remote"
|
||||||
|
"github.com/prometheus/prometheus/tsdb"
|
||||||
|
"github.com/prometheus/prometheus/tsdb/index"
|
||||||
"github.com/prometheus/prometheus/util/httputil"
|
"github.com/prometheus/prometheus/util/httputil"
|
||||||
"github.com/prometheus/prometheus/util/stats"
|
"github.com/prometheus/prometheus/util/stats"
|
||||||
)
|
)
|
||||||
|
@ -157,7 +156,7 @@ type apiFunc func(r *http.Request) apiFuncResult
|
||||||
// TSDBAdmin defines the tsdb interfaces used by the v1 API for admin operations.
|
// TSDBAdmin defines the tsdb interfaces used by the v1 API for admin operations.
|
||||||
type TSDBAdmin interface {
|
type TSDBAdmin interface {
|
||||||
CleanTombstones() error
|
CleanTombstones() error
|
||||||
Delete(mint, maxt int64, ms ...tsdbLabels.Matcher) error
|
Delete(mint, maxt int64, ms ...*labels.Matcher) error
|
||||||
Dir() string
|
Dir() string
|
||||||
Snapshot(dir string, withHead bool) error
|
Snapshot(dir string, withHead bool) error
|
||||||
Head() *tsdb.Head
|
Head() *tsdb.Head
|
||||||
|
@ -1173,12 +1172,7 @@ func (api *API) deleteSeries(r *http.Request) apiFuncResult {
|
||||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
var selector tsdbLabels.Selector
|
if err := db.Delete(timestamp.FromTime(start), timestamp.FromTime(end), matchers...); err != nil {
|
||||||
for _, m := range matchers {
|
|
||||||
selector = append(selector, convertMatcher(m))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := db.Delete(timestamp.FromTime(start), timestamp.FromTime(end), selector...); err != nil {
|
|
||||||
return apiFuncResult{nil, &apiError{errorInternal, err}, nil, nil}
|
return apiFuncResult{nil, &apiError{errorInternal, err}, nil, nil}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1241,31 +1235,6 @@ func (api *API) cleanTombstones(r *http.Request) apiFuncResult {
|
||||||
return apiFuncResult{nil, nil, nil, nil}
|
return apiFuncResult{nil, nil, nil, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertMatcher(m *labels.Matcher) tsdbLabels.Matcher {
|
|
||||||
switch m.Type {
|
|
||||||
case labels.MatchEqual:
|
|
||||||
return tsdbLabels.NewEqualMatcher(m.Name, m.Value)
|
|
||||||
|
|
||||||
case labels.MatchNotEqual:
|
|
||||||
return tsdbLabels.Not(tsdbLabels.NewEqualMatcher(m.Name, m.Value))
|
|
||||||
|
|
||||||
case labels.MatchRegexp:
|
|
||||||
res, err := tsdbLabels.NewRegexpMatcher(m.Name, "^(?:"+m.Value+")$")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
|
|
||||||
case labels.MatchNotRegexp:
|
|
||||||
res, err := tsdbLabels.NewRegexpMatcher(m.Name, "^(?:"+m.Value+")$")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return tsdbLabels.Not(res)
|
|
||||||
}
|
|
||||||
panic("storage.convertMatcher: invalid matcher type")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *API) respond(w http.ResponseWriter, data interface{}, warnings storage.Warnings) {
|
func (api *API) respond(w http.ResponseWriter, data interface{}, warnings storage.Warnings) {
|
||||||
statusMessage := statusSuccess
|
statusMessage := statusSuccess
|
||||||
var warningStrings []string
|
var warningStrings []string
|
||||||
|
|
|
@ -39,8 +39,6 @@ import (
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
"github.com/prometheus/common/promlog"
|
"github.com/prometheus/common/promlog"
|
||||||
"github.com/prometheus/common/route"
|
"github.com/prometheus/common/route"
|
||||||
"github.com/prometheus/prometheus/tsdb"
|
|
||||||
tsdbLabels "github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"github.com/prometheus/prometheus/pkg/gate"
|
"github.com/prometheus/prometheus/pkg/gate"
|
||||||
|
@ -52,6 +50,7 @@ import (
|
||||||
"github.com/prometheus/prometheus/scrape"
|
"github.com/prometheus/prometheus/scrape"
|
||||||
"github.com/prometheus/prometheus/storage"
|
"github.com/prometheus/prometheus/storage"
|
||||||
"github.com/prometheus/prometheus/storage/remote"
|
"github.com/prometheus/prometheus/storage/remote"
|
||||||
|
"github.com/prometheus/prometheus/tsdb"
|
||||||
"github.com/prometheus/prometheus/util/teststorage"
|
"github.com/prometheus/prometheus/util/teststorage"
|
||||||
"github.com/prometheus/prometheus/util/testutil"
|
"github.com/prometheus/prometheus/util/testutil"
|
||||||
)
|
)
|
||||||
|
@ -1323,8 +1322,8 @@ type fakeDB struct {
|
||||||
closer func()
|
closer func()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fakeDB) CleanTombstones() error { return f.err }
|
func (f *fakeDB) CleanTombstones() error { return f.err }
|
||||||
func (f *fakeDB) Delete(mint, maxt int64, ms ...tsdbLabels.Matcher) error { return f.err }
|
func (f *fakeDB) Delete(mint, maxt int64, ms ...*labels.Matcher) error { return f.err }
|
||||||
func (f *fakeDB) Dir() string {
|
func (f *fakeDB) Dir() string {
|
||||||
dir, _ := ioutil.TempDir("", "fakeDB")
|
dir, _ := ioutil.TempDir("", "fakeDB")
|
||||||
f.closer = func() {
|
f.closer = func() {
|
||||||
|
|
|
@ -26,14 +26,15 @@ import (
|
||||||
|
|
||||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/prometheus/prometheus/tsdb"
|
|
||||||
tsdbLabels "github.com/prometheus/prometheus/tsdb/labels"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
|
"github.com/prometheus/prometheus/pkg/labels"
|
||||||
"github.com/prometheus/prometheus/pkg/timestamp"
|
"github.com/prometheus/prometheus/pkg/timestamp"
|
||||||
pb "github.com/prometheus/prometheus/prompb"
|
pb "github.com/prometheus/prometheus/prompb"
|
||||||
|
"github.com/prometheus/prometheus/tsdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
// API encapsulates all API services.
|
// API encapsulates all API services.
|
||||||
|
@ -186,32 +187,29 @@ func (s *Admin) DeleteSeries(_ context.Context, r *pb.SeriesDeleteRequest) (*pb.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
var matchers tsdbLabels.Selector
|
var matchers []*labels.Matcher
|
||||||
|
|
||||||
for _, m := range r.Matchers {
|
for _, m := range r.Matchers {
|
||||||
var lm tsdbLabels.Matcher
|
var lm *labels.Matcher
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
switch m.Type {
|
switch m.Type {
|
||||||
case pb.LabelMatcher_EQ:
|
case pb.LabelMatcher_EQ:
|
||||||
lm = tsdbLabels.NewEqualMatcher(m.Name, m.Value)
|
lm, err = labels.NewMatcher(labels.MatchEqual, m.Name, m.Value)
|
||||||
case pb.LabelMatcher_NEQ:
|
case pb.LabelMatcher_NEQ:
|
||||||
lm = tsdbLabels.Not(tsdbLabels.NewEqualMatcher(m.Name, m.Value))
|
lm, err = labels.NewMatcher(labels.MatchNotEqual, m.Name, m.Value)
|
||||||
case pb.LabelMatcher_RE:
|
case pb.LabelMatcher_RE:
|
||||||
lm, err = tsdbLabels.NewRegexpMatcher(m.Name, m.Value)
|
lm, err = labels.NewMatcher(labels.MatchRegexp, m.Name, m.Value)
|
||||||
if err != nil {
|
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "bad regexp matcher: %s", err)
|
|
||||||
}
|
|
||||||
case pb.LabelMatcher_NRE:
|
case pb.LabelMatcher_NRE:
|
||||||
lm, err = tsdbLabels.NewRegexpMatcher(m.Name, m.Value)
|
lm, err = labels.NewMatcher(labels.MatchNotRegexp, m.Name, m.Value)
|
||||||
if err != nil {
|
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "bad regexp matcher: %s", err)
|
|
||||||
}
|
|
||||||
lm = tsdbLabels.Not(lm)
|
|
||||||
default:
|
default:
|
||||||
return nil, status.Error(codes.InvalidArgument, "unknown matcher type")
|
return nil, status.Error(codes.InvalidArgument, "unknown matcher type")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Errorf(codes.InvalidArgument, "bad matcher: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
matchers = append(matchers, lm)
|
matchers = append(matchers, lm)
|
||||||
}
|
}
|
||||||
db := s.db()
|
db := s.db()
|
||||||
|
|
Loading…
Reference in a new issue