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.
This commit is contained in:
2026-07-20 10:21:46 +02:00
parent 7692f7a6c5
commit 2e0afa9c7d
2 changed files with 83 additions and 13 deletions
+6 -12
View File
@@ -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;
}
+77 -1
View File
@@ -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::<ZSTD_CCtx_params>::zeroed();
let params = storage.as_mut_ptr();
unsafe {
(*params).format = 1;
(*params).customMem.opaque = ptr::dangling_mut::<c_void>();
(*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 = [