From 4c6a00722ffe9070362380f0bdf9f393868dd21e Mon Sep 17 00:00:00 2001 From: ddidderr Date: Sat, 18 Jul 2026 05:11:26 +0200 Subject: [PATCH] feat(compress): move parameter update policy to Rust Move ZSTD_isUpdateAuthorized behind the existing Rust parameter API while retaining the C context-stage checks, diagnostics, and mutation flow. Test Plan: - cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression (187 tests) - cargo clippy for library, benches, and tests - make -B -C lib -j2 lib --- lib/compress/zstd_compress.c | 48 +---------------- rust/src/zstd_compress_params_api.rs | 78 ++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 46 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index e41539794..11dbf05c5 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -106,6 +106,7 @@ int ZSTD_rust_cctx_params_is_multithreaded(void); int ZSTD_rust_cctx_params_nb_workers_max(void); int ZSTD_rust_cctx_params_job_size_min(void); int ZSTD_rust_cctx_params_job_size_max(void); +int ZSTD_rust_isUpdateAuthorized(int param); ZSTD_CCtx_params* ZSTD_rust_createCCtxParams(ZSTD_customMem customMem); size_t ZSTD_rust_freeCCtxParams(ZSTD_CCtx_params* params); size_t ZSTD_rust_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, @@ -684,52 +685,7 @@ int ZSTD_rust_cctx_params_job_size_max(void) static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param) { - switch(param) - { - case ZSTD_c_compressionLevel: - case ZSTD_c_hashLog: - case ZSTD_c_chainLog: - case ZSTD_c_searchLog: - case ZSTD_c_minMatch: - case ZSTD_c_targetLength: - case ZSTD_c_strategy: - case ZSTD_c_blockSplitterLevel: - return 1; - - case ZSTD_c_format: - case ZSTD_c_windowLog: - case ZSTD_c_contentSizeFlag: - case ZSTD_c_checksumFlag: - case ZSTD_c_dictIDFlag: - case ZSTD_c_forceMaxWindow : - case ZSTD_c_nbWorkers: - case ZSTD_c_jobSize: - case ZSTD_c_overlapLog: - case ZSTD_c_rsyncable: - case ZSTD_c_enableDedicatedDictSearch: - case ZSTD_c_enableLongDistanceMatching: - case ZSTD_c_ldmHashLog: - case ZSTD_c_ldmMinMatch: - case ZSTD_c_ldmBucketSizeLog: - case ZSTD_c_ldmHashRateLog: - case ZSTD_c_forceAttachDict: - case ZSTD_c_literalCompressionMode: - case ZSTD_c_targetCBlockSize: - case ZSTD_c_srcSizeHint: - case ZSTD_c_stableInBuffer: - case ZSTD_c_stableOutBuffer: - case ZSTD_c_blockDelimiters: - case ZSTD_c_validateSequences: - case ZSTD_c_splitAfterSequences: - case ZSTD_c_useRowMatchFinder: - case ZSTD_c_deterministicRefPrefix: - case ZSTD_c_prefetchCDictTables: - case ZSTD_c_enableSeqProducerFallback: - case ZSTD_c_maxBlockSize: - case ZSTD_c_repcodeResolution: - default: - return 0; - } + return ZSTD_rust_isUpdateAuthorized((int)param); } size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value) diff --git a/rust/src/zstd_compress_params_api.rs b/rust/src/zstd_compress_params_api.rs index 49940bdfe..be28b091e 100644 --- a/rust/src/zstd_compress_params_api.rs +++ b/rust/src/zstd_compress_params_api.rs @@ -176,6 +176,26 @@ const C_MAX_BLOCK_SIZE: c_int = 1015; const C_REPCODE_RESOLUTION: c_int = 1016; const C_BLOCK_SPLITTER_LEVEL: c_int = 1017; +#[inline] +fn is_update_authorized(param: c_int) -> bool { + matches!( + param, + C_COMPRESSION_LEVEL + | C_HASH_LOG + | C_CHAIN_LOG + | C_SEARCH_LOG + | C_MIN_MATCH + | C_TARGET_LENGTH + | C_STRATEGY + | C_BLOCK_SPLITTER_LEVEL + ) +} + +#[no_mangle] +pub extern "C" fn ZSTD_rust_isUpdateAuthorized(param: c_int) -> c_int { + is_update_authorized(param) as c_int +} + #[cfg(not(test))] unsafe extern "C" { fn ZSTD_rust_cctx_params_is_multithreaded() -> c_int; @@ -974,6 +994,64 @@ mod tests { use std::mem::{align_of, offset_of, size_of, MaybeUninit}; use std::sync::atomic::{AtomicUsize, Ordering}; + #[test] + fn update_authorization_matches_the_c_parameter_policy() { + let authorized = [ + C_COMPRESSION_LEVEL, + C_HASH_LOG, + C_CHAIN_LOG, + C_SEARCH_LOG, + C_MIN_MATCH, + C_TARGET_LENGTH, + C_STRATEGY, + C_BLOCK_SPLITTER_LEVEL, + ]; + let unauthorized = [ + C_FORMAT, + C_WINDOW_LOG, + C_CONTENT_SIZE_FLAG, + C_CHECKSUM_FLAG, + C_DICT_ID_FLAG, + C_FORCE_MAX_WINDOW, + C_NB_WORKERS, + C_JOB_SIZE, + C_OVERLAP_LOG, + C_RSYNCABLE, + C_ENABLE_DEDICATED_DICT_SEARCH, + C_ENABLE_LDM, + C_LDM_HASH_LOG, + C_LDM_MIN_MATCH, + C_LDM_BUCKET_SIZE_LOG, + C_LDM_HASH_RATE_LOG, + C_FORCE_ATTACH_DICT, + C_LITERAL_COMPRESSION_MODE, + C_TARGET_C_BLOCK_SIZE, + C_SRC_SIZE_HINT, + C_STABLE_IN_BUFFER, + C_STABLE_OUT_BUFFER, + C_BLOCK_DELIMITERS, + C_VALIDATE_SEQUENCES, + C_SPLIT_AFTER_SEQUENCES, + C_USE_ROW_MATCH_FINDER, + C_DETERMINISTIC_REF_PREFIX, + C_PREFETCH_CDICT_TABLES, + C_ENABLE_SEQ_PRODUCER_FALLBACK, + C_MAX_BLOCK_SIZE, + C_REPCODE_RESOLUTION, + -1, + 1018, + ]; + + for param in authorized { + assert!(is_update_authorized(param)); + assert_eq!(ZSTD_rust_isUpdateAuthorized(param), 1); + } + for param in unauthorized { + assert!(!is_update_authorized(param)); + assert_eq!(ZSTD_rust_isUpdateAuthorized(param), 0); + } + } + #[test] fn private_parameter_mirror_matches_the_c_layout() { let pointer_size = size_of::();