2017-04-10 11:59:45 -07:00
|
|
|
// 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.
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
package index
|
2016-12-09 11:45:46 -08:00
|
|
|
|
|
|
|
import (
|
2017-01-19 22:58:19 -08:00
|
|
|
"bufio"
|
2016-12-09 12:23:34 -08:00
|
|
|
"encoding/binary"
|
2017-02-15 15:24:53 -08:00
|
|
|
"hash"
|
2017-11-30 06:34:49 -08:00
|
|
|
"hash/crc32"
|
2016-12-09 11:45:46 -08:00
|
|
|
"io"
|
2019-01-11 09:31:26 -08:00
|
|
|
"io/ioutil"
|
2017-10-09 06:21:46 -07:00
|
|
|
"math"
|
2017-02-23 01:50:22 -08:00
|
|
|
"os"
|
2017-02-24 22:24:20 -08:00
|
|
|
"path/filepath"
|
2016-12-09 12:23:34 -08:00
|
|
|
"sort"
|
2016-12-12 02:38:43 -08:00
|
|
|
"strings"
|
2016-12-20 04:10:37 -08:00
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2019-11-18 11:53:33 -08:00
|
|
|
"github.com/prometheus/prometheus/pkg/labels"
|
2019-08-13 01:34:14 -07:00
|
|
|
"github.com/prometheus/prometheus/tsdb/chunks"
|
|
|
|
"github.com/prometheus/prometheus/tsdb/encoding"
|
|
|
|
tsdb_errors "github.com/prometheus/prometheus/tsdb/errors"
|
|
|
|
"github.com/prometheus/prometheus/tsdb/fileutil"
|
2016-12-09 11:45:46 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// MagicIndex 4 bytes at the head of an index file.
|
|
|
|
MagicIndex = 0xBAAAD700
|
2019-01-11 09:31:26 -08:00
|
|
|
// HeaderLen represents number of bytes reserved of index for header.
|
|
|
|
HeaderLen = 5
|
2016-12-09 11:45:46 -08:00
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
// FormatV1 represents 1 version of index.
|
|
|
|
FormatV1 = 1
|
|
|
|
// FormatV2 represents 2 version of index.
|
|
|
|
FormatV2 = 2
|
2018-11-07 07:52:41 -08:00
|
|
|
|
2019-12-08 11:16:46 -08:00
|
|
|
labelNameSeparator = "\xff"
|
2019-01-29 00:32:32 -08:00
|
|
|
|
|
|
|
indexFilename = "index"
|
2017-02-23 01:50:22 -08:00
|
|
|
)
|
|
|
|
|
2017-04-25 23:33:54 -07:00
|
|
|
type indexWriterSeries struct {
|
|
|
|
labels labels.Labels
|
2017-11-30 06:34:49 -08:00
|
|
|
chunks []chunks.Meta // series file offset of chunks
|
2017-04-25 23:33:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
type indexWriterSeriesSlice []*indexWriterSeries
|
|
|
|
|
|
|
|
func (s indexWriterSeriesSlice) Len() int { return len(s) }
|
|
|
|
func (s indexWriterSeriesSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
|
|
|
|
|
|
func (s indexWriterSeriesSlice) Less(i, j int) bool {
|
|
|
|
return labels.Compare(s[i].labels, s[j].labels) < 0
|
|
|
|
}
|
|
|
|
|
|
|
|
type indexWriterStage uint8
|
|
|
|
|
|
|
|
const (
|
2017-08-05 04:31:48 -07:00
|
|
|
idxStageNone indexWriterStage = iota
|
|
|
|
idxStageSymbols
|
|
|
|
idxStageSeries
|
2017-04-25 23:33:54 -07:00
|
|
|
idxStageLabelIndex
|
|
|
|
idxStagePostings
|
|
|
|
idxStageDone
|
|
|
|
)
|
|
|
|
|
|
|
|
func (s indexWriterStage) String() string {
|
|
|
|
switch s {
|
2017-08-05 04:31:48 -07:00
|
|
|
case idxStageNone:
|
|
|
|
return "none"
|
|
|
|
case idxStageSymbols:
|
|
|
|
return "symbols"
|
|
|
|
case idxStageSeries:
|
|
|
|
return "series"
|
2017-04-25 23:33:54 -07:00
|
|
|
case idxStageLabelIndex:
|
|
|
|
return "label index"
|
|
|
|
case idxStagePostings:
|
|
|
|
return "postings"
|
|
|
|
case idxStageDone:
|
|
|
|
return "done"
|
|
|
|
}
|
|
|
|
return "<unknown>"
|
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
// The table gets initialized with sync.Once but may still cause a race
|
|
|
|
// with any other use of the crc32 package anywhere. Thus we initialize it
|
|
|
|
// before.
|
|
|
|
var castagnoliTable *crc32.Table
|
2016-12-09 11:45:46 -08:00
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
func init() {
|
|
|
|
castagnoliTable = crc32.MakeTable(crc32.Castagnoli)
|
|
|
|
}
|
2016-12-09 11:45:46 -08:00
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
// newCRC32 initializes a CRC32 hash with a preconfigured polynomial, so the
|
|
|
|
// polynomial may be easily changed in one location at a later time, if necessary.
|
|
|
|
func newCRC32() hash.Hash32 {
|
|
|
|
return crc32.New(castagnoliTable)
|
2016-12-09 11:45:46 -08:00
|
|
|
}
|
|
|
|
|
2018-01-10 11:19:16 -08:00
|
|
|
// Writer implements the IndexWriter interface for the standard
|
2016-12-09 11:45:46 -08:00
|
|
|
// serialization format.
|
2017-11-30 06:34:49 -08:00
|
|
|
type Writer struct {
|
2017-04-26 09:01:13 -07:00
|
|
|
f *os.File
|
|
|
|
fbuf *bufio.Writer
|
|
|
|
pos uint64
|
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
toc TOC
|
2017-04-25 23:33:54 -07:00
|
|
|
stage indexWriterStage
|
2016-12-09 11:45:46 -08:00
|
|
|
|
2017-03-02 14:35:02 -08:00
|
|
|
// Reusable memory.
|
2019-02-22 09:11:11 -08:00
|
|
|
buf1 encoding.Encbuf
|
|
|
|
buf2 encoding.Encbuf
|
2017-03-02 14:35:02 -08:00
|
|
|
uint32s []uint32
|
|
|
|
|
2019-07-09 23:31:44 -07:00
|
|
|
symbols map[string]uint32 // symbol offsets
|
|
|
|
seriesOffsets map[uint64]uint64 // offsets of series
|
|
|
|
labelIndexes []labelIndexHashEntry // label index offsets
|
|
|
|
postings []postingsHashEntry // postings lists offsets
|
2017-08-05 04:31:48 -07:00
|
|
|
|
|
|
|
// Hold last series to validate that clients insert new series in order.
|
|
|
|
lastSeries labels.Labels
|
2017-02-15 15:24:53 -08:00
|
|
|
|
|
|
|
crc32 hash.Hash
|
2018-01-10 11:19:16 -08:00
|
|
|
|
|
|
|
Version int
|
2016-12-09 12:23:34 -08:00
|
|
|
}
|
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
// TOC represents index Table Of Content that states where each section of index starts.
|
|
|
|
type TOC struct {
|
|
|
|
Symbols uint64
|
|
|
|
Series uint64
|
|
|
|
LabelIndices uint64
|
|
|
|
LabelIndicesTable uint64
|
|
|
|
Postings uint64
|
|
|
|
PostingsTable uint64
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewTOCFromByteSlice return parsed TOC from given index byte slice.
|
|
|
|
func NewTOCFromByteSlice(bs ByteSlice) (*TOC, error) {
|
|
|
|
if bs.Len() < indexTOCLen {
|
2019-02-22 09:11:11 -08:00
|
|
|
return nil, encoding.ErrInvalidSize
|
2019-01-11 09:31:26 -08:00
|
|
|
}
|
|
|
|
b := bs.Range(bs.Len()-indexTOCLen, bs.Len())
|
|
|
|
|
|
|
|
expCRC := binary.BigEndian.Uint32(b[len(b)-4:])
|
2019-02-22 09:11:11 -08:00
|
|
|
d := encoding.Decbuf{B: b[:len(b)-4]}
|
2019-01-11 09:31:26 -08:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
if d.Crc32(castagnoliTable) != expCRC {
|
|
|
|
return nil, errors.Wrap(encoding.ErrInvalidChecksum, "read TOC")
|
2019-01-11 09:31:26 -08:00
|
|
|
}
|
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
if err := d.Err(); err != nil {
|
2019-01-11 09:31:26 -08:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &TOC{
|
2019-02-22 09:11:11 -08:00
|
|
|
Symbols: d.Be64(),
|
|
|
|
Series: d.Be64(),
|
|
|
|
LabelIndices: d.Be64(),
|
|
|
|
LabelIndicesTable: d.Be64(),
|
|
|
|
Postings: d.Be64(),
|
|
|
|
PostingsTable: d.Be64(),
|
2019-01-11 09:31:26 -08:00
|
|
|
}, nil
|
2017-04-26 09:01:13 -07:00
|
|
|
}
|
|
|
|
|
2018-02-12 02:40:12 -08:00
|
|
|
// NewWriter returns a new Writer to the given filename. It serializes data in format version 2.
|
2017-11-30 06:34:49 -08:00
|
|
|
func NewWriter(fn string) (*Writer, error) {
|
|
|
|
dir := filepath.Dir(fn)
|
|
|
|
|
2017-02-24 22:24:20 -08:00
|
|
|
df, err := fileutil.OpenDir(dir)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-02-01 23:46:23 -08:00
|
|
|
defer df.Close() // Close for platform windows.
|
|
|
|
|
|
|
|
if err := os.RemoveAll(fn); err != nil {
|
|
|
|
return nil, errors.Wrap(err, "remove any existing index at path")
|
|
|
|
}
|
2017-10-31 07:37:41 -07:00
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
f, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY, 0666)
|
2017-02-24 22:24:20 -08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-04-03 01:16:54 -07:00
|
|
|
if err := df.Sync(); err != nil {
|
2017-02-24 22:24:20 -08:00
|
|
|
return nil, errors.Wrap(err, "sync dir")
|
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
iw := &Writer{
|
2017-04-25 23:33:54 -07:00
|
|
|
f: f,
|
|
|
|
fbuf: bufio.NewWriterSize(f, 1<<22),
|
|
|
|
pos: 0,
|
2017-08-05 04:31:48 -07:00
|
|
|
stage: idxStageNone,
|
2017-03-02 14:35:02 -08:00
|
|
|
|
|
|
|
// Reusable memory.
|
2019-02-22 09:11:11 -08:00
|
|
|
buf1: encoding.Encbuf{B: make([]byte, 0, 1<<22)},
|
|
|
|
buf2: encoding.Encbuf{B: make([]byte, 0, 1<<22)},
|
2017-03-02 14:35:02 -08:00
|
|
|
uint32s: make([]uint32, 0, 1<<15),
|
|
|
|
|
|
|
|
// Caches.
|
2017-08-05 04:31:48 -07:00
|
|
|
symbols: make(map[string]uint32, 1<<13),
|
2017-09-04 07:08:38 -07:00
|
|
|
seriesOffsets: make(map[uint64]uint64, 1<<16),
|
2017-08-26 09:04:00 -07:00
|
|
|
crc32: newCRC32(),
|
2016-12-09 12:23:34 -08:00
|
|
|
}
|
2017-02-24 22:24:20 -08:00
|
|
|
if err := iw.writeMeta(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return iw, nil
|
2016-12-09 12:23:34 -08:00
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
func (w *Writer) write(bufs ...[]byte) error {
|
2017-04-25 08:21:24 -07:00
|
|
|
for _, b := range bufs {
|
|
|
|
n, err := w.fbuf.Write(b)
|
2017-04-26 09:01:13 -07:00
|
|
|
w.pos += uint64(n)
|
2017-04-25 08:21:24 -07:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-01-05 04:58:09 -08:00
|
|
|
// For now the index file must not grow beyond 64GiB. Some of the fixed-sized
|
2017-04-28 05:28:25 -07:00
|
|
|
// offset references in v1 are only 4 bytes large.
|
2017-04-26 09:01:13 -07:00
|
|
|
// Once we move to compressed/varint representations in those areas, this limitation
|
|
|
|
// can be lifted.
|
2018-01-05 04:58:09 -08:00
|
|
|
if w.pos > 16*math.MaxUint32 {
|
2018-01-10 11:19:16 -08:00
|
|
|
return errors.Errorf("exceeding max size of 64GiB")
|
2017-04-26 09:01:13 -07:00
|
|
|
}
|
2017-04-25 08:21:24 -07:00
|
|
|
}
|
|
|
|
return nil
|
2016-12-09 12:23:34 -08:00
|
|
|
}
|
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
func (w *Writer) writeAt(buf []byte, pos uint64) error {
|
|
|
|
if err := w.fbuf.Flush(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
_, err := w.f.WriteAt(buf, int64(pos))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2018-02-09 04:11:03 -08:00
|
|
|
// addPadding adds zero byte padding until the file size is a multiple size.
|
2017-11-30 06:34:49 -08:00
|
|
|
func (w *Writer) addPadding(size int) error {
|
|
|
|
p := w.pos % uint64(size)
|
2017-04-28 05:28:25 -07:00
|
|
|
if p == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
2017-11-30 06:34:49 -08:00
|
|
|
p = uint64(size) - p
|
2017-04-28 05:28:25 -07:00
|
|
|
return errors.Wrap(w.write(make([]byte, p)), "add padding")
|
|
|
|
}
|
|
|
|
|
2017-04-26 09:01:13 -07:00
|
|
|
// ensureStage handles transitions between write stages and ensures that IndexWriter
|
|
|
|
// methods are called in an order valid for the implementation.
|
2017-11-30 06:34:49 -08:00
|
|
|
func (w *Writer) ensureStage(s indexWriterStage) error {
|
2017-04-26 09:01:13 -07:00
|
|
|
if w.stage == s {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if w.stage > s {
|
|
|
|
return errors.Errorf("invalid stage %q, currently at %q", s, w.stage)
|
|
|
|
}
|
|
|
|
|
2017-08-05 04:31:48 -07:00
|
|
|
// Mark start of sections in table of contents.
|
|
|
|
switch s {
|
|
|
|
case idxStageSymbols:
|
2019-01-11 09:31:26 -08:00
|
|
|
w.toc.Symbols = w.pos
|
2017-08-05 04:31:48 -07:00
|
|
|
case idxStageSeries:
|
2019-01-11 09:31:26 -08:00
|
|
|
w.toc.Series = w.pos
|
2017-04-26 09:01:13 -07:00
|
|
|
|
|
|
|
case idxStageLabelIndex:
|
2019-01-11 09:31:26 -08:00
|
|
|
w.toc.LabelIndices = w.pos
|
2017-04-26 09:01:13 -07:00
|
|
|
|
|
|
|
case idxStagePostings:
|
2019-01-11 09:31:26 -08:00
|
|
|
w.toc.Postings = w.pos
|
2017-10-02 06:56:57 -07:00
|
|
|
|
|
|
|
case idxStageDone:
|
2019-01-11 09:31:26 -08:00
|
|
|
w.toc.LabelIndicesTable = w.pos
|
2019-07-09 23:31:44 -07:00
|
|
|
if err := w.writeLabelIndexesOffsetTable(); err != nil {
|
2017-04-26 09:01:13 -07:00
|
|
|
return err
|
|
|
|
}
|
2019-01-11 09:31:26 -08:00
|
|
|
w.toc.PostingsTable = w.pos
|
2019-07-09 23:31:44 -07:00
|
|
|
if err := w.writePostingsOffsetTable(); err != nil {
|
2017-04-26 09:01:13 -07:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := w.writeTOC(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
w.stage = s
|
|
|
|
return nil
|
|
|
|
}
|
2016-12-10 09:08:50 -08:00
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
func (w *Writer) writeMeta() error {
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutBE32(MagicIndex)
|
|
|
|
w.buf1.PutByte(FormatV2)
|
2016-12-09 12:23:34 -08:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
return w.write(w.buf1.Get())
|
2016-12-09 11:45:46 -08:00
|
|
|
}
|
|
|
|
|
2018-01-10 11:19:16 -08:00
|
|
|
// AddSeries adds the series one at a time along with its chunks.
|
2017-11-30 06:34:49 -08:00
|
|
|
func (w *Writer) AddSeries(ref uint64, lset labels.Labels, chunks ...chunks.Meta) error {
|
2017-08-05 04:31:48 -07:00
|
|
|
if err := w.ensureStage(idxStageSeries); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if labels.Compare(lset, w.lastSeries) <= 0 {
|
|
|
|
return errors.Errorf("out-of-order series added with label set %q", lset)
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, ok := w.seriesOffsets[ref]; ok {
|
2017-02-24 22:24:20 -08:00
|
|
|
return errors.Errorf("series with reference %d already added", ref)
|
|
|
|
}
|
2018-02-09 04:11:03 -08:00
|
|
|
// We add padding to 16 bytes to increase the addressable space we get through 4 byte
|
|
|
|
// series references.
|
2018-09-20 01:33:52 -07:00
|
|
|
if err := w.addPadding(16); err != nil {
|
|
|
|
return errors.Errorf("failed to write padding bytes: %v", err)
|
|
|
|
}
|
2018-02-09 04:11:03 -08:00
|
|
|
|
|
|
|
if w.pos%16 != 0 {
|
|
|
|
return errors.Errorf("series write not 16-byte aligned at %d", w.pos)
|
|
|
|
}
|
2018-01-05 04:58:09 -08:00
|
|
|
w.seriesOffsets[ref] = w.pos / 16
|
2017-08-05 04:31:48 -07:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf2.Reset()
|
|
|
|
w.buf2.PutUvarint(len(lset))
|
2017-08-05 04:31:48 -07:00
|
|
|
|
2016-12-09 12:23:34 -08:00
|
|
|
for _, l := range lset {
|
2018-01-16 20:37:57 -08:00
|
|
|
// here we have an index for the symbol file if v2, otherwise it's an offset
|
2018-01-16 19:19:01 -08:00
|
|
|
index, ok := w.symbols[l.Name]
|
2017-08-05 04:31:48 -07:00
|
|
|
if !ok {
|
|
|
|
return errors.Errorf("symbol entry for %q does not exist", l.Name)
|
|
|
|
}
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf2.PutUvarint32(index)
|
2017-08-05 04:31:48 -07:00
|
|
|
|
2018-01-16 19:19:01 -08:00
|
|
|
index, ok = w.symbols[l.Value]
|
2017-08-05 04:31:48 -07:00
|
|
|
if !ok {
|
|
|
|
return errors.Errorf("symbol entry for %q does not exist", l.Value)
|
|
|
|
}
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf2.PutUvarint32(index)
|
2016-12-09 12:23:34 -08:00
|
|
|
}
|
2016-12-10 00:44:00 -08:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf2.PutUvarint(len(chunks))
|
2017-08-05 04:31:48 -07:00
|
|
|
|
2017-09-07 12:05:28 -07:00
|
|
|
if len(chunks) > 0 {
|
|
|
|
c := chunks[0]
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf2.PutVarint64(c.MinTime)
|
|
|
|
w.buf2.PutUvarint64(uint64(c.MaxTime - c.MinTime))
|
|
|
|
w.buf2.PutUvarint64(c.Ref)
|
2017-09-07 12:05:28 -07:00
|
|
|
t0 := c.MaxTime
|
|
|
|
ref0 := int64(c.Ref)
|
|
|
|
|
|
|
|
for _, c := range chunks[1:] {
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf2.PutUvarint64(uint64(c.MinTime - t0))
|
|
|
|
w.buf2.PutUvarint64(uint64(c.MaxTime - c.MinTime))
|
2017-09-07 12:05:28 -07:00
|
|
|
t0 = c.MaxTime
|
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf2.PutVarint64(int64(c.Ref) - ref0)
|
2017-09-07 12:05:28 -07:00
|
|
|
ref0 = int64(c.Ref)
|
|
|
|
}
|
2017-08-05 04:31:48 -07:00
|
|
|
}
|
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutUvarint(w.buf2.Len())
|
2017-08-05 04:31:48 -07:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf2.PutHash(w.crc32)
|
2017-08-05 04:31:48 -07:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
if err := w.write(w.buf1.Get(), w.buf2.Get()); err != nil {
|
2017-08-05 04:31:48 -07:00
|
|
|
return errors.Wrap(err, "write series data")
|
2016-12-10 00:44:00 -08:00
|
|
|
}
|
2017-08-05 04:31:48 -07:00
|
|
|
|
|
|
|
w.lastSeries = append(w.lastSeries[:0], lset...)
|
|
|
|
|
2017-02-24 22:24:20 -08:00
|
|
|
return nil
|
2016-12-09 11:45:46 -08:00
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
func (w *Writer) AddSymbols(sym map[string]struct{}) error {
|
2017-08-05 04:31:48 -07:00
|
|
|
if err := w.ensureStage(idxStageSymbols); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-12-09 12:23:34 -08:00
|
|
|
// Generate sorted list of strings we will store as reference table.
|
2017-08-05 04:31:48 -07:00
|
|
|
symbols := make([]string, 0, len(sym))
|
|
|
|
|
|
|
|
for s := range sym {
|
2016-12-09 12:23:34 -08:00
|
|
|
symbols = append(symbols, s)
|
|
|
|
}
|
|
|
|
sort.Strings(symbols)
|
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
startPos := w.pos
|
|
|
|
// Leave 4 bytes of space for the length, which will be calculated later.
|
|
|
|
if err := w.write([]byte("alen")); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
w.crc32.Reset()
|
2016-12-09 12:23:34 -08:00
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutBE32int(len(symbols))
|
|
|
|
w.buf1.WriteToHash(w.crc32)
|
|
|
|
if err := w.write(w.buf1.Get()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-04-28 05:17:53 -07:00
|
|
|
|
2017-08-05 04:31:48 -07:00
|
|
|
w.symbols = make(map[string]uint32, len(symbols))
|
|
|
|
|
2018-01-16 19:19:01 -08:00
|
|
|
for index, s := range symbols {
|
2018-01-17 22:46:22 -08:00
|
|
|
w.symbols[s] = uint32(index)
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutUvarintStr(s)
|
|
|
|
w.buf1.WriteToHash(w.crc32)
|
|
|
|
if err := w.write(w.buf1.Get()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-12-09 13:12:16 -08:00
|
|
|
}
|
2016-12-09 12:23:34 -08:00
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
// Write out the length.
|
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutBE32int(int(w.pos - startPos - 4))
|
|
|
|
if err := w.writeAt(w.buf1.Get(), startPos); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-04-25 07:45:44 -07:00
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutHashSum(w.crc32)
|
|
|
|
return w.write(w.buf1.Get())
|
2016-12-09 13:27:43 -08:00
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
func (w *Writer) WriteLabelIndex(names []string, values []string) error {
|
2017-04-28 05:17:53 -07:00
|
|
|
if len(values)%len(names) != 0 {
|
|
|
|
return errors.Errorf("invalid value list length %d for %d names", len(values), len(names))
|
|
|
|
}
|
2017-04-25 23:33:54 -07:00
|
|
|
if err := w.ensureStage(idxStageLabelIndex); err != nil {
|
|
|
|
return errors.Wrap(err, "ensure stage")
|
2017-01-19 05:01:38 -08:00
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
valt, err := NewStringTuples(values, len(names))
|
2016-12-12 02:38:43 -08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
2016-12-09 12:40:38 -08:00
|
|
|
}
|
2016-12-12 02:38:43 -08:00
|
|
|
sort.Sort(valt)
|
2016-12-09 12:40:38 -08:00
|
|
|
|
2017-04-28 05:28:25 -07:00
|
|
|
// Align beginning to 4 bytes for more efficient index list scans.
|
2017-11-30 06:34:49 -08:00
|
|
|
if err := w.addPadding(4); err != nil {
|
2017-04-28 05:28:25 -07:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-07-09 23:31:44 -07:00
|
|
|
w.labelIndexes = append(w.labelIndexes, labelIndexHashEntry{
|
2017-04-26 09:01:13 -07:00
|
|
|
keys: names,
|
|
|
|
offset: w.pos,
|
2016-12-09 13:12:16 -08:00
|
|
|
})
|
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
startPos := w.pos
|
|
|
|
// Leave 4 bytes of space for the length, which will be calculated later.
|
|
|
|
if err := w.write([]byte("alen")); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
w.crc32.Reset()
|
|
|
|
|
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutBE32int(len(names))
|
|
|
|
w.buf1.PutBE32int(valt.Len())
|
|
|
|
w.buf1.WriteToHash(w.crc32)
|
|
|
|
if err := w.write(w.buf1.Get()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-12-09 12:40:38 -08:00
|
|
|
|
2018-01-16 20:37:57 -08:00
|
|
|
// here we have an index for the symbol file if v2, otherwise it's an offset
|
2018-10-02 11:03:12 -07:00
|
|
|
for _, v := range valt.entries {
|
2018-01-16 19:19:01 -08:00
|
|
|
index, ok := w.symbols[v]
|
2017-08-05 04:31:48 -07:00
|
|
|
if !ok {
|
|
|
|
return errors.Errorf("symbol entry for %q does not exist", v)
|
|
|
|
}
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutBE32(index)
|
|
|
|
w.buf1.WriteToHash(w.crc32)
|
|
|
|
if err := w.write(w.buf1.Get()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-04-25 07:45:44 -07:00
|
|
|
}
|
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
// Write out the length.
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf1.Reset()
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.PutBE32int(int(w.pos - startPos - 4))
|
|
|
|
if err := w.writeAt(w.buf1.Get(), startPos); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-04-25 10:01:25 -07:00
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutHashSum(w.crc32)
|
|
|
|
return w.write(w.buf1.Get())
|
2016-12-09 11:45:46 -08:00
|
|
|
}
|
|
|
|
|
2019-07-09 23:31:44 -07:00
|
|
|
// writeLabelIndexesOffsetTable writes the label indices offset table.
|
|
|
|
func (w *Writer) writeLabelIndexesOffsetTable() error {
|
2019-12-11 04:49:13 -08:00
|
|
|
startPos := w.pos
|
|
|
|
// Leave 4 bytes of space for the length, which will be calculated later.
|
|
|
|
if err := w.write([]byte("alen")); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
w.crc32.Reset()
|
|
|
|
|
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutBE32int(len(w.labelIndexes))
|
|
|
|
w.buf1.WriteToHash(w.crc32)
|
|
|
|
if err := w.write(w.buf1.Get()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-04-26 09:01:13 -07:00
|
|
|
|
2019-07-09 23:31:44 -07:00
|
|
|
for _, e := range w.labelIndexes {
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutUvarint(len(e.keys))
|
2017-04-26 09:01:13 -07:00
|
|
|
for _, k := range e.keys {
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.PutUvarintStr(k)
|
|
|
|
}
|
|
|
|
w.buf1.PutUvarint64(e.offset)
|
|
|
|
w.buf1.WriteToHash(w.crc32)
|
|
|
|
if err := w.write(w.buf1.Get()); err != nil {
|
|
|
|
return err
|
2017-04-26 09:01:13 -07:00
|
|
|
}
|
|
|
|
}
|
2019-12-11 04:49:13 -08:00
|
|
|
// Write out the length.
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf1.Reset()
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.PutBE32int(int(w.pos - startPos - 4))
|
|
|
|
if err := w.writeAt(w.buf1.Get(), startPos); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-04-26 09:01:13 -07:00
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutHashSum(w.crc32)
|
|
|
|
return w.write(w.buf1.Get())
|
2017-04-26 09:01:13 -07:00
|
|
|
}
|
|
|
|
|
2019-07-09 23:31:44 -07:00
|
|
|
// writePostingsOffsetTable writes the postings offset table.
|
|
|
|
func (w *Writer) writePostingsOffsetTable() error {
|
2019-12-11 04:49:13 -08:00
|
|
|
startPos := w.pos
|
|
|
|
// Leave 4 bytes of space for the length, which will be calculated later.
|
|
|
|
if err := w.write([]byte("alen")); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
w.crc32.Reset()
|
|
|
|
|
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutBE32int(len(w.postings))
|
|
|
|
w.buf1.WriteToHash(w.crc32)
|
|
|
|
if err := w.write(w.buf1.Get()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-07-09 23:31:44 -07:00
|
|
|
|
|
|
|
for _, e := range w.postings {
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutUvarint(2)
|
|
|
|
w.buf1.PutUvarintStr(e.name)
|
|
|
|
w.buf1.PutUvarintStr(e.value)
|
|
|
|
w.buf1.PutUvarint64(e.offset)
|
|
|
|
w.buf1.WriteToHash(w.crc32)
|
|
|
|
if err := w.write(w.buf1.Get()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-07-09 23:31:44 -07:00
|
|
|
}
|
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
// Write out the length.
|
2019-07-09 23:31:44 -07:00
|
|
|
w.buf1.Reset()
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.PutBE32int(int(w.pos - startPos - 4))
|
|
|
|
if err := w.writeAt(w.buf1.Get(), startPos); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-07-09 23:31:44 -07:00
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutHashSum(w.crc32)
|
|
|
|
return w.write(w.buf1.Get())
|
2019-07-09 23:31:44 -07:00
|
|
|
}
|
|
|
|
|
2017-04-26 09:01:13 -07:00
|
|
|
const indexTOCLen = 6*8 + 4
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
func (w *Writer) writeTOC() error {
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf1.Reset()
|
2017-04-26 09:01:13 -07:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf1.PutBE64(w.toc.Symbols)
|
|
|
|
w.buf1.PutBE64(w.toc.Series)
|
|
|
|
w.buf1.PutBE64(w.toc.LabelIndices)
|
|
|
|
w.buf1.PutBE64(w.toc.LabelIndicesTable)
|
|
|
|
w.buf1.PutBE64(w.toc.Postings)
|
|
|
|
w.buf1.PutBE64(w.toc.PostingsTable)
|
2017-04-26 09:01:13 -07:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf1.PutHash(w.crc32)
|
2017-04-26 09:01:13 -07:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
return w.write(w.buf1.Get())
|
2017-04-26 09:01:13 -07:00
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
func (w *Writer) WritePostings(name, value string, it Postings) error {
|
2017-04-25 23:33:54 -07:00
|
|
|
if err := w.ensureStage(idxStagePostings); err != nil {
|
|
|
|
return errors.Wrap(err, "ensure stage")
|
2017-02-01 22:58:54 -08:00
|
|
|
}
|
|
|
|
|
2017-04-28 05:28:25 -07:00
|
|
|
// Align beginning to 4 bytes for more efficient postings list scans.
|
2017-11-30 06:34:49 -08:00
|
|
|
if err := w.addPadding(4); err != nil {
|
2017-04-28 05:28:25 -07:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2019-07-09 23:31:44 -07:00
|
|
|
w.postings = append(w.postings, postingsHashEntry{
|
|
|
|
name: name,
|
|
|
|
value: value,
|
2017-04-26 09:01:13 -07:00
|
|
|
offset: w.pos,
|
2016-12-10 00:44:00 -08:00
|
|
|
})
|
|
|
|
|
2016-12-20 04:10:37 -08:00
|
|
|
// Order of the references in the postings list does not imply order
|
|
|
|
// of the series references within the persisted block they are mapped to.
|
|
|
|
// We have to sort the new references again.
|
2017-03-02 14:35:02 -08:00
|
|
|
refs := w.uint32s[:0]
|
2016-12-20 04:10:37 -08:00
|
|
|
|
2016-12-10 00:44:00 -08:00
|
|
|
for it.Next() {
|
2017-08-05 04:31:48 -07:00
|
|
|
offset, ok := w.seriesOffsets[it.At()]
|
2017-01-02 01:34:55 -08:00
|
|
|
if !ok {
|
2017-08-05 04:31:48 -07:00
|
|
|
return errors.Errorf("%p series for reference %d not found", w, it.At())
|
2017-01-02 01:34:55 -08:00
|
|
|
}
|
2017-09-04 07:08:38 -07:00
|
|
|
if offset > (1<<32)-1 {
|
|
|
|
return errors.Errorf("series offset %d exceeds 4 bytes", offset)
|
|
|
|
}
|
|
|
|
refs = append(refs, uint32(offset))
|
2016-12-20 04:10:37 -08:00
|
|
|
}
|
|
|
|
if err := it.Err(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-03-02 14:35:02 -08:00
|
|
|
sort.Sort(uint32slice(refs))
|
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
startPos := w.pos
|
|
|
|
// Leave 4 bytes of space for the length, which will be calculated later.
|
|
|
|
if err := w.write([]byte("alen")); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
w.crc32.Reset()
|
|
|
|
|
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutBE32int(len(refs))
|
|
|
|
w.buf1.WriteToHash(w.crc32)
|
|
|
|
if err := w.write(w.buf1.Get()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-04-28 05:17:53 -07:00
|
|
|
|
2016-12-20 04:10:37 -08:00
|
|
|
for _, r := range refs {
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutBE32(r)
|
|
|
|
w.buf1.WriteToHash(w.crc32)
|
|
|
|
if err := w.write(w.buf1.Get()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2016-12-10 00:44:00 -08:00
|
|
|
}
|
2017-08-06 11:41:24 -07:00
|
|
|
w.uint32s = refs
|
2016-12-10 00:44:00 -08:00
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
// Write out the length.
|
2019-02-22 09:11:11 -08:00
|
|
|
w.buf1.Reset()
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.PutBE32int(int(w.pos - startPos - 4))
|
|
|
|
if err := w.writeAt(w.buf1.Get(), startPos); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-04-25 07:45:44 -07:00
|
|
|
|
2019-12-11 04:49:13 -08:00
|
|
|
w.buf1.Reset()
|
|
|
|
w.buf1.PutHashSum(w.crc32)
|
|
|
|
return w.write(w.buf1.Get())
|
2016-12-09 11:45:46 -08:00
|
|
|
}
|
|
|
|
|
2017-03-02 14:35:02 -08:00
|
|
|
type uint32slice []uint32
|
|
|
|
|
|
|
|
func (s uint32slice) Len() int { return len(s) }
|
|
|
|
func (s uint32slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
|
|
func (s uint32slice) Less(i, j int) bool { return s[i] < s[j] }
|
|
|
|
|
2019-07-09 23:31:44 -07:00
|
|
|
type labelIndexHashEntry struct {
|
2017-04-26 09:01:13 -07:00
|
|
|
keys []string
|
|
|
|
offset uint64
|
2016-12-09 13:12:16 -08:00
|
|
|
}
|
|
|
|
|
2019-07-09 23:31:44 -07:00
|
|
|
type postingsHashEntry struct {
|
|
|
|
name, value string
|
|
|
|
offset uint64
|
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
func (w *Writer) Close() error {
|
2017-04-26 09:01:13 -07:00
|
|
|
if err := w.ensureStage(idxStageDone); err != nil {
|
2017-01-09 09:34:29 -08:00
|
|
|
return err
|
|
|
|
}
|
2017-04-25 07:45:44 -07:00
|
|
|
if err := w.fbuf.Flush(); err != nil {
|
2017-02-24 22:24:20 -08:00
|
|
|
return err
|
|
|
|
}
|
2019-04-03 01:16:54 -07:00
|
|
|
if err := w.f.Sync(); err != nil {
|
2017-02-24 22:24:20 -08:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
return w.f.Close()
|
2016-12-09 11:45:46 -08:00
|
|
|
}
|
2017-03-07 03:47:49 -08:00
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
type Reader struct {
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
b ByteSlice
|
|
|
|
toc *TOC
|
2017-03-07 03:47:49 -08:00
|
|
|
|
|
|
|
// Close that releases the underlying resources of the byte slice.
|
|
|
|
c io.Closer
|
|
|
|
|
|
|
|
// Cached hashmaps of section offsets.
|
2019-01-11 09:31:26 -08:00
|
|
|
labels map[string]uint64
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
// Map of LabelName to a list of some LabelValues's position in the offset table.
|
|
|
|
// The first and last values for each name are always present.
|
|
|
|
postings map[string][]postingOffset
|
2017-10-02 06:56:57 -07:00
|
|
|
// Cache of read symbols. Strings that are returned when reading from the
|
|
|
|
// block are always backed by true strings held in here rather than
|
|
|
|
// strings that are backed by byte slices from the mmap'd index file. This
|
|
|
|
// prevents memory faults when applications work with read symbols after
|
2018-11-02 02:52:45 -07:00
|
|
|
// the block has been unmapped. The older format has sparse indexes so a map
|
|
|
|
// must be used, but the new format is not so we can use a slice.
|
2019-01-11 09:31:26 -08:00
|
|
|
symbolsV1 map[uint32]string
|
|
|
|
symbolsV2 []string
|
|
|
|
symbolsTableSize uint64
|
2017-10-27 09:29:59 -07:00
|
|
|
|
2018-01-10 11:19:16 -08:00
|
|
|
dec *Decoder
|
2017-12-01 03:06:37 -08:00
|
|
|
|
2018-01-10 11:19:16 -08:00
|
|
|
version int
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
type postingOffset struct {
|
|
|
|
value string
|
|
|
|
off int
|
|
|
|
}
|
|
|
|
|
2017-11-09 09:27:09 -08:00
|
|
|
// ByteSlice abstracts a byte slice.
|
|
|
|
type ByteSlice interface {
|
|
|
|
Len() int
|
|
|
|
Range(start, end int) []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
type realByteSlice []byte
|
|
|
|
|
|
|
|
func (b realByteSlice) Len() int {
|
|
|
|
return len(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b realByteSlice) Range(start, end int) []byte {
|
|
|
|
return b[start:end]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b realByteSlice) Sub(start, end int) ByteSlice {
|
|
|
|
return b[start:end]
|
|
|
|
}
|
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
// NewReader returns a new index reader on the given byte slice. It automatically
|
2018-02-12 02:40:12 -08:00
|
|
|
// handles different format versions.
|
2018-02-09 04:11:03 -08:00
|
|
|
func NewReader(b ByteSlice) (*Reader, error) {
|
2019-01-11 09:31:26 -08:00
|
|
|
return newReader(b, ioutil.NopCloser(nil))
|
2018-01-08 09:33:35 -08:00
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
// NewFileReader returns a new index reader against the given index file.
|
2018-02-09 04:11:03 -08:00
|
|
|
func NewFileReader(path string) (*Reader, error) {
|
2017-11-30 06:34:49 -08:00
|
|
|
f, err := fileutil.OpenMmapFile(path)
|
2017-03-07 03:47:49 -08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2019-04-03 01:34:04 -07:00
|
|
|
r, err := newReader(realByteSlice(f.Bytes()), f)
|
|
|
|
if err != nil {
|
|
|
|
var merr tsdb_errors.MultiError
|
|
|
|
merr.Add(err)
|
|
|
|
merr.Add(f.Close())
|
|
|
|
return nil, merr
|
|
|
|
}
|
|
|
|
|
|
|
|
return r, nil
|
2017-11-09 09:27:09 -08:00
|
|
|
}
|
|
|
|
|
2018-02-09 04:11:03 -08:00
|
|
|
func newReader(b ByteSlice, c io.Closer) (*Reader, error) {
|
2017-11-30 06:34:49 -08:00
|
|
|
r := &Reader{
|
2017-12-01 02:01:40 -08:00
|
|
|
b: b,
|
|
|
|
c: c,
|
2018-02-01 23:46:23 -08:00
|
|
|
labels: map[string]uint64{},
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
postings: map[string][]postingOffset{},
|
2017-10-02 06:56:57 -07:00
|
|
|
}
|
2018-01-12 11:06:20 -08:00
|
|
|
|
2018-02-09 04:11:03 -08:00
|
|
|
// Verify header.
|
2019-01-11 09:31:26 -08:00
|
|
|
if r.b.Len() < HeaderLen {
|
2019-02-22 09:11:11 -08:00
|
|
|
return nil, errors.Wrap(encoding.ErrInvalidSize, "index header")
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
2017-11-09 09:27:09 -08:00
|
|
|
if m := binary.BigEndian.Uint32(r.b.Range(0, 4)); m != MagicIndex {
|
2017-03-07 03:47:49 -08:00
|
|
|
return nil, errors.Errorf("invalid magic number %x", m)
|
|
|
|
}
|
2018-02-09 04:11:03 -08:00
|
|
|
r.version = int(r.b.Range(4, 5)[0])
|
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
if r.version != FormatV1 && r.version != FormatV2 {
|
2018-02-09 04:11:03 -08:00
|
|
|
return nil, errors.Errorf("unknown index file version %d", r.version)
|
|
|
|
}
|
2017-03-07 03:47:49 -08:00
|
|
|
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
var err error
|
|
|
|
r.toc, err = NewTOCFromByteSlice(b)
|
2019-01-11 09:31:26 -08:00
|
|
|
if err != nil {
|
2017-04-26 09:01:13 -07:00
|
|
|
return nil, errors.Wrap(err, "read TOC")
|
|
|
|
}
|
2019-01-11 09:31:26 -08:00
|
|
|
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
r.symbolsV2, r.symbolsV1, err = ReadSymbols(r.b, r.version, int(r.toc.Symbols))
|
2019-01-11 09:31:26 -08:00
|
|
|
if err != nil {
|
2017-10-02 06:56:57 -07:00
|
|
|
return nil, errors.Wrap(err, "read symbols")
|
|
|
|
}
|
2017-03-07 03:47:49 -08:00
|
|
|
|
2018-11-02 02:52:45 -07:00
|
|
|
// Use the strings already allocated by symbols, rather than
|
|
|
|
// re-allocating them again below.
|
2019-01-11 09:31:26 -08:00
|
|
|
// Additionally, calculate symbolsTableSize.
|
|
|
|
allocatedSymbols := make(map[string]string, len(r.symbolsV1)+len(r.symbolsV2))
|
|
|
|
for _, s := range r.symbolsV1 {
|
|
|
|
r.symbolsTableSize += uint64(len(s) + 8)
|
|
|
|
allocatedSymbols[s] = s
|
2018-11-02 02:52:45 -07:00
|
|
|
}
|
2019-01-11 09:31:26 -08:00
|
|
|
for _, s := range r.symbolsV2 {
|
|
|
|
r.symbolsTableSize += uint64(len(s) + 8)
|
|
|
|
allocatedSymbols[s] = s
|
2018-11-02 02:52:45 -07:00
|
|
|
}
|
|
|
|
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
if err := ReadOffsetTable(r.b, r.toc.LabelIndicesTable, func(key []string, off uint64, _ int) error {
|
2017-12-01 02:01:40 -08:00
|
|
|
if len(key) != 1 {
|
2019-01-11 09:31:26 -08:00
|
|
|
return errors.Errorf("unexpected key length for label indices table %d", len(key))
|
2017-12-01 02:01:40 -08:00
|
|
|
}
|
2019-01-11 09:31:26 -08:00
|
|
|
|
|
|
|
r.labels[allocatedSymbols[key[0]]] = off
|
2017-12-01 02:01:40 -08:00
|
|
|
return nil
|
2019-01-11 09:31:26 -08:00
|
|
|
}); err != nil {
|
2017-04-26 09:01:13 -07:00
|
|
|
return nil, errors.Wrap(err, "read label index table")
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
2019-01-11 09:31:26 -08:00
|
|
|
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
var lastKey []string
|
|
|
|
lastOff := 0
|
|
|
|
valueCount := 0
|
|
|
|
// For the postings offset table we keep every label name but only every nth
|
|
|
|
// label value (plus the first and last one), to save memory.
|
|
|
|
if err := ReadOffsetTable(r.b, r.toc.PostingsTable, func(key []string, _ uint64, off int) error {
|
2017-12-01 02:01:40 -08:00
|
|
|
if len(key) != 2 {
|
2019-01-11 09:31:26 -08:00
|
|
|
return errors.Errorf("unexpected key length for posting table %d", len(key))
|
2017-12-01 02:01:40 -08:00
|
|
|
}
|
2018-11-02 03:45:09 -07:00
|
|
|
if _, ok := r.postings[key[0]]; !ok {
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
// Next label name.
|
|
|
|
r.postings[allocatedSymbols[key[0]]] = []postingOffset{}
|
|
|
|
if lastKey != nil {
|
|
|
|
// Always include last value for each label name.
|
|
|
|
r.postings[lastKey[0]] = append(r.postings[lastKey[0]], postingOffset{value: allocatedSymbols[lastKey[1]], off: lastOff})
|
|
|
|
}
|
|
|
|
lastKey = nil
|
|
|
|
valueCount = 0
|
|
|
|
}
|
|
|
|
if valueCount%32 == 0 {
|
|
|
|
r.postings[key[0]] = append(r.postings[key[0]], postingOffset{value: allocatedSymbols[key[1]], off: off})
|
|
|
|
lastKey = nil
|
|
|
|
} else {
|
|
|
|
lastKey = key
|
|
|
|
lastOff = off
|
2018-11-02 03:45:09 -07:00
|
|
|
}
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
valueCount++
|
2017-12-01 02:01:40 -08:00
|
|
|
return nil
|
2019-01-11 09:31:26 -08:00
|
|
|
}); err != nil {
|
2017-12-01 02:01:40 -08:00
|
|
|
return nil, errors.Wrap(err, "read postings table")
|
|
|
|
}
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
if lastKey != nil {
|
|
|
|
r.postings[lastKey[0]] = append(r.postings[lastKey[0]], postingOffset{value: allocatedSymbols[lastKey[1]], off: lastOff})
|
|
|
|
}
|
|
|
|
// Trim any extra space in the slices.
|
|
|
|
for k, v := range r.postings {
|
|
|
|
l := make([]postingOffset, len(v))
|
|
|
|
copy(l, v)
|
|
|
|
r.postings[k] = l
|
|
|
|
}
|
2017-12-01 03:06:37 -08:00
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
r.dec = &Decoder{LookupSymbol: r.lookupSymbol}
|
2017-12-01 03:06:37 -08:00
|
|
|
|
2017-12-01 02:01:40 -08:00
|
|
|
return r, nil
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
|
2018-02-21 12:06:19 -08:00
|
|
|
// Version returns the file format version of the underlying index.
|
|
|
|
func (r *Reader) Version() int {
|
|
|
|
return r.version
|
|
|
|
}
|
|
|
|
|
2017-12-01 03:06:37 -08:00
|
|
|
// Range marks a byte range.
|
|
|
|
type Range struct {
|
|
|
|
Start, End int64
|
|
|
|
}
|
|
|
|
|
|
|
|
// PostingsRanges returns a new map of byte range in the underlying index file
|
|
|
|
// for all postings lists.
|
|
|
|
func (r *Reader) PostingsRanges() (map[labels.Label]Range, error) {
|
|
|
|
m := map[labels.Label]Range{}
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
if err := ReadOffsetTable(r.b, r.toc.PostingsTable, func(key []string, off uint64, _ int) error {
|
|
|
|
if len(key) != 2 {
|
|
|
|
return errors.Errorf("unexpected key length for posting table %d", len(key))
|
|
|
|
}
|
|
|
|
d := encoding.NewDecbufAt(r.b, int(off), castagnoliTable)
|
|
|
|
if d.Err() != nil {
|
|
|
|
return d.Err()
|
2017-12-01 03:06:37 -08:00
|
|
|
}
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
m[labels.Label{Name: key[0], Value: key[1]}] = Range{
|
|
|
|
Start: int64(off) + 4,
|
|
|
|
End: int64(off) + 4 + int64(d.Len()),
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return nil, errors.Wrap(err, "read postings table")
|
2017-12-01 03:06:37 -08:00
|
|
|
}
|
|
|
|
return m, nil
|
|
|
|
}
|
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
// ReadSymbols reads the symbol table fully into memory and allocates proper strings for them.
|
2017-10-02 06:56:57 -07:00
|
|
|
// Strings backed by the mmap'd memory would cause memory faults if applications keep using them
|
|
|
|
// after the reader is closed.
|
2019-01-11 09:31:26 -08:00
|
|
|
func ReadSymbols(bs ByteSlice, version int, off int) ([]string, map[uint32]string, error) {
|
2017-04-26 09:01:13 -07:00
|
|
|
if off == 0 {
|
2019-01-11 09:31:26 -08:00
|
|
|
return nil, nil, nil
|
2017-04-26 09:01:13 -07:00
|
|
|
}
|
2019-02-22 09:11:11 -08:00
|
|
|
d := encoding.NewDecbufAt(bs, off, castagnoliTable)
|
2017-11-09 09:27:09 -08:00
|
|
|
|
2017-10-02 06:56:57 -07:00
|
|
|
var (
|
2019-02-22 09:11:11 -08:00
|
|
|
origLen = d.Len()
|
|
|
|
cnt = d.Be32int()
|
2019-01-11 09:31:26 -08:00
|
|
|
basePos = uint32(off) + 4
|
2019-02-22 09:11:11 -08:00
|
|
|
nextPos = basePos + uint32(origLen-d.Len())
|
2019-01-11 09:31:26 -08:00
|
|
|
symbolSlice []string
|
|
|
|
symbols = map[uint32]string{}
|
2017-10-02 06:56:57 -07:00
|
|
|
)
|
2019-01-22 01:47:31 -08:00
|
|
|
if version == FormatV2 {
|
2019-01-11 09:31:26 -08:00
|
|
|
symbolSlice = make([]string, 0, cnt)
|
2018-01-16 20:37:57 -08:00
|
|
|
}
|
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
for d.Err() == nil && d.Len() > 0 && cnt > 0 {
|
|
|
|
s := d.UvarintStr()
|
2017-10-02 06:56:57 -07:00
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
if version == FormatV2 {
|
|
|
|
symbolSlice = append(symbolSlice, s)
|
2018-01-16 20:37:57 -08:00
|
|
|
} else {
|
2019-01-11 09:31:26 -08:00
|
|
|
symbols[nextPos] = s
|
2019-02-22 09:11:11 -08:00
|
|
|
nextPos = basePos + uint32(origLen-d.Len())
|
2018-01-16 20:37:57 -08:00
|
|
|
}
|
2017-10-02 06:56:57 -07:00
|
|
|
cnt--
|
|
|
|
}
|
2019-02-22 09:11:11 -08:00
|
|
|
return symbolSlice, symbols, errors.Wrap(d.Err(), "read symbols")
|
2017-10-02 06:56:57 -07:00
|
|
|
}
|
2017-04-26 09:01:13 -07:00
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
// ReadOffsetTable reads an offset table and at the given position calls f for each
|
|
|
|
// found entry. If f returns an error it stops decoding and returns the received error.
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
func ReadOffsetTable(bs ByteSlice, off uint64, f func([]string, uint64, int) error) error {
|
2019-02-22 09:11:11 -08:00
|
|
|
d := encoding.NewDecbufAt(bs, int(off), castagnoliTable)
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
startLen := d.Len()
|
2019-02-22 09:11:11 -08:00
|
|
|
cnt := d.Be32()
|
2017-04-26 09:01:13 -07:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
for d.Err() == nil && d.Len() > 0 && cnt > 0 {
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
offsetPos := startLen - d.Len()
|
2019-02-22 09:11:11 -08:00
|
|
|
keyCount := d.Uvarint()
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
// The Postings offset table takes only 2 keys per entry (name and value of label),
|
|
|
|
// and the LabelIndices offset table takes only 1 key per entry (a label name).
|
|
|
|
// Hence setting the size to max of both, i.e. 2.
|
|
|
|
keys := make([]string, 0, 2)
|
2017-04-26 09:01:13 -07:00
|
|
|
|
|
|
|
for i := 0; i < keyCount; i++ {
|
2019-02-22 09:11:11 -08:00
|
|
|
keys = append(keys, d.UvarintStr())
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
2019-02-22 09:11:11 -08:00
|
|
|
o := d.Uvarint64()
|
|
|
|
if d.Err() != nil {
|
2017-12-01 02:01:40 -08:00
|
|
|
break
|
|
|
|
}
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
if err := f(keys, o, offsetPos); err != nil {
|
2017-12-01 02:01:40 -08:00
|
|
|
return err
|
|
|
|
}
|
2017-04-26 09:01:13 -07:00
|
|
|
cnt--
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
2019-02-22 09:11:11 -08:00
|
|
|
return d.Err()
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
|
2017-12-01 03:06:37 -08:00
|
|
|
// Close the reader and its underlying resources.
|
2017-11-30 06:34:49 -08:00
|
|
|
func (r *Reader) Close() error {
|
2017-03-07 03:47:49 -08:00
|
|
|
return r.c.Close()
|
|
|
|
}
|
|
|
|
|
2017-11-30 06:34:49 -08:00
|
|
|
func (r *Reader) lookupSymbol(o uint32) (string, error) {
|
2019-01-11 09:31:26 -08:00
|
|
|
if int(o) < len(r.symbolsV2) {
|
|
|
|
return r.symbolsV2[o], nil
|
2018-11-02 02:52:45 -07:00
|
|
|
}
|
2019-01-11 09:31:26 -08:00
|
|
|
s, ok := r.symbolsV1[o]
|
2017-10-02 06:56:57 -07:00
|
|
|
if !ok {
|
|
|
|
return "", errors.Errorf("unknown symbol offset %d", o)
|
2017-04-25 10:40:52 -07:00
|
|
|
}
|
2017-04-26 11:32:34 -07:00
|
|
|
return s, nil
|
2017-04-25 10:40:52 -07:00
|
|
|
}
|
|
|
|
|
2017-12-01 03:06:37 -08:00
|
|
|
// Symbols returns a set of symbols that exist within the index.
|
2017-11-30 06:34:49 -08:00
|
|
|
func (r *Reader) Symbols() (map[string]struct{}, error) {
|
2019-01-11 09:31:26 -08:00
|
|
|
res := make(map[string]struct{}, len(r.symbolsV1)+len(r.symbolsV2))
|
2017-08-05 04:31:48 -07:00
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
for _, s := range r.symbolsV1 {
|
2017-10-02 06:56:57 -07:00
|
|
|
res[s] = struct{}{}
|
2017-08-05 04:31:48 -07:00
|
|
|
}
|
2019-01-11 09:31:26 -08:00
|
|
|
for _, s := range r.symbolsV2 {
|
2018-11-02 02:52:45 -07:00
|
|
|
res[s] = struct{}{}
|
|
|
|
}
|
2017-10-02 06:56:57 -07:00
|
|
|
return res, nil
|
2017-08-05 04:31:48 -07:00
|
|
|
}
|
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
// SymbolTableSize returns the symbol table size in bytes.
|
2018-11-02 02:52:45 -07:00
|
|
|
func (r *Reader) SymbolTableSize() uint64 {
|
2019-01-11 09:31:26 -08:00
|
|
|
return r.symbolsTableSize
|
2017-12-01 03:06:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// LabelValues returns value tuples that exist for the given label name tuples.
|
2017-11-30 06:34:49 -08:00
|
|
|
func (r *Reader) LabelValues(names ...string) (StringTuples, error) {
|
2017-04-26 09:01:13 -07:00
|
|
|
|
2019-12-08 11:16:46 -08:00
|
|
|
key := strings.Join(names, labelNameSeparator)
|
2017-03-07 03:47:49 -08:00
|
|
|
off, ok := r.labels[key]
|
|
|
|
if !ok {
|
2017-03-20 03:37:06 -07:00
|
|
|
// XXX(fabxc): hot fix. Should return a partial data error and handle cases
|
|
|
|
// where the entire block has no data gracefully.
|
|
|
|
return emptyStringTuples{}, nil
|
|
|
|
//return nil, fmt.Errorf("label index doesn't exist")
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
d := encoding.NewDecbufAt(r.b, int(off), castagnoliTable)
|
2017-04-25 10:01:25 -07:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
nc := d.Be32int()
|
|
|
|
d.Be32() // consume unused value entry count.
|
2017-03-07 03:47:49 -08:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
if d.Err() != nil {
|
|
|
|
return nil, errors.Wrap(d.Err(), "read label value index")
|
2017-10-26 12:34:31 -07:00
|
|
|
}
|
2017-03-07 03:47:49 -08:00
|
|
|
st := &serializedStringTuples{
|
2018-10-02 11:03:12 -07:00
|
|
|
idsCount: nc,
|
2019-02-22 09:11:11 -08:00
|
|
|
idsBytes: d.Get(),
|
2018-10-02 11:03:12 -07:00
|
|
|
lookup: r.lookupSymbol,
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
return st, nil
|
|
|
|
}
|
|
|
|
|
2017-03-20 03:37:06 -07:00
|
|
|
type emptyStringTuples struct{}
|
|
|
|
|
|
|
|
func (emptyStringTuples) At(i int) ([]string, error) { return nil, nil }
|
|
|
|
func (emptyStringTuples) Len() int { return 0 }
|
|
|
|
|
2018-11-07 07:52:41 -08:00
|
|
|
// LabelIndices returns a slice of label names for which labels or label tuples value indices exist.
|
|
|
|
// NOTE: This is deprecated. Use `LabelNames()` instead.
|
2017-11-30 06:34:49 -08:00
|
|
|
func (r *Reader) LabelIndices() ([][]string, error) {
|
2019-01-11 09:31:26 -08:00
|
|
|
var res [][]string
|
2017-03-07 03:47:49 -08:00
|
|
|
for s := range r.labels {
|
2019-12-08 11:16:46 -08:00
|
|
|
res = append(res, strings.Split(s, labelNameSeparator))
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
2018-01-10 23:50:42 -08:00
|
|
|
// Series reads the series with the given ID and writes its labels and chunks into lbls and chks.
|
2017-12-01 03:06:37 -08:00
|
|
|
func (r *Reader) Series(id uint64, lbls *labels.Labels, chks *[]chunks.Meta) error {
|
2018-01-10 11:19:16 -08:00
|
|
|
offset := id
|
2018-02-09 04:11:03 -08:00
|
|
|
// In version 2 series IDs are no longer exact references but series are 16-byte padded
|
|
|
|
// and the ID is the multiple of 16 of the actual position.
|
2019-01-11 09:31:26 -08:00
|
|
|
if r.version == FormatV2 {
|
2018-02-09 04:11:03 -08:00
|
|
|
offset = id * 16
|
2018-01-10 11:19:16 -08:00
|
|
|
}
|
2019-02-22 09:11:11 -08:00
|
|
|
d := encoding.NewDecbufUvarintAt(r.b, int(offset), castagnoliTable)
|
|
|
|
if d.Err() != nil {
|
|
|
|
return d.Err()
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
2019-02-22 09:11:11 -08:00
|
|
|
return errors.Wrap(r.dec.Series(d.Get(), lbls, chks), "read series")
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
func (r *Reader) Postings(name string, values ...string) (Postings, error) {
|
2018-11-02 03:45:09 -07:00
|
|
|
e, ok := r.postings[name]
|
|
|
|
if !ok {
|
|
|
|
return EmptyPostings(), nil
|
|
|
|
}
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
|
|
|
|
if len(values) == 0 {
|
2017-12-01 03:06:37 -08:00
|
|
|
return EmptyPostings(), nil
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
|
|
|
|
res := make([]Postings, 0, len(values))
|
|
|
|
skip := 0
|
|
|
|
valueIndex := 0
|
|
|
|
for valueIndex < len(values) && values[valueIndex] < e[0].value {
|
|
|
|
// Discard values before the start.
|
|
|
|
valueIndex++
|
2017-12-01 03:06:37 -08:00
|
|
|
}
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
for valueIndex < len(values) {
|
|
|
|
value := values[valueIndex]
|
|
|
|
|
|
|
|
i := sort.Search(len(e), func(i int) bool { return e[i].value >= value })
|
|
|
|
if i == len(e) {
|
|
|
|
// We're past the end.
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if i > 0 && e[i].value != value {
|
|
|
|
// Need to look from previous entry.
|
|
|
|
i--
|
|
|
|
}
|
|
|
|
// Don't Crc32 the entire postings offset table, this is very slow
|
|
|
|
// so hope any issues were caught at startup.
|
|
|
|
d := encoding.NewDecbufAt(r.b, int(r.toc.PostingsTable), nil)
|
|
|
|
d.Skip(e[i].off)
|
|
|
|
|
|
|
|
// Iterate on the offset table.
|
|
|
|
var postingsOff uint64 // The offset into the postings table.
|
|
|
|
for d.Err() == nil {
|
|
|
|
if skip == 0 {
|
|
|
|
// These are always the same number of bytes,
|
|
|
|
// and it's faster to skip than parse.
|
|
|
|
skip = d.Len()
|
|
|
|
d.Uvarint() // Keycount.
|
|
|
|
d.UvarintBytes() // Label name.
|
|
|
|
skip -= d.Len()
|
|
|
|
} else {
|
|
|
|
d.Skip(skip)
|
|
|
|
}
|
|
|
|
v := d.UvarintBytes() // Label value.
|
|
|
|
postingsOff = d.Uvarint64() // Offset.
|
|
|
|
for string(v) >= value {
|
|
|
|
if string(v) == value {
|
|
|
|
// Read from the postings table.
|
|
|
|
d2 := encoding.NewDecbufAt(r.b, int(postingsOff), castagnoliTable)
|
|
|
|
_, p, err := r.dec.Postings(d2.Get())
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "decode postings")
|
|
|
|
}
|
|
|
|
res = append(res, p)
|
|
|
|
}
|
|
|
|
valueIndex++
|
|
|
|
if valueIndex == len(values) {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
value = values[valueIndex]
|
|
|
|
}
|
|
|
|
if i+1 == len(e) || value >= e[i+1].value || valueIndex == len(values) {
|
|
|
|
// Need to go to a later postings offset entry, if there is one.
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if d.Err() != nil {
|
|
|
|
return nil, errors.Wrap(d.Err(), "get postings offset entry")
|
|
|
|
}
|
2017-12-01 03:06:37 -08:00
|
|
|
}
|
Reduce memory used by postings offset table.
Rather than keeping the offset of each postings list, instead
keep the nth offset of the offset of the posting list. As postings
list offsets have always been sorted, we can then get to the closest
entry before the one we want an iterate forwards.
I haven't done much tuning on the 32 number, it was chosen to try
not to read through more than a 4k page of data.
Switch to a bulk interface for fetching postings. Use it to avoid having
to re-read parts of the posting offset table when querying lots of it.
For a index with what BenchmarkHeadPostingForMatchers uses RAM
for r.postings drops from 3.79MB to 80.19kB or about 48x.
Bytes allocated go down by 30%, and suprisingly CPU usage drops by
4-6% for typical queries too.
benchmark old ns/op new ns/op delta
BenchmarkPostingsForMatchers/Block/n="1"-4 35231 36673 +4.09%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 563380 540627 -4.04%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 536782 534186 -0.48%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 533990 541550 +1.42%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 113374598 117969608 +4.05%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 146329884 139651442 -4.56%
BenchmarkPostingsForMatchers/Block/i=~""-4 50346510 44961127 -10.70%
BenchmarkPostingsForMatchers/Block/i!=""-4 41261550 35356165 -14.31%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 112544418 116904010 +3.87%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 112487086 116864918 +3.89%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 41094758 35457904 -13.72%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 41906372 36151473 -13.73%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 147262414 140424800 -4.64%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 28615629 27872072 -2.60%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 147117177 140462403 -4.52%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 175096826 167902298 -4.11%
benchmark old allocs new allocs delta
BenchmarkPostingsForMatchers/Block/n="1"-4 4 6 +50.00%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 7 11 +57.14%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 15 17 +13.33%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 100010 100012 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 200069 200040 -0.01%
BenchmarkPostingsForMatchers/Block/i=~""-4 200072 200045 -0.01%
BenchmarkPostingsForMatchers/Block/i!=""-4 200070 200041 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 100013 100017 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 100017 100023 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 200073 200046 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 200075 200050 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 200074 200049 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 111165 111150 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 200078 200055 -0.01%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 311282 311238 -0.01%
benchmark old bytes new bytes delta
BenchmarkPostingsForMatchers/Block/n="1"-4 264 296 +12.12%
BenchmarkPostingsForMatchers/Block/n="1",j="foo"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/j="foo",n="1"-4 360 424 +17.78%
BenchmarkPostingsForMatchers/Block/n="1",j!="foo"-4 520 552 +6.15%
BenchmarkPostingsForMatchers/Block/i=~".*"-4 1600461 1600482 +0.00%
BenchmarkPostingsForMatchers/Block/i=~".+"-4 24900801 17259077 -30.69%
BenchmarkPostingsForMatchers/Block/i=~""-4 24900836 17259151 -30.69%
BenchmarkPostingsForMatchers/Block/i!=""-4 24900760 17259048 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",j="foo"-4 1600557 1600621 +0.00%
BenchmarkPostingsForMatchers/Block/n="1",i=~".*",i!="2",j="foo"-4 1600717 1600813 +0.01%
BenchmarkPostingsForMatchers/Block/n="1",i!=""-4 24900856 17259176 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i!="",j="foo"-4 24900952 17259304 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",j="foo"-4 24900993 17259333 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~"1.+",j="foo"-4 3788311 3142630 -17.04%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!="2",j="foo"-4 24901137 17259509 -30.69%
BenchmarkPostingsForMatchers/Block/n="1",i=~".+",i!~"2.*",j="foo"-4 28693086 20405680 -28.88%
Signed-off-by: Brian Brazil <brian.brazil@robustperception.io>
2019-12-05 10:27:40 -08:00
|
|
|
|
|
|
|
return Merge(res...), nil
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
|
2017-12-01 03:06:37 -08:00
|
|
|
// SortedPostings returns the given postings list reordered so that the backing series
|
|
|
|
// are sorted.
|
2017-11-30 06:34:49 -08:00
|
|
|
func (r *Reader) SortedPostings(p Postings) Postings {
|
2017-08-05 04:31:48 -07:00
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
2019-01-16 02:03:52 -08:00
|
|
|
// Size returns the size of an index file.
|
|
|
|
func (r *Reader) Size() int64 {
|
|
|
|
return int64(r.b.Len())
|
|
|
|
}
|
|
|
|
|
2018-11-07 07:52:41 -08:00
|
|
|
// LabelNames returns all the unique label names present in the index.
|
|
|
|
func (r *Reader) LabelNames() ([]string, error) {
|
|
|
|
labelNamesMap := make(map[string]struct{}, len(r.labels))
|
|
|
|
for key := range r.labels {
|
|
|
|
// 'key' contains the label names concatenated with the
|
2019-12-08 11:16:46 -08:00
|
|
|
// delimiter 'labelNameSeparator'.
|
|
|
|
names := strings.Split(key, labelNameSeparator)
|
2018-11-07 07:52:41 -08:00
|
|
|
for _, name := range names {
|
|
|
|
if name == allPostingsKey.Name {
|
|
|
|
// This is not from any metric.
|
|
|
|
// It is basically an empty label name.
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
labelNamesMap[name] = struct{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
labelNames := make([]string, 0, len(labelNamesMap))
|
|
|
|
for name := range labelNamesMap {
|
|
|
|
labelNames = append(labelNames, name)
|
|
|
|
}
|
|
|
|
sort.Strings(labelNames)
|
|
|
|
return labelNames, nil
|
|
|
|
}
|
|
|
|
|
2017-03-07 03:47:49 -08:00
|
|
|
type stringTuples struct {
|
2018-10-02 11:03:12 -07:00
|
|
|
length int // tuple length
|
|
|
|
entries []string // flattened tuple entries
|
2019-07-09 23:28:28 -07:00
|
|
|
swapBuf []string
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
|
2018-10-02 11:03:12 -07:00
|
|
|
func NewStringTuples(entries []string, length int) (*stringTuples, error) {
|
|
|
|
if len(entries)%length != 0 {
|
2019-02-22 09:11:11 -08:00
|
|
|
return nil, errors.Wrap(encoding.ErrInvalidSize, "string tuple list")
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
2019-07-09 23:28:28 -07:00
|
|
|
return &stringTuples{
|
|
|
|
entries: entries,
|
|
|
|
length: length,
|
|
|
|
}, nil
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
|
2018-10-02 11:03:12 -07:00
|
|
|
func (t *stringTuples) Len() int { return len(t.entries) / t.length }
|
|
|
|
func (t *stringTuples) At(i int) ([]string, error) { return t.entries[i : i+t.length], nil }
|
2017-03-07 03:47:49 -08:00
|
|
|
|
|
|
|
func (t *stringTuples) Swap(i, j int) {
|
2019-07-09 23:28:28 -07:00
|
|
|
if t.swapBuf == nil {
|
|
|
|
t.swapBuf = make([]string, t.length)
|
|
|
|
}
|
|
|
|
copy(t.swapBuf, t.entries[i:i+t.length])
|
2018-10-02 11:03:12 -07:00
|
|
|
for k := 0; k < t.length; k++ {
|
|
|
|
t.entries[i+k] = t.entries[j+k]
|
2019-07-09 23:28:28 -07:00
|
|
|
t.entries[j+k] = t.swapBuf[k]
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *stringTuples) Less(i, j int) bool {
|
2018-10-02 11:03:12 -07:00
|
|
|
for k := 0; k < t.length; k++ {
|
|
|
|
d := strings.Compare(t.entries[i+k], t.entries[j+k])
|
2017-03-07 03:47:49 -08:00
|
|
|
|
|
|
|
if d < 0 {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if d > 0 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
type serializedStringTuples struct {
|
2018-10-02 11:03:12 -07:00
|
|
|
idsCount int
|
|
|
|
idsBytes []byte // bytes containing the ids pointing to the string in the lookup table.
|
|
|
|
lookup func(uint32) (string, error)
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t *serializedStringTuples) Len() int {
|
2018-10-02 11:03:12 -07:00
|
|
|
return len(t.idsBytes) / (4 * t.idsCount)
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (t *serializedStringTuples) At(i int) ([]string, error) {
|
2018-10-02 11:03:12 -07:00
|
|
|
if len(t.idsBytes) < (i+t.idsCount)*4 {
|
2019-02-22 09:11:11 -08:00
|
|
|
return nil, encoding.ErrInvalidSize
|
2017-03-07 03:47:49 -08:00
|
|
|
}
|
2018-10-02 11:03:12 -07:00
|
|
|
res := make([]string, 0, t.idsCount)
|
2017-03-07 03:47:49 -08:00
|
|
|
|
2018-10-02 11:03:12 -07:00
|
|
|
for k := 0; k < t.idsCount; k++ {
|
|
|
|
offset := binary.BigEndian.Uint32(t.idsBytes[(i+k)*4:])
|
2017-03-07 03:47:49 -08:00
|
|
|
|
|
|
|
s, err := t.lookup(offset)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "symbol lookup")
|
|
|
|
}
|
|
|
|
res = append(res, s)
|
|
|
|
}
|
|
|
|
|
|
|
|
return res, nil
|
|
|
|
}
|
2017-12-01 03:06:37 -08:00
|
|
|
|
2018-01-08 09:33:35 -08:00
|
|
|
// Decoder provides decoding methods for the v1 and v2 index file format.
|
2017-12-01 03:06:37 -08:00
|
|
|
//
|
|
|
|
// It currently does not contain decoding methods for all entry types but can be extended
|
|
|
|
// by them if there's demand.
|
2018-01-10 11:19:16 -08:00
|
|
|
type Decoder struct {
|
2019-01-11 09:31:26 -08:00
|
|
|
LookupSymbol func(uint32) (string, error)
|
2017-12-01 03:06:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Postings returns a postings list for b and its number of elements.
|
2018-01-10 11:19:16 -08:00
|
|
|
func (dec *Decoder) Postings(b []byte) (int, Postings, error) {
|
2019-02-22 09:11:11 -08:00
|
|
|
d := encoding.Decbuf{B: b}
|
|
|
|
n := d.Be32int()
|
|
|
|
l := d.Get()
|
|
|
|
return n, newBigEndianPostings(l), d.Err()
|
2017-12-01 03:06:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Series decodes a series entry from the given byte slice into lset and chks.
|
2018-01-10 11:19:16 -08:00
|
|
|
func (dec *Decoder) Series(b []byte, lbls *labels.Labels, chks *[]chunks.Meta) error {
|
2017-12-01 03:06:37 -08:00
|
|
|
*lbls = (*lbls)[:0]
|
|
|
|
*chks = (*chks)[:0]
|
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
d := encoding.Decbuf{B: b}
|
2017-12-01 03:06:37 -08:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
k := d.Uvarint()
|
2017-12-01 03:06:37 -08:00
|
|
|
|
|
|
|
for i := 0; i < k; i++ {
|
2019-02-22 09:11:11 -08:00
|
|
|
lno := uint32(d.Uvarint())
|
|
|
|
lvo := uint32(d.Uvarint())
|
2017-12-01 03:06:37 -08:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
if d.Err() != nil {
|
|
|
|
return errors.Wrap(d.Err(), "read series label offsets")
|
2017-12-01 03:06:37 -08:00
|
|
|
}
|
|
|
|
|
2019-01-11 09:31:26 -08:00
|
|
|
ln, err := dec.LookupSymbol(lno)
|
2017-12-01 03:06:37 -08:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "lookup label name")
|
|
|
|
}
|
2019-01-11 09:31:26 -08:00
|
|
|
lv, err := dec.LookupSymbol(lvo)
|
2017-12-01 03:06:37 -08:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "lookup label value")
|
|
|
|
}
|
|
|
|
|
|
|
|
*lbls = append(*lbls, labels.Label{Name: ln, Value: lv})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read the chunks meta data.
|
2019-02-22 09:11:11 -08:00
|
|
|
k = d.Uvarint()
|
2017-12-01 03:06:37 -08:00
|
|
|
|
|
|
|
if k == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
t0 := d.Varint64()
|
|
|
|
maxt := int64(d.Uvarint64()) + t0
|
|
|
|
ref0 := int64(d.Uvarint64())
|
2017-12-01 03:06:37 -08:00
|
|
|
|
|
|
|
*chks = append(*chks, chunks.Meta{
|
|
|
|
Ref: uint64(ref0),
|
|
|
|
MinTime: t0,
|
|
|
|
MaxTime: maxt,
|
|
|
|
})
|
|
|
|
t0 = maxt
|
|
|
|
|
|
|
|
for i := 1; i < k; i++ {
|
2019-02-22 09:11:11 -08:00
|
|
|
mint := int64(d.Uvarint64()) + t0
|
|
|
|
maxt := int64(d.Uvarint64()) + mint
|
2017-12-01 03:06:37 -08:00
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
ref0 += d.Varint64()
|
2017-12-01 03:06:37 -08:00
|
|
|
t0 = maxt
|
|
|
|
|
2019-02-22 09:11:11 -08:00
|
|
|
if d.Err() != nil {
|
|
|
|
return errors.Wrapf(d.Err(), "read meta for chunk %d", i)
|
2017-12-01 03:06:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
*chks = append(*chks, chunks.Meta{
|
|
|
|
Ref: uint64(ref0),
|
|
|
|
MinTime: mint,
|
|
|
|
MaxTime: maxt,
|
|
|
|
})
|
|
|
|
}
|
2019-02-22 09:11:11 -08:00
|
|
|
return d.Err()
|
2017-12-01 03:06:37 -08:00
|
|
|
}
|