diff --git a/tsdb/block.go b/tsdb/block.go index d219995d7..48ebb348b 100644 --- a/tsdb/block.go +++ b/tsdb/block.go @@ -63,7 +63,7 @@ type IndexReader interface { Symbols() index.StringIter // LabelValues returns sorted possible label values. - LabelValues(name string) (index.StringTuples, error) + LabelValues(name string) ([]string, error) // Postings returns the postings list iterator for the label pairs. // The Postings here contain the offsets to the series inside the index. @@ -87,14 +87,6 @@ type IndexReader interface { Close() error } -// StringTuples provides access to a sorted list of string tuples. -type StringTuples interface { - // Total number of tuples in the list. - Len() int - // At returns the tuple at position i. - At(i int) ([]string, error) -} - // ChunkWriter serializes a time block of chunked series data. type ChunkWriter interface { // WriteChunks writes several chunks. The Chunk field of the ChunkMetas @@ -433,7 +425,7 @@ func (r blockIndexReader) Symbols() index.StringIter { return r.ir.Symbols() } -func (r blockIndexReader) LabelValues(name string) (index.StringTuples, error) { +func (r blockIndexReader) LabelValues(name string) ([]string, error) { st, err := r.ir.LabelValues(name) return st, errors.Wrapf(err, "block: %s", r.b.Meta().ULID) } diff --git a/tsdb/cmd/tsdb/main.go b/tsdb/cmd/tsdb/main.go index 0f8d8c00d..3b26493f6 100644 --- a/tsdb/cmd/tsdb/main.go +++ b/tsdb/cmd/tsdb/main.go @@ -559,17 +559,9 @@ func analyzeBlock(b tsdb.BlockReader, limit int) error { return err } var cumulativeLength uint64 - - for i := 0; i < values.Len(); i++ { - value, err := values.At(i) - if err != nil { - return err - } - for _, str := range value { - cumulativeLength += uint64(len(str)) - } + for _, str := range values { + cumulativeLength += uint64(len(str)) } - postingInfos = append(postingInfos, postingInfo{n, cumulativeLength}) } @@ -582,7 +574,7 @@ func analyzeBlock(b tsdb.BlockReader, limit int) error { if err != nil { return err } - postingInfos = append(postingInfos, postingInfo{n, uint64(lv.Len())}) + postingInfos = append(postingInfos, postingInfo{n, uint64(len(lv))}) } fmt.Printf("\nHighest cardinality labels:\n") printInfo(postingInfos) @@ -592,25 +584,19 @@ func analyzeBlock(b tsdb.BlockReader, limit int) error { if err != nil { return err } - for i := 0; i < lv.Len(); i++ { - names, err := lv.At(i) + for _, n := range lv { + postings, err := ir.Postings("__name__", n) if err != nil { return err } - for _, n := range names { - postings, err := ir.Postings("__name__", n) - if err != nil { - return err - } - count := 0 - for postings.Next() { - count++ - } - if postings.Err() != nil { - return postings.Err() - } - postingInfos = append(postingInfos, postingInfo{n, uint64(count)}) + count := 0 + for postings.Next() { + count++ } + if postings.Err() != nil { + return postings.Err() + } + postingInfos = append(postingInfos, postingInfo{n, uint64(count)}) } fmt.Printf("\nHighest cardinality metric names:\n") printInfo(postingInfos) diff --git a/tsdb/head.go b/tsdb/head.go index 78c713334..314048248 100644 --- a/tsdb/head.go +++ b/tsdb/head.go @@ -1352,7 +1352,7 @@ func (h *headIndexReader) Symbols() index.StringIter { } // LabelValues returns the possible label values -func (h *headIndexReader) LabelValues(name string) (index.StringTuples, error) { +func (h *headIndexReader) LabelValues(name string) ([]string, error) { h.head.symMtx.RLock() sl := make([]string, 0, len(h.head.values[name])) for s := range h.head.values[name] { @@ -1360,8 +1360,7 @@ func (h *headIndexReader) LabelValues(name string) (index.StringTuples, error) { } h.head.symMtx.RUnlock() sort.Strings(sl) - - return index.NewStringTuples(sl) + return sl, nil } // LabelNames returns all the unique label names present in the head. diff --git a/tsdb/index/index.go b/tsdb/index/index.go index eb04322c2..81d4a808b 100644 --- a/tsdb/index/index.go +++ b/tsdb/index/index.go @@ -993,14 +993,6 @@ func (w *Writer) Close() error { return ensureErr } -// StringTuples provides access to a sorted list of string tuples. -type StringTuples interface { - // Total number of tuples in the list. - Len() int - // At returns the tuple at position i. - At(i int) (string, error) -} - // StringIter iterates over a sorted list of strings. type StringIter interface { // Next advances the iterator and returns true if another value was found. @@ -1424,26 +1416,26 @@ func (r *Reader) SymbolTableSize() uint64 { // LabelValues returns value tuples that exist for the given label name. // It is not safe to use the return value beyond the lifetime of the byte slice // passed into the Reader. -func (r *Reader) LabelValues(name string) (StringTuples, error) { +func (r *Reader) LabelValues(name string) ([]string, error) { if r.version == FormatV1 { e, ok := r.postingsV1[name] if !ok { - return emptyStringTuples{}, nil + return nil, nil } values := make([]string, 0, len(e)) for k := range e { values = append(values, k) } sort.Strings(values) - return NewStringTuples(values, 1) + return values, nil } e, ok := r.postings[name] if !ok { - return emptyStringTuples{}, nil + return nil, nil } if len(e) == 0 { - return emptyStringTuples{}, nil + return nil, nil } values := make([]string, 0, len(e)*symbolFactor) @@ -1473,14 +1465,9 @@ func (r *Reader) LabelValues(name string) (StringTuples, error) { if d.Err() != nil { return nil, errors.Wrap(d.Err(), "get postings offset entry") } - return NewStringTuples(values) + return values, nil } -type emptyStringTuples struct{} - -func (emptyStringTuples) At(i int) (string, error) { return "", nil } -func (emptyStringTuples) Len() int { return 0 } - // Series reads the series with the given ID and writes its labels and chunks into lbls and chks. func (r *Reader) Series(id uint64, lbls *labels.Labels, chks *[]chunks.Meta) error { offset := id @@ -1621,27 +1608,6 @@ func (r *Reader) LabelNames() ([]string, error) { return labelNames, nil } -type stringTuples struct { - entries []string // flattened tuple entries -} - -func NewStringTuples(entries []string) (*stringTuples, error) { - return &stringTuples{ - entries: entries, - }, nil -} - -func (t *stringTuples) Len() int { return len(t.entries) } -func (t *stringTuples) At(i int) (string, error) { return t.entries[i], nil } - -func (t *stringTuples) Swap(i, j int) { - t.entries[i], t.entries[j] = t.entries[j], t.entries[i] -} - -func (t *stringTuples) Less(i, j int) bool { - return t.entries[i] < t.entries[j] -} - // NewStringListIterator returns a StringIter for the given sorted list of strings. func NewStringListIter(s []string) StringIter { return &stringListIter{l: s} diff --git a/tsdb/index/index_test.go b/tsdb/index/index_test.go index 8da2a41c9..5868184ac 100644 --- a/tsdb/index/index_test.go +++ b/tsdb/index/index_test.go @@ -85,14 +85,14 @@ func (m mockIndex) Close() error { return nil } -func (m mockIndex) LabelValues(name string) (StringTuples, error) { +func (m mockIndex) LabelValues(name string) ([]string, error) { values := []string{} for l := range m.postings { if l.Name == name { values = append(values, l.Value) } } - return NewStringTuples(values) + return values, nil } func (m mockIndex) Postings(name string, values ...string) (Postings, error) { @@ -451,21 +451,13 @@ func TestPersistence_index_e2e(t *testing.T) { } for k, v := range labelPairs { sort.Strings(v) - tplsExp, err := NewStringTuples(v) + + res, err := ir.LabelValues(k) testutil.Ok(t, err) - tplsRes, err := ir.LabelValues(k) - testutil.Ok(t, err) - - testutil.Equals(t, tplsExp.Len(), tplsRes.Len()) - for i := 0; i < tplsExp.Len(); i++ { - strsExp, err := tplsExp.At(i) - testutil.Ok(t, err) - - strsRes, err := tplsRes.At(i) - testutil.Ok(t, err) - - testutil.Equals(t, strsExp, strsRes) + testutil.Equals(t, len(v), len(res)) + for i := 0; i < len(v); i++ { + testutil.Equals(t, v[i], res[i]) } } diff --git a/tsdb/querier.go b/tsdb/querier.go index d8e35eae6..bd2fa9d13 100644 --- a/tsdb/querier.go +++ b/tsdb/querier.go @@ -218,20 +218,7 @@ func (q *blockQuerier) Select(ms ...*labels.Matcher) (SeriesSet, error) { } func (q *blockQuerier) LabelValues(name string) ([]string, error) { - tpls, err := q.index.LabelValues(name) - if err != nil { - return nil, err - } - res := make([]string, 0, tpls.Len()) - - for i := 0; i < tpls.Len(); i++ { - val, err := tpls.At(i) - if err != nil { - return nil, err - } - res = append(res, val) - } - return res, nil + return q.index.LabelValues(name) } func (q *blockQuerier) LabelNames() ([]string, error) { @@ -412,17 +399,13 @@ func postingsForMatcher(ix IndexReader, m *labels.Matcher) (index.Postings, erro } } - tpls, err := ix.LabelValues(m.Name) + vals, err := ix.LabelValues(m.Name) if err != nil { return nil, err } var res []string - for i := 0; i < tpls.Len(); i++ { - val, err := tpls.At(i) - if err != nil { - return nil, err - } + for _, val := range vals { if m.Matches(val) { res = append(res, val) } @@ -437,18 +420,13 @@ func postingsForMatcher(ix IndexReader, m *labels.Matcher) (index.Postings, erro // 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) { - tpls, err := ix.LabelValues(m.Name) + vals, err := ix.LabelValues(m.Name) if err != nil { return nil, err } var res []string - for i := 0; i < tpls.Len(); i++ { - val, err := tpls.At(i) - if err != nil { - return nil, err - } - + for _, val := range vals { if !m.Matches(val) { res = append(res, val) } diff --git a/tsdb/querier_test.go b/tsdb/querier_test.go index 7c7cf8c76..44782ce86 100644 --- a/tsdb/querier_test.go +++ b/tsdb/querier_test.go @@ -1356,14 +1356,15 @@ func (m mockIndex) Close() error { return nil } -func (m mockIndex) LabelValues(name string) (index.StringTuples, error) { +func (m mockIndex) LabelValues(name string) ([]string, error) { values := []string{} for l := range m.postings { if l.Name == name { values = append(values, l.Value) } } - return index.NewStringTuples(values) + sort.Strings(values) + return values, nil } func (m mockIndex) Postings(name string, values ...string) (index.Postings, error) {