feat(compress): move CCtx parameter bounds to Rust
Route public CCtx parameter bounds through the Rust policy implementation while keeping build-specific MT limits supplied by the C configuration. Preserve clamping and validation behavior for migrated parameters and add focused Rust coverage. Test Plan: cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression; cargo clippy --manifest-path rust/Cargo.toml; cargo clippy --manifest-path rust/Cargo.toml --benches; cargo clippy --manifest-path rust/Cargo.toml --tests; make -B -C lib -j2 lib; make -B -C tests -j2 test-cli-tests; make -B -C tests -j2 test-zstream
This commit is contained in:
+24
-212
@@ -81,12 +81,15 @@ size_t ZSTD_rust_params_maxNbSeq(size_t blockSize, U32 minMatch,
|
||||
size_t ZSTD_rust_params_resolveMaxBlockSize(size_t maxBlockSize);
|
||||
|
||||
/* CCtx parameter state is mirrored by rust/src/zstd_compress_params_api.rs.
|
||||
* Keep bounds and build-configuration policy in C, and expose only the
|
||||
* private helpers required by that Rust ABI implementation. */
|
||||
* Rust owns parameter bounds and clamping; C exposes only the
|
||||
* build-configuration values required by that narrow ABI. */
|
||||
ZSTD_bounds ZSTD_rust_cctx_params_get_bounds(int param);
|
||||
size_t ZSTD_rust_cctx_params_clamp_bounds(int param, int* value);
|
||||
int ZSTD_rust_cctx_params_within_bounds(int param, int value);
|
||||
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);
|
||||
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,
|
||||
@@ -600,216 +603,7 @@ static void ZSTD_CCtxParams_setZstdParams(
|
||||
|
||||
ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
|
||||
{
|
||||
ZSTD_bounds bounds = { 0, 0, 0 };
|
||||
|
||||
switch(param)
|
||||
{
|
||||
/* The compression level and the seven core compression parameters are
|
||||
* bounded by the Rust leaf. */
|
||||
case ZSTD_c_compressionLevel:
|
||||
case ZSTD_c_windowLog:
|
||||
case ZSTD_c_hashLog:
|
||||
case ZSTD_c_chainLog:
|
||||
case ZSTD_c_searchLog:
|
||||
case ZSTD_c_minMatch:
|
||||
case ZSTD_c_targetLength:
|
||||
case ZSTD_c_strategy:
|
||||
return ZSTD_rust_params_getBounds((int)param);
|
||||
|
||||
case ZSTD_c_contentSizeFlag:
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = 1;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_checksumFlag:
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = 1;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_dictIDFlag:
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = 1;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_nbWorkers:
|
||||
bounds.lowerBound = 0;
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
bounds.upperBound = ZSTDMT_NBWORKERS_MAX;
|
||||
#else
|
||||
bounds.upperBound = 0;
|
||||
#endif
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_jobSize:
|
||||
bounds.lowerBound = 0;
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
bounds.upperBound = ZSTDMT_JOBSIZE_MAX;
|
||||
#else
|
||||
bounds.upperBound = 0;
|
||||
#endif
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_overlapLog:
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
bounds.lowerBound = ZSTD_OVERLAPLOG_MIN;
|
||||
bounds.upperBound = ZSTD_OVERLAPLOG_MAX;
|
||||
#else
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = 0;
|
||||
#endif
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_enableDedicatedDictSearch:
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = 1;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_enableLongDistanceMatching:
|
||||
bounds.lowerBound = (int)ZSTD_ps_auto;
|
||||
bounds.upperBound = (int)ZSTD_ps_disable;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_ldmHashLog:
|
||||
bounds.lowerBound = ZSTD_LDM_HASHLOG_MIN;
|
||||
bounds.upperBound = ZSTD_LDM_HASHLOG_MAX;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_ldmMinMatch:
|
||||
bounds.lowerBound = ZSTD_LDM_MINMATCH_MIN;
|
||||
bounds.upperBound = ZSTD_LDM_MINMATCH_MAX;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_ldmBucketSizeLog:
|
||||
bounds.lowerBound = ZSTD_LDM_BUCKETSIZELOG_MIN;
|
||||
bounds.upperBound = ZSTD_LDM_BUCKETSIZELOG_MAX;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_ldmHashRateLog:
|
||||
bounds.lowerBound = ZSTD_LDM_HASHRATELOG_MIN;
|
||||
bounds.upperBound = ZSTD_LDM_HASHRATELOG_MAX;
|
||||
return bounds;
|
||||
|
||||
/* experimental parameters */
|
||||
case ZSTD_c_rsyncable:
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = 1;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_forceMaxWindow :
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = 1;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_format:
|
||||
ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);
|
||||
bounds.lowerBound = ZSTD_f_zstd1;
|
||||
bounds.upperBound = ZSTD_f_zstd1_magicless; /* note : how to ensure at compile time that this is the highest value enum ? */
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_forceAttachDict:
|
||||
ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceLoad);
|
||||
bounds.lowerBound = ZSTD_dictDefaultAttach;
|
||||
bounds.upperBound = ZSTD_dictForceLoad; /* note : how to ensure at compile time that this is the highest value enum ? */
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_literalCompressionMode:
|
||||
ZSTD_STATIC_ASSERT(ZSTD_ps_auto < ZSTD_ps_enable && ZSTD_ps_enable < ZSTD_ps_disable);
|
||||
bounds.lowerBound = (int)ZSTD_ps_auto;
|
||||
bounds.upperBound = (int)ZSTD_ps_disable;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_targetCBlockSize:
|
||||
bounds.lowerBound = ZSTD_TARGETCBLOCKSIZE_MIN;
|
||||
bounds.upperBound = ZSTD_TARGETCBLOCKSIZE_MAX;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_srcSizeHint:
|
||||
bounds.lowerBound = ZSTD_SRCSIZEHINT_MIN;
|
||||
bounds.upperBound = ZSTD_SRCSIZEHINT_MAX;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_stableInBuffer:
|
||||
case ZSTD_c_stableOutBuffer:
|
||||
bounds.lowerBound = (int)ZSTD_bm_buffered;
|
||||
bounds.upperBound = (int)ZSTD_bm_stable;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_blockDelimiters:
|
||||
bounds.lowerBound = (int)ZSTD_sf_noBlockDelimiters;
|
||||
bounds.upperBound = (int)ZSTD_sf_explicitBlockDelimiters;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_validateSequences:
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = 1;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_splitAfterSequences:
|
||||
bounds.lowerBound = (int)ZSTD_ps_auto;
|
||||
bounds.upperBound = (int)ZSTD_ps_disable;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_blockSplitterLevel:
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = ZSTD_BLOCKSPLITTER_LEVEL_MAX;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_useRowMatchFinder:
|
||||
bounds.lowerBound = (int)ZSTD_ps_auto;
|
||||
bounds.upperBound = (int)ZSTD_ps_disable;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_deterministicRefPrefix:
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = 1;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_prefetchCDictTables:
|
||||
bounds.lowerBound = (int)ZSTD_ps_auto;
|
||||
bounds.upperBound = (int)ZSTD_ps_disable;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_enableSeqProducerFallback:
|
||||
bounds.lowerBound = 0;
|
||||
bounds.upperBound = 1;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_maxBlockSize:
|
||||
bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN;
|
||||
bounds.upperBound = ZSTD_BLOCKSIZE_MAX;
|
||||
return bounds;
|
||||
|
||||
case ZSTD_c_repcodeResolution:
|
||||
bounds.lowerBound = (int)ZSTD_ps_auto;
|
||||
bounds.upperBound = (int)ZSTD_ps_disable;
|
||||
return bounds;
|
||||
|
||||
default:
|
||||
bounds.error = ERROR(parameter_unsupported);
|
||||
return bounds;
|
||||
}
|
||||
}
|
||||
|
||||
/* ZSTD_cParam_clampBounds:
|
||||
* Clamps the value into the bounded range.
|
||||
*/
|
||||
static size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value)
|
||||
{
|
||||
ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);
|
||||
if (ZSTD_isError(bounds.error)) return bounds.error;
|
||||
if (*value < bounds.lowerBound) *value = bounds.lowerBound;
|
||||
if (*value > bounds.upperBound) *value = bounds.upperBound;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t ZSTD_rust_cctx_params_clamp_bounds(int param, int* value)
|
||||
{
|
||||
return ZSTD_cParam_clampBounds((ZSTD_cParameter)param, value);
|
||||
}
|
||||
|
||||
int ZSTD_rust_cctx_params_within_bounds(int param, int value)
|
||||
{
|
||||
return ZSTD_cParam_withinBounds((ZSTD_cParameter)param, value);
|
||||
return ZSTD_rust_cctx_params_get_bounds((int)param);
|
||||
}
|
||||
|
||||
int ZSTD_rust_cctx_params_is_multithreaded(void)
|
||||
@@ -821,6 +615,15 @@ int ZSTD_rust_cctx_params_is_multithreaded(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
int ZSTD_rust_cctx_params_nb_workers_max(void)
|
||||
{
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
return ZSTDMT_NBWORKERS_MAX;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ZSTD_rust_cctx_params_job_size_min(void)
|
||||
{
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
@@ -830,6 +633,15 @@ int ZSTD_rust_cctx_params_job_size_min(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
int ZSTD_rust_cctx_params_job_size_max(void)
|
||||
{
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
return ZSTDMT_JOBSIZE_MAX;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define BOUNDCHECK(cParam, val) \
|
||||
do { \
|
||||
RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \
|
||||
|
||||
Reference in New Issue
Block a user