diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index b17de4cb0..1c9d6846f 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -3924,17 +3924,7 @@ U32 ZSTD_getCParamsExclusionMask(void) return mask; } -ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams( - const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode) -{ - return ZSTD_rust_params_getCParamsFromCCtxParams( - CCtxParams->compressionLevel, CCtxParams->srcSizeHint, - srcSizeHint, dictSize, (int)mode, - (int)CCtxParams->ldmParams.enableLdm, - ZSTD_LDM_DEFAULT_WINDOW_LOG, CCtxParams->cParams, - (int)CCtxParams->useRowMatchFinder, - ZSTD_getCParamsExclusionMask()); -} +/* ZSTD_getCParamsFromCCtxParams() is implemented directly by Rust. */ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal( const ZSTD_compressionParameters* cParams, diff --git a/rust/src/zstd_compress_params_api.rs b/rust/src/zstd_compress_params_api.rs index 510607655..7afb83e9a 100644 --- a/rust/src/zstd_compress_params_api.rs +++ b/rust/src/zstd_compress_params_api.rs @@ -129,6 +129,7 @@ pub struct ZSTD_CCtx_params { const DEFAULT_CLEVEL: c_int = 3; const NO_CLEVEL: c_int = 0; +const ZSTD_LDM_DEFAULT_WINDOW_LOG: u32 = 27; const PS_AUTO: c_int = 0; const PS_DISABLE: c_int = 2; @@ -204,12 +205,23 @@ pub extern "C" fn ZSTD_rust_isUpdateAuthorized(param: c_int) -> c_int { #[cfg(not(test))] unsafe extern "C" { + fn ZSTD_getCParamsExclusionMask() -> u32; fn ZSTD_rust_cctx_params_is_multithreaded() -> c_int; fn ZSTD_rust_cctx_params_nb_workers_max() -> c_int; fn ZSTD_rust_cctx_params_job_size_min() -> c_int; fn ZSTD_rust_cctx_params_job_size_max() -> c_int; } +#[cfg(not(test))] +fn cparams_exclusion_mask() -> u32 { + unsafe { ZSTD_getCParamsExclusionMask() } +} + +#[cfg(test)] +fn cparams_exclusion_mask() -> u32 { + 0 +} + #[derive(Clone, Copy)] struct BoundsConfig { multithreaded: bool, @@ -582,6 +594,34 @@ pub unsafe extern "C" fn ZSTD_rust_CCtxParams_setZstdParams( unsafe { set_zstd_params_impl(cctx_params, zstd_params) } } +/// Rust implementation of the private `ZSTD_getCParamsFromCCtxParams()` +/// policy leaf. +/// +/// The `ZSTD_CCtx_params` mirror is layout-checked in this module. The +/// exclusion mask remains supplied by C so build-time block-compressor +/// configuration continues to follow the C preprocessor configuration. +#[no_mangle] +pub unsafe extern "C" fn ZSTD_getCParamsFromCCtxParams( + cctx_params: *const ZSTD_CCtx_params, + src_size_hint: u64, + dict_size: usize, + mode: c_int, +) -> ZSTD_compressionParameters { + let cctx_params = unsafe { &*cctx_params }; + ZSTD_rust_params_getCParamsFromCCtxParams( + cctx_params.compressionLevel, + cctx_params.srcSizeHint, + src_size_hint, + dict_size, + mode, + cctx_params.ldmParams.enableLdm, + ZSTD_LDM_DEFAULT_WINDOW_LOG, + cctx_params.cParams, + cctx_params.useRowMatchFinder, + cparams_exclusion_mask(), + ) +} + /// Prepares the parameter subset used by `ZSTD_createCDict_advanced2()`. /// /// The C dictionary allocator remains responsible for allocation and @@ -1334,6 +1374,39 @@ mod tests { ); } + #[test] + fn direct_cparams_projection_matches_the_scalar_policy_leaf() { + let mut storage = MaybeUninit::::zeroed(); + let params = storage.as_mut_ptr(); + + unsafe { + assert_eq!(ZSTD_CCtxParams_init(params, DEFAULT_CLEVEL), 0); + (*params).srcSizeHint = 16 * 1024; + + let expected = ZSTD_rust_params_getCParamsFromCCtxParams( + (*params).compressionLevel, + (*params).srcSizeHint, + ZSTD_CONTENTSIZE_UNKNOWN, + 0, + ZSTD_RUST_CPM_NO_ATTACH_DICT, + (*params).ldmParams.enableLdm, + ZSTD_LDM_DEFAULT_WINDOW_LOG, + (*params).cParams, + (*params).useRowMatchFinder, + 0, + ); + assert_eq!( + ZSTD_getCParamsFromCCtxParams( + params, + ZSTD_CONTENTSIZE_UNKNOWN, + 0, + ZSTD_RUST_CPM_NO_ATTACH_DICT, + ), + expected + ); + } + } + #[test] fn target_c_block_size_predicate_uses_zero_as_the_disable_value() { let mut storage = MaybeUninit::::zeroed();