From 2e0afa9c7d614f7da14f16d882a346786602affd Mon Sep 17 00:00:00 2001 From: ddidderr Date: Mon, 20 Jul 2026 10:21:46 +0200 Subject: [PATCH] refactor(compress): move CCtx construction policy to Rust Move reset, parameter copy, and default policy resolution from ZSTD_makeCCtxParamsFromCParams into Rust through a pointer-based ABI function. Keep the private LDM adjustment and its invariants in C while Rust owns the stable parameter-object policy and focused reset/resolution coverage. Test Plan: - worker git diff and capped format checks - parent capped root clippy and native build - parent capped upstream make -j1 -C tests test - parent capped CLI clippy and tests All parent verification is serial under a 40 GiB virtual-memory cap. Standalone root Rust unit linking remains unavailable because the crate imports C-owned bridge symbols. --- lib/compress/zstd_compress.c | 18 +++---- rust/src/zstd_compress_params_api.rs | 78 +++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 13 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 3436462b6..4043e1a1a 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2015,6 +2015,9 @@ int ZSTD_rust_cctx_params_job_size_min(void); int ZSTD_rust_cctx_params_job_size_max(void); ZSTD_CCtx_params* ZSTD_rust_createCCtxParams(ZSTD_customMem customMem); size_t ZSTD_rust_freeCCtxParams(ZSTD_CCtx_params* params); +void ZSTD_rust_makeCCtxParamsFromCParams( + ZSTD_CCtx_params* cctxParams, + const ZSTD_compressionParameters* cParams); void ZSTD_rust_CCtxParams_init_internal( ZSTD_CCtx_params* cctxParams, const ZSTD_parameters* params, int compressionLevel); @@ -3615,23 +3618,14 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams( ZSTD_compressionParameters cParams) { ZSTD_CCtx_params cctxParams; - /* should not matter, as all cParams are presumed properly defined */ - ZSTD_CCtxParams_init(&cctxParams, ZSTD_CLEVEL_DEFAULT); - cctxParams.cParams = cParams; - - /* Adjust advanced params according to cParams */ - cctxParams.ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams.ldmParams.enableLdm, &cParams); + /* Rust owns reset, copy, and default policy. Keep the C LDM adapter and + * assertions here because they depend on the private C parameter type. */ + ZSTD_rust_makeCCtxParamsFromCParams(&cctxParams, &cParams); if (cctxParams.ldmParams.enableLdm == ZSTD_ps_enable) { ZSTD_ldm_adjustParameters(&cctxParams.ldmParams, &cParams); assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog); assert(cctxParams.ldmParams.hashRateLog < 32); } - cctxParams.postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.postBlockSplitter, &cParams); - cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams); - cctxParams.validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams.validateSequences); - cctxParams.maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams.maxBlockSize); - cctxParams.searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams.searchForExternalRepcodes, - cctxParams.compressionLevel); assert(!ZSTD_checkCParams(cParams)); return cctxParams; } diff --git a/rust/src/zstd_compress_params_api.rs b/rust/src/zstd_compress_params_api.rs index 6cba51b58..a190c48f6 100644 --- a/rust/src/zstd_compress_params_api.rs +++ b/rust/src/zstd_compress_params_api.rs @@ -17,7 +17,8 @@ use crate::zstd_compress_params::{ ZSTD_rust_params_checkCParams, ZSTD_rust_params_dedicatedDictSearchIsSupported, ZSTD_rust_params_dedicatedDictSearch_getCParams, ZSTD_rust_params_getBounds, ZSTD_rust_params_getCParamsFromCCtxParams, ZSTD_rust_params_getCParamsInternal, - ZSTD_rust_params_overrideCParams, ZSTD_rust_params_resolveExternalRepcodeSearch, + ZSTD_rust_params_overrideCParams, ZSTD_rust_params_resolveBlockSplitterMode, + ZSTD_rust_params_resolveEnableLdm, ZSTD_rust_params_resolveExternalRepcodeSearch, ZSTD_rust_params_resolveExternalSequenceValidation, ZSTD_rust_params_resolveMaxBlockSize, ZSTD_rust_params_resolveRowMatchFinderMode, ZSTD_CONTENTSIZE_UNKNOWN, ZSTD_RUST_CPM_CREATE_CDICT, ZSTD_RUST_PS_AUTO, ZSTD_RUST_PS_DISABLE, ZSTD_RUST_PS_ENABLE, @@ -462,6 +463,43 @@ pub unsafe extern "C" fn ZSTD_rust_CCtxParams_init_internal( unsafe { init_internal_impl(cctx_params, zstd_params, compression_level) } } +unsafe fn make_cctx_params_from_cparams_impl( + cctx_params: *mut ZSTD_CCtx_params, + cparams: *const ZSTD_compressionParameters, +) { + unsafe { + let _ = init_impl(cctx_params, DEFAULT_CLEVEL); + (*cctx_params).cParams = *cparams; + (*cctx_params).ldmParams.enableLdm = + ZSTD_rust_params_resolveEnableLdm(ZSTD_RUST_PS_AUTO, *cparams); + (*cctx_params).postBlockSplitter = + ZSTD_rust_params_resolveBlockSplitterMode(ZSTD_RUST_PS_AUTO, *cparams); + (*cctx_params).useRowMatchFinder = + ZSTD_rust_params_resolveRowMatchFinderMode(ZSTD_RUST_PS_AUTO, *cparams); + (*cctx_params).validateSequences = + ZSTD_rust_params_resolveExternalSequenceValidation((*cctx_params).validateSequences); + (*cctx_params).maxBlockSize = + ZSTD_rust_params_resolveMaxBlockSize((*cctx_params).maxBlockSize); + (*cctx_params).searchForExternalRepcodes = ZSTD_rust_params_resolveExternalRepcodeSearch( + (*cctx_params).searchForExternalRepcodes, + (*cctx_params).compressionLevel, + ); + } +} + +/// Builds the context parameters used by the C size-estimation adapters. +/// +/// The output is written through a pointer so the private `repr(C)` object is +/// never returned by value across the language boundary. C retains LDM +/// parameter adjustment and validation assertions around this policy leaf. +#[no_mangle] +pub unsafe extern "C" fn ZSTD_rust_makeCCtxParamsFromCParams( + cctx_params: *mut ZSTD_CCtx_params, + cparams: *const ZSTD_compressionParameters, +) { + unsafe { make_cctx_params_from_cparams_impl(cctx_params, cparams) } +} + #[inline] fn resolve_row_match_finder(cparams: ZSTD_compressionParameters) -> c_int { if (STRATEGY_GREEDY..=STRATEGY_LAZY2).contains(&cparams.strategy) && cparams.windowLog > 14 { @@ -1564,6 +1602,44 @@ mod tests { } } + #[test] + fn make_cctx_params_from_cparams_resets_and_resolves_defaults() { + let cparams = ZSTD_compressionParameters { + windowLog: 27, + chainLog: 27, + hashLog: 25, + searchLog: 9, + minMatch: 4, + targetLength: 32, + strategy: STRATEGY_BTOPT, + }; + let mut storage = MaybeUninit::::zeroed(); + let params = storage.as_mut_ptr(); + + unsafe { + (*params).format = 1; + (*params).customMem.opaque = ptr::dangling_mut::(); + (*params).ldmParams.hashLog = 99; + + ZSTD_rust_makeCCtxParamsFromCParams(params, &cparams); + + assert_eq!((*params).cParams, cparams); + assert_eq!((*params).compressionLevel, DEFAULT_CLEVEL); + assert_eq!((*params).fParams.contentSizeFlag, 1); + assert_eq!((*params).fParams.checksumFlag, 0); + assert_eq!((*params).fParams.noDictIDFlag, 0); + assert_eq!((*params).ldmParams.enableLdm, ZSTD_RUST_PS_ENABLE); + assert_eq!((*params).ldmParams.hashLog, 0); + assert_eq!((*params).postBlockSplitter, ZSTD_RUST_PS_ENABLE); + assert_eq!((*params).useRowMatchFinder, ZSTD_RUST_PS_DISABLE); + assert_eq!((*params).validateSequences, 0); + assert_eq!((*params).maxBlockSize, BLOCKSIZE_MAX); + assert_eq!((*params).searchForExternalRepcodes, ZSTD_RUST_PS_DISABLE); + assert_eq!((*params).format, 0); + assert!((*params).customMem.opaque.is_null()); + } + } + #[test] fn advanced_init_resolves_policy_and_resets_internal_fields() { let cases = [