refactor(compress): expose parameter policy leaves from Rust

Remove the C forwarding wrappers around compression-parameter policy leaves
that are now implemented directly under their caller-facing ABI symbols.
Keep the private C parameter construction and resource logic in C, while Rust
continues to own the pure row-matchfinder, block-splitter, LDM, external
sequence/repcode, dictionary-tagging, block-size, and overflow predicates.

Test Plan: Pending capped full verification after the companion CLI leaf commit.
This commit is contained in:
2026-07-20 11:00:57 +02:00
parent 5ccc6f89fb
commit 03ac61063d
3 changed files with 99 additions and 188 deletions
+12 -13
View File
@@ -29,14 +29,13 @@ use crate::zstd_compress_frame::{
};
use crate::zstd_compress_literals::min_gain;
use crate::zstd_compress_params::{
ZSTD_compressionParameters, ZSTD_frameParameters, ZSTD_parameters, ZSTD_rustMatchStateSizing,
ZSTD_rust_params_adjustCParams, ZSTD_rust_params_allocateChainTable,
ZSTD_compressionParameters, ZSTD_frameParameters, ZSTD_parameters, ZSTD_resolveMaxBlockSize,
ZSTD_rustMatchStateSizing, ZSTD_rust_params_adjustCParams, ZSTD_rust_params_allocateChainTable,
ZSTD_rust_params_checkCParams, ZSTD_rust_params_defaultCLevel,
ZSTD_rust_params_estimateMatchStateSize, ZSTD_rust_params_getParamsInternal,
ZSTD_rust_params_maxNbSeq, ZSTD_rust_params_resolveMaxBlockSize,
ZSTD_rust_params_rowMatchFinderUsed, ZSTD_rust_params_selectBlockCompressor,
ZSTD_rust_params_selectCParams, ZSTD_RUST_CPM_NO_ATTACH_DICT, ZSTD_RUST_PS_AUTO,
ZSTD_RUST_PS_DISABLE, ZSTD_RUST_PS_ENABLE,
ZSTD_rust_params_maxNbSeq, ZSTD_rust_params_rowMatchFinderUsed,
ZSTD_rust_params_selectBlockCompressor, ZSTD_rust_params_selectCParams,
ZSTD_RUST_CPM_NO_ATTACH_DICT, ZSTD_RUST_PS_AUTO, ZSTD_RUST_PS_DISABLE, ZSTD_RUST_PS_ENABLE,
};
use crate::zstd_compress_params_api::{
ZSTD_CCtxParams_setParameter, ZSTD_CCtx_params, ZSTD_customMem, ZSTD_rust_isUpdateAuthorized,
@@ -7018,7 +7017,7 @@ fn index_too_close_to_max(next_src_base_offset: usize) -> bool {
/// Return whether a scalar C window offset is within the overflow margin.
#[no_mangle]
pub extern "C" fn ZSTD_rust_indexTooCloseToMax(next_src_base_offset: usize) -> c_int {
pub extern "C" fn ZSTD_indexTooCloseToMax(next_src_base_offset: usize) -> c_int {
index_too_close_to_max(next_src_base_offset) as c_int
}
@@ -7029,7 +7028,7 @@ fn dict_too_big(loaded_dict_size: usize) -> bool {
/// Return whether a dictionary exceeds the maximum loadable chunk size.
#[no_mangle]
pub extern "C" fn ZSTD_rust_dictTooBig(loaded_dict_size: usize) -> c_int {
pub extern "C" fn ZSTD_dictTooBig(loaded_dict_size: usize) -> c_int {
dict_too_big(loaded_dict_size) as c_int
}
@@ -7577,7 +7576,7 @@ pub unsafe extern "C" fn ZSTD_rust_estimateCCtxWorkspaceSize(
let sizing = unsafe { *sizing };
let window_limit = 1u64.checked_shl(cparams.windowLog).unwrap_or(u64::MAX);
let window_size = (window_limit.min(pledged_src_size).min(usize::MAX as u64) as usize).max(1);
let block_size = ZSTD_rust_params_resolveMaxBlockSize(max_block_size).min(window_size);
let block_size = ZSTD_resolveMaxBlockSize(max_block_size).min(window_size);
let max_nb_seq = ZSTD_rust_params_maxNbSeq(block_size, cparams.minMatch, use_sequence_producer);
let token_space = cctx_cwksp_alloc_size(
sizing.wildcopyOverlength.wrapping_add(block_size),
@@ -14157,8 +14156,8 @@ mod tests {
let threshold = ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN;
assert!(!index_too_close_to_max(threshold));
assert!(index_too_close_to_max(threshold + 1));
assert_eq!(ZSTD_rust_indexTooCloseToMax(threshold), 0);
assert_eq!(ZSTD_rust_indexTooCloseToMax(threshold + 1), 1);
assert_eq!(ZSTD_indexTooCloseToMax(threshold), 0);
assert_eq!(ZSTD_indexTooCloseToMax(threshold + 1), 1);
}
#[derive(Default)]
@@ -14373,8 +14372,8 @@ mod tests {
assert!(!dict_too_big(0));
assert!(!dict_too_big(ZSTD_CHUNKSIZE_MAX));
assert!(dict_too_big(ZSTD_CHUNKSIZE_MAX + 1));
assert_eq!(ZSTD_rust_dictTooBig(ZSTD_CHUNKSIZE_MAX), 0);
assert_eq!(ZSTD_rust_dictTooBig(ZSTD_CHUNKSIZE_MAX + 1), 1);
assert_eq!(ZSTD_dictTooBig(ZSTD_CHUNKSIZE_MAX), 0);
assert_eq!(ZSTD_dictTooBig(ZSTD_CHUNKSIZE_MAX + 1), 1);
}
#[test]
+46 -78
View File
@@ -5,9 +5,9 @@
//! Context-free compression-parameter selection and sizing leaves.
//!
//! The public `ZSTD_*` symbols remain C-owned thin adapters. Rust owns the
//! context-free getter policy behind scalar ABI functions. `zstd_compress.c`
//! still owns configuration-sensitive policy: private `ZSTD_CCtx_params`
//! The pure `ZSTD_*` policy leaves are exported directly from Rust under their
//! caller symbols. `zstd_compress.c` still owns configuration-sensitive
//! policy: private `ZSTD_CCtx_params`
//! layouts, the C-preprocessor construction of excluded block-compressor
//! bits, LDM workspace sizing, and ASAN workspace policy. The Rust policy
//! leaves receive those build values as explicit scalar inputs, retaining
@@ -428,7 +428,7 @@ fn row_match_finder_used(strategy: c_int, mode: c_int) -> bool {
/// C ABI for `ZSTD_rowMatchFinderSupported()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_rowMatchFinderSupported(strategy: c_int) -> c_int {
pub extern "C" fn ZSTD_rowMatchFinderSupported(strategy: c_int) -> c_int {
c_int::from(strategy_supports_row_match_finder(strategy))
}
@@ -471,7 +471,7 @@ fn resolve_row_match_finder(mode: c_int, cparams: ZSTD_compressionParameters) ->
/// C ABI for `ZSTD_resolveRowMatchFinderMode()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_resolveRowMatchFinderMode(
pub extern "C" fn ZSTD_resolveRowMatchFinderMode(
mode: c_int,
cparams: ZSTD_compressionParameters,
) -> c_int {
@@ -492,7 +492,7 @@ fn resolve_block_splitter(mode: c_int, cparams: ZSTD_compressionParameters) -> c
/// C ABI for `ZSTD_resolveBlockSplitterMode()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_resolveBlockSplitterMode(
pub extern "C" fn ZSTD_resolveBlockSplitterMode(
mode: c_int,
cparams: ZSTD_compressionParameters,
) -> c_int {
@@ -513,10 +513,7 @@ fn resolve_enable_ldm(mode: c_int, cparams: ZSTD_compressionParameters) -> c_int
/// C ABI for `ZSTD_resolveEnableLdm()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_resolveEnableLdm(
mode: c_int,
cparams: ZSTD_compressionParameters,
) -> c_int {
pub extern "C" fn ZSTD_resolveEnableLdm(mode: c_int, cparams: ZSTD_compressionParameters) -> c_int {
resolve_enable_ldm(mode, cparams)
}
@@ -534,7 +531,7 @@ fn resolve_external_repcode_search(mode: c_int, compression_level: c_int) -> c_i
/// C ABI for `ZSTD_resolveExternalRepcodeSearch()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_resolveExternalRepcodeSearch(
pub extern "C" fn ZSTD_resolveExternalRepcodeSearch(
mode: c_int,
compression_level: c_int,
) -> c_int {
@@ -548,7 +545,7 @@ fn resolve_external_sequence_validation(mode: c_int) -> c_int {
/// C ABI for `ZSTD_resolveExternalSequenceValidation()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_resolveExternalSequenceValidation(mode: c_int) -> c_int {
pub extern "C" fn ZSTD_resolveExternalSequenceValidation(mode: c_int) -> c_int {
resolve_external_sequence_validation(mode)
}
@@ -690,9 +687,7 @@ fn get_cparam_mode(
/// C ABI for `ZSTD_CDictIndicesAreTagged()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_cdictIndicesAreTagged(
cparams: ZSTD_compressionParameters,
) -> c_int {
pub extern "C" fn ZSTD_CDictIndicesAreTagged(cparams: ZSTD_compressionParameters) -> c_int {
c_int::from(cdict_indices_are_tagged(cparams))
}
@@ -1517,7 +1512,7 @@ pub extern "C" fn ZSTD_rust_params_maxNbSeq(
/// Pure leaf for private `ZSTD_resolveMaxBlockSize()`.
#[no_mangle]
pub extern "C" fn ZSTD_rust_params_resolveMaxBlockSize(maxBlockSize: usize) -> usize {
pub extern "C" fn ZSTD_resolveMaxBlockSize(maxBlockSize: usize) -> usize {
if maxBlockSize == 0 {
ZSTD_BLOCKSIZE_MAX
} else {
@@ -1525,6 +1520,15 @@ pub extern "C" fn ZSTD_rust_params_resolveMaxBlockSize(maxBlockSize: usize) -> u
}
}
/* These crate-local aliases keep the parameter API modules outside this
* cleanup source-compatible. They are not `no_mangle` C exports. */
pub(crate) use ZSTD_resolveBlockSplitterMode as ZSTD_rust_params_resolveBlockSplitterMode;
pub(crate) use ZSTD_resolveEnableLdm as ZSTD_rust_params_resolveEnableLdm;
pub(crate) use ZSTD_resolveExternalRepcodeSearch as ZSTD_rust_params_resolveExternalRepcodeSearch;
pub(crate) use ZSTD_resolveExternalSequenceValidation as ZSTD_rust_params_resolveExternalSequenceValidation;
pub(crate) use ZSTD_resolveMaxBlockSize as ZSTD_rust_params_resolveMaxBlockSize;
pub(crate) use ZSTD_resolveRowMatchFinderMode as ZSTD_rust_params_resolveRowMatchFinderMode;
#[inline]
fn get_block_size(max_block_size: usize, window_log: u32) -> usize {
max_block_size.min(1usize << window_log)
@@ -1717,10 +1721,10 @@ mod tests {
#[test]
fn row_match_finder_policy_preserves_strategy_and_window_boundaries() {
assert_eq!(ZSTD_rust_params_rowMatchFinderSupported(ZSTD_FAST), 0);
assert_eq!(ZSTD_rust_params_rowMatchFinderSupported(ZSTD_GREEDY), 1);
assert_eq!(ZSTD_rust_params_rowMatchFinderSupported(ZSTD_LAZY2), 1);
assert_eq!(ZSTD_rust_params_rowMatchFinderSupported(ZSTD_BTLAZY2), 0);
assert_eq!(ZSTD_rowMatchFinderSupported(ZSTD_FAST), 0);
assert_eq!(ZSTD_rowMatchFinderSupported(ZSTD_GREEDY), 1);
assert_eq!(ZSTD_rowMatchFinderSupported(ZSTD_LAZY2), 1);
assert_eq!(ZSTD_rowMatchFinderSupported(ZSTD_BTLAZY2), 0);
assert_eq!(
ZSTD_rust_params_rowMatchFinderUsed(ZSTD_GREEDY, ZSTD_RUST_PS_ENABLE),
@@ -1736,31 +1740,19 @@ mod tests {
);
assert_eq!(
ZSTD_rust_params_resolveRowMatchFinderMode(
ZSTD_RUST_PS_AUTO,
policy_cparams(ZSTD_GREEDY, 14),
),
ZSTD_resolveRowMatchFinderMode(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_GREEDY, 14),),
ZSTD_RUST_PS_DISABLE
);
assert_eq!(
ZSTD_rust_params_resolveRowMatchFinderMode(
ZSTD_RUST_PS_AUTO,
policy_cparams(ZSTD_GREEDY, 15),
),
ZSTD_resolveRowMatchFinderMode(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_GREEDY, 15),),
ZSTD_RUST_PS_ENABLE
);
assert_eq!(
ZSTD_rust_params_resolveRowMatchFinderMode(
ZSTD_RUST_PS_AUTO,
policy_cparams(ZSTD_BTLAZY2, 31),
),
ZSTD_resolveRowMatchFinderMode(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_BTLAZY2, 31),),
ZSTD_RUST_PS_DISABLE
);
assert_eq!(
ZSTD_rust_params_resolveRowMatchFinderMode(
ZSTD_RUST_PS_ENABLE,
policy_cparams(ZSTD_FAST, 14),
),
ZSTD_resolveRowMatchFinderMode(ZSTD_RUST_PS_ENABLE, policy_cparams(ZSTD_FAST, 14),),
ZSTD_RUST_PS_ENABLE
);
}
@@ -1826,51 +1818,36 @@ mod tests {
#[test]
fn block_splitter_and_ldm_policy_match_window_boundaries() {
assert_eq!(
ZSTD_rust_params_resolveBlockSplitterMode(
ZSTD_RUST_PS_AUTO,
policy_cparams(ZSTD_BTOPT, 16),
),
ZSTD_resolveBlockSplitterMode(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_BTOPT, 16),),
ZSTD_RUST_PS_DISABLE
);
assert_eq!(
ZSTD_rust_params_resolveBlockSplitterMode(
ZSTD_RUST_PS_AUTO,
policy_cparams(ZSTD_BTOPT, 17),
),
ZSTD_resolveBlockSplitterMode(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_BTOPT, 17),),
ZSTD_RUST_PS_ENABLE
);
assert_eq!(
ZSTD_rust_params_resolveBlockSplitterMode(
ZSTD_RUST_PS_AUTO,
policy_cparams(ZSTD_BTLAZY2, 31),
),
ZSTD_resolveBlockSplitterMode(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_BTLAZY2, 31),),
ZSTD_RUST_PS_DISABLE
);
assert_eq!(
ZSTD_rust_params_resolveBlockSplitterMode(
ZSTD_RUST_PS_ENABLE,
policy_cparams(ZSTD_FAST, 1),
),
ZSTD_resolveBlockSplitterMode(ZSTD_RUST_PS_ENABLE, policy_cparams(ZSTD_FAST, 1),),
ZSTD_RUST_PS_ENABLE
);
assert_eq!(
ZSTD_rust_params_resolveEnableLdm(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_BTOPT, 26),),
ZSTD_resolveEnableLdm(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_BTOPT, 26),),
ZSTD_RUST_PS_DISABLE
);
assert_eq!(
ZSTD_rust_params_resolveEnableLdm(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_BTOPT, 27),),
ZSTD_resolveEnableLdm(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_BTOPT, 27),),
ZSTD_RUST_PS_ENABLE
);
assert_eq!(
ZSTD_rust_params_resolveEnableLdm(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_BTLAZY2, 31),),
ZSTD_resolveEnableLdm(ZSTD_RUST_PS_AUTO, policy_cparams(ZSTD_BTLAZY2, 31),),
ZSTD_RUST_PS_DISABLE
);
assert_eq!(
ZSTD_rust_params_resolveEnableLdm(
ZSTD_RUST_PS_DISABLE,
policy_cparams(ZSTD_BTULTRA2, 31),
),
ZSTD_resolveEnableLdm(ZSTD_RUST_PS_DISABLE, policy_cparams(ZSTD_BTULTRA2, 31),),
ZSTD_RUST_PS_DISABLE
);
}
@@ -1898,36 +1875,30 @@ mod tests {
#[test]
fn external_repcode_and_cdict_tagging_match_boundaries() {
assert_eq!(
ZSTD_rust_params_resolveExternalRepcodeSearch(ZSTD_RUST_PS_AUTO, 9),
ZSTD_resolveExternalRepcodeSearch(ZSTD_RUST_PS_AUTO, 9),
ZSTD_RUST_PS_DISABLE
);
assert_eq!(
ZSTD_rust_params_resolveExternalRepcodeSearch(ZSTD_RUST_PS_AUTO, 10),
ZSTD_resolveExternalRepcodeSearch(ZSTD_RUST_PS_AUTO, 10),
ZSTD_RUST_PS_ENABLE
);
assert_eq!(
ZSTD_rust_params_resolveExternalRepcodeSearch(ZSTD_RUST_PS_DISABLE, 100),
ZSTD_resolveExternalRepcodeSearch(ZSTD_RUST_PS_DISABLE, 100),
ZSTD_RUST_PS_DISABLE
);
assert_eq!(
ZSTD_rust_params_resolveExternalRepcodeSearch(ZSTD_RUST_PS_ENABLE, -100),
ZSTD_resolveExternalRepcodeSearch(ZSTD_RUST_PS_ENABLE, -100),
ZSTD_RUST_PS_ENABLE
);
assert_eq!(ZSTD_CDictIndicesAreTagged(policy_cparams(ZSTD_FAST, 1)), 1);
assert_eq!(ZSTD_CDictIndicesAreTagged(policy_cparams(ZSTD_DFAST, 1)), 1);
assert_eq!(
ZSTD_rust_params_cdictIndicesAreTagged(policy_cparams(ZSTD_FAST, 1)),
1
);
assert_eq!(
ZSTD_rust_params_cdictIndicesAreTagged(policy_cparams(ZSTD_DFAST, 1)),
1
);
assert_eq!(
ZSTD_rust_params_cdictIndicesAreTagged(policy_cparams(ZSTD_GREEDY, 1)),
ZSTD_CDictIndicesAreTagged(policy_cparams(ZSTD_GREEDY, 1)),
0
);
assert_eq!(
ZSTD_rust_params_cdictIndicesAreTagged(policy_cparams(ZSTD_BTULTRA2, 1)),
ZSTD_CDictIndicesAreTagged(policy_cparams(ZSTD_BTULTRA2, 1)),
0
);
}
@@ -2267,10 +2238,7 @@ mod tests {
#[test]
fn external_sequence_validation_preserves_its_int_mode() {
for mode in [c_int::MIN, -1, 0, 1, c_int::MAX] {
assert_eq!(
ZSTD_rust_params_resolveExternalSequenceValidation(mode),
mode
);
assert_eq!(ZSTD_resolveExternalSequenceValidation(mode), mode);
}
}
@@ -2838,7 +2806,7 @@ mod tests {
);
assert_eq!(ZSTD_rust_params_maxNbSeq(100, 3, 0), 33);
assert_eq!(ZSTD_rust_params_maxNbSeq(100, 4, 0), 25);
assert_eq!(ZSTD_rust_params_resolveMaxBlockSize(0), 128 * 1024);
assert_eq!(ZSTD_resolveMaxBlockSize(0), 128 * 1024);
}
#[test]