55package block
66
77import (
8- "encoding/binary"
98 "math/rand/v2"
109 "slices"
1110 "sync"
@@ -15,7 +14,6 @@ import (
1514 "github.com/cockroachdb/pebble/internal/bytealloc"
1615 "github.com/cockroachdb/pebble/internal/invariants"
1716 "github.com/cockroachdb/pebble/objstorage"
18- "github.com/golang/snappy"
1917)
2018
2119// Compression is the per-block compression algorithm to use.
@@ -114,55 +112,21 @@ func (i CompressionIndicator) String() string {
114112
115113// DecompressedLen returns the length of the provided block once decompressed,
116114// allowing the caller to allocate a buffer exactly sized to the decompressed
117- // payload. For some compression algorithms, the payload is prefixed with a
118- // varint encoding the length of the decompressed block. In such cases, a
119- // non-zero prefixLength is returned indicating the length of this prefix.
120- func DecompressedLen (
121- algo CompressionIndicator , b []byte ,
122- ) (decompressedLen int , prefixLength int , err error ) {
123- switch algo {
124- case NoCompressionIndicator :
125- return len (b ), 0 , nil
126- case SnappyCompressionIndicator :
127- l , err := snappy .DecodedLen (b )
128- return l , 0 , err
129- case ZstdCompressionIndicator :
130- // This will also be used by zlib, bzip2 and lz4 to retrieve the decodedLen
131- // if we implement these algorithms in the future.
132- decodedLenU64 , varIntLen := binary .Uvarint (b )
133- if varIntLen <= 0 {
134- return 0 , 0 , base .CorruptionErrorf ("pebble/table: compression block has invalid length" )
135- }
136- return int (decodedLenU64 ), varIntLen , nil
137- default :
138- return 0 , 0 , base .CorruptionErrorf ("pebble/table: unknown block compression: %d" , errors .Safe (algo ))
139- }
115+ // payload.
116+ func DecompressedLen (algo CompressionIndicator , b []byte ) (decompressedLen int , err error ) {
117+ decompressor := GetDecompressor (algo )
118+ return decompressor .DecompressedLen (b )
140119}
141120
142121// DecompressInto decompresses compressed into buf. The buf slice must have the
143122// exact size as the decompressed value. Callers may use DecompressedLen to
144123// determine the correct size.
145124func DecompressInto (algo CompressionIndicator , compressed []byte , buf []byte ) error {
146- var result []byte
147- var err error
148- switch algo {
149- case NoCompressionIndicator :
150- result = buf [:len (compressed )]
151- copy (result , compressed )
152- case SnappyCompressionIndicator :
153- result , err = snappy .Decode (buf , compressed )
154- case ZstdCompressionIndicator :
155- result , err = decodeZstd (buf , compressed )
156- default :
157- return base .CorruptionErrorf ("pebble/table: unknown block compression: %d" , errors .Safe (algo ))
158- }
125+ decompressor := GetDecompressor (algo )
126+ err := decompressor .DecompressInto (buf , compressed )
159127 if err != nil {
160128 return base .MarkCorruptionError (err )
161129 }
162- if len (result ) != len (buf ) || (len (result ) > 0 && & result [0 ] != & buf [0 ]) {
163- return base .CorruptionErrorf ("pebble/table: decompressed into unexpected buffer: %p != %p" ,
164- errors .Safe (result ), errors .Safe (buf ))
165- }
166130 return nil
167131}
168132
@@ -249,7 +213,8 @@ func CompressAndChecksum(
249213 // least 12.5%.
250214 algo := NoCompressionIndicator
251215 if compression != NoCompression {
252- algo , buf = compress (compression , blockData , buf )
216+ compressor := GetCompressor (compression )
217+ algo , buf = compressor .Compress (buf , blockData )
253218 if len (buf ) >= len (blockData )- len (blockData )/ 8 {
254219 algo = NoCompressionIndicator
255220 }
@@ -270,30 +235,6 @@ func CompressAndChecksum(
270235 return pb
271236}
272237
273- // compress compresses a sstable block, using dstBuf as the desired destination.
274- //
275- // The result is aliased to dstBuf if that buffer had enough capacity, otherwise
276- // it is a newly-allocated buffer.
277- func compress (
278- compression Compression , b []byte , dstBuf []byte ,
279- ) (indicator CompressionIndicator , compressed []byte ) {
280- switch compression {
281- case SnappyCompression :
282- // snappy relies on the length of the buffer, and not the capacity to
283- // determine if it needs to make an allocation.
284- dstBuf = dstBuf [:cap (dstBuf ):cap (dstBuf )]
285- return SnappyCompressionIndicator , snappy .Encode (dstBuf , b )
286- case ZstdCompression :
287- if len (dstBuf ) < binary .MaxVarintLen64 {
288- dstBuf = append (dstBuf , make ([]byte , binary .MaxVarintLen64 - len (dstBuf ))... )
289- }
290- varIntLen := binary .PutUvarint (dstBuf , uint64 (len (b )))
291- return ZstdCompressionIndicator , encodeZstd (dstBuf , varIntLen , b )
292- default :
293- panic ("unreachable" )
294- }
295- }
296-
297238// A Buffer is a buffer for encoding a block. The caller mutates the buffer to
298239// construct the uncompressed block, and calls CompressAndChecksum to produce
299240// the physical, possibly-compressed PhysicalBlock. A Buffer recycles byte
0 commit comments