.github
ci(i386): cross-compile to GOARCH=386 instead of docker+old image
tools
[tools] Add flatten_imports to allow easy update of zstd version
allocations.h
Update vendored zstd to 1.5.6
bits.h
Update vendored zstd to 1.5.7
bitstream.h
Update vendored zstd to 1.5.7
clevels.h
Update vendored zstd to 1.5.5
compiler.h
Update vendored zstd to 1.5.7
cover.c
Update vendored zstd to 1.5.7
cover.h
Update vendored zstd to 1.5.6
cpu.h
Update vendored zstd to 1.5.7
debug.c
Update vendored zstd to 1.5.6
debug.h
Update vendored zstd to 1.5.7
divsufsort.c
Add preprocessor directives to zstd c source files
divsufsort.h
Update vendored zstd to 1.5.7
entropy_common.c
Update vendored zstd to 1.5.5
error_private.c
Update vendored zstd to 1.5.7
error_private.h
Update vendored zstd to 1.5.7
errors_test.go
[tests][errors] Make TestFindIsDstSizeTooSmallError stricter
errors.go
Remove ZSTD_STATIC_LINKING_ONLY constraint
external_zstd.go
Add version constraint for building against external library
fastcover.c
Update vendored zstd to 1.5.6
fse_compress.c
Update vendored zstd to 1.5.6
fse_decompress.c
Update vendored zstd to 1.5.7
fse.h
Update vendored zstd to 1.5.7
go.mod
Bump minimum Go version to 1.24
helpers_test.go
[zstd_stream] Add test to isolate stream decompression
hist.c
Update vendored zstd to 1.5.7
hist.h
Update vendored zstd to 1.5.7
huf_compress.c
Update vendored zstd to 1.5.6
huf_decompress_amd64.S
Update vendored zstd to 1.5.7
huf_decompress.c
Update vendored zstd to 1.5.6
huf.h
Update vendored zstd to 1.5.7
LICENSE
add simplified 3-clause bsd licence
mem.h
Update vendored zstd to 1.5.7
pool.c
Update vendored zstd to 1.5.6
pool.h
Update vendored zstd to 1.5.7
portability_macros.h
Update vendored zstd to 1.5.7
README.md
Update Readme for 1.5.7
threading.c
Update vendored zstd to 1.5.6
threading.h
Update vendored zstd to 1.5.7
update.txt
zstd 1.3.3
xxhash.c
Update vendored zstd to 1.5.6
xxhash.h
Update vendored zstd to 1.5.7
zbuff_common.c
Update vendored zstd to 1.5.5
zbuff_compress.c
Update vendored zstd to 1.5.5
zbuff_decompress.c
Update vendored zstd to 1.5.5
zbuff.h
Update vendored zstd to 1.5.5
zdict.c
Update vendored zstd to 1.5.7
zdict.h
Update vendored zstd to 1.5.7
zstd_bulk.go
Decompress: guess a multiple of the input for unknown-size frames
zstd_bullk_test.go
[bulk] Add extra empty payload decompression test
zstd_common.c
Update vendored zstd to 1.5.5
zstd_compress_internal.h
Update vendored zstd to 1.5.7
zstd_compress_literals.c
Update vendored zstd to 1.5.7
zstd_compress_literals.h
Update vendored zstd to 1.5.5
zstd_compress_sequences.c
Update vendored zstd to 1.5.7
zstd_compress_sequences.h
Update vendored zstd to 1.5.7
zstd_compress_superblock.c
Update vendored zstd to 1.5.7
zstd_compress_superblock.h
Update vendored zstd to 1.5.5
zstd_compress.c
Update vendored zstd to 1.5.7
zstd_ctx_test.go
add Ctx.DecompressInto for decompression of payloads with known sizes
zstd_ctx.go
Decompress: reuse the caller-supplied buffer for unknown-size frames
zstd_cwksp.h
Update vendored zstd to 1.5.7
zstd_ddict.c
Update vendored zstd to 1.5.5
zstd_ddict.h
Update vendored zstd to 1.5.5
zstd_decompress_block.c
Update vendored zstd to 1.5.7
zstd_decompress_block.h
Update vendored zstd to 1.5.6
zstd_decompress_internal.h
Update vendored zstd to 1.5.7
zstd_decompress.c
Update vendored zstd to 1.5.7
zstd_deps.h
Update vendored zstd to 1.5.7
zstd_double_fast.c
Update vendored zstd to 1.5.7
zstd_double_fast.h
Update vendored zstd to 1.5.7
zstd_errors.h
Update vendored zstd to 1.5.7
zstd_fast.c
Update vendored zstd to 1.5.7
zstd_fast.h
Update vendored zstd to 1.5.7
zstd_hint_test.go
Decompress: guess a multiple of the input for unknown-size frames
zstd_internal.h
Update vendored zstd to 1.5.7
zstd_lazy.c
Update vendored zstd to 1.5.7
zstd_lazy.h
Update vendored zstd to 1.5.7
zstd_ldm_geartab.h
Update vendored zstd to 1.5.5
zstd_ldm.c
Update vendored zstd to 1.5.7
zstd_ldm.h
Update vendored zstd to 1.5.7
zstd_legacy.h
Update vendored zstd to 1.5.6
ZSTD_LICENSE
Update vendored zstd to 1.5.5
zstd_opt.c
Update vendored zstd to 1.5.7
zstd_opt.h
Update vendored zstd to 1.5.7
zstd_preSplit.c
Update vendored zstd to 1.5.7
zstd_preSplit.h
Update vendored zstd to 1.5.7
zstd_reuse_buffer_test.go
Decompress: reuse the caller-supplied buffer for unknown-size frames
zstd_small_stream_test.go
zstd_stream.go: remove intermediate source buffer for Writer.
zstd_stream_test.go
Fix C memory leak in Writer.Close() and reader.Close()
zstd_stream.go
Fix C memory leak in Writer.Close() and reader.Close()
zstd_test.go
add DecompressInto for decompression of payloads with known sizes
zstd_trace.h
Update vendored zstd to 1.5.7
zstd_v01.c
Update vendored zstd to 1.5.7
zstd_v01.h
Update vendored zstd to 1.5.5
zstd_v02.c
Update vendored zstd to 1.5.7
zstd_v02.h
Update vendored zstd to 1.5.5
zstd_v03.c
Update vendored zstd to 1.5.7
zstd_v03.h
Update vendored zstd to 1.5.5
zstd_v04.c
Update vendored zstd to 1.5.6
zstd_v04.h
Update vendored zstd to 1.5.5
zstd_v05.c
Update vendored zstd to 1.5.7
zstd_v05.h
Update vendored zstd to 1.5.5
zstd_v06.c
Update vendored zstd to 1.5.7
zstd_v06.h
Update vendored zstd to 1.5.5
zstd_v07.c
Update vendored zstd to 1.5.7
zstd_v07.h
Update vendored zstd to 1.5.5
zstd.go
Decompress: guess a multiple of the input for unknown-size frames
zstd.h
Update vendored zstd to 1.5.7
zstdmt_compress.c
Update vendored zstd to 1.5.7
zstdmt_compress.h
Update vendored zstd to 1.5.7

Zstd Go Wrapper

C Zstd Homepage

The current headers and C files are from v1.5.7 (Commit f8745da).

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.

Building against an external libzstd

By default, zstd source code is vendored in this repository and the binding will be built with the vendored source code bundled.

If you want to build this binding against an external static or shared libzstd library, you can use the external_libzstd build tag. This will look for the libzstd pkg-config file and extract build and linking parameters from that pkg-config file.

Note that it requires at least libzstd 1.4.0.

go build -tags external_libzstd

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 by 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)

// Flush writes any unwritten data to the underlying writer
(w *Writer) Flush() 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.