diff options
Diffstat (limited to 'internal/compress/zlib')
| -rw-r--r-- | internal/compress/zlib/reader.go | 23 | ||||
| -rw-r--r-- | internal/compress/zlib/reader_reset.go | 11 | ||||
| -rw-r--r-- | internal/compress/zlib/writer.go | 7 | ||||
| -rw-r--r-- | internal/compress/zlib/writer_header.go | 5 |
4 files changed, 37 insertions, 9 deletions
diff --git a/internal/compress/zlib/reader.go b/internal/compress/zlib/reader.go index f58a904a..74357525 100644 --- a/internal/compress/zlib/reader.go +++ b/internal/compress/zlib/reader.go @@ -34,12 +34,14 @@ and to read that data back: package zlib import ( + "bytes" "encoding/binary" "errors" "hash" "io" - "lindenii.org/go/furgit/internal/compress/flate" + "github.com/klauspost/compress/flate" + "lindenii.org/go/lgo/intconv" "lindenii.org/go/lgo/sync" ) @@ -74,6 +76,7 @@ type Reader struct { trailerRead uint64 err error scratch [4]byte + br bytes.Reader } // NewReader creates a new ReadCloser. @@ -99,6 +102,23 @@ func NewReaderDict(r io.Reader, dict []byte) (*Reader, error) { return z, nil } +// NewReaderBytes is like [NewReader] but reads directly from payload, +// reusing a [bytes.Reader] pooled with the returned Reader +// instead of allocating a fresh one per call. +// It is the caller's responsibility to call Close on the ReadCloser when done. +func NewReaderBytes(payload []byte) (*Reader, error) { + z := readerPool.Get() + + z.br.Reset(payload) + + err := z.reset(&z.br, nil) + if err != nil { + return nil, err + } + + return z, nil +} + // Read decompresses bytes from receiver into p. func (z *Reader) Read(p []byte) (int, error) { if z.err != nil { @@ -167,6 +187,7 @@ func (z *Reader) Close() error { return z.err } + z.br.Reset(nil) readerPool.Put(z) return nil diff --git a/internal/compress/zlib/reader_reset.go b/internal/compress/zlib/reader_reset.go index b1b9afa6..6a9340c2 100644 --- a/internal/compress/zlib/reader_reset.go +++ b/internal/compress/zlib/reader_reset.go @@ -10,14 +10,15 @@ import ( "errors" "io" + "github.com/klauspost/compress/flate" + "lindenii.org/go/furgit/internal/adler32" - "lindenii.org/go/furgit/internal/compress/flate" "lindenii.org/go/lgo/intconv" ) // reset resets receiver to read a new zlib stream. func (z *Reader) reset(r io.Reader, dict []byte) error { - *z = Reader{decompressor: z.decompressor} + *z = Reader{decompressor: z.decompressor, digest: z.digest, br: z.br} var input flate.Reader if fr, ok := r.(flate.Reader); ok { @@ -95,7 +96,11 @@ func (z *Reader) reset(r io.Reader, dict []byte) error { return z.err } - z.digest = adler32.New() + if z.digest == nil { + z.digest = adler32.New() + } else { + z.digest.Reset() + } return nil } diff --git a/internal/compress/zlib/writer.go b/internal/compress/zlib/writer.go index ae327e6d..0fcb2ca8 100644 --- a/internal/compress/zlib/writer.go +++ b/internal/compress/zlib/writer.go @@ -10,7 +10,8 @@ import ( "hash" "io" - "lindenii.org/go/furgit/internal/compress/flate" + "github.com/klauspost/compress/flate" + "lindenii.org/go/lgo/sync" ) @@ -70,7 +71,7 @@ func NewWriterLevel(w io.Writer, level int) (*Writer, error) { // the Writer is closed. func NewWriterLevelDict(w io.Writer, level int, dict []byte) (*Writer, error) { if level < HuffmanOnly || level > BestCompression { - return nil, fmt.Errorf("zlib: invalid compression level: %d", level) + return nil, fmt.Errorf("zlib: invalid compression level: %d", level) //nolint:err113 } z := writerPool.Get() @@ -139,7 +140,7 @@ func (z *Writer) Write(p []byte) (n int, err error) { if err != nil { z.err = err - return n, err + return n, err //nolint:wrapcheck } _, err = z.digest.Write(p) diff --git a/internal/compress/zlib/writer_header.go b/internal/compress/zlib/writer_header.go index 6a5f09de..00407f49 100644 --- a/internal/compress/zlib/writer_header.go +++ b/internal/compress/zlib/writer_header.go @@ -7,8 +7,9 @@ package zlib import ( "encoding/binary" + "github.com/klauspost/compress/flate" + "lindenii.org/go/furgit/internal/adler32" - "lindenii.org/go/furgit/internal/compress/flate" ) // writeHeader writes the ZLIB header. @@ -61,7 +62,7 @@ func (z *Writer) writeHeader() (err error) { // after a Reset call. z.compressor, err = flate.NewWriterDict(z.w, z.level, z.dict) if err != nil { - return err + return err //nolint:wrapcheck } z.digest = adler32.New() |
