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_resolveExternalRepcodeSearch(int mode, int cLevel);
|
||||||
int ZSTD_rust_params_cdictIndicesAreTagged(ZSTD_compressionParameters cParams);
|
int ZSTD_rust_params_cdictIndicesAreTagged(ZSTD_compressionParameters cParams);
|
||||||
int ZSTD_rust_params_dedicatedDictSearchIsSupported(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.
|
/* CCtx parameter state is mirrored by rust/src/zstd_compress_params_api.rs.
|
||||||
* Rust owns parameter bounds and clamping; C exposes only the
|
* 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_greedy:
|
||||||
case ZSTD_lazy:
|
case ZSTD_lazy:
|
||||||
case ZSTD_lazy2:
|
case ZSTD_lazy2:
|
||||||
cParams.hashLog += ZSTD_LAZY_DDSS_BUCKET_LOG;
|
cParams.hashLog = ZSTD_rust_params_dedicatedDictSearch_getHashLog(cParams.hashLog);
|
||||||
break;
|
break;
|
||||||
case ZSTD_btlazy2:
|
case ZSTD_btlazy2:
|
||||||
case ZSTD_btopt:
|
case ZSTD_btopt:
|
||||||
@@ -5688,10 +5690,7 @@ static void ZSTD_dedicatedDictSearch_revertCParams(
|
|||||||
case ZSTD_greedy:
|
case ZSTD_greedy:
|
||||||
case ZSTD_lazy:
|
case ZSTD_lazy:
|
||||||
case ZSTD_lazy2:
|
case ZSTD_lazy2:
|
||||||
cParams->hashLog -= ZSTD_LAZY_DDSS_BUCKET_LOG;
|
cParams->hashLog = ZSTD_rust_params_dedicatedDictSearch_revertHashLog(cParams->hashLog);
|
||||||
if (cParams->hashLog < ZSTD_HASHLOG_MIN) {
|
|
||||||
cParams->hashLog = ZSTD_HASHLOG_MIN;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case ZSTD_btlazy2:
|
case ZSTD_btlazy2:
|
||||||
case ZSTD_btopt:
|
case ZSTD_btopt:
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ const ZSTD_WINDOWLOG_MAX: c_int = 30;
|
|||||||
const ZSTD_WINDOWLOG_MAX: c_int = 31;
|
const ZSTD_WINDOWLOG_MAX: c_int = 31;
|
||||||
const ZSTD_HASHLOG_MIN: c_int = 6;
|
const ZSTD_HASHLOG_MIN: c_int = 6;
|
||||||
const ZSTD_HASHLOG_MAX: c_int = 30;
|
const ZSTD_HASHLOG_MAX: c_int = 30;
|
||||||
|
const ZSTD_LAZY_DDSS_BUCKET_LOG: u32 = 2;
|
||||||
const ZSTD_CHAINLOG_MIN: c_int = ZSTD_HASHLOG_MIN;
|
const ZSTD_CHAINLOG_MIN: c_int = ZSTD_HASHLOG_MIN;
|
||||||
#[cfg(target_pointer_width = "32")]
|
#[cfg(target_pointer_width = "32")]
|
||||||
const ZSTD_CHAINLOG_MAX: c_int = 29;
|
const ZSTD_CHAINLOG_MAX: c_int = 29;
|
||||||
@@ -439,6 +440,18 @@ fn dedicated_dict_search_is_supported(cparams: ZSTD_compressionParameters) -> bo
|
|||||||
&& cparams.chainLog <= 24
|
&& 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()`.
|
/// C ABI for `ZSTD_CDictIndicesAreTagged()`.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn ZSTD_rust_params_cdictIndicesAreTagged(
|
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_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]
|
#[inline]
|
||||||
fn dict_and_window_log(window_log: u32, src_size: u64, dict_size: u64) -> u32 {
|
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. */
|
/* 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);
|
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]
|
#[test]
|
||||||
fn external_sequence_validation_preserves_its_int_mode() {
|
fn external_sequence_validation_preserves_its_int_mode() {
|
||||||
for mode in [c_int::MIN, -1, 0, 1, c_int::MAX] {
|
for mode in [c_int::MIN, -1, 0, 1, c_int::MAX] {
|
||||||
|
|||||||
Reference in New Issue
Block a user