github.com/vc42/parquet-go@v0.0.0-20240320194221-1a9adb5f23f5/compress/zstd/zstd.go (about) 1 // Package zstd implements the ZSTD parquet compression codec. 2 package zstd 3 4 import ( 5 "sync" 6 7 "github.com/klauspost/compress/zstd" 8 "github.com/vc42/parquet-go/format" 9 ) 10 11 type Level = zstd.EncoderLevel 12 13 const ( 14 // SpeedFastest will choose the fastest reasonable compression. 15 // This is roughly equivalent to the fastest Zstandard mode. 16 SpeedFastest = zstd.SpeedFastest 17 18 // SpeedDefault is the default "pretty fast" compression option. 19 // This is roughly equivalent to the default Zstandard mode (level 3). 20 SpeedDefault = zstd.SpeedDefault 21 22 // SpeedBetterCompression will yield better compression than the default. 23 // Currently it is about zstd level 7-8 with ~ 2x-3x the default CPU usage. 24 // By using this, notice that CPU usage may go up in the future. 25 SpeedBetterCompression = zstd.SpeedBetterCompression 26 27 // SpeedBestCompression will choose the best available compression option. 28 // This will offer the best compression no matter the CPU cost. 29 SpeedBestCompression = zstd.SpeedBestCompression 30 ) 31 32 const ( 33 DefaultLevel = SpeedDefault 34 ) 35 36 type Codec struct { 37 Level Level 38 39 encoders sync.Pool // *zstd.Encoder 40 decoders sync.Pool // *zstd.Decoder 41 } 42 43 func (c *Codec) String() string { 44 return "ZSTD" 45 } 46 47 func (c *Codec) CompressionCodec() format.CompressionCodec { 48 return format.Zstd 49 } 50 51 func (c *Codec) Encode(dst, src []byte) ([]byte, error) { 52 e, _ := c.encoders.Get().(*zstd.Encoder) 53 if e == nil { 54 var err error 55 e, err = zstd.NewWriter(nil, 56 zstd.WithEncoderConcurrency(1), 57 zstd.WithEncoderLevel(c.level()), 58 zstd.WithZeroFrames(true), 59 zstd.WithEncoderCRC(false), 60 ) 61 if err != nil { 62 return dst[:0], err 63 } 64 } 65 defer c.encoders.Put(e) 66 return e.EncodeAll(src, dst[:0]), nil 67 } 68 69 func (c *Codec) Decode(dst, src []byte) ([]byte, error) { 70 d, _ := c.decoders.Get().(*zstd.Decoder) 71 if d == nil { 72 var err error 73 d, err = zstd.NewReader(nil, 74 zstd.WithDecoderConcurrency(1), 75 ) 76 if err != nil { 77 return dst[:0], err 78 } 79 } 80 defer c.decoders.Put(d) 81 return d.DecodeAll(src, dst[:0]) 82 } 83 84 func (c *Codec) level() Level { 85 if c.Level != 0 { 86 return c.Level 87 } 88 return DefaultLevel 89 }