mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-24 21:24:05 -08:00
tsdb: faster CRC check by avoiding allocations (#10789)
Instead of creating a new hashing object every time, call `crc32.Checksum` which computes the answer without allocations. Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
This commit is contained in:
parent
7a78897d0b
commit
9f79a6f4b5
|
@ -15,7 +15,6 @@ package chunks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
|
@ -166,6 +165,17 @@ func newCRC32() hash.Hash32 {
|
||||||
return crc32.New(castagnoliTable)
|
return crc32.New(castagnoliTable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the CRC of data matches that stored in sum, computed when the chunk was stored.
|
||||||
|
func checkCRC32(data, sum []byte) error {
|
||||||
|
got := crc32.Checksum(data, castagnoliTable)
|
||||||
|
// This combination of shifts is the inverse of digest.Sum() in go/src/hash/crc32.
|
||||||
|
want := uint32(sum[0])<<24 + uint32(sum[1])<<16 + uint32(sum[2])<<8 + uint32(sum[3])
|
||||||
|
if got != want {
|
||||||
|
return errors.Errorf("checksum mismatch expected:%x, actual:%x", want, got)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Writer implements the ChunkWriter interface for the standard
|
// Writer implements the ChunkWriter interface for the standard
|
||||||
// serialization format.
|
// serialization format.
|
||||||
type Writer struct {
|
type Writer struct {
|
||||||
|
@ -547,7 +557,6 @@ func (s *Reader) Size() int64 {
|
||||||
// Chunk returns a chunk from a given reference.
|
// Chunk returns a chunk from a given reference.
|
||||||
func (s *Reader) Chunk(ref ChunkRef) (chunkenc.Chunk, error) {
|
func (s *Reader) Chunk(ref ChunkRef) (chunkenc.Chunk, error) {
|
||||||
sgmIndex, chkStart := BlockChunkRef(ref).Unpack()
|
sgmIndex, chkStart := BlockChunkRef(ref).Unpack()
|
||||||
chkCRC32 := newCRC32()
|
|
||||||
|
|
||||||
if sgmIndex >= len(s.bs) {
|
if sgmIndex >= len(s.bs) {
|
||||||
return nil, errors.Errorf("segment index %d out of range", sgmIndex)
|
return nil, errors.Errorf("segment index %d out of range", sgmIndex)
|
||||||
|
@ -576,14 +585,10 @@ func (s *Reader) Chunk(ref ChunkRef) (chunkenc.Chunk, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sum := sgmBytes.Range(chkDataEnd, chkEnd)
|
sum := sgmBytes.Range(chkDataEnd, chkEnd)
|
||||||
if _, err := chkCRC32.Write(sgmBytes.Range(chkEncStart, chkDataEnd)); err != nil {
|
if err := checkCRC32(sgmBytes.Range(chkEncStart, chkDataEnd), sum); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if act := chkCRC32.Sum(nil); !bytes.Equal(act, sum) {
|
|
||||||
return nil, errors.Errorf("checksum mismatch expected:%x, actual:%x", sum, act)
|
|
||||||
}
|
|
||||||
|
|
||||||
chkData := sgmBytes.Range(chkDataStart, chkDataEnd)
|
chkData := sgmBytes.Range(chkDataStart, chkDataEnd)
|
||||||
chkEnc := sgmBytes.Range(chkEncStart, chkEncStart+ChunkEncodingSize)[0]
|
chkEnc := sgmBytes.Range(chkEncStart, chkEncStart+ChunkEncodingSize)[0]
|
||||||
return s.pool.Get(chunkenc.Encoding(chkEnc), chkData)
|
return s.pool.Get(chunkenc.Encoding(chkEnc), chkData)
|
||||||
|
|
Loading…
Reference in a new issue