Skip to content

Commit fb07627

Browse files
committed
first attempt at reusing objects in rcompress with sync.Pool, readers only for now
1 parent 5389a1f commit fb07627

File tree

1 file changed

+46
-5
lines changed

1 file changed

+46
-5
lines changed

groot/internal/rcompress/rcompress.go

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"errors"
1414
"fmt"
1515
"io"
16+
"sync"
1617

1718
"github.com/klauspost/compress/flate"
1819
"github.com/klauspost/compress/zlib"
@@ -371,21 +372,22 @@ func Decompress(dst []byte, src io.Reader) error {
371372
lr := &io.LimitedReader{R: src, N: srcsz}
372373
switch kindOf(hdr) {
373374
case ZLIB:
374-
rc, err := zlib.NewReader(lr)
375+
rc, err := zlibNewReader(lr)
375376
if err != nil {
376377
return fmt.Errorf("rcompress: could not create ZLIB reader: %w", err)
377378
}
378-
defer rc.Close()
379-
380379
_, err = io.ReadFull(rc, dst[beg:end])
380+
rc.Close()
381+
zlibReaderPool.Put(rc)
381382
if err != nil {
382383
return fmt.Errorf("rcompress: could not decompress ZLIB buffer: %w", err)
383384
}
384385

385386
case LZ4:
386-
src := make([]byte, srcsz)
387+
src := lz4NewBuffer(srcsz)
387388
_, err = io.ReadFull(lr, src)
388389
if err != nil {
390+
lz4BufferPool.Put(src)
389391
return fmt.Errorf("rcompress: could not read LZ4 block: %w", err)
390392
}
391393
const chksum = 8
@@ -396,7 +398,9 @@ func Decompress(dst []byte, src io.Reader) error {
396398
case srcsz > tgtsz:
397399
// no compression
398400
copy(dst[beg:end], src[chksum:])
401+
lz4BufferPool.Put(src)
399402
default:
403+
lz4BufferPool.Put(src)
400404
return fmt.Errorf("rcompress: could not decompress LZ4 block: %w", err)
401405
}
402406
}
@@ -419,11 +423,13 @@ func Decompress(dst []byte, src io.Reader) error {
419423
}
420424

421425
case ZSTD:
422-
rc, err := zstd.NewReader(lr)
426+
rc, err := zstdNewReader(lr)
423427
if err != nil {
424428
return fmt.Errorf("rcompress: could not create ZSTD reader: %w", err)
425429
}
426430
_, err = io.ReadFull(rc, dst[beg:end])
431+
rc.Reset(nil)
432+
zstdReaderPool.Put(rc)
427433
if err != nil {
428434
return fmt.Errorf("rcompress: could not decompress ZSTD block: %w", err)
429435
}
@@ -457,3 +463,38 @@ func (w *wbuff) Write(p []byte) (int, error) {
457463
var (
458464
_ io.Writer = (*wbuff)(nil)
459465
)
466+
467+
// TODO writers, need to index by options (e.g. compression level)
468+
var (
469+
lz4BufferPool = sync.Pool{}
470+
zlibReaderPool = sync.Pool{}
471+
zstdReaderPool = sync.Pool{}
472+
)
473+
474+
func lz4NewBuffer(size int64) []byte {
475+
var b []byte
476+
if bi := lz4BufferPool.Get(); bi != nil {
477+
b = bi.([]byte)
478+
}
479+
if int64(cap(b)) >= size {
480+
return b[:size]
481+
}
482+
return make([]byte, size)
483+
}
484+
485+
func zlibNewReader(r io.Reader) (io.ReadCloser, error) {
486+
if ri := zlibReaderPool.Get(); ri != nil {
487+
ri.(zlib.Resetter).Reset(r, nil)
488+
return ri.(io.ReadCloser), nil
489+
}
490+
return zlib.NewReader(r)
491+
}
492+
493+
func zstdNewReader(r io.Reader) (*zstd.Decoder, error) {
494+
if ri := zstdReaderPool.Get(); ri != nil {
495+
rd := ri.(*zstd.Decoder)
496+
rd.Reset(r)
497+
return rd, nil
498+
}
499+
return zstd.NewReader(r)
500+
}

0 commit comments

Comments
 (0)