Re-use zstd and zlib readers

This commit is contained in:
Caleb Gardner
2025-04-16 05:49:42 -05:00
parent 8a2556ea0d
commit 4c8c9f0b47
3 changed files with 43 additions and 14 deletions
+20 -6
View File
@@ -2,17 +2,31 @@ package decompress
import ( import (
"bytes" "bytes"
"compress/zlib"
"io" "io"
"sync"
"github.com/klauspost/compress/zlib"
) )
type Zlib struct{} type Zlib struct {
pool sync.Pool
}
func (z Zlib) Decompress(data []byte) ([]byte, error) { func NewZlib() *Zlib {
rdr, err := zlib.NewReader(bytes.NewReader(data)) return &Zlib{}
}
func (z *Zlib) Decompress(data []byte) ([]byte, error) {
rdr := z.pool.Get()
defer z.pool.Put(rdr)
var err error
if rdr == nil {
rdr, err = zlib.NewReader(bytes.NewReader(data))
} else {
err = rdr.(zlib.Resetter).Reset(bytes.NewReader(data), nil)
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer rdr.Close() return io.ReadAll(rdr.(io.ReadCloser))
return io.ReadAll(rdr)
} }
+21 -6
View File
@@ -1,16 +1,31 @@
package decompress package decompress
import ( import (
"sync"
"github.com/klauspost/compress/zstd" "github.com/klauspost/compress/zstd"
) )
type Zstd struct{} type Zstd struct {
pool sync.Pool
}
func (z Zstd) Decompress(data []byte) ([]byte, error) { func NewZstd() *Zstd {
rdr, err := zstd.NewReader(nil, zstd.WithDecoderLowmem(true), zstd.WithDecoderConcurrency(1)) return &Zstd{
if err != nil { pool: sync.Pool{
return nil, err New: func() any {
rdr, _ := zstd.NewReader(nil, zstd.WithDecoderLowmem(true), zstd.WithDecoderConcurrency(1))
return rdr
},
},
} }
defer rdr.Close() }
func (z *Zstd) Decompress(data []byte) ([]byte, error) {
rdr := z.pool.Get().(*zstd.Decoder)
defer func() {
rdr.Reset(nil)
z.pool.Put(rdr)
}()
return rdr.DecodeAll(data, nil) return rdr.DecodeAll(data, nil)
} }
+2 -2
View File
@@ -56,7 +56,7 @@ func NewReader(r io.ReaderAt) (rdr Reader, err error) {
} }
switch rdr.Superblock.CompType { switch rdr.Superblock.CompType {
case ZlibCompression: case ZlibCompression:
rdr.d = decompress.Zlib{} rdr.d = decompress.NewZlib()
case LZMACompression: case LZMACompression:
rdr.d, err = decompress.NewLzma() rdr.d, err = decompress.NewLzma()
if err != nil { if err != nil {
@@ -72,7 +72,7 @@ func NewReader(r io.ReaderAt) (rdr Reader, err error) {
case LZ4Compression: case LZ4Compression:
rdr.d = decompress.NewLz4() rdr.d = decompress.NewLz4()
case ZSTDCompression: case ZSTDCompression:
rdr.d = decompress.Zstd{} rdr.d = decompress.NewZstd()
default: default:
return rdr, errors.New("invalid compression type. possible corrupted archive") return rdr, errors.New("invalid compression type. possible corrupted archive")
} }