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:
@@ -122,6 +122,8 @@ int ZSTD_rust_params_resolveEnableLdm(
|
||||
int ZSTD_rust_params_resolveExternalRepcodeSearch(int mode, int cLevel);
|
||||
int ZSTD_rust_params_cdictIndicesAreTagged(ZSTD_compressionParameters cParams);
|
||||
int ZSTD_rust_params_dedicatedDictSearchIsSupported(ZSTD_compressionParameters cParams);
|
||||
U32 ZSTD_rust_params_dedicatedDictSearch_getHashLog(U32 hashLog);
|
||||
U32 ZSTD_rust_params_dedicatedDictSearch_revertHashLog(U32 hashLog);
|
||||
|
||||
/* CCtx parameter state is mirrored by rust/src/zstd_compress_params_api.rs.
|
||||
* Rust owns parameter bounds and clamping; C exposes only the
|
||||
@@ -5663,7 +5665,7 @@ static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const
|
||||
case ZSTD_greedy:
|
||||
case ZSTD_lazy:
|
||||
case ZSTD_lazy2:
|
||||
cParams.hashLog += ZSTD_LAZY_DDSS_BUCKET_LOG;
|
||||
cParams.hashLog = ZSTD_rust_params_dedicatedDictSearch_getHashLog(cParams.hashLog);
|
||||
break;
|
||||
case ZSTD_btlazy2:
|
||||
case ZSTD_btopt:
|
||||
@@ -5688,10 +5690,7 @@ static void ZSTD_dedicatedDictSearch_revertCParams(
|
||||
case ZSTD_greedy:
|
||||
case ZSTD_lazy:
|
||||
case ZSTD_lazy2:
|
||||
cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG;
|
||||
if (cParams->hashLog < ZSTD_HASHLOG_MIN) {
|
||||
cParams->hashLog = ZSTD_HASHLOG_MIN;
|
||||
}
|
||||
cParams->hashLog = ZSTD_rust_params_dedicatedDictSearch_revertHashLog(cParams->hashLog);
|
||||
break;
|
||||
case ZSTD_btlazy2:
|
||||
case ZSTD_btopt:
|
||||
|
||||
@@ -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] {
|
||||
|
||||
Reference in New Issue
Block a user