diff --git a/tsdb/chunkenc/float_histogram.go b/tsdb/chunkenc/float_histogram.go index 09b40d2401..7e9bf0085a 100644 --- a/tsdb/chunkenc/float_histogram.go +++ b/tsdb/chunkenc/float_histogram.go @@ -41,7 +41,7 @@ type FloatHistogramChunk struct { // NewFloatHistogramChunk returns a new chunk with float histogram encoding. func NewFloatHistogramChunk() *FloatHistogramChunk { - b := make([]byte, 3, 128) + b := make([]byte, histogramHeaderSize, chunkAllocationSize) return &FloatHistogramChunk{b: bstream{stream: b, count: 0}} } @@ -75,7 +75,7 @@ func (c *FloatHistogramChunk) NumSamples() int { // GetCounterResetHeader returns the info about the first 2 bits of the chunk // header. func (c *FloatHistogramChunk) GetCounterResetHeader() CounterResetHeader { - return CounterResetHeader(c.Bytes()[2] & CounterResetHeaderMask) + return CounterResetHeader(c.Bytes()[histogramFlagPos] & CounterResetHeaderMask) } // Compact implements the Chunk interface. @@ -89,7 +89,7 @@ func (c *FloatHistogramChunk) Compact() { // Appender implements the Chunk interface. func (c *FloatHistogramChunk) Appender() (Appender, error) { - if len(c.b.stream) == 3 { // Avoid allocating an Iterator when chunk is empty. + if len(c.b.stream) == histogramHeaderSize { // Avoid allocating an Iterator when chunk is empty. return &FloatHistogramAppender{b: &c.b, t: math.MinInt64, sum: xorValue{leading: 0xff}, cnt: xorValue{leading: 0xff}, zCnt: xorValue{leading: 0xff}}, nil } it := c.iterator(nil) @@ -153,14 +153,11 @@ func (c *FloatHistogramChunk) iterator(it Iterator) *floatHistogramIterator { func newFloatHistogramIterator(b []byte) *floatHistogramIterator { it := &floatHistogramIterator{ - br: newBReader(b), + br: newBReader(b[histogramHeaderSize:]), numTotal: binary.BigEndian.Uint16(b), t: math.MinInt64, } - // The first 3 bytes contain chunk headers. - // We skip that for actual samples. - _, _ = it.br.readBits(24) - it.counterResetHeader = CounterResetHeader(b[2] & CounterResetHeaderMask) + it.counterResetHeader = CounterResetHeader(b[histogramFlagPos] & CounterResetHeaderMask) return it } @@ -185,11 +182,11 @@ type FloatHistogramAppender struct { } func (a *FloatHistogramAppender) GetCounterResetHeader() CounterResetHeader { - return CounterResetHeader(a.b.bytes()[2] & CounterResetHeaderMask) + return CounterResetHeader(a.b.bytes()[histogramFlagPos] & CounterResetHeaderMask) } func (a *FloatHistogramAppender) setCounterResetHeader(cr CounterResetHeader) { - a.b.bytes()[2] = (a.b.bytes()[2] & (^CounterResetHeaderMask)) | (byte(cr) & CounterResetHeaderMask) + a.b.bytes()[histogramFlagPos] = (a.b.bytes()[histogramFlagPos] & (^CounterResetHeaderMask)) | (byte(cr) & CounterResetHeaderMask) } func (a *FloatHistogramAppender) NumSamples() int { @@ -665,7 +662,7 @@ func (a *FloatHistogramAppender) recode( happ.appendFloatHistogram(tOld, hOld) } - happ.setCounterResetHeader(CounterResetHeader(byts[2] & CounterResetHeaderMask)) + happ.setCounterResetHeader(CounterResetHeader(byts[histogramFlagPos] & CounterResetHeaderMask)) return hc, app } @@ -920,11 +917,11 @@ func (it *floatHistogramIterator) Err() error { func (it *floatHistogramIterator) Reset(b []byte) { // The first 3 bytes contain chunk headers. // We skip that for actual samples. - it.br = newBReader(b[3:]) + it.br = newBReader(b[histogramHeaderSize:]) it.numTotal = binary.BigEndian.Uint16(b) it.numRead = 0 - it.counterResetHeader = CounterResetHeader(b[2] & CounterResetHeaderMask) + it.counterResetHeader = CounterResetHeader(b[histogramFlagPos] & CounterResetHeaderMask) it.t, it.tDelta = 0, 0 it.cnt, it.zCnt, it.sum = xorValue{}, xorValue{}, xorValue{} diff --git a/tsdb/chunkenc/histogram.go b/tsdb/chunkenc/histogram.go index e818ca4d91..4a8460fa85 100644 --- a/tsdb/chunkenc/histogram.go +++ b/tsdb/chunkenc/histogram.go @@ -42,7 +42,7 @@ type HistogramChunk struct { // NewHistogramChunk returns a new chunk with histogram encoding of the given // size. func NewHistogramChunk() *HistogramChunk { - b := make([]byte, 3, 128) + b := make([]byte, histogramHeaderSize, chunkAllocationSize) return &HistogramChunk{b: bstream{stream: b, count: 0}} } @@ -78,15 +78,18 @@ const ( // UnknownCounterReset means we cannot say if this chunk was created due to a counter reset or not. // An explicit counter reset detection needs to happen during query time. UnknownCounterReset CounterResetHeader = 0b00000000 + // CounterResetHeaderMask is the mask to get the counter reset header bits. + CounterResetHeaderMask byte = 0b11000000 + // Position within the header bytes at the start of the stream. + histogramFlagPos = 2 + // Total header size. + histogramHeaderSize = 3 ) -// CounterResetHeaderMask is the mask to get the counter reset header bits. -const CounterResetHeaderMask byte = 0b11000000 - // GetCounterResetHeader returns the info about the first 2 bits of the chunk // header. func (c *HistogramChunk) GetCounterResetHeader() CounterResetHeader { - return CounterResetHeader(c.Bytes()[2] & CounterResetHeaderMask) + return CounterResetHeader(c.Bytes()[histogramFlagPos] & CounterResetHeaderMask) } // Compact implements the Chunk interface. @@ -100,7 +103,7 @@ func (c *HistogramChunk) Compact() { // Appender implements the Chunk interface. func (c *HistogramChunk) Appender() (Appender, error) { - if len(c.b.stream) == 3 { // Avoid allocating an Iterator when chunk is empty. + if len(c.b.stream) == histogramHeaderSize { // Avoid allocating an Iterator when chunk is empty. return &HistogramAppender{b: &c.b, t: math.MinInt64, leading: 0xff}, nil } it := c.iterator(nil) @@ -150,14 +153,11 @@ func countSpans(spans []histogram.Span) int { func newHistogramIterator(b []byte) *histogramIterator { it := &histogramIterator{ - br: newBReader(b), + br: newBReader(b[histogramHeaderSize:]), numTotal: binary.BigEndian.Uint16(b), t: math.MinInt64, } - // The first 3 bytes contain chunk headers. - // We skip that for actual samples. - _, _ = it.br.readBits(24) - it.counterResetHeader = CounterResetHeader(b[2] & CounterResetHeaderMask) + it.counterResetHeader = CounterResetHeader(b[histogramFlagPos] & CounterResetHeaderMask) return it } @@ -206,11 +206,11 @@ type HistogramAppender struct { } func (a *HistogramAppender) GetCounterResetHeader() CounterResetHeader { - return CounterResetHeader(a.b.bytes()[2] & CounterResetHeaderMask) + return CounterResetHeader(a.b.bytes()[histogramFlagPos] & CounterResetHeaderMask) } func (a *HistogramAppender) setCounterResetHeader(cr CounterResetHeader) { - a.b.bytes()[2] = (a.b.bytes()[2] & (^CounterResetHeaderMask)) | (byte(cr) & CounterResetHeaderMask) + a.b.bytes()[histogramFlagPos] = (a.b.bytes()[histogramFlagPos] & (^CounterResetHeaderMask)) | (byte(cr) & CounterResetHeaderMask) } func (a *HistogramAppender) NumSamples() int { @@ -710,7 +710,7 @@ func (a *HistogramAppender) recode( happ.appendHistogram(tOld, hOld) } - happ.setCounterResetHeader(CounterResetHeader(byts[2] & CounterResetHeaderMask)) + happ.setCounterResetHeader(CounterResetHeader(byts[histogramFlagPos] & CounterResetHeaderMask)) return hc, app } @@ -1026,11 +1026,11 @@ func (it *histogramIterator) Err() error { func (it *histogramIterator) Reset(b []byte) { // The first 3 bytes contain chunk headers. // We skip that for actual samples. - it.br = newBReader(b[3:]) + it.br = newBReader(b[histogramHeaderSize:]) it.numTotal = binary.BigEndian.Uint16(b) it.numRead = 0 - it.counterResetHeader = CounterResetHeader(b[2] & CounterResetHeaderMask) + it.counterResetHeader = CounterResetHeader(b[histogramFlagPos] & CounterResetHeaderMask) it.t, it.cnt, it.zCnt = 0, 0, 0 it.tDelta, it.cntDelta, it.zCntDelta = 0, 0, 0 diff --git a/tsdb/chunkenc/xor.go b/tsdb/chunkenc/xor.go index 13778f6641..29e2110705 100644 --- a/tsdb/chunkenc/xor.go +++ b/tsdb/chunkenc/xor.go @@ -52,6 +52,8 @@ import ( ) const ( + chunkHeaderSize = 2 + chunkAllocationSize = 128 chunkCompactCapacityThreshold = 32 ) @@ -62,7 +64,7 @@ type XORChunk struct { // NewXORChunk returns a new chunk with XOR encoding. func NewXORChunk() *XORChunk { - b := make([]byte, 2, 128) + b := make([]byte, chunkHeaderSize, chunkAllocationSize) return &XORChunk{b: bstream{stream: b, count: 0}} } @@ -98,7 +100,7 @@ func (c *XORChunk) Compact() { // It is not valid to call Appender() multiple times concurrently or to use multiple // Appenders on the same chunk. func (c *XORChunk) Appender() (Appender, error) { - if len(c.b.stream) == 2 { // Avoid allocating an Iterator when chunk is empty. + if len(c.b.stream) == chunkHeaderSize { // Avoid allocating an Iterator when chunk is empty. return &xorAppender{b: &c.b, t: math.MinInt64, leading: 0xff}, nil } it := c.iterator(nil) @@ -131,7 +133,7 @@ func (c *XORChunk) iterator(it Iterator) *xorIterator { return &xorIterator{ // The first 2 bytes contain chunk headers. // We skip that for actual samples. - br: newBReader(c.b.bytes()[2:]), + br: newBReader(c.b.bytes()[chunkHeaderSize:]), numTotal: binary.BigEndian.Uint16(c.b.bytes()), t: math.MinInt64, } @@ -282,7 +284,7 @@ func (it *xorIterator) Err() error { func (it *xorIterator) Reset(b []byte) { // The first 2 bytes contain chunk headers. // We skip that for actual samples. - it.br = newBReader(b[2:]) + it.br = newBReader(b[chunkHeaderSize:]) it.numTotal = binary.BigEndian.Uint16(b) it.numRead = 0