feat(compress): move dedicated dict param reversion to Rust

Port ZSTD_dedicatedDictSearch_revertCParams to a Rust leaf that accepts and
returns the complete repr(C) compression-parameter struct. Keep the existing
C pointer wrapper and call order before ZSTD_adjustCParams_internal, while
changing only hashLog for greedy, lazy, and lazy2 strategies.

Test Plan:
- cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression
- cargo clippy --manifest-path rust/Cargo.toml --no-default-features --features compression (and --benches/--tests, rerun after fmt)
- cargo +nightly fmt --manifest-path rust/Cargo.toml
- make -B -C lib -j2 lib
- make -B -C tests -j2 fuzzer
- tests/fuzzer -s4560 -t47 -i48 -v
- tests/fuzzer -s4560 -t57 -i1057 -v
- make -B -C tests -j2 test-zstream
- git diff --check
This commit is contained in:
2026-07-18 10:17:53 +02:00
parent ac7683de9f
commit b581042717
2 changed files with 94 additions and 31 deletions
+3 -16
View File
@@ -132,7 +132,8 @@ 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);
ZSTD_compressionParameters
ZSTD_rust_params_dedicatedDictSearch_revertCParams(ZSTD_compressionParameters cParams);
int ZSTD_rust_params_shouldAttachDict(int strategy, int dedicatedDictSearch,
U64 pledgedSrcSize, int attachDictPref,
int forceWindow);
@@ -5678,21 +5679,7 @@ static ZSTD_compressionParameters ZSTD_dedicatedDictSearch_getCParams(int const
*/
static void ZSTD_dedicatedDictSearch_revertCParams(
ZSTD_compressionParameters* cParams) {
switch (cParams->strategy) {
case ZSTD_fast:
case ZSTD_dfast:
break;
case ZSTD_greedy:
case ZSTD_lazy:
case ZSTD_lazy2:
cParams->hashLog = ZSTD_rust_params_dedicatedDictSearch_revertHashLog(cParams->hashLog);
break;
case ZSTD_btlazy2:
case ZSTD_btopt:
case ZSTD_btultra:
case ZSTD_btultra2:
break;
}
*cParams = ZSTD_rust_params_dedicatedDictSearch_revertCParams(*cParams);
}
/*! ZSTD_getCParams_internal() :
+91 -15
View File
@@ -455,6 +455,19 @@ fn dedicated_dict_search_revert_hash_log(hash_log: u32) -> u32 {
.max(ZSTD_HASHLOG_MIN as u32)
}
#[inline]
fn dedicated_dict_search_revert_cparams(
mut cparams: ZSTD_compressionParameters,
) -> ZSTD_compressionParameters {
match cparams.strategy {
ZSTD_GREEDY | ZSTD_LAZY | ZSTD_LAZY2 => {
cparams.hashLog = dedicated_dict_search_revert_hash_log(cparams.hashLog);
}
_ => {}
}
cparams
}
const ATTACH_DICT_SIZE_CUTOFFS: [u64; 10] = [
8 * 1024, /* unused */
8 * 1024, /* ZSTD_fast */
@@ -531,10 +544,12 @@ pub extern "C" fn ZSTD_rust_params_dedicatedDictSearch_getHashLog(hash_log: u32)
dedicated_dict_search_get_hash_log(hash_log)
}
/// C ABI for the hash-log adjustment used by `ZSTD_dedicatedDictSearch_revertCParams()`.
/// C ABI for `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)
pub extern "C" fn ZSTD_rust_params_dedicatedDictSearch_revertCParams(
cparams: ZSTD_compressionParameters,
) -> ZSTD_compressionParameters {
dedicated_dict_search_revert_cparams(cparams)
}
/// C ABI for `ZSTD_shouldAttachDict()`.
@@ -1403,7 +1418,7 @@ mod tests {
assert_eq!(adjusted, if should_adjust { 14 } else { original });
let reverted = if should_adjust {
ZSTD_rust_params_dedicatedDictSearch_revertHashLog(adjusted)
dedicated_dict_search_revert_hash_log(adjusted)
} else {
adjusted
};
@@ -1412,25 +1427,86 @@ mod tests {
assert_eq!(ZSTD_rust_params_dedicatedDictSearch_getHashLog(u32::MAX), 1);
assert_eq!(
ZSTD_rust_params_dedicatedDictSearch_revertHashLog(ZSTD_HASHLOG_MIN as u32),
dedicated_dict_search_revert_hash_log(ZSTD_HASHLOG_MIN as u32),
ZSTD_HASHLOG_MIN as u32
);
assert_eq!(
ZSTD_rust_params_dedicatedDictSearch_revertHashLog(ZSTD_HASHLOG_MIN as u32 + 1),
dedicated_dict_search_revert_hash_log(ZSTD_HASHLOG_MIN as u32 + 1),
ZSTD_HASHLOG_MIN as u32
);
assert_eq!(
ZSTD_rust_params_dedicatedDictSearch_revertHashLog(ZSTD_HASHLOG_MIN as u32 + 2),
dedicated_dict_search_revert_hash_log(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
);
assert_eq!(dedicated_dict_search_revert_hash_log(0), u32::MAX - 1);
assert_eq!(dedicated_dict_search_revert_hash_log(1), u32::MAX);
}
#[test]
fn dedicated_dict_search_revert_cparams_preserves_fields_and_strategy_policy() {
let strategies = [
ZSTD_FAST,
ZSTD_DFAST,
ZSTD_GREEDY,
ZSTD_LAZY,
ZSTD_LAZY2,
ZSTD_BTLAZY2,
ZSTD_BTOPT,
ZSTD_BTULTRA,
ZSTD_BTULTRA2,
-1,
99,
];
for strategy in strategies {
let input = ZSTD_compressionParameters {
windowLog: 21,
chainLog: 19,
hashLog: 12,
searchLog: 5,
minMatch: 4,
targetLength: 48,
strategy,
};
let output = dedicated_dict_search_revert_cparams(input);
let expected_hash_log = if matches!(strategy, ZSTD_GREEDY | ZSTD_LAZY | ZSTD_LAZY2) {
10
} else {
input.hashLog
};
assert_eq!(output.hashLog, expected_hash_log, "strategy {strategy}");
assert_eq!(output.windowLog, input.windowLog, "strategy {strategy}");
assert_eq!(output.chainLog, input.chainLog, "strategy {strategy}");
assert_eq!(output.searchLog, input.searchLog, "strategy {strategy}");
assert_eq!(output.minMatch, input.minMatch, "strategy {strategy}");
assert_eq!(
output.targetLength, input.targetLength,
"strategy {strategy}"
);
assert_eq!(output.strategy, input.strategy, "strategy {strategy}");
}
for strategy in [ZSTD_GREEDY, ZSTD_LAZY, ZSTD_LAZY2] {
let mut input = ZSTD_compressionParameters {
hashLog: ZSTD_HASHLOG_MIN as u32,
strategy,
..ZSTD_compressionParameters::default()
};
assert_eq!(dedicated_dict_search_revert_cparams(input).hashLog, 6);
input.hashLog = 0;
assert_eq!(
dedicated_dict_search_revert_cparams(input).hashLog,
u32::MAX - 1
);
input.hashLog = 1;
assert_eq!(
dedicated_dict_search_revert_cparams(input).hashLog,
u32::MAX
);
}
}
#[test]