# zstd **Fast compression and small binary patches, linked into your program.** - **Whole buffers or streams.** Compress a slice in one call, or a file of any size through two 64 KiB stack buffers. - **Patches, not re-downloads.** `diff` turns an old file and a new one into a patch a fraction of the new file's size; `patch` applies it. - **Wrong input fails loudly.** A patch carries a checksum of the new file, so applying it to the wrong old file is an error, not silent garbage. - **Your allocator.** zstd's own tables go through an Odin allocator and are freed before each call returns. | At a glance | | |---|---| | Version | zstd **1.5.7** | | Licence | BSD (zstd is dual BSD and GPLv2; jm takes it under BSD) | | Links | Statically, from `zstd/lib/zstd.a` | | Builds with | `just zstd` | | Used by | `jm:selfupdate`, for update patches | ## Quick start ```odin data := transmute([]byte)string("the same words, the same words, the same words") packed := must(zstd.compress(make([]byte, zstd.compress_bound(len(data))), data, {level = 19})) plain := must(zstd.decompress(make([]byte, len(data)), packed)) ``` For files, `compress_stream` and `decompress_stream` take an `io.Writer` and an `io.Reader`. For patches, `diff(dst, old, new)` writes one and `patch(dst, old, src)` applies it. ## What a patch saves A patch from `diff` is a zstd frame compressed with the old file as its prefix, so `zstd -d --patch-from=old` applies one too. Measured on brain-cli release builds (darwin-arm64, 2.19 MB): | Between | Patch | Compressed build | |---|---:|---:| | Two builds 15 commits apart | 197 KB | 946 KB | | Two builds of one commit | 5.4 KB | 946 KB | > [!WARNING] > Builds are not reproducible. Make patches against the published files, > never against rebuilds.
Under the hood: provenance and bindings `zstd/vendor/zstd.c` is zstd **1.5.7**'s single-file library, generated by `build/single_file_libs/create_single_file_library.sh` from the release tarball. The tarball's SHA-256 (`eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3`) was checked against the one the release publishes. `zstd.h`, `zstd_errors.h`, `zdict.h` and `LICENSE` are copied beside it. The amalgamation holds compression, decompression and the dictionary builder, without the legacy formats or assembly. `just zstd` compiles it into `zstd/lib/zstd.a`, as `just sqlite` does for SQLite. `ffi.odin` binds all of `zstd.h`'s stable API, `zdict.h`'s, and the experimental `_advanced` constructors. Those constructors let the wrapper route zstd's allocations through an Odin allocator.
## See also - [Packages](packages.md): `jm:selfupdate`, which ships updates as these patches - [SQLite](sqlite.md): the other vendored C library built the same way - [Fuzzing](fuzzing.md): the `jm:zstd` property suite