Cache label name and last value when adding series
@@ -103,6 +103,12 @@ func newCRC32() hash.Hash32 {
return crc32.New(castagnoliTable)
}
+type symbolCacheEntry struct {
+ index uint32
+ lastValue string
+ lastValueIndex uint32
+}
+
// Writer implements the IndexWriter interface for the standard
// serialization format.
type Writer struct {
@@ -129,6 +135,7 @@ type Writer struct {
symbols *Symbols
symbolFile *fileutil.MmapFile
lastSymbol string
+ symbolCache map[string]symbolCacheEntry
labelIndexes []labelIndexHashEntry // Label index offsets.
labelNames map[string]uint64 // Label names, and their usage.
@@ -224,6 +231,7 @@ func NewWriter(ctx context.Context, fn string) (*Writer, error) {
buf1: encoding.Encbuf{B: make([]byte, 0, 1<<22)},
buf2: encoding.Encbuf{B: make([]byte, 0, 1<<22)},
+ symbolCache: make(map[string]symbolCacheEntry, 1<<8),
labelNames: make(map[string]uint64, 1<<8),
crc32: newCRC32(),
}
@@ -430,18 +438,31 @@ func (w *Writer) AddSeries(ref uint64, lset labels.Labels, chunks ...chunks.Meta
w.buf2.PutUvarint(len(lset))
for _, l := range lset {
- index, err := w.symbols.ReverseLookup(l.Name)
+ var err error
+ cacheEntry, ok := w.symbolCache[l.Name]
+ nameIndex := cacheEntry.index
+ if !ok {
+ nameIndex, err = w.symbols.ReverseLookup(l.Name)
if err != nil {
return errors.Errorf("symbol entry for %q does not exist, %v", l.Name, err)
}
+ }
w.labelNames[l.Name]++
- w.buf2.PutUvarint32(index)
+ w.buf2.PutUvarint32(nameIndex)
- index, err = w.symbols.ReverseLookup(l.Value)
+ valueIndex := cacheEntry.lastValueIndex
+ if !ok || cacheEntry.lastValue != l.Value {
+ valueIndex, err = w.symbols.ReverseLookup(l.Value)
if err != nil {
return errors.Errorf("symbol entry for %q does not exist, %v", l.Value, err)
}
- w.buf2.PutUvarint32(index)
+ w.symbolCache[l.Name] = symbolCacheEntry{
+ index: nameIndex,
+ lastValue: l.Value,
+ lastValueIndex: valueIndex,
+ }
+ }
+ w.buf2.PutUvarint32(valueIndex)
}
w.buf2.PutUvarint(len(chunks))
