feat(compress): move literal compression policy to Rust
ZSTD_literalsCompressionIsDisabled() previously switched on the private ZSTD_CCtx_params layout in a header inline helper. Replace that switch with a scalar ABI call that extracts only literalCompressionMode, strategy, and targetLength in C. The Rust helper preserves the enable and disable results, the fast-strategy auto rule, and C's debug assertion plus release fallthrough for invalid modes. Keep callers and compression state ownership in C, and cover the policy truth table and debug invalid-mode invariant in Rust. Test Plan: - Compression-feature clippy for the library, benches, and tests before and after nightly formatting -- passed. - `cargo +nightly fmt --manifest-path rust/Cargo.toml` -- passed. - `cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression zstd_compress_params` -- passed (43 tests). - `make -B -C lib -j2 lib` -- passed. - `make -C tests test-rust-lib-smoke` -- passed. - `tests/fuzzer -s4560 -t47 -i48 -v` and `-s4560 -t56 -i57 -v` -- passed. - `make -C tests -j2 test-zstream` -- passed (84 named, 5,416, and 8,387 randomized cases). - `git diff --check` and `git diff --cached --check` -- passed.
This commit is contained in:
@@ -668,19 +668,16 @@ MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
|
||||
return (srcSize >> minlog) + 2;
|
||||
}
|
||||
|
||||
int ZSTD_rust_params_literalsCompressionIsDisabled(int literalCompressionMode,
|
||||
int strategy,
|
||||
U32 targetLength);
|
||||
|
||||
MEM_STATIC int ZSTD_literalsCompressionIsDisabled(const ZSTD_CCtx_params* cctxParams)
|
||||
{
|
||||
switch (cctxParams->literalCompressionMode) {
|
||||
case ZSTD_ps_enable:
|
||||
return 0;
|
||||
case ZSTD_ps_disable:
|
||||
return 1;
|
||||
default:
|
||||
assert(0 /* impossible: pre-validated */);
|
||||
ZSTD_FALLTHROUGH;
|
||||
case ZSTD_ps_auto:
|
||||
return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
|
||||
}
|
||||
return ZSTD_rust_params_literalsCompressionIsDisabled(
|
||||
(int)cctxParams->literalCompressionMode,
|
||||
(int)cctxParams->cParams.strategy,
|
||||
cctxParams->cParams.targetLength);
|
||||
}
|
||||
|
||||
/*! ZSTD_safecopyLiterals() :
|
||||
|
||||
@@ -449,6 +449,37 @@ pub extern "C" fn ZSTD_rust_params_resolveExternalSequenceValidation(mode: c_int
|
||||
resolve_external_sequence_validation(mode)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn literals_compression_is_disabled(
|
||||
literal_compression_mode: c_int,
|
||||
strategy: c_int,
|
||||
target_length: u32,
|
||||
) -> c_int {
|
||||
match literal_compression_mode {
|
||||
ZSTD_RUST_PS_ENABLE => 0,
|
||||
ZSTD_RUST_PS_DISABLE => 1,
|
||||
ZSTD_RUST_PS_AUTO => c_int::from(strategy == ZSTD_FAST && target_length > 0),
|
||||
_ => {
|
||||
debug_assert!(false, "invalid ZSTD_ParamSwitch_e literal mode");
|
||||
c_int::from(strategy == ZSTD_FAST && target_length > 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// C ABI for `ZSTD_literalsCompressionIsDisabled()`.
|
||||
///
|
||||
/// The C wrapper extracts these scalar fields so the private
|
||||
/// `ZSTD_CCtx_params` layout does not cross the Rust boundary. Invalid modes
|
||||
/// retain C's debug assertion and release-mode fallthrough to the auto policy.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ZSTD_rust_params_literalsCompressionIsDisabled(
|
||||
literal_compression_mode: c_int,
|
||||
strategy: c_int,
|
||||
target_length: u32,
|
||||
) -> c_int {
|
||||
literals_compression_is_disabled(literal_compression_mode, strategy, target_length)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn cdict_indices_are_tagged(cparams: ZSTD_compressionParameters) -> bool {
|
||||
cparams.strategy == ZSTD_FAST || cparams.strategy == ZSTD_DFAST
|
||||
@@ -1835,6 +1866,45 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn literal_compression_policy_matches_mode_strategy_and_target_length() {
|
||||
for strategy in [ZSTD_FAST, ZSTD_DFAST, ZSTD_BTULTRA2] {
|
||||
for target_length in [0, 1] {
|
||||
assert_eq!(
|
||||
ZSTD_rust_params_literalsCompressionIsDisabled(
|
||||
ZSTD_RUST_PS_ENABLE,
|
||||
strategy,
|
||||
target_length,
|
||||
),
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
ZSTD_rust_params_literalsCompressionIsDisabled(
|
||||
ZSTD_RUST_PS_DISABLE,
|
||||
strategy,
|
||||
target_length,
|
||||
),
|
||||
1
|
||||
);
|
||||
assert_eq!(
|
||||
ZSTD_rust_params_literalsCompressionIsDisabled(
|
||||
ZSTD_RUST_PS_AUTO,
|
||||
strategy,
|
||||
target_length,
|
||||
),
|
||||
c_int::from(strategy == ZSTD_FAST && target_length > 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn literal_compression_policy_rejects_invalid_mode_in_debug() {
|
||||
literals_compression_is_disabled(99, ZSTD_FAST, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn level_tables_match_representative_clevels_entries() {
|
||||
let large = select_cparams(3, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_RUST_CPM_UNKNOWN);
|
||||
|
||||
Reference in New Issue
Block a user