feat(compress): move CParamMode policy to Rust

Keep C responsible for extracting the cdict and CCtx scalar fields while
moving the attach-versus-copy mode decision into the Rust parameter module.
The Rust ABI short-circuits absent cdicts and reuses the established
attachment predicate, preserving unknown-size, force-attach, force-copy, and
force-window behavior.

Test Plan:
- cargo test --manifest-path rust/Cargo.toml --no-default-features
  --features compression
  cparam_mode_preserves_cdict_presence_and_attachment_policy -- passed
- make -B -C lib -j2 lib -- passed
- make -C tests -j2 fuzzer -- passed
- ./tests/fuzzer -s4560 -t47 -i48 -v -- passed
- Required clippy normal/benches/tests, nightly fmt, and diff checks -- passed
This commit is contained in:
2026-07-18 09:42:58 +02:00
parent 527cf01031
commit 3c51a97814
2 changed files with 108 additions and 4 deletions
+93
View File
@@ -485,6 +485,30 @@ fn should_attach_dict(
&& force_window == 0)
}
#[inline]
fn get_cparam_mode(
cdict_present: c_int,
cdict_strategy: c_int,
cdict_dedicated_search: c_int,
pledged_src_size: u64,
params_attach_dict_pref: c_int,
params_force_window: c_int,
) -> c_int {
if cdict_present != 0
&& should_attach_dict(
cdict_strategy,
cdict_dedicated_search,
pledged_src_size,
params_attach_dict_pref,
params_force_window,
)
{
ZSTD_RUST_CPM_ATTACH_DICT
} else {
ZSTD_RUST_CPM_NO_ATTACH_DICT
}
}
/// C ABI for `ZSTD_CDictIndicesAreTagged()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_cdictIndicesAreTagged(
@@ -531,6 +555,26 @@ pub extern "C" fn ZSTD_rust_params_shouldAttachDict(
))
}
/// C ABI for `ZSTD_getCParamMode()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_getCParamMode(
cdict_present: c_int,
cdict_strategy: c_int,
cdict_dedicated_search: c_int,
pledged_src_size: u64,
params_attach_dict_pref: c_int,
params_force_window: c_int,
) -> c_int {
get_cparam_mode(
cdict_present,
cdict_strategy,
cdict_dedicated_search,
pledged_src_size,
params_attach_dict_pref,
params_force_window,
)
}
#[inline]
fn dict_and_window_log(window_log: u32, src_size: u64, dict_size: u64) -> u32 {
/* 1ULL << ZSTD_WINDOWLOG_MAX, which is smaller for 32-bit builds. */
@@ -1468,6 +1512,55 @@ mod tests {
);
}
#[test]
fn cparam_mode_preserves_cdict_presence_and_attachment_policy() {
assert_eq!(
ZSTD_rust_params_getCParamMode(0, ZSTD_FAST, 0, 1, ZSTD_DICT_FORCE_ATTACH, 0,),
ZSTD_RUST_CPM_NO_ATTACH_DICT
);
assert_eq!(
ZSTD_rust_params_getCParamMode(1, ZSTD_FAST, 0, 8 * 1024, 0, 0),
ZSTD_RUST_CPM_ATTACH_DICT
);
assert_eq!(
ZSTD_rust_params_getCParamMode(
1,
ZSTD_FAST,
0,
8 * 1024 + 1,
ZSTD_DICT_FORCE_ATTACH,
0,
),
ZSTD_RUST_CPM_ATTACH_DICT
);
assert_eq!(
ZSTD_rust_params_getCParamMode(
1,
ZSTD_FAST,
0,
ZSTD_CONTENTSIZE_UNKNOWN,
ZSTD_DICT_FORCE_COPY,
0,
),
ZSTD_RUST_CPM_NO_ATTACH_DICT
);
assert_eq!(
ZSTD_rust_params_getCParamMode(1, ZSTD_FAST, 0, ZSTD_CONTENTSIZE_UNKNOWN, 0, 0,),
ZSTD_RUST_CPM_ATTACH_DICT
);
assert_eq!(
ZSTD_rust_params_getCParamMode(
1,
ZSTD_FAST,
0,
ZSTD_CONTENTSIZE_UNKNOWN,
ZSTD_DICT_FORCE_ATTACH,
1,
),
ZSTD_RUST_CPM_NO_ATTACH_DICT
);
}
#[test]
fn external_sequence_validation_preserves_its_int_mode() {
for mode in [c_int::MIN, -1, 0, 1, c_int::MAX] {