// Package compress provides the generic APIs implemented by parquet compression // codecs. // // https://github.com/apache/parquet-format/blob/master/Compression.md
package compress import ( ) // The Codec interface represents parquet compression codecs implemented by the // compress sub-packages. // // Codec instances must be safe to use concurrently from multiple goroutines. type Codec interface { // Returns a human-readable name for the codec. String() string // Returns the code of the compression codec in the parquet format. CompressionCodec() format.CompressionCodec // Writes the compressed version of src to dst and returns it. // // The method automatically reallocates the output buffer if its capacity // was too small to hold the compressed data. Encode(dst, src []byte) ([]byte, error) // Writes the uncompressed version of src to dst and returns it. // // The method automatically reallocates the output buffer if its capacity // was too small to hold the uncompressed data. Decode(dst, src []byte) ([]byte, error) } type Reader interface { io.ReadCloser Reset(io.Reader) error } type Writer interface { io.WriteCloser Reset(io.Writer) } type Compressor struct { writers sync.Pool // *writer } type writer struct { output bytes.Buffer writer Writer } func ( *Compressor) (, []byte, func(io.Writer) (Writer, error)) ([]byte, error) { , := .writers.Get().(*writer) if != nil { .output = *bytes.NewBuffer([:0]) .writer.Reset(&.output) } else { = new(writer) .output = *bytes.NewBuffer([:0]) var error if .writer, = (&.output); != nil { return , } } defer func() { .output = *bytes.NewBuffer(nil) .writer.Reset(io.Discard) .writers.Put() }() if , := .writer.Write(); != nil { return .output.Bytes(), } if := .writer.Close(); != nil { return .output.Bytes(), } return .output.Bytes(), nil } type Decompressor struct { readers sync.Pool // *reader } type reader struct { input bytes.Reader reader Reader } func ( *Decompressor) (, []byte, func(io.Reader) (Reader, error)) ([]byte, error) { , := .readers.Get().(*reader) if != nil { .input.Reset() if := .reader.Reset(&.input); != nil { return , } } else { = new(reader) .input.Reset() var error if .reader, = (&.input); != nil { return , } } defer func() { .input.Reset(nil) if := .reader.Reset(nil); == nil { .readers.Put() } }() if cap() == 0 { = make([]byte, 0, 2*len()) } else { = [:0] } for { , := .reader.Read([len():cap()]) = [:len()+] if != nil { if == io.EOF { = nil } return , } if len() == cap() { := make([]byte, len(), 2*len()) copy(, ) = } } }