feat(compress): move dedicated dict hash-log transforms to Rust

Keep dedicated-dictionary strategy dispatch, parameter selection, and call-site
control flow in C while routing only the hashLog field transformations through
scalar Rust ABI helpers. The helpers use wrapping u32 arithmetic so overflow
and the existing subtract-then-clamp behavior remain identical to C.

Test Plan:
- `cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression dedicated_dict_search_hash_log_adjustments_match_strategy_cases` -- passed
- `make -B -C lib -j2 lib` -- passed
- `make -C tests -j2 fuzzer` -- passed
- `./tests/fuzzer -s4560 -t47 -i48 -v` -- passed
- clippy normal, benches, and tests before and after formatting -- passed
- `cargo +nightly fmt --manifest-path rust/Cargo.toml` and `git diff --check` -- passed
This commit is contained in:
2026-07-18 09:13:36 +02:00
parent c86d18be81
commit ae9667052a
2 changed files with 84 additions and 5 deletions
+80
View File
@@ -32,6 +32,7 @@ const ZSTD_WINDOWLOG_MAX: c_int = 30;
const ZSTD_WINDOWLOG_MAX: c_int = 31;
const ZSTD_HASHLOG_MIN: c_int = 6;
const ZSTD_HASHLOG_MAX: c_int = 30;
const ZSTD_LAZY_DDSS_BUCKET_LOG: u32 = 2;
const ZSTD_CHAINLOG_MIN: c_int = ZSTD_HASHLOG_MIN;
#[cfg(target_pointer_width = "32")]
const ZSTD_CHAINLOG_MAX: c_int = 29;
@@ -439,6 +440,18 @@ fn dedicated_dict_search_is_supported(cparams: ZSTD_compressionParameters) -> bo
&& cparams.chainLog <= 24
}
#[inline]
fn dedicated_dict_search_get_hash_log(hash_log: u32) -> u32 {
hash_log.wrapping_add(ZSTD_LAZY_DDSS_BUCKET_LOG)
}
#[inline]
fn dedicated_dict_search_revert_hash_log(hash_log: u32) -> u32 {
hash_log
.wrapping_sub(ZSTD_LAZY_DDSS_BUCKET_LOG)
.max(ZSTD_HASHLOG_MIN as u32)
}
/// C ABI for `ZSTD_CDictIndicesAreTagged()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_cdictIndicesAreTagged(
@@ -455,6 +468,18 @@ pub extern "C" fn ZSTD_rust_params_dedicatedDictSearchIsSupported(
c_int::from(dedicated_dict_search_is_supported(cparams))
}
/// C ABI for the hash-log adjustment used by `ZSTD_dedicatedDictSearch_getCParams()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_dedicatedDictSearch_getHashLog(hash_log: u32) -> u32 {
dedicated_dict_search_get_hash_log(hash_log)
}
/// C ABI for the hash-log adjustment used by `ZSTD_dedicatedDictSearch_revertCParams()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_dedicatedDictSearch_revertHashLog(hash_log: u32) -> u32 {
dedicated_dict_search_revert_hash_log(hash_log)
}
#[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. */
@@ -1258,6 +1283,61 @@ mod tests {
assert_eq!(supported(ZSTD_LAZY2, 25, 26), 0);
}
#[test]
fn dedicated_dict_search_hash_log_adjustments_match_strategy_cases() {
let strategies = [
ZSTD_FAST,
ZSTD_DFAST,
ZSTD_GREEDY,
ZSTD_LAZY,
ZSTD_LAZY2,
ZSTD_BTLAZY2,
ZSTD_BTOPT,
ZSTD_BTULTRA,
ZSTD_BTULTRA2,
];
for strategy in strategies {
let should_adjust = matches!(strategy, ZSTD_GREEDY | ZSTD_LAZY | ZSTD_LAZY2);
let original = 12;
let adjusted = if should_adjust {
ZSTD_rust_params_dedicatedDictSearch_getHashLog(original)
} else {
original
};
assert_eq!(adjusted, if should_adjust { 14 } else { original });
let reverted = if should_adjust {
ZSTD_rust_params_dedicatedDictSearch_revertHashLog(adjusted)
} else {
adjusted
};
assert_eq!(reverted, original);
}
assert_eq!(ZSTD_rust_params_dedicatedDictSearch_getHashLog(u32::MAX), 1);
assert_eq!(
ZSTD_rust_params_dedicatedDictSearch_revertHashLog(ZSTD_HASHLOG_MIN as u32),
ZSTD_HASHLOG_MIN as u32
);
assert_eq!(
ZSTD_rust_params_dedicatedDictSearch_revertHashLog(ZSTD_HASHLOG_MIN as u32 + 1),
ZSTD_HASHLOG_MIN as u32
);
assert_eq!(
ZSTD_rust_params_dedicatedDictSearch_revertHashLog(ZSTD_HASHLOG_MIN as u32 + 2),
ZSTD_HASHLOG_MIN as u32
);
assert_eq!(
ZSTD_rust_params_dedicatedDictSearch_revertHashLog(0),
u32::MAX - 1
);
assert_eq!(
ZSTD_rust_params_dedicatedDictSearch_revertHashLog(1),
u32::MAX
);
}
#[test]
fn external_sequence_validation_preserves_its_int_mode() {
for mode in [c_int::MIN, -1, 0, 1, c_int::MAX] {