Fix label index write and add read path
This commit is contained in:
parent
10943b6d88
commit
ae379f385b
87
reader.go
87
reader.go
|
@ -61,15 +61,12 @@ type IndexReader interface {
|
|||
Series(ref uint32) (Series, error)
|
||||
}
|
||||
|
||||
// StringTuple is a tuple of strings.
|
||||
type StringTuple []string
|
||||
|
||||
// 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) (StringTuple, error)
|
||||
At(i int) ([]string, error)
|
||||
}
|
||||
|
||||
type indexReader struct {
|
||||
|
@ -188,4 +185,86 @@ func (r *indexReader) LabelValues(names ...string) (StringTuples, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("section: %s", err)
|
||||
}
|
||||
if flag != flagStd {
|
||||
return nil, errInvalidFlag
|
||||
}
|
||||
if len(b) < 1 {
|
||||
return nil, errInvalidSize
|
||||
}
|
||||
|
||||
st := &serializedStringTuples{
|
||||
l: int(b[0]),
|
||||
b: b[1:],
|
||||
lookup: r.lookupSymbol,
|
||||
}
|
||||
return st, nil
|
||||
}
|
||||
|
||||
type stringTuples struct {
|
||||
l int // tuple length
|
||||
s []string // flattened tuple entries
|
||||
}
|
||||
|
||||
func newStringTuples(s []string, l int) (*stringTuples, error) {
|
||||
if len(s)%l != 0 {
|
||||
return nil, errInvalidSize
|
||||
}
|
||||
return &stringTuples{s: s, l: l}, nil
|
||||
}
|
||||
|
||||
func (t *stringTuples) Len() int { return len(t.s) / t.l }
|
||||
func (t *stringTuples) At(i int) ([]string, error) { return t.s[i : i+t.l], nil }
|
||||
|
||||
func (t *stringTuples) Swap(i, j int) {
|
||||
c := make([]string, t.l)
|
||||
copy(c, t.s[i:i+t.l])
|
||||
|
||||
for k := 0; k < t.l; k++ {
|
||||
t.s[i+k] = t.s[j+k]
|
||||
t.s[j+k] = c[k]
|
||||
}
|
||||
}
|
||||
|
||||
func (t *stringTuples) Less(i, j int) bool {
|
||||
for k := 0; k < t.l; k++ {
|
||||
d := strings.Compare(t.s[i+k], t.s[j+k])
|
||||
|
||||
if d < 0 {
|
||||
return true
|
||||
}
|
||||
if d > 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type serializedStringTuples struct {
|
||||
l int
|
||||
b []byte
|
||||
lookup func(uint32) ([]byte, error)
|
||||
}
|
||||
|
||||
func (t *serializedStringTuples) Len() int {
|
||||
// TODO(fabxc): Cache this?
|
||||
return len(t.b) / (4 * t.l)
|
||||
}
|
||||
|
||||
func (t *serializedStringTuples) At(i int) ([]string, error) {
|
||||
if len(t.b) < (i+t.l)*4 {
|
||||
return nil, errInvalidSize
|
||||
}
|
||||
res := make([]string, t.l)
|
||||
|
||||
for k := 0; k < t.l; k++ {
|
||||
offset := binary.BigEndian.Uint32(t.b[i*4:])
|
||||
|
||||
b, err := t.lookup(offset)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("lookup: %s", err)
|
||||
}
|
||||
res = append(res, string(b))
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
|
26
writer.go
26
writer.go
|
@ -2,11 +2,11 @@ package tsdb
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -319,26 +319,32 @@ func (w *indexWriter) writeSeries() error {
|
|||
}
|
||||
|
||||
func (w *indexWriter) WriteLabelIndex(names []string, values []string) error {
|
||||
if len(names) != 1 {
|
||||
return fmt.Errorf("not supported")
|
||||
valt, err := newStringTuples(values, len(names))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sort.Strings(values)
|
||||
sort.Sort(valt)
|
||||
|
||||
w.labelIndexes = append(w.labelIndexes, hashEntry{
|
||||
name: names[0],
|
||||
name: strings.Join(names, string(sep)),
|
||||
offset: uint32(w.n),
|
||||
})
|
||||
|
||||
l := uint32(len(values) * 4)
|
||||
l := 1 + uint32(len(values)*4)
|
||||
|
||||
return w.section(l, flagStd, func(wr io.Writer) error {
|
||||
for _, v := range values {
|
||||
o := w.symbols[v]
|
||||
// First byte indicates tuple size for index.
|
||||
if err := w.write(wr, []byte{byte(len(names))}); err != nil {
|
||||
return err
|
||||
}
|
||||
buf := make([]byte, 4)
|
||||
|
||||
if err := binary.Write(wr, binary.BigEndian, o); err != nil {
|
||||
for _, v := range valt.s {
|
||||
binary.BigEndian.PutUint32(buf, w.symbols[v])
|
||||
|
||||
if err := w.write(wr, buf); err != nil {
|
||||
return err
|
||||
}
|
||||
w.n += 4
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue