@@ -6,16 +6,11 @@ package block
6
6
7
7
import (
8
8
"runtime"
9
- "slices"
10
9
"strings"
11
- "sync"
12
10
13
11
"github.com/cockroachdb/errors"
14
12
"github.com/cockroachdb/pebble/internal/base"
15
- "github.com/cockroachdb/pebble/internal/bytealloc"
16
13
"github.com/cockroachdb/pebble/internal/compression"
17
- "github.com/cockroachdb/pebble/internal/invariants"
18
- "github.com/cockroachdb/pebble/objstorage"
19
14
)
20
15
21
16
// CompressionProfile contains the parameters for compressing blocks in an
@@ -243,203 +238,3 @@ func DecompressInto(ci CompressionIndicator, compressed []byte, buf []byte) erro
243
238
}
244
239
return nil
245
240
}
246
-
247
- // PhysicalBlock represents a block (possibly compressed) as it is stored
248
- // physically on disk, including its trailer.
249
- type PhysicalBlock struct {
250
- // data contains the possibly compressed block data.
251
- data []byte
252
- trailer Trailer
253
- }
254
-
255
- // NewPhysicalBlock returns a new PhysicalBlock with the provided block
256
- // data. The trailer is set from the last TrailerLen bytes of the
257
- // block. The data could be compressed.
258
- func NewPhysicalBlock (data []byte ) PhysicalBlock {
259
- trailer := Trailer (data [len (data )- TrailerLen :])
260
- data = data [:len (data )- TrailerLen ]
261
- return PhysicalBlock {data : data , trailer : trailer }
262
- }
263
-
264
- // LengthWithTrailer returns the length of the data block, including the trailer.
265
- func (b * PhysicalBlock ) LengthWithTrailer () int {
266
- return len (b .data ) + TrailerLen
267
- }
268
-
269
- // LengthWithoutTrailer returns the length of the data block, excluding the trailer.
270
- func (b * PhysicalBlock ) LengthWithoutTrailer () int {
271
- return len (b .data )
272
- }
273
-
274
- // CloneWithByteAlloc returns a deep copy of the block, using the provided
275
- // bytealloc.A to allocate memory for the new copy.
276
- func (b * PhysicalBlock ) CloneWithByteAlloc (a * bytealloc.A ) PhysicalBlock {
277
- var data []byte
278
- * a , data = (* a ).Alloc (len (b .data ))
279
- copy (data , b .data )
280
- return PhysicalBlock {
281
- data : data ,
282
- trailer : b .trailer ,
283
- }
284
- }
285
-
286
- // Clone returns a deep copy of the block.
287
- func (b PhysicalBlock ) Clone () PhysicalBlock {
288
- data := make ([]byte , len (b .data ))
289
- copy (data , b .data )
290
- return PhysicalBlock {data : data , trailer : b .trailer }
291
- }
292
-
293
- // WriteTo writes the block (including its trailer) to the provided Writable. If
294
- // err == nil, n is the number of bytes successfully written to the Writable.
295
- //
296
- // WriteTo might mangle the block data.
297
- func (b * PhysicalBlock ) WriteTo (w objstorage.Writable ) (n int , err error ) {
298
- if err := w .Write (b .data ); err != nil {
299
- return 0 , err
300
- }
301
- if err := w .Write (b .trailer [:]); err != nil {
302
- return 0 , err
303
- }
304
-
305
- // WriteTo is allowed to mangle the data. Mangle it ourselves some of the time
306
- // in invariant builds to catch callers that don't handle this.
307
- if invariants .Enabled && invariants .Sometimes (1 ) {
308
- invariants .Mangle (b .data )
309
- }
310
- return len (b .data ) + len (b .trailer ), nil
311
- }
312
-
313
- // CompressAndChecksum compresses and checksums the provided block, returning
314
- // the compressed block and its trailer. The result is appended to the dst
315
- // argument.
316
- func CompressAndChecksum (
317
- dst * []byte , blockData []byte , blockKind Kind , compressor * Compressor , checksummer * Checksummer ,
318
- ) PhysicalBlock {
319
- buf := (* dst )[:0 ]
320
- ci , buf := compressor .Compress (buf , blockData , blockKind )
321
- * dst = buf
322
-
323
- // Calculate the checksum.
324
- pb := PhysicalBlock {data : buf }
325
- checksum := checksummer .Checksum (buf , byte (ci ))
326
- pb .trailer = MakeTrailer (byte (ci ), checksum )
327
- return pb
328
- }
329
-
330
- // CopyAndChecksum copies the provided block (without compressing it) and
331
- // checksums it, returning the physical block. The result is appended to the dst
332
- // argument.
333
- //
334
- // Note that we still need to provide a Compressor so we can inform it of the
335
- // uncompressed block (for statistics).
336
- func CopyAndChecksum (
337
- dst * []byte , blockData []byte , blockKind Kind , compressor * Compressor , checksummer * Checksummer ,
338
- ) PhysicalBlock {
339
- buf := * dst
340
- buf = append (buf [:0 ], blockData ... )
341
- * dst = buf
342
-
343
- // Calculate the checksum.
344
- pb := PhysicalBlock {data : buf }
345
- checksum := checksummer .Checksum (buf , byte (NoCompressionIndicator ))
346
- pb .trailer = MakeTrailer (byte (NoCompressionIndicator ), checksum )
347
- compressor .UncompressedBlock (len (blockData ), blockKind )
348
- return pb
349
- }
350
-
351
- // CompressAndChecksumToTempBuffer compresses and checksums the provided block
352
- // into a TempBuffer. The caller should Release() the TempBuffer once it is no
353
- // longer necessary.
354
- func CompressAndChecksumToTempBuffer (
355
- blockData []byte , blockKind Kind , compressor * Compressor , checksummer * Checksummer ,
356
- ) (PhysicalBlock , * TempBuffer ) {
357
- // Grab a buffer to use as the destination for compression.
358
- compressedBuf := NewTempBuffer ()
359
- pb := CompressAndChecksum (& compressedBuf .b , blockData , blockKind , compressor , checksummer )
360
- return pb , compressedBuf
361
- }
362
-
363
- // CopyAndChecksumToTempBuffer copies (without compressing) and checksums
364
- // the provided block into a TempBuffer. The caller should Release() the
365
- // TempBuffer once it is no longer necessary.
366
- func CopyAndChecksumToTempBuffer (
367
- blockData []byte , blockKind Kind , compressor * Compressor , checksummer * Checksummer ,
368
- ) (PhysicalBlock , * TempBuffer ) {
369
- // Grab a buffer to use as the destination for compression.
370
- compressedBuf := NewTempBuffer ()
371
- pb := CopyAndChecksum (& compressedBuf .b , blockData , blockKind , compressor , checksummer )
372
- return pb , compressedBuf
373
- }
374
-
375
- // TempBuffer is a buffer that is used temporarily and is released back to a
376
- // pool for reuse.
377
- type TempBuffer struct {
378
- b []byte
379
- }
380
-
381
- // NewTempBuffer returns a TempBuffer from the pool. The buffer will have zero
382
- // size and length and arbitrary capacity.
383
- func NewTempBuffer () * TempBuffer {
384
- tb := tempBufferPool .Get ().(* TempBuffer )
385
- if invariants .Enabled && len (tb .b ) > 0 {
386
- panic ("NewTempBuffer length not 0" )
387
- }
388
- return tb
389
- }
390
-
391
- // Data returns the byte slice currently backing the Buffer.
392
- func (tb * TempBuffer ) Data () []byte {
393
- return tb .b
394
- }
395
-
396
- // Size returns the current size of the buffer.
397
- func (tb * TempBuffer ) Size () int {
398
- return len (tb .b )
399
- }
400
-
401
- // Append appends the contents of v to the buffer, growing the buffer if
402
- // necessary. Returns the offset at which it was appended.
403
- func (tb * TempBuffer ) Append (v []byte ) (startOffset int ) {
404
- startOffset = len (tb .b )
405
- tb .b = append (tb .b , v ... )
406
- return startOffset
407
- }
408
-
409
- // Resize resizes the buffer to the specified length, allocating if necessary.
410
- // If the length is longer than the current length, the values of the new bytes
411
- // are arbitrary.
412
- func (tb * TempBuffer ) Resize (length int ) {
413
- if length > cap (tb .b ) {
414
- tb .b = slices .Grow (tb .b , length - len (tb .b ))
415
- }
416
- tb .b = tb .b [:length ]
417
- }
418
-
419
- // Reset is equivalent to Resize(0).
420
- func (tb * TempBuffer ) Reset () {
421
- tb .b = tb .b [:0 ]
422
- }
423
-
424
- // Release releases the buffer back to the pool for reuse.
425
- func (tb * TempBuffer ) Release () {
426
- // Note we avoid releasing buffers that are larger than the configured
427
- // maximum to the pool. This avoids holding on to occasional large buffers
428
- // necessary for e.g. singular large values.
429
- if tb .b != nil && len (tb .b ) < tempBufferMaxReusedSize {
430
- invariants .MaybeMangle (tb .b )
431
- tb .b = tb .b [:0 ]
432
- tempBufferPool .Put (tb )
433
- }
434
- }
435
-
436
- // tempBufferPool is a pool of buffers that are used to temporarily hold either
437
- // compressed or uncompressed block data.
438
- var tempBufferPool = sync.Pool {
439
- New : func () any {
440
- return & TempBuffer {b : make ([]byte , 0 , tempBufferInitialSize )}
441
- },
442
- }
443
-
444
- const tempBufferInitialSize = 32 * 1024
445
- const tempBufferMaxReusedSize = 256 * 1024
0 commit comments