Skip to content

Commit

Permalink
zstd: Reuse zip decoders (#514)
Browse files Browse the repository at this point in the history
* zstd: Reuse zip decoders

Now that decoding is stateless we can pool decoders.
  • Loading branch information
klauspost authored Mar 6, 2022
1 parent dbd783b commit 0a250cb
Showing 1 changed file with 8 additions and 10 deletions.
18 changes: 8 additions & 10 deletions zstd/zip.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const ZipMethodPKWare = 20

var zipReaderPool sync.Pool

// newZipReader cannot be used since we would leak goroutines...
// newZipReader creates a pooled zip decompressor.
func newZipReader(r io.Reader) io.ReadCloser {
dec, ok := zipReaderPool.Get().(*Decoder)
if ok {
Expand All @@ -44,10 +44,14 @@ func (r *pooledZipReader) Read(p []byte) (n int, err error) {
r.mu.Lock()
defer r.mu.Unlock()
if r.dec == nil {
return 0, errors.New("Read after Close")
return 0, errors.New("read after close or EOF")
}
dec, err := r.dec.Read(p)

if err == io.EOF {
err = r.dec.Reset(nil)
zipReaderPool.Put(r.dec)
r.dec = nil
}
return dec, err
}

Expand Down Expand Up @@ -112,11 +116,5 @@ func ZipCompressor(opts ...EOption) func(w io.Writer) (io.WriteCloser, error) {
// ZipDecompressor returns a decompressor that can be registered with zip libraries.
// See ZipCompressor for example.
func ZipDecompressor() func(r io.Reader) io.ReadCloser {
return func(r io.Reader) io.ReadCloser {
d, err := NewReader(r, WithDecoderConcurrency(1), WithDecoderLowmem(true))
if err != nil {
panic(err)
}
return d.IOReadCloser()
}
return newZipReader
}

0 comments on commit 0a250cb

Please sign in to comment.