mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Extract labels package
This commit is contained in:
parent
ee217adc7e
commit
ede733ab6c
|
@ -14,6 +14,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fabxc/tsdb"
|
"github.com/fabxc/tsdb"
|
||||||
|
"github.com/fabxc/tsdb/labels"
|
||||||
dto "github.com/prometheus/client_model/go"
|
dto "github.com/prometheus/client_model/go"
|
||||||
"github.com/prometheus/common/expfmt"
|
"github.com/prometheus/common/expfmt"
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
|
@ -162,16 +163,16 @@ func (b *writeBenchmark) ingestScrapesShard(metrics []model.Metric, scrapeCount
|
||||||
ts := int64(model.Now())
|
ts := int64(model.Now())
|
||||||
|
|
||||||
type sample struct {
|
type sample struct {
|
||||||
labels tsdb.Labels
|
labels labels.Labels
|
||||||
value int64
|
value int64
|
||||||
}
|
}
|
||||||
|
|
||||||
scrape := make(map[uint64]*sample, len(metrics))
|
scrape := make(map[uint64]*sample, len(metrics))
|
||||||
|
|
||||||
for _, m := range metrics {
|
for _, m := range metrics {
|
||||||
lset := make(tsdb.Labels, 0, len(m))
|
lset := make(labels.Labels, 0, len(m))
|
||||||
for k, v := range m {
|
for k, v := range m {
|
||||||
lset = append(lset, tsdb.Label{Name: string(k), Value: string(v)})
|
lset = append(lset, labels.Label{Name: string(k), Value: string(v)})
|
||||||
}
|
}
|
||||||
sort.Sort(lset)
|
sort.Sort(lset)
|
||||||
|
|
||||||
|
|
91
db.go
91
db.go
|
@ -7,7 +7,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -15,8 +14,8 @@ import (
|
||||||
|
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
"github.com/cespare/xxhash"
|
|
||||||
"github.com/fabxc/tsdb/chunks"
|
"github.com/fabxc/tsdb/chunks"
|
||||||
|
"github.com/fabxc/tsdb/labels"
|
||||||
"github.com/go-kit/kit/log"
|
"github.com/go-kit/kit/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -112,7 +111,7 @@ type Appender interface {
|
||||||
// AddSeries(Labels) uint64
|
// AddSeries(Labels) uint64
|
||||||
|
|
||||||
// Add adds a sample pair for the referenced series.
|
// Add adds a sample pair for the referenced series.
|
||||||
Add(lset Labels, t int64, v float64)
|
Add(lset labels.Labels, t int64, v float64)
|
||||||
|
|
||||||
// Commit submits the collected samples and purges the batch.
|
// Commit submits the collected samples and purges the batch.
|
||||||
Commit() error
|
Commit() error
|
||||||
|
@ -131,7 +130,7 @@ type bucketAppender struct {
|
||||||
buckets [][]hashedSample
|
buckets [][]hashedSample
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ba *bucketAppender) Add(lset Labels, t int64, v float64) {
|
func (ba *bucketAppender) Add(lset labels.Labels, t int64, v float64) {
|
||||||
h := lset.Hash()
|
h := lset.Hash()
|
||||||
s := h >> (64 - shardShift)
|
s := h >> (64 - shardShift)
|
||||||
|
|
||||||
|
@ -163,7 +162,7 @@ func (ba *bucketAppender) Commit() error {
|
||||||
|
|
||||||
type hashedSample struct {
|
type hashedSample struct {
|
||||||
hash uint64
|
hash uint64
|
||||||
labels Labels
|
labels labels.Labels
|
||||||
|
|
||||||
t int64
|
t int64
|
||||||
v float64
|
v float64
|
||||||
|
@ -334,7 +333,7 @@ func (s *Shard) persist() error {
|
||||||
|
|
||||||
// chunkDesc wraps a plain data chunk and provides cached meta data about it.
|
// chunkDesc wraps a plain data chunk and provides cached meta data about it.
|
||||||
type chunkDesc struct {
|
type chunkDesc struct {
|
||||||
lset Labels
|
lset labels.Labels
|
||||||
chunk chunks.Chunk
|
chunk chunks.Chunk
|
||||||
|
|
||||||
// Caching fields.
|
// Caching fields.
|
||||||
|
@ -363,86 +362,6 @@ func (cd *chunkDesc) append(ts int64, v float64) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 }
|
|
||||||
|
|
||||||
// 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 l.Name != o[i].Name || l.Value != o[i].Value {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewLabels returns a sorted Labels from the given labels.
|
|
||||||
// The caller has to guarantee that all label names are unique.
|
|
||||||
func NewLabels(ls ...Label) Labels {
|
|
||||||
set := make(Labels, 0, len(ls))
|
|
||||||
for _, l := range ls {
|
|
||||||
set = append(set, l)
|
|
||||||
}
|
|
||||||
sort.Sort(set)
|
|
||||||
|
|
||||||
return set
|
|
||||||
}
|
|
||||||
|
|
||||||
// LabelsFromMap returns new sorted Labels from the given map.
|
|
||||||
func LabelsFromMap(m map[string]string) Labels {
|
|
||||||
l := make([]Label, 0, len(m))
|
|
||||||
for k, v := range m {
|
|
||||||
l = append(l, Label{Name: k, Value: v})
|
|
||||||
}
|
|
||||||
return NewLabels(l...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The MultiError type implements the error interface, and contains the
|
// The MultiError type implements the error interface, and contains the
|
||||||
// Errors used to construct it.
|
// Errors used to construct it.
|
||||||
type MultiError []error
|
type MultiError []error
|
||||||
|
|
5
head.go
5
head.go
|
@ -7,6 +7,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/fabxc/tsdb/chunks"
|
"github.com/fabxc/tsdb/chunks"
|
||||||
|
"github.com/fabxc/tsdb/labels"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HeadBlock handles reads and writes of time series data within a time window.
|
// HeadBlock handles reads and writes of time series data within a time window.
|
||||||
|
@ -99,7 +100,7 @@ func (h *HeadBlock) Series(ref uint32, mint, maxt int64) (Series, error) {
|
||||||
|
|
||||||
// get retrieves the chunk with the hash and label set and creates
|
// get retrieves the chunk with the hash and label set and creates
|
||||||
// a new one if it doesn't exist yet.
|
// a new one if it doesn't exist yet.
|
||||||
func (h *HeadBlock) get(hash uint64, lset Labels) *chunkDesc {
|
func (h *HeadBlock) get(hash uint64, lset labels.Labels) *chunkDesc {
|
||||||
cds := h.descs[hash]
|
cds := h.descs[hash]
|
||||||
for _, cd := range cds {
|
for _, cd := range cds {
|
||||||
if cd.lset.Equals(lset) {
|
if cd.lset.Equals(lset) {
|
||||||
|
@ -122,7 +123,7 @@ func (h *HeadBlock) get(hash uint64, lset Labels) *chunkDesc {
|
||||||
}
|
}
|
||||||
|
|
||||||
// append adds the sample to the headblock.
|
// append adds the sample to the headblock.
|
||||||
func (h *HeadBlock) append(hash uint64, lset Labels, ts int64, v float64) error {
|
func (h *HeadBlock) append(hash uint64, lset labels.Labels, ts int64, v float64) error {
|
||||||
if err := h.get(hash, lset).append(ts, v); err != nil {
|
if err := h.get(hash, lset).append(ts, v); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
89
labels/labels.go
Normal file
89
labels/labels.go
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
package labels
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/cespare/xxhash"
|
||||||
|
)
|
||||||
|
|
||||||
|
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 }
|
||||||
|
|
||||||
|
// 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 l.Name != o[i].Name || l.Value != o[i].Value {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLabels returns a sorted Labels from the given labels.
|
||||||
|
// The caller has to guarantee that all label names are unique.
|
||||||
|
func NewLabels(ls ...Label) Labels {
|
||||||
|
set := make(Labels, 0, len(ls))
|
||||||
|
for _, l := range ls {
|
||||||
|
set = append(set, l)
|
||||||
|
}
|
||||||
|
sort.Sort(set)
|
||||||
|
|
||||||
|
return set
|
||||||
|
}
|
||||||
|
|
||||||
|
// LabelsFromMap returns new sorted Labels from the given map.
|
||||||
|
func LabelsFromMap(m map[string]string) Labels {
|
||||||
|
l := make([]Label, 0, len(m))
|
||||||
|
for k, v := range m {
|
||||||
|
l = append(l, Label{Name: k, Value: v})
|
||||||
|
}
|
||||||
|
return NewLabels(l...)
|
||||||
|
}
|
68
labels/selector.go
Normal file
68
labels/selector.go
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package labels
|
||||||
|
|
||||||
|
import "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
|
||||||
|
}
|
||||||
|
|
||||||
|
type equalMatcher struct {
|
||||||
|
name, value string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *equalMatcher) Name() string { return m.name }
|
||||||
|
func (m *equalMatcher) Matches(v string) bool { return v == 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) }
|
||||||
|
|
||||||
|
// 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 ®expMatcher{name: name, re: re}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// notMatcher inverts the matching result for a matcher.
|
||||||
|
type notMatcher struct {
|
||||||
|
Matcher
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *notMatcher) Matches(v string) bool {
|
||||||
|
return !m.Matcher.Matches(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not inverts the matcher's matching result.
|
||||||
|
func Not(m Matcher) Matcher {
|
||||||
|
return ¬Matcher{m}
|
||||||
|
}
|
50
querier.go
50
querier.go
|
@ -7,38 +7,20 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fabxc/tsdb/chunks"
|
"github.com/fabxc/tsdb/chunks"
|
||||||
|
"github.com/fabxc/tsdb/labels"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Matcher matches a string.
|
|
||||||
type Matcher interface {
|
|
||||||
Name() string
|
|
||||||
// Match returns true if the matcher applies to the string value.
|
|
||||||
Match(v string) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type equalMatcher struct {
|
|
||||||
name string
|
|
||||||
value string
|
|
||||||
}
|
|
||||||
|
|
||||||
func MatchEquals(n, v string) Matcher {
|
|
||||||
return &equalMatcher{name: n, value: v}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *equalMatcher) Name() string { return m.name }
|
|
||||||
func (m *equalMatcher) Match(v string) bool { return v == m.value }
|
|
||||||
|
|
||||||
// Querier provides querying access over time series data of a fixed
|
// Querier provides querying access over time series data of a fixed
|
||||||
// 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(...Matcher) SeriesSet
|
Select(...labels.Matcher) SeriesSet
|
||||||
|
|
||||||
// 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)
|
||||||
// LabelValuesFor returns all potential values for a label name.
|
// LabelValuesFor returns all potential values for a label name.
|
||||||
// under the constraint of another label.
|
// under the constraint of another label.
|
||||||
LabelValuesFor(string, Label) ([]string, error)
|
LabelValuesFor(string, labels.Label) ([]string, error)
|
||||||
|
|
||||||
// Close releases the resources of the Querier.
|
// Close releases the resources of the Querier.
|
||||||
Close() error
|
Close() error
|
||||||
|
@ -47,7 +29,7 @@ type Querier interface {
|
||||||
// Series represents a single time series.
|
// Series represents a single time series.
|
||||||
type Series interface {
|
type Series interface {
|
||||||
// Labels returns the complete set of labels identifying the series.
|
// Labels returns the complete set of labels identifying the series.
|
||||||
Labels() Labels
|
Labels() labels.Labels
|
||||||
|
|
||||||
// Iterator returns a new iterator of the data of the series.
|
// Iterator returns a new iterator of the data of the series.
|
||||||
Iterator() SeriesIterator
|
Iterator() SeriesIterator
|
||||||
|
@ -75,7 +57,7 @@ func (db *DB) Querier(mint, maxt int64) Querier {
|
||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *querier) Select(ms ...Matcher) SeriesSet {
|
func (q *querier) Select(ms ...labels.Matcher) SeriesSet {
|
||||||
// We gather the non-overlapping series from every shard and simply
|
// We gather the non-overlapping series from every shard and simply
|
||||||
// return their union.
|
// return their union.
|
||||||
r := &mergedSeriesSet{}
|
r := &mergedSeriesSet{}
|
||||||
|
@ -134,7 +116,7 @@ func mergeStrings(a, b []string) []string {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *querier) LabelValuesFor(string, Label) ([]string, error) {
|
func (q *querier) LabelValuesFor(string, labels.Label) ([]string, error) {
|
||||||
return nil, fmt.Errorf("not implemented")
|
return nil, fmt.Errorf("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,11 +162,11 @@ func (q *shardQuerier) LabelValues(n string) ([]string, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *shardQuerier) LabelValuesFor(string, Label) ([]string, error) {
|
func (q *shardQuerier) LabelValuesFor(string, labels.Label) ([]string, error) {
|
||||||
return nil, fmt.Errorf("not implemented")
|
return nil, fmt.Errorf("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *shardQuerier) Select(ms ...Matcher) SeriesSet {
|
func (q *shardQuerier) Select(ms ...labels.Matcher) SeriesSet {
|
||||||
// Sets from different blocks have no time overlap. The reference numbers
|
// Sets from different blocks have no time overlap. The reference numbers
|
||||||
// they emit point to series sorted in lexicographic order.
|
// they emit point to series sorted in lexicographic order.
|
||||||
// We can fully connect partial series by simply comparing with the previous
|
// We can fully connect partial series by simply comparing with the previous
|
||||||
|
@ -221,7 +203,7 @@ func newBlockQuerier(ix IndexReader, s SeriesReader, mint, maxt int64) *blockQue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *blockQuerier) Select(ms ...Matcher) SeriesSet {
|
func (q *blockQuerier) Select(ms ...labels.Matcher) SeriesSet {
|
||||||
var its []Postings
|
var its []Postings
|
||||||
for _, m := range ms {
|
for _, m := range ms {
|
||||||
its = append(its, q.selectSingle(m))
|
its = append(its, q.selectSingle(m))
|
||||||
|
@ -235,7 +217,7 @@ func (q *blockQuerier) Select(ms ...Matcher) SeriesSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *blockQuerier) selectSingle(m Matcher) Postings {
|
func (q *blockQuerier) selectSingle(m labels.Matcher) Postings {
|
||||||
tpls, err := q.index.LabelValues(m.Name())
|
tpls, err := q.index.LabelValues(m.Name())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errPostings{err: err}
|
return errPostings{err: err}
|
||||||
|
@ -249,7 +231,7 @@ func (q *blockQuerier) selectSingle(m Matcher) Postings {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errPostings{err: err}
|
return errPostings{err: err}
|
||||||
}
|
}
|
||||||
if m.Match(vals[0]) {
|
if m.Matches(vals[0]) {
|
||||||
res = append(res, vals[0])
|
res = append(res, vals[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,7 +277,7 @@ func (q *blockQuerier) LabelValues(name string) ([]string, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *blockQuerier) LabelValuesFor(string, Label) ([]string, error) {
|
func (q *blockQuerier) LabelValuesFor(string, labels.Label) ([]string, error) {
|
||||||
return nil, fmt.Errorf("not implemented")
|
return nil, fmt.Errorf("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +342,7 @@ func newShardSeriesSet(a, b SeriesSet) *shardSeriesSet {
|
||||||
|
|
||||||
// compareLabels compares the two label sets.
|
// compareLabels compares the two label sets.
|
||||||
// The result will be 0 if a==b, <0 if a < b, and >0 if a > b.
|
// The result will be 0 if a==b, <0 if a < b, and >0 if a > b.
|
||||||
func compareLabels(a, b Labels) int {
|
func compareLabels(a, b labels.Labels) int {
|
||||||
l := len(a)
|
l := len(a)
|
||||||
if len(b) < l {
|
if len(b) < l {
|
||||||
l = len(b)
|
l = len(b)
|
||||||
|
@ -475,7 +457,7 @@ func (s *blockSeriesSet) Err() error { return s.err }
|
||||||
// chunkSeries is a series that is backed by a sequence of chunks holding
|
// chunkSeries is a series that is backed by a sequence of chunks holding
|
||||||
// time series data.
|
// time series data.
|
||||||
type chunkSeries struct {
|
type chunkSeries struct {
|
||||||
labels Labels
|
labels labels.Labels
|
||||||
chunks []ChunkMeta // in-order chunk refs
|
chunks []ChunkMeta // in-order chunk refs
|
||||||
|
|
||||||
// chunk is a function that retrieves chunks based on a reference
|
// chunk is a function that retrieves chunks based on a reference
|
||||||
|
@ -483,7 +465,7 @@ type chunkSeries struct {
|
||||||
chunk func(ref uint32) (chunks.Chunk, error)
|
chunk func(ref uint32) (chunks.Chunk, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *chunkSeries) Labels() Labels {
|
func (s *chunkSeries) Labels() labels.Labels {
|
||||||
return s.labels
|
return s.labels
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,7 +507,7 @@ type chainedSeries struct {
|
||||||
series []Series
|
series []Series
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *chainedSeries) Labels() Labels {
|
func (s *chainedSeries) Labels() labels.Labels {
|
||||||
return s.series[0].Labels()
|
return s.series[0].Labels()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fabxc/tsdb/chunks"
|
"github.com/fabxc/tsdb/chunks"
|
||||||
|
"github.com/fabxc/tsdb/labels"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -269,7 +270,7 @@ func (r *indexReader) Series(ref uint32, mint, maxt int64) (Series, error) {
|
||||||
//
|
//
|
||||||
// The references are expected to be sorted and match the order of
|
// The references are expected to be sorted and match the order of
|
||||||
// the underlying strings.
|
// the underlying strings.
|
||||||
labels := make(Labels, 0, k)
|
lbls := make(labels.Labels, 0, k)
|
||||||
|
|
||||||
for i := 0; i < len(offsets); i += 2 {
|
for i := 0; i < len(offsets); i += 2 {
|
||||||
n, err := r.lookupSymbol(offsets[i])
|
n, err := r.lookupSymbol(offsets[i])
|
||||||
|
@ -280,7 +281,7 @@ func (r *indexReader) Series(ref uint32, mint, maxt int64) (Series, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "symbol lookup")
|
return nil, errors.Wrap(err, "symbol lookup")
|
||||||
}
|
}
|
||||||
labels = append(labels, Label{
|
lbls = append(lbls, labels.Label{
|
||||||
Name: string(n),
|
Name: string(n),
|
||||||
Value: string(v),
|
Value: string(v),
|
||||||
})
|
})
|
||||||
|
@ -337,7 +338,7 @@ func (r *indexReader) Series(ref uint32, mint, maxt int64) (Series, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &chunkSeries{
|
return &chunkSeries{
|
||||||
labels: labels,
|
labels: lbls,
|
||||||
chunks: chunks,
|
chunks: chunks,
|
||||||
chunk: r.series.Chunk,
|
chunk: r.series.Chunk,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
|
@ -10,12 +10,15 @@ import (
|
||||||
|
|
||||||
func BenchmarkLabelMapAccess(b *testing.B) {
|
func BenchmarkLabelMapAccess(b *testing.B) {
|
||||||
m := map[string]string{
|
m := map[string]string{
|
||||||
"job": "node",
|
"job": "node",
|
||||||
"instance": "123.123.1.211:9090",
|
"instance": "123.123.1.211:9090",
|
||||||
"path": "/api/v1/namespaces/<namespace>/deployments/<name>",
|
"path": "/api/v1/namespaces/<namespace>/deployments/<name>",
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"namespace": "system",
|
"namespace": "system",
|
||||||
"status": "500",
|
"status": "500",
|
||||||
|
"prometheus": "prometheus-core-1",
|
||||||
|
"datacenter": "eu-west-1",
|
||||||
|
"pod_name": "abcdef-99999-defee",
|
||||||
}
|
}
|
||||||
|
|
||||||
var v string
|
var v string
|
||||||
|
@ -33,12 +36,15 @@ func BenchmarkLabelMapAccess(b *testing.B) {
|
||||||
|
|
||||||
func BenchmarkLabelSetAccess(b *testing.B) {
|
func BenchmarkLabelSetAccess(b *testing.B) {
|
||||||
m := map[string]string{
|
m := map[string]string{
|
||||||
"job": "node",
|
"job": "node",
|
||||||
"instance": "123.123.1.211:9090",
|
"instance": "123.123.1.211:9090",
|
||||||
"path": "/api/v1/namespaces/<namespace>/deployments/<name>",
|
"path": "/api/v1/namespaces/<namespace>/deployments/<name>",
|
||||||
"method": "GET",
|
"method": "GET",
|
||||||
"namespace": "system",
|
"namespace": "system",
|
||||||
"status": "500",
|
"status": "500",
|
||||||
|
"prometheus": "prometheus-core-1",
|
||||||
|
"datacenter": "eu-west-1",
|
||||||
|
"pod_name": "abcdef-99999-defee",
|
||||||
}
|
}
|
||||||
ls := tsdb.LabelsFromMap(m)
|
ls := tsdb.LabelsFromMap(m)
|
||||||
|
|
||||||
|
|
11
writer.go
11
writer.go
|
@ -10,6 +10,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bradfitz/slice"
|
"github.com/bradfitz/slice"
|
||||||
|
"github.com/fabxc/tsdb/labels"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ type SeriesWriter interface {
|
||||||
// WriteSeries writes the time series data chunks for a single series.
|
// WriteSeries writes the time series data chunks for a single series.
|
||||||
// The reference is used to resolve the correct series in the written index.
|
// The reference is used to resolve the correct series in the written index.
|
||||||
// It only has to be valid for the duration of the write.
|
// It only has to be valid for the duration of the write.
|
||||||
WriteSeries(ref uint32, l Labels, cds []*chunkDesc) error
|
WriteSeries(ref uint32, l labels.Labels, cds []*chunkDesc) error
|
||||||
|
|
||||||
// Size returns the size of the data written so far.
|
// Size returns the size of the data written so far.
|
||||||
Size() int64
|
Size() int64
|
||||||
|
@ -71,7 +72,7 @@ func (w *seriesWriter) writeMeta() error {
|
||||||
return w.write(w.w, b[:])
|
return w.write(w.w, b[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *seriesWriter) WriteSeries(ref uint32, lset Labels, chks []*chunkDesc) error {
|
func (w *seriesWriter) WriteSeries(ref uint32, lset labels.Labels, chks []*chunkDesc) error {
|
||||||
// Initialize with meta data.
|
// Initialize with meta data.
|
||||||
if w.n == 0 {
|
if w.n == 0 {
|
||||||
if err := w.writeMeta(); err != nil {
|
if err := w.writeMeta(); err != nil {
|
||||||
|
@ -156,7 +157,7 @@ type IndexWriter interface {
|
||||||
// of chunks that the index can reference.
|
// of chunks that the index can reference.
|
||||||
// The reference number is used to resolve a series against the postings
|
// The reference number is used to resolve a series against the postings
|
||||||
// list iterator. It only has to be available during the write processing.
|
// list iterator. It only has to be available during the write processing.
|
||||||
AddSeries(ref uint32, l Labels, chunks ...ChunkMeta)
|
AddSeries(ref uint32, l labels.Labels, chunks ...ChunkMeta)
|
||||||
|
|
||||||
// WriteStats writes final stats for the indexed block.
|
// WriteStats writes final stats for the indexed block.
|
||||||
WriteStats(BlockStats) error
|
WriteStats(BlockStats) error
|
||||||
|
@ -177,7 +178,7 @@ type IndexWriter interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type indexWriterSeries struct {
|
type indexWriterSeries struct {
|
||||||
labels Labels
|
labels labels.Labels
|
||||||
chunks []ChunkMeta // series file offset of chunks
|
chunks []ChunkMeta // series file offset of chunks
|
||||||
offset uint32 // index file offset of series reference
|
offset uint32 // index file offset of series reference
|
||||||
}
|
}
|
||||||
|
@ -240,7 +241,7 @@ func (w *indexWriter) writeMeta() error {
|
||||||
return w.write(w.w, b[:])
|
return w.write(w.w, b[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *indexWriter) AddSeries(ref uint32, lset Labels, chunks ...ChunkMeta) {
|
func (w *indexWriter) AddSeries(ref uint32, lset labels.Labels, chunks ...ChunkMeta) {
|
||||||
// Populate the symbol table from all label sets we have to reference.
|
// Populate the symbol table from all label sets we have to reference.
|
||||||
for _, l := range lset {
|
for _, l := range lset {
|
||||||
w.symbols[l.Name] = 0
|
w.symbols[l.Name] = 0
|
||||||
|
|
Loading…
Reference in a new issue