1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
[]
= "structured-zstd"
= "0.0.50"
= "1.92"
= [
"Moritz Borcherding <moritz.borcherding@web.de>",
"Dmitry Prudnikov <mail@polaz.com>",
]
= "2024"
= "Apache-2.0"
= "https://structured-world.github.io/structured-zstd/dev/bench/"
= "https://github.com/structured-world/structured-zstd"
= "Pure-Rust Zstandard (zstd) compression and decompression: all levels, streaming, dictionaries, no_std and WebAssembly ready — no FFI, no cmake"
= ["fuzz_decodecorpus/*", "decodecorpus_files/*", "dict_tests/files/**"]
# Package metadata points at a crate-local symlink so the packaged crate and repo root README stay in sync.
= "README.md"
= ["zstd", "zstandard", "decompression", "compression", "no-std"]
= ["compression", "no-std", "wasm", "encoding"]
# The C-binding benches, conformance tests, and FFI diagnostic examples live in
# the non-published `ffi-bench` crate so this library never depends on the C
# `zstd` bindings. Auto-discovery is disabled because those source files still
# physically live under `benches/`, `tests/`, and `examples/` here and are
# compiled as targets of `ffi-bench` via explicit `path` entries.
#
# Consequence for new tests: `tests/` auto-discovery is OFF, so a pure-Rust
# integration test dropped into `zstd/tests/` would NOT run under
# `cargo test -p structured-zstd`. Add pure-Rust tests as unit tests under
# `src/` (the `#[cfg(test)] mod tests` tree, which always runs) or, if a
# `tests/`-style integration file is required, register it with an explicit
# `[[test]]` entry here. C-binding tests always go to `ffi-bench`.
= false
= false
= false
# The command-line tool ships from this crate rather than a second package, so
# `cargo add structured-zstd` and `cargo install structured-zstd` name the same
# thing. It carries no dependencies of its own — argument parsing, progress
# display and its error type are written against `std` — so `required-features`
# names only library capabilities, all of which are in `default`. That is what
# makes `cargo install structured-zstd` work with no flags while a library
# consumer's dependency graph stays untouched: a `no_std` build simply does not
# select this target.
#
# The list is what the parser ADVERTISES, not the minimum that links: `-t` must
# actually verify checksums (which needs `hash`, pulled in by `ldm`) and
# `--long` must actually do long-distance matching, or a custom
# `--no-default-features` install would answer `OK` for a frame whose checksum
# is corrupt. A tool that reports success without doing the check is worse than
# one that refuses to build.
#
# Deliberately NOT named `zstd`: `cargo install` writes into a directory that
# usually precedes `/usr/bin` on `PATH`, so that name would shadow the system
# tool for everyone who installs this. It dispatches on `argv[0]`, so an
# alternatives entry or a `unzstd` / `zstdcat` symlink still selects the
# matching default mode.
[[]]
= "structured-zstd"
= "src/bin/structured-zstd/main.rs"
= ["std", "dict-builder", "ldm"]
# docs.rs builds the crate with the public feature set so feature-gated
# items (e.g. the `dictionary` module behind `dict-builder`) appear in the
# published documentation. We list the public features explicitly rather
# than using `all-features = true` because the manifest also exposes
# `rustc-dep-of-std` (libstd-build-only — swaps in `rustc-std-workspace-*`
# crates), `bench-internals` (widens the API surface for benches), and
# `fuzz-exports` (widens it for fuzz targets); none of these should appear
# on docs.rs. The `--cfg docsrs` flag activates the
# `#[cfg_attr(docsrs, doc(cfg(...)))]` annotations that render feature
# badges on each item.
[]
= ["std", "hash", "ldm", "dict-builder", "lsm"]
= ["--cfg", "docsrs"]
[]
# Locked behind the `hash` feature flag
= { = "2.0", = false, = ["xxhash64"], = true }
= { = "2.3.0", = true }
# Optional sync primitive for the FSE default-table cache on no-atomic
# targets (Cortex-M0/M0+, AVR, MSP430 — anywhere `target_has_atomic =
# "ptr"` is false). When this feature is enabled the cache uses a
# critical-section-protected `static mut` slot; when disabled the
# no-atomic build skips the cache entirely and returns an owned
# `Box<FSETable>` per call, dropped with the owning `FrameCompressor`
# (no leak — same memory shape as the pre-cache status quo on those
# targets). On targets with atomic pointer support (every modern
# desktop / server / mobile / Cortex-M3+ / RISC-V-A target) the dep
# is dead code and never instantiated — those targets use the lock-
# free `AtomicPtr` path unconditionally.
= { = "1.2", = true }
# Internal feature, only used when building as part of libstd, not part of the
# stable interface of this crate.
= { = "0.1.2", = true }
= { = "1.0.0", = true, = "rustc-std-workspace-core" }
= { = "1.0.0", = true, = "rustc-std-workspace-alloc" }
[]
# This library imports zero C bindings. The `zstd` (libzstd) cross-checks,
# the criterion benches, the `dhat` profiling examples, and the FFI parity
# tests all live in the sibling `ffi-bench` crate, which depends on both this
# crate and `zstd`. Only the pure-Rust unit/integration tests run here.
= "0.10"
[]
= [
"hash",
"ldm",
"std",
"kernel-scalar",
"kernel-sse",
"kernel-bmi2",
"kernel-avx2",
# `kernel-vbmi2` (AVX-512) is intentionally OFF by default: on AVX-512
# hosts the runtime dispatch otherwise selects the VBMI2 decode tier, which
# the dashboard's AVX-512 runner measured far SLOWER than the AVX2 tier
# (AVX-512 license-based frequency downclocking stalls the whole decode,
# and the bursty/memory-bound decode never amortizes the heavier kernel).
# With it off, AVX-512 hosts fall back to the AVX2 tier (faster there). The
# kernel is kept and can be opted in via `--features kernel-vbmi2` for a
# sustained-AVX-512 workload that genuinely benefits.
"kernel-neon",
"kernel-sve",
"kernel-simd128",
# Present in `default` so the bundled command-line tool, whose `--train`
# needs it, builds from a plain `cargo install structured-zstd`. It adds
# one small dependency (`fastrand`) and no transitive ones; a build that
# does not want it turns default features off, as `no_std` builds already
# do.
"dict-builder",
]
# Per-CPU-tier kernel selection, covering the decoder and the encoder. The
# default build enables every kernel except `kernel-vbmi2`; with `std`,
# `detect_cpu_kernel()` (decode) and `fastpath::select_kernel()` (encode) pick
# the best tier at runtime — a universal binary that adapts to any CPU. On
# `no_std` the tier is fixed at compile time from `target_feature`, baking
# the chosen ISA into the build; on wasm it is always compile-time, since the
# kernels there additionally require `target_feature = "simd128"`.
# Constrained targets can trim the SIMD trampolines + their
# dispatch arms by disabling the tiers they don't need; the scalar kernel
# is always compiled as the fallback, so the lowest enabled tier always has
# a backstop. Each feature only affects builds for its architecture (a
# `kernel-avx2` flag is inert on aarch64, `kernel-neon` inert on x86), so
# the all-on default is safe everywhere. `kernel-vbmi2` and `kernel-sve` are
# decoder-only: the encoder has no AVX-512 or SVE tier. `kernel-sse` covers
# two encoder tiers, SSE4.2 and a plain-SSE2 fallback for CPUs without it.
# The implication chain mirrors the
# real ISA dependency: AVX2 implies BMI2 implies SSE2; SVE implies NEON.
# `kernel-scalar` is a marker only: the scalar kernel is compiled
# unconditionally (it is the mandatory fallback), so this flag gates no code.
# It exists so the scalar tier can be named explicitly in a feature set; a
# scalar-only build is equivalently `--no-default-features` (no SIMD tier
# enabled) or `--no-default-features --features kernel-scalar`.
= []
= []
= ["kernel-sse"]
= ["kernel-bmi2"]
= ["kernel-avx2"]
= []
= ["kernel-neon"]
# WebAssembly fixed-128-bit SIMD tier (`simd128`). Inert on non-wasm targets
# the same way `kernel-neon` is inert on x86. wasm has no runtime CPU
# detection, so the tier is chosen at compile time from `target_feature =
# "simd128"`; consumers build with `-C target-feature=+simd128`. Covers the
# two 128-bit-class kernels that port directly (row tag-scan, match-copy);
# the 256-bit (AVX2/VBMI2) and scalar-bit-manip (BMI2) kernels have no
# simd128 equivalent and stay scalar on wasm.
= []
= ["std", "dep:fastrand"]
= ["dep:twox-hash"]
# Long-distance matching in the encoder. Implies `hash`: the LDM match finder
# hashes each `min_match_length` window with XXH64. Without it the parameter
# builder still accepts `enable_long_distance_matching(true)` and the frame
# stays valid, but no long-distance matches are produced.
#
# Not to be confused with `lsm` below (storage-format extensions) — the names
# differ by one letter and mean unrelated things.
= ["hash"]
# Opt-in cache for FSE default tables on no-atomic targets. See
# `fse_encoder::default_*_table` for the implementation split. On
# targets with atomic pointer support this feature is a no-op.
= ["dep:critical-section"]
= []
# ---------------------------------------------------------------------------
# Internal features. NOT part of the public API: they widen the crate's
# surface or add diagnostics for this repository's own benches, fuzz targets
# and examples. They carry no stability guarantee and can change or disappear
# in any release, so downstream crates should not enable them. Excluded from
# the docs.rs feature set above for the same reason.
# ---------------------------------------------------------------------------
# Widens the API surface so the benches in `ffi-bench` can reach internals.
# CI enforces that the parity benches do NOT enable it, since the wider
# surface would bias a Rust-vs-C comparison.
= []
# Widens the API surface for the fuzz targets.
= []
# Diagnostic-only: atomic histograms of the match/literal copy shape on the
# decode path (call counts + size buckets + requested-vs-overshoot byte
# totals). Off in every shipping / bench build (zero codegen impact). Enabled
# by the `copy_shape` example to capture the copy-call distribution, which is
# deterministic from the compressed input and therefore architecture-
# independent (only the per-call timing is CPU-tier specific).
= ["std"]
# Diagnostic tracing of the Fast kernel's inner loop — per-iteration state
# dumps gated at compile time so production builds carry zero cost. Runtime
# activation via `STRUCTURED_ZSTD_KERNEL_TRACE=1` env var. Used by the
# `trace_fast_kernel` example for #220 ratio-divergence investigation.
= ["std"]
# Opt-in storage-format extensions: typed Rust APIs that downstream
# storage / wire-format consumers (lsm-tree, future graph stores) can
# layer on top of the spec-mandated zstd decoder behaviour. Default
# off, no C FFI symbols added regardless of this feature's state.
# Currently exposes:
# - expected-field validation setters on `FrameDecoder`
# (`expect_dict_id` / `expect_window_descriptor`) for wire-format
# consumers that need post-AEAD-decrypt sanity checks against a
# pinned `dict_id` / `window_descriptor`.
# - typed `SkippableFrame` builder + `write_skippable_frame` free
# function in `zstd::skippable` for RFC 8878 §3.1 skippable
# frames (16-variant magic + 4-byte LE length + payload).
# Other typed APIs land here over time as bilateral storage-format
# work expands the surface.
= []
# Internal feature, only used when building as part of libstd, not part of the
# stable interface of this crate.
= ["dep:compiler_builtins", "dep:core", "dep:alloc"]
# All benches, integration tests, and FFI diagnostic examples are targets of
# the non-published `ffi-bench` crate (they link the C `zstd` bindings); their
# source files remain under `benches/`, `tests/`, and `examples/` here and are
# referenced from `../ffi-bench/Cargo.toml` via `path`.