From b5810427175d1954b96f4caeea973f7f06f75ce3 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Sat, 18 Jul 2026 10:17:53 +0200 Subject: [PATCH] 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 --- lib/compress/zstd_compress.c | 19 +----- rust/src/zstd_compress_params.rs | 106 ++++++++++++++++++++++++++----- 2 files changed, 94 insertions(+), 31 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index ac7067ba8..fd51c0f10 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -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() : diff --git a/rust/src/zstd_compress_params.rs b/rust/src/zstd_compress_params.rs index 1ff5be9b0..29aa190b8 100644 --- a/rust/src/zstd_compress_params.rs +++ b/rust/src/zstd_compress_params.rs @@ -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]