feat(params): move context-free getters into Rust
Compression-parameter table selection and adjustment were already implemented as Rust leaves, but the internal and public ZSTD_getCParams/ZSTD_getParams helpers still assembled those results in the C translation unit. That left source-size and dictionary-mode policy duplicated at the C/Rust boundary. Add Rust implementations for the internal and public getter policies. The internal helpers preserve a zero source size as a known empty input, while the public helpers retain the API rule that zero means unknown. The C side keeps only the build-specific exclusion-mask construction and thin ABI adapters, so reduced builds continue to select the same available strategy cascade. Test Plan: - `cargo test --manifest-path rust/Cargo.toml --lib -- --test-threads=1` -- passed (411 tests). - `cargo clippy --manifest-path rust/Cargo.toml --lib -- -D warnings` -- passed. - `cargo +nightly fmt --manifest-path rust/Cargo.toml -- --check` -- passed. - `make -B -C lib -j2 lib` -- passed. - Focused tests cover public zero-to-unknown translation, internal zero semantics, default frame parameters, and dictionary attachment modes.
This commit is contained in:
@@ -148,6 +148,18 @@ ZSTD_compressionParameters
|
|||||||
ZSTD_rust_params_adjustCParams(ZSTD_compressionParameters cParams, U64 srcSize,
|
ZSTD_rust_params_adjustCParams(ZSTD_compressionParameters cParams, U64 srcSize,
|
||||||
size_t dictSize, int mode,
|
size_t dictSize, int mode,
|
||||||
int useRowMatchFinder);
|
int useRowMatchFinder);
|
||||||
|
ZSTD_compressionParameters ZSTD_rust_params_getCParamsInternal(
|
||||||
|
int compressionLevel, U64 srcSizeHint, size_t dictSize, int mode,
|
||||||
|
U32 exclusionMask);
|
||||||
|
ZSTD_parameters ZSTD_rust_params_getParamsInternal(
|
||||||
|
int compressionLevel, U64 srcSizeHint, size_t dictSize, int mode,
|
||||||
|
U32 exclusionMask);
|
||||||
|
ZSTD_compressionParameters ZSTD_rust_params_getCParams(
|
||||||
|
int compressionLevel, U64 srcSizeHint, size_t dictSize,
|
||||||
|
U32 exclusionMask);
|
||||||
|
ZSTD_parameters ZSTD_rust_params_getParams(
|
||||||
|
int compressionLevel, U64 srcSizeHint, size_t dictSize,
|
||||||
|
U32 exclusionMask);
|
||||||
ZSTD_compressionParameters ZSTD_rust_params_applyStrategyExclusions(
|
ZSTD_compressionParameters ZSTD_rust_params_applyStrategyExclusions(
|
||||||
ZSTD_compressionParameters cParams, U32 exclusionMask);
|
ZSTD_compressionParameters cParams, U32 exclusionMask);
|
||||||
ZSTD_compressionParameters ZSTD_rust_params_getCParamsFromCCtxParams(
|
ZSTD_compressionParameters ZSTD_rust_params_getCParamsFromCCtxParams(
|
||||||
@@ -5697,12 +5709,9 @@ static void ZSTD_dedicatedDictSearch_revertCParams(
|
|||||||
* Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_CParamMode_e`. */
|
* Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_CParamMode_e`. */
|
||||||
static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
|
static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
|
||||||
{
|
{
|
||||||
/* Table selection is context-free and lives in Rust; the adjustment step
|
return ZSTD_rust_params_getCParamsInternal(
|
||||||
* stays behind ZSTD_adjustCParams_internal() so this build's strategy
|
compressionLevel, srcSizeHint, dictSize, (int)mode,
|
||||||
* cascade applies. */
|
ZSTD_getCParamsExclusionMask());
|
||||||
ZSTD_compressionParameters const cp = ZSTD_rust_params_selectCParams(
|
|
||||||
compressionLevel, srcSizeHint, dictSize, (int)mode);
|
|
||||||
return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize, mode, ZSTD_ps_auto);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! ZSTD_getCParams() :
|
/*! ZSTD_getCParams() :
|
||||||
@@ -5710,8 +5719,9 @@ static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel,
|
|||||||
* Size values are optional, provide 0 if not known or unused */
|
* Size values are optional, provide 0 if not known or unused */
|
||||||
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
|
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
|
||||||
{
|
{
|
||||||
if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
|
return ZSTD_rust_params_getCParams(
|
||||||
return ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
|
compressionLevel, srcSizeHint, dictSize,
|
||||||
|
ZSTD_getCParamsExclusionMask());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! ZSTD_getParams() :
|
/*! ZSTD_getParams() :
|
||||||
@@ -5721,9 +5731,10 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
|
|||||||
static ZSTD_parameters
|
static ZSTD_parameters
|
||||||
ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
|
ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
|
||||||
{
|
{
|
||||||
ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode);
|
|
||||||
DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
|
DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
|
||||||
return ZSTD_rust_params_makeParams(cParams);
|
return ZSTD_rust_params_getParamsInternal(
|
||||||
|
compressionLevel, srcSizeHint, dictSize, (int)mode,
|
||||||
|
ZSTD_getCParamsExclusionMask());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! ZSTD_getParams() :
|
/*! ZSTD_getParams() :
|
||||||
@@ -5732,8 +5743,9 @@ ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, si
|
|||||||
* Fields of `ZSTD_frameParameters` are set to default values */
|
* Fields of `ZSTD_frameParameters` are set to default values */
|
||||||
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
|
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
|
||||||
{
|
{
|
||||||
if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
|
return ZSTD_rust_params_getParams(
|
||||||
return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
|
compressionLevel, srcSizeHint, dictSize,
|
||||||
|
ZSTD_getCParamsExclusionMask());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZSTD_registerSequenceProducer(
|
void ZSTD_registerSequenceProducer(
|
||||||
|
|||||||
@@ -5,13 +5,14 @@
|
|||||||
|
|
||||||
//! Context-free compression-parameter selection and sizing leaves.
|
//! Context-free compression-parameter selection and sizing leaves.
|
||||||
//!
|
//!
|
||||||
//! This module deliberately does **not** own the public `ZSTD_*` symbols yet.
|
//! The public `ZSTD_*` symbols remain C-owned thin adapters. Rust owns the
|
||||||
//! `zstd_compress.c` still owns configuration-sensitive policy: private
|
//! context-free getter policy behind scalar ABI functions. `zstd_compress.c`
|
||||||
//! `ZSTD_CCtx_params` layouts, the C-preprocessor construction of excluded
|
//! still owns configuration-sensitive policy: private `ZSTD_CCtx_params`
|
||||||
//! block-compressor bits, LDM workspace sizing, and ASAN workspace policy.
|
//! layouts, the C-preprocessor construction of excluded block-compressor
|
||||||
//! The Rust policy leaves receive those build values as explicit scalar inputs,
|
//! bits, LDM workspace sizing, and ASAN workspace policy. The Rust policy
|
||||||
//! retaining byte-for-byte C behavior for reduced builds without exposing
|
//! leaves receive those build values as explicit scalar inputs, retaining
|
||||||
//! private C state across the ABI.
|
//! byte-for-byte C behavior for reduced builds without exposing private C
|
||||||
|
//! state across the ABI.
|
||||||
|
|
||||||
use crate::errors::{ZstdErrorCode, ERROR};
|
use crate::errors::{ZstdErrorCode, ERROR};
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
@@ -855,6 +856,77 @@ fn select_cparams(
|
|||||||
cparams
|
cparams
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_cparams_internal(
|
||||||
|
compression_level: c_int,
|
||||||
|
src_size_hint: u64,
|
||||||
|
dict_size: usize,
|
||||||
|
mode: c_int,
|
||||||
|
exclusion_mask: u32,
|
||||||
|
) -> ZSTD_compressionParameters {
|
||||||
|
/* ZSTD_getCParams_internal() preserves srcSizeHint == 0 as a known empty
|
||||||
|
* input. Only the public getter translates zero to UNKNOWN. */
|
||||||
|
let cparams = select_cparams(compression_level, src_size_hint, dict_size, mode);
|
||||||
|
adjust_cparams(
|
||||||
|
apply_strategy_exclusions(cparams, exclusion_mask),
|
||||||
|
src_size_hint,
|
||||||
|
dict_size,
|
||||||
|
mode,
|
||||||
|
ZSTD_RUST_PS_AUTO,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_params_internal(
|
||||||
|
compression_level: c_int,
|
||||||
|
src_size_hint: u64,
|
||||||
|
dict_size: usize,
|
||||||
|
mode: c_int,
|
||||||
|
exclusion_mask: u32,
|
||||||
|
) -> ZSTD_parameters {
|
||||||
|
make_params(get_cparams_internal(
|
||||||
|
compression_level,
|
||||||
|
src_size_hint,
|
||||||
|
dict_size,
|
||||||
|
mode,
|
||||||
|
exclusion_mask,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cparams_public(
|
||||||
|
compression_level: c_int,
|
||||||
|
src_size_hint: u64,
|
||||||
|
dict_size: usize,
|
||||||
|
exclusion_mask: u32,
|
||||||
|
) -> ZSTD_compressionParameters {
|
||||||
|
let src_size_hint = if src_size_hint == 0 {
|
||||||
|
ZSTD_CONTENTSIZE_UNKNOWN
|
||||||
|
} else {
|
||||||
|
src_size_hint
|
||||||
|
};
|
||||||
|
get_cparams_internal(
|
||||||
|
compression_level,
|
||||||
|
src_size_hint,
|
||||||
|
dict_size,
|
||||||
|
ZSTD_RUST_CPM_UNKNOWN,
|
||||||
|
exclusion_mask,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_params_public(
|
||||||
|
compression_level: c_int,
|
||||||
|
src_size_hint: u64,
|
||||||
|
dict_size: usize,
|
||||||
|
exclusion_mask: u32,
|
||||||
|
) -> ZSTD_parameters {
|
||||||
|
make_params(get_cparams_public(
|
||||||
|
compression_level,
|
||||||
|
src_size_hint,
|
||||||
|
dict_size,
|
||||||
|
exclusion_mask,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
fn get_cparams_from_cctx_params(
|
fn get_cparams_from_cctx_params(
|
||||||
compression_level: c_int,
|
compression_level: c_int,
|
||||||
cctx_src_size_hint: c_int,
|
cctx_src_size_hint: c_int,
|
||||||
@@ -873,15 +945,12 @@ fn get_cparams_from_cctx_params(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ZSTD_getCParams_internal() selects and performs the first adjustment. */
|
/* ZSTD_getCParams_internal() selects and performs the first adjustment. */
|
||||||
let mut cparams = adjust_cparams(
|
let mut cparams = get_cparams_internal(
|
||||||
apply_strategy_exclusions(
|
compression_level,
|
||||||
select_cparams(compression_level, src_size_hint, dict_size, mode),
|
|
||||||
exclusion_mask,
|
|
||||||
),
|
|
||||||
src_size_hint,
|
src_size_hint,
|
||||||
dict_size,
|
dict_size,
|
||||||
mode,
|
mode,
|
||||||
ZSTD_RUST_PS_AUTO,
|
exclusion_mask,
|
||||||
);
|
);
|
||||||
|
|
||||||
if enable_ldm == ZSTD_RUST_PS_ENABLE {
|
if enable_ldm == ZSTD_RUST_PS_ENABLE {
|
||||||
@@ -1043,6 +1112,57 @@ pub extern "C" fn ZSTD_rust_params_adjustCParams(
|
|||||||
adjust_cparams(cparams, srcSize, dictSize, mode, useRowMatchFinder)
|
adjust_cparams(cparams, srcSize, dictSize, mode, useRowMatchFinder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reproduces `ZSTD_getCParams_internal()` without translating a zero source
|
||||||
|
/// size to `ZSTD_CONTENTSIZE_UNKNOWN`.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ZSTD_rust_params_getCParamsInternal(
|
||||||
|
compressionLevel: c_int,
|
||||||
|
srcSizeHint: u64,
|
||||||
|
dictSize: usize,
|
||||||
|
mode: c_int,
|
||||||
|
exclusionMask: u32,
|
||||||
|
) -> ZSTD_compressionParameters {
|
||||||
|
get_cparams_internal(compressionLevel, srcSizeHint, dictSize, mode, exclusionMask)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reproduces `ZSTD_getParams_internal()` without translating a zero source
|
||||||
|
/// size to `ZSTD_CONTENTSIZE_UNKNOWN`.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ZSTD_rust_params_getParamsInternal(
|
||||||
|
compressionLevel: c_int,
|
||||||
|
srcSizeHint: u64,
|
||||||
|
dictSize: usize,
|
||||||
|
mode: c_int,
|
||||||
|
exclusionMask: u32,
|
||||||
|
) -> ZSTD_parameters {
|
||||||
|
get_params_internal(compressionLevel, srcSizeHint, dictSize, mode, exclusionMask)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reproduces the public `ZSTD_getCParams()` source-size policy: zero means
|
||||||
|
/// an unknown size, while the internal helper keeps zero as a known empty
|
||||||
|
/// input.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ZSTD_rust_params_getCParams(
|
||||||
|
compressionLevel: c_int,
|
||||||
|
srcSizeHint: u64,
|
||||||
|
dictSize: usize,
|
||||||
|
exclusionMask: u32,
|
||||||
|
) -> ZSTD_compressionParameters {
|
||||||
|
get_cparams_public(compressionLevel, srcSizeHint, dictSize, exclusionMask)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reproduces the public `ZSTD_getParams()` source-size policy and default
|
||||||
|
/// frame-parameter construction.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ZSTD_rust_params_getParams(
|
||||||
|
compressionLevel: c_int,
|
||||||
|
srcSizeHint: u64,
|
||||||
|
dictSize: usize,
|
||||||
|
exclusionMask: u32,
|
||||||
|
) -> ZSTD_parameters {
|
||||||
|
get_params_public(compressionLevel, srcSizeHint, dictSize, exclusionMask)
|
||||||
|
}
|
||||||
|
|
||||||
/// Reproduces `ZSTD_getCParamsFromCCtxParams()` from scalar snapshots.
|
/// Reproduces `ZSTD_getCParamsFromCCtxParams()` from scalar snapshots.
|
||||||
///
|
///
|
||||||
/// The C shim supplies the private build policy as an exclusion mask and the
|
/// The C shim supplies the private build policy as an exclusion mask and the
|
||||||
@@ -2075,6 +2195,78 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn public_getters_translate_zero_to_unknown_but_internal_getters_do_not() {
|
||||||
|
let public_zero = ZSTD_rust_params_getCParams(3, 0, 1, 0);
|
||||||
|
let public_unknown = ZSTD_rust_params_getCParams(3, ZSTD_CONTENTSIZE_UNKNOWN, 1, 0);
|
||||||
|
assert_eq!(public_zero, public_unknown);
|
||||||
|
|
||||||
|
let internal_zero = ZSTD_rust_params_getCParamsInternal(3, 0, 1, ZSTD_RUST_CPM_UNKNOWN, 0);
|
||||||
|
assert_eq!(internal_zero.windowLog, 10);
|
||||||
|
assert_eq!(public_unknown.windowLog, 14);
|
||||||
|
assert_ne!(internal_zero, public_unknown);
|
||||||
|
|
||||||
|
let public_params_zero = ZSTD_rust_params_getParams(3, 0, 1, 0);
|
||||||
|
let public_params_unknown = ZSTD_rust_params_getParams(3, ZSTD_CONTENTSIZE_UNKNOWN, 1, 0);
|
||||||
|
assert_eq!(public_params_zero, public_params_unknown);
|
||||||
|
assert_eq!(public_params_zero.cParams, public_zero);
|
||||||
|
assert_eq!(
|
||||||
|
ZSTD_rust_params_getParamsInternal(3, 0, 1, ZSTD_RUST_CPM_UNKNOWN, 0).cParams,
|
||||||
|
internal_zero
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn getter_modes_preserve_dictionary_attachment_boundaries() {
|
||||||
|
let attached_with_dict = ZSTD_rust_params_getCParamsInternal(
|
||||||
|
3,
|
||||||
|
ZSTD_CONTENTSIZE_UNKNOWN,
|
||||||
|
1,
|
||||||
|
ZSTD_RUST_CPM_ATTACH_DICT,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
let attached_without_dict = ZSTD_rust_params_getCParamsInternal(
|
||||||
|
3,
|
||||||
|
ZSTD_CONTENTSIZE_UNKNOWN,
|
||||||
|
0,
|
||||||
|
ZSTD_RUST_CPM_ATTACH_DICT,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
assert_eq!(attached_with_dict, attached_without_dict);
|
||||||
|
|
||||||
|
let no_attach = ZSTD_rust_params_getCParamsInternal(
|
||||||
|
3,
|
||||||
|
ZSTD_CONTENTSIZE_UNKNOWN,
|
||||||
|
1,
|
||||||
|
ZSTD_RUST_CPM_NO_ATTACH_DICT,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
let create_cdict = ZSTD_rust_params_getCParamsInternal(
|
||||||
|
3,
|
||||||
|
ZSTD_CONTENTSIZE_UNKNOWN,
|
||||||
|
1,
|
||||||
|
ZSTD_RUST_CPM_CREATE_CDICT,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
assert_eq!(attached_with_dict.windowLog, 21);
|
||||||
|
assert_eq!(no_attach.windowLog, 14);
|
||||||
|
assert_eq!(create_cdict.windowLog, 10);
|
||||||
|
assert!(attached_with_dict.windowLog > no_attach.windowLog);
|
||||||
|
assert!(no_attach.windowLog > create_cdict.windowLog);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
ZSTD_rust_params_getCParamsInternal(
|
||||||
|
3,
|
||||||
|
ZSTD_CONTENTSIZE_UNKNOWN,
|
||||||
|
1,
|
||||||
|
ZSTD_RUST_CPM_UNKNOWN,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
.windowLog,
|
||||||
|
no_attach.windowLog
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn cctx_policy_params(
|
fn cctx_policy_params(
|
||||||
cctx_src_size_hint: c_int,
|
cctx_src_size_hint: c_int,
|
||||||
src_size_hint: u64,
|
src_size_hint: u64,
|
||||||
|
|||||||
Reference in New Issue
Block a user