refactor(cdict): move match-state reset policy to Rust

CDict initialization still hard-coded the match-state reset policies in its
C callback, even though Rust already owned the surrounding content branch,
workspace reservation, and callback ordering. That left the reset target and
cleanup policy split across the language boundary and made the intended CDict
reset contract implicit.

Extend the existing repr(C) reset callback with the three private enum values.
Rust now selects make-clean, index-reset, and the CDict reset target before
calling the opaque C operation. C retains the private ZSTD_CDict, workspace,
and match-state layouts and only casts the projected values for
ZSTD_reset_matchState(). Focused by-reference and by-copy probes record the
values and preserve reserve, reset, and insert ordering.

Test Plan:
- `rustfmt --check --edition 2021 rust/src/zstd_compress_dictionary.rs` -- passed.
- GCC and Clang syntax-only checks for `lib/compress/zstd_compress.c` under
  `ulimit -v 41943040` -- passed.
- `cargo check --manifest-path rust/Cargo.toml --lib --tests` under the cap -- passed.
- Serial `cargo clippy` lib, benches, and tests passes with `-D warnings`,
  plus `cargo +nightly fmt --all -- --check` -- passed.
- `cargo test --manifest-path rust/Cargo.toml --lib zstd_compress_dictionary
  -- --test-threads=1` compiled but could not link the standalone test binary
  because three pre-existing C bridge symbols are unavailable outside the
  native harness; no native, upstream, or fuzzer tests were run.
This commit is contained in:
2026-07-21 09:44:30 +02:00
parent d8403672d5
commit 2eb56f3434
2 changed files with 34 additions and 4 deletions
+27 -1
View File
@@ -1337,7 +1337,8 @@ pub unsafe extern "C" fn ZSTD_rust_compressBeginUsingDict(
type InitCDictReserveContentFn = unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void;
type InitCDictReserveEntropyFn = unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void;
type InitCDictResetMatchStateFn = unsafe extern "C" fn(*mut c_void, *const c_void, c_int) -> usize;
type InitCDictResetMatchStateFn =
unsafe extern "C" fn(*mut c_void, *const c_void, c_int, c_int, c_int, c_int) -> usize;
type InitCDictInsertDictionaryFn = unsafe extern "C" fn(
*mut c_void,
*const c_void,
@@ -1408,6 +1409,10 @@ const _: () = {
};
const CDICT_DEFAULT_CLEVEL: c_int = 3;
// Values mirror the private C enums passed to ZSTD_reset_matchState().
const CDICT_RESET_COMP_POLICY_MAKE_CLEAN: c_int = 0;
const CDICT_RESET_INDEX_POLICY_RESET: c_int = 1;
const CDICT_RESET_TARGET_CDICT: c_int = 0;
/// Initialize a private CDict through narrow C callbacks.
#[no_mangle]
@@ -1492,6 +1497,9 @@ pub unsafe extern "C" fn ZSTD_rust_initCDict(
state.callback_context,
state.c_params.cast(),
*state.use_row_match_finder,
CDICT_RESET_COMP_POLICY_MAKE_CLEAN,
CDICT_RESET_INDEX_POLICY_RESET,
CDICT_RESET_TARGET_CDICT,
)
};
if ERR_isError(reset_match_result) {
@@ -2801,6 +2809,9 @@ mod tests {
reserve_content_available: bool,
reset_c_params: ZSTD_compressionParameters,
reset_use_row_match_finder: c_int,
reset_comp_policy: c_int,
reset_index_policy: c_int,
reset_target: c_int,
inserted_params: *const c_void,
inserted_dict: *const c_void,
inserted_size: usize,
@@ -2822,6 +2833,9 @@ mod tests {
reserve_content_available: true,
reset_c_params: ZSTD_compressionParameters::default(),
reset_use_row_match_finder: 0,
reset_comp_policy: 0,
reset_index_policy: 0,
reset_target: 0,
inserted_params: ptr::null(),
inserted_dict: ptr::null(),
inserted_size: 0,
@@ -2868,11 +2882,17 @@ mod tests {
context: *mut c_void,
c_params: *const c_void,
use_row_match_finder: c_int,
comp_policy: c_int,
index_policy: c_int,
reset_target: c_int,
) -> usize {
let probe = unsafe { init_cdict_probe(context) };
probe.events.push("reset-match");
probe.reset_c_params = unsafe { *c_params.cast::<ZSTD_compressionParameters>() };
probe.reset_use_row_match_finder = use_row_match_finder;
probe.reset_comp_policy = comp_policy;
probe.reset_index_policy = index_policy;
probe.reset_target = reset_target;
probe.reset_match_result
}
@@ -2965,6 +2985,9 @@ mod tests {
assert_eq!(dict_content, dictionary.as_ptr().cast());
assert_eq!(probe.reset_c_params, c_params);
assert_eq!(probe.reset_use_row_match_finder, use_row_match_finder);
assert_eq!(probe.reset_comp_policy, CDICT_RESET_COMP_POLICY_MAKE_CLEAN);
assert_eq!(probe.reset_index_policy, CDICT_RESET_INDEX_POLICY_RESET);
assert_eq!(probe.reset_target, CDICT_RESET_TARGET_CDICT);
assert_eq!(probe.inserted_params, params);
assert_eq!(probe.inserted_dict, dictionary.as_ptr().cast());
assert_eq!(probe.inserted_size, dictionary.len());
@@ -3061,6 +3084,9 @@ mod tests {
assert_eq!(dict_content, probe.content_storage.as_ptr().cast());
assert_eq!(probe.inserted_dict, dict_content);
assert_eq!(dict_content_size, dictionary.len());
assert_eq!(probe.reset_comp_policy, CDICT_RESET_COMP_POLICY_MAKE_CLEAN);
assert_eq!(probe.reset_index_policy, CDICT_RESET_INDEX_POLICY_RESET);
assert_eq!(probe.reset_target, CDICT_RESET_TARGET_CDICT);
assert_eq!(probe.inserted_dtlm, ZSTD_DTL_FULL);
assert_eq!(probe.inserted_tfp, ZSTD_TFP_FOR_CDICT as c_int);
assert_eq!(probe.reserved_entropy_size, HUF_WORKSPACE_SIZE);