From 0a06fa778ccdaddc0d221a79858b70d93eb4ee34 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Sat, 18 Jul 2026 08:40:32 +0200 Subject: [PATCH] feat(compress): move C parameter overrides to Rust The compression-parameter override helper previously lived in C and selectively copied each nonzero field from a caller-provided override structure. Move that pure field-wise operation into the Rust compression-parameter module, while keeping the existing repr(C) structure and pointer-based ABI at both C call sites. Zero-valued overrides continue to leave the current parameter untouched. Test Plan: - `cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression` -- passed (252 tests) - `make -B -C lib -j2 lib` -- passed - `make -C tests -j2 fuzzer` and `tests/fuzzer -s4560 -t47 -i48 -v` -- passed - required clippy passes, nightly fmt, and `git diff --check` -- passed --- lib/compress/zstd_compress.c | 19 ++------ rust/src/zstd_compress_params.rs | 75 ++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 15 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 440845b63..ccf843280 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -104,6 +104,8 @@ size_t ZSTD_rust_params_maxNbSeq(size_t blockSize, U32 minMatch, int useSequenceProducer); size_t ZSTD_rust_params_resolveMaxBlockSize(size_t maxBlockSize); size_t ZSTD_rust_params_getBlockSize(size_t maxBlockSize, U32 windowLog); +void ZSTD_rust_params_overrideCParams(ZSTD_compressionParameters* cParams, + const ZSTD_compressionParameters* overrides); int ZSTD_rust_params_rowMatchFinderSupported(int strategy); int ZSTD_rust_params_rowMatchFinderUsed(int strategy, int mode); int ZSTD_rust_params_resolveRowMatchFinderMode( @@ -1158,19 +1160,6 @@ ZSTD_adjustCParams(ZSTD_compressionParameters cPar, static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode); -static void ZSTD_overrideCParams( - ZSTD_compressionParameters* cParams, - const ZSTD_compressionParameters* overrides) -{ - if (overrides->windowLog) cParams->windowLog = overrides->windowLog; - if (overrides->hashLog) cParams->hashLog = overrides->hashLog; - if (overrides->chainLog) cParams->chainLog = overrides->chainLog; - if (overrides->searchLog) cParams->searchLog = overrides->searchLog; - if (overrides->minMatch) cParams->minMatch = overrides->minMatch; - if (overrides->targetLength) cParams->targetLength = overrides->targetLength; - if (overrides->strategy) cParams->strategy = overrides->strategy; -} - ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) { @@ -1181,7 +1170,7 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( } cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode); if (CCtxParams->ldmParams.enableLdm == ZSTD_ps_enable) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG; - ZSTD_overrideCParams(&cParams, &CCtxParams->cParams); + ZSTD_rust_params_overrideCParams(&cParams, &CCtxParams->cParams); assert(!ZSTD_checkCParams(cParams)); /* srcSizeHint == 0 means 0 */ return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize, mode, CCtxParams->useRowMatchFinder); @@ -4131,7 +4120,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced2( if (cctxParams.enableDedicatedDictSearch) { cParams = ZSTD_dedicatedDictSearch_getCParams( cctxParams.compressionLevel, dictSize); - ZSTD_overrideCParams(&cParams, &cctxParams.cParams); + ZSTD_rust_params_overrideCParams(&cParams, &cctxParams.cParams); } else { cParams = ZSTD_getCParamsFromCCtxParams( &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict); diff --git a/rust/src/zstd_compress_params.rs b/rust/src/zstd_compress_params.rs index a4b9e991d..3e6ec9f7b 100644 --- a/rust/src/zstd_compress_params.rs +++ b/rust/src/zstd_compress_params.rs @@ -905,6 +905,44 @@ fn get_block_size(max_block_size: usize, window_log: u32) -> usize { max_block_size.min(1usize << window_log) } +#[inline] +fn override_cparams( + cparams: &mut ZSTD_compressionParameters, + overrides: &ZSTD_compressionParameters, +) { + if overrides.windowLog != 0 { + cparams.windowLog = overrides.windowLog; + } + if overrides.hashLog != 0 { + cparams.hashLog = overrides.hashLog; + } + if overrides.chainLog != 0 { + cparams.chainLog = overrides.chainLog; + } + if overrides.searchLog != 0 { + cparams.searchLog = overrides.searchLog; + } + if overrides.minMatch != 0 { + cparams.minMatch = overrides.minMatch; + } + if overrides.targetLength != 0 { + cparams.targetLength = overrides.targetLength; + } + if overrides.strategy != 0 { + cparams.strategy = overrides.strategy; + } +} + +/// Pure leaf for the private `ZSTD_overrideCParams()` helper. +#[no_mangle] +pub unsafe extern "C" fn ZSTD_rust_params_overrideCParams( + cparams: *mut ZSTD_compressionParameters, + overrides: *const ZSTD_compressionParameters, +) { + let (cparams, overrides) = unsafe { (&mut *cparams, &*overrides) }; + override_cparams(cparams, overrides); +} + /// Pure leaf for the deprecated `ZSTD_getBlockSize()` path. #[no_mangle] pub extern "C" fn ZSTD_rust_params_getBlockSize(maxBlockSize: usize, windowLog: u32) -> usize { @@ -1337,4 +1375,41 @@ mod tests { assert_eq!(ZSTD_rust_params_getBlockSize(128 * 1024, 16), 64 * 1024); assert_eq!(ZSTD_rust_params_getBlockSize(128 * 1024, 17), 128 * 1024); } + + #[test] + fn cparam_overrides_replace_only_nonzero_fields() { + let mut cparams = ZSTD_compressionParameters { + windowLog: 10, + chainLog: 11, + hashLog: 12, + searchLog: 13, + minMatch: 14, + targetLength: 15, + strategy: 16, + }; + let overrides = ZSTD_compressionParameters { + windowLog: 20, + chainLog: 0, + hashLog: 22, + searchLog: 0, + minMatch: 24, + targetLength: 0, + strategy: 26, + }; + + unsafe { ZSTD_rust_params_overrideCParams(&mut cparams, &overrides) }; + + assert_eq!( + cparams, + ZSTD_compressionParameters { + windowLog: 20, + chainLog: 11, + hashLog: 22, + searchLog: 13, + minMatch: 24, + targetLength: 15, + strategy: 26, + } + ); + } }