Zstd wrapper for Go
Clone or download
Viq111 Merge pull request #49 from vrischmann/fix-decompress
prevent a out of range panic in Decompress
Latest commit 1e382f5 Jan 2, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github [github] Add issue templating Apr 10, 2017
.travis.yml [travis] Add build for 32bits centos Oct 29, 2018
LICENSE add simplified 3-clause bsd licence Jul 2, 2016
README.md Update README for zstd 1.3.4 Mar 30, 2018
ZSTD_LICENSE Update zstd to 1.1.3 Feb 22, 2017
bitstream.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
compiler.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
cover.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
cpu.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
divsufsort.c Adding C sources for zStd 1.0 in favor of shared lib. Sep 7, 2016
divsufsort.h Adding C sources for zStd 1.0 in favor of shared lib. Sep 7, 2016
entropy_common.c Update to zstd 1.3.0 Aug 10, 2017
error_private.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
error_private.h zstd 1.3.3 Jan 25, 2018
errors.go [zstd] Linting Mar 14, 2018
errors_test.go [tests][errors] Make TestFindIsDstSizeTooSmallError stricter Mar 14, 2018
fse.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
fse_compress.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
fse_decompress.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
huf.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
huf_compress.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
huf_decompress.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
mem.h zstd 1.3.3 Jan 25, 2018
pool.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
pool.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
threading.c zstd 1.3.3 Jan 25, 2018
threading.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
travis_test_32.sh [travis] Add build for 32bits centos Oct 29, 2018
update.txt zstd 1.3.3 Jan 25, 2018
xxhash.c zstd 1.3.3 Jan 25, 2018
xxhash.h Update to zstd 1.3.0 Aug 10, 2017
zbuff.h zstd 1.3.3 Jan 25, 2018
zbuff_common.c zstd 1.3.3 Jan 25, 2018
zbuff_compress.c zstd 1.3.3 Jan 25, 2018
zbuff_decompress.c zstd 1.3.3 Jan 25, 2018
zdict.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zdict.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd.go prevent a out of range panic in Decompress Dec 30, 2018
zstd.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_common.c zstd 1.3.3 Jan 25, 2018
zstd_compress.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_compress_internal.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_decompress.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_double_fast.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_double_fast.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_errors.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_fast.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_fast.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_internal.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_lazy.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_lazy.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_ldm.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_ldm.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_legacy.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_opt.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_opt.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_stream.go Make errShortRead private and move it upper in the file Aug 28, 2018
zstd_stream_test.go stream - Add test for empty payload Oct 1, 2018
zstd_test.go prevent a out of range panic in Decompress Dec 30, 2018
zstd_v01.c zstd 1.3.3 Jan 25, 2018
zstd_v01.h zstd 1.3.3 Jan 25, 2018
zstd_v02.c zstd 1.3.3 Jan 25, 2018
zstd_v02.h zstd 1.3.3 Jan 25, 2018
zstd_v03.c zstd 1.3.3 Jan 25, 2018
zstd_v03.h zstd 1.3.3 Jan 25, 2018
zstd_v04.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_v04.h zstd 1.3.3 Jan 25, 2018
zstd_v05.c zstd 1.3.3 Jan 25, 2018
zstd_v05.h zstd 1.3.3 Jan 25, 2018
zstd_v06.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_v06.h zstd 1.3.3 Jan 25, 2018
zstd_v07.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstd_v07.h zstd 1.3.3 Jan 25, 2018
zstdmt_compress.c Update vendored zstd c lib to 1.3.4 Mar 30, 2018
zstdmt_compress.h Update vendored zstd c lib to 1.3.4 Mar 30, 2018

README.md

Zstd Go Wrapper

C Zstd Homepage

The current headers and C files are from v1.3.4 (Commit 2555975).

Usage

There are two main APIs:

  • simple Compress/Decompress
  • streaming API (io.Reader/io.Writer)

The compress/decompress APIs mirror that of lz4, while the streaming API was designed to be a drop-in replacement for zlib.

Simple Compress/Decompress

// Compress compresses the byte array given in src and writes it to dst.
// If you already have a buffer allocated, you can pass it to prevent allocation
// If not, you can pass nil as dst.
// If the buffer is too small, it will be reallocated, resized, and returned bu the function
// If dst is nil, this will allocate the worst case size (CompressBound(src))
Compress(dst, src []byte) ([]byte, error)
// CompressLevel is the same as Compress but you can pass another compression level
CompressLevel(dst, src []byte, level int) ([]byte, error)
// Decompress will decompress your payload into dst.
// If you already have a buffer allocated, you can pass it to prevent allocation
// If not, you can pass nil as dst (allocates a 4*src size as default).
// If the buffer is too small, it will retry 3 times by doubling the dst size
// After max retries, it will switch to the slower stream API to be sure to be able
// to decompress. Currently switches if compression ratio > 4*2**3=32.
Decompress(dst, src []byte) ([]byte, error)

Stream API

// NewWriter creates a new object that can optionally be initialized with
// a precomputed dictionary. If dict is nil, compress without a dictionary.
// The dictionary array should not be changed during the use of this object.
// You MUST CALL Close() to write the last bytes of a zstd stream and free C objects.
NewWriter(w io.Writer) *Writer
NewWriterLevel(w io.Writer, level int) *Writer
NewWriterLevelDict(w io.Writer, level int, dict []byte) *Writer

// Write compresses the input data and write it to the underlying writer
(w *Writer) Write(p []byte) (int, error)

// Close flushes the buffer and frees C zstd objects
(w *Writer) Close() error
// NewReader returns a new io.ReadCloser that will decompress data from the
// underlying reader.  If a dictionary is provided to NewReaderDict, it must
// not be modified until Close is called.  It is the caller's responsibility
// to call Close, which frees up C objects.
NewReader(r io.Reader) io.ReadCloser
NewReaderDict(r io.Reader, dict []byte) io.ReadCloser

Benchmarks (benchmarked with v0.5.0)

The author of Zstd also wrote lz4. Zstd is intended to occupy a speed/ratio level similar to what zlib currently provides. In our tests, the can always be made to be better than zlib by chosing an appropriate level while still keeping compression and decompression time faster than zlib.

You can run the benchmarks against your own payloads by using the Go benchmarks tool. Just export your payload filepath as the PAYLOAD environment variable and run the benchmarks:

go test -bench .

Compression of a 7Mb pdf zstd (this wrapper) vs czlib:

BenchmarkCompression               5     221056624 ns/op      67.34 MB/s
BenchmarkDecompression           100      18370416 ns/op     810.32 MB/s

BenchmarkFzlibCompress             2     610156603 ns/op      24.40 MB/s
BenchmarkFzlibDecompress          20      81195246 ns/op     183.33 MB/s

Ratio is also better by a margin of ~20%. Compression speed is always better than zlib on all the payloads we tested; However, czlib has optimisations that make it faster at decompressiong small payloads:

Testing with size: 11... czlib: 8.97 MB/s, zstd: 3.26 MB/s
Testing with size: 27... czlib: 23.3 MB/s, zstd: 8.22 MB/s
Testing with size: 62... czlib: 31.6 MB/s, zstd: 19.49 MB/s
Testing with size: 141... czlib: 74.54 MB/s, zstd: 42.55 MB/s
Testing with size: 323... czlib: 155.14 MB/s, zstd: 99.39 MB/s
Testing with size: 739... czlib: 235.9 MB/s, zstd: 216.45 MB/s
Testing with size: 1689... czlib: 116.45 MB/s, zstd: 345.64 MB/s
Testing with size: 3858... czlib: 176.39 MB/s, zstd: 617.56 MB/s
Testing with size: 8811... czlib: 254.11 MB/s, zstd: 824.34 MB/s
Testing with size: 20121... czlib: 197.43 MB/s, zstd: 1339.11 MB/s
Testing with size: 45951... czlib: 201.62 MB/s, zstd: 1951.57 MB/s

zstd starts to shine with payloads > 1KB

Stability - Current state: STABLE

The C library seems to be pretty stable and according to the author has been tested and fuzzed.

For the Go wrapper, the test cover most usual cases and we have succesfully tested it on all staging and prod data.