From cec7f383bba62eab02946c298af86d9d407fb0f9 Mon Sep 17 00:00:00 2001 From: Klaus Post Date: Sun, 6 Mar 2022 13:41:02 +0100 Subject: [PATCH 1/2] zstd: Reuse zip decoders Now that decoding is stateless we can pool decoders. --- zstd/zip.go | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/zstd/zip.go b/zstd/zip.go index 967f29b312..752ef59a70 100644 --- a/zstd/zip.go +++ b/zstd/zip.go @@ -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 { @@ -47,7 +47,11 @@ func (r *pooledZipReader) Read(p []byte) (n int, err error) { return 0, errors.New("Read after Close") } 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 } @@ -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 } From ba09e55d117b358927a601b95d96040152c18203 Mon Sep 17 00:00:00 2001 From: Klaus Post Date: Sun, 6 Mar 2022 13:43:02 +0100 Subject: [PATCH 2/2] Clean error message. --- zstd/zip.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zstd/zip.go b/zstd/zip.go index 752ef59a70..ffffcbc254 100644 --- a/zstd/zip.go +++ b/zstd/zip.go @@ -44,7 +44,7 @@ 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 {