From a909fa6b8ad04e20b09f44a5a347b5421faaa647 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Wed, 22 Jul 2026 00:46:44 +0200 Subject: [PATCH] feat(compress): move dictionary mode selection to Rust The block-compressor dispatch already selected its strategy and row-mode index in Rust, but C still classified the match state into no-dictionary, ext-dictionary, attached-dictionary, or dedicated-dictionary mode. Project the window and match-state scalars into Rust so that four-way policy is centralized with compressor dispatch while C retains private match-state access. Test Plan: - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo check --tests (rust) - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --tests -- -A clippy::manual-bits -D warnings (rust) - ulimit -v 41943040; make -j1 - ulimit -v 41943040; make -j1 -C tests test --- lib/compress/zstd_compress_internal.h | 12 +++++---- rust/src/zstd_compress.rs | 35 +++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index 9f37957c5..2cc6c2480 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -712,6 +712,9 @@ void ZSTD_rust_windowInit(ZSTD_rust_windowUpdateState* state); U32 ZSTD_rust_windowIsEmpty(const void* nextSrc, const void* base, U32 dictLimit, U32 lowLimit); U32 ZSTD_rust_windowHasExtDict(U32 dictLimit, U32 lowLimit); +int ZSTD_rust_matchStateDictMode(U32 dictLimit, U32 lowLimit, + int hasDictMatchState, + int dedicatedDictSearch); ZSTD_rust_windowDictState ZSTD_rust_windowEnforceMaxDist( U32 blockEndIdx, U32 maxDist, ZSTD_rust_windowDictState state); U32 ZSTD_rust_windowCheckDictValidity(U32 blockEndIdx, U32 maxDist, @@ -1121,11 +1124,10 @@ MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window) */ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_MatchState_t *ms) { - return ZSTD_window_hasExtDict(ms->window) ? - ZSTD_extDict : - ms->dictMatchState != NULL ? - (ms->dictMatchState->dedicatedDictSearch ? ZSTD_dedicatedDictSearch : ZSTD_dictMatchState) : - ZSTD_noDict; + return (ZSTD_dictMode_e)ZSTD_rust_matchStateDictMode( + ms->window.dictLimit, ms->window.lowLimit, + ms->dictMatchState != NULL, + ms->dictMatchState != NULL && ms->dictMatchState->dedicatedDictSearch); } /* Defining this macro to non-zero tells zstd to run the overflow correction diff --git a/rust/src/zstd_compress.rs b/rust/src/zstd_compress.rs index 1e03e8b89..547620a17 100644 --- a/rust/src/zstd_compress.rs +++ b/rust/src/zstd_compress.rs @@ -1326,6 +1326,10 @@ type BlockCompressorFn = const ZSTD_RUST_BLOCK_COMPRESSOR_TABLE_WIDTH: usize = 10; const ZSTD_RUST_ROW_BLOCK_COMPRESSOR_TABLE_WIDTH: usize = 3; const ZSTD_RUST_DICT_MODE_COUNT: c_int = 4; +const ZSTD_RUST_DICT_MODE_NO_DICT: c_int = 0; +const ZSTD_RUST_DICT_MODE_EXT_DICT: c_int = 1; +const ZSTD_RUST_DICT_MODE_MATCH_STATE: c_int = 2; +const ZSTD_RUST_DICT_MODE_DEDICATED: c_int = 3; const ZSTD_RUST_BLOCK_COMPRESSOR_MAX_STRATEGY: c_int = ZSTD_RUST_BLOCK_COMPRESSOR_TABLE_WIDTH as c_int - 1; @@ -10945,6 +10949,28 @@ pub extern "C" fn ZSTD_rust_windowHasExtDict(dict_limit: u32, low_limit: u32) -> (low_limit < dict_limit) as c_uint } +/// Select the compressor dictionary mode from the C-owned window scalars. +/// Rust owns the four-way policy; C retains only private match-state access. +#[no_mangle] +pub extern "C" fn ZSTD_rust_matchStateDictMode( + dict_limit: u32, + low_limit: u32, + has_dict_match_state: c_int, + dedicated_dict_search: c_int, +) -> c_int { + if low_limit < dict_limit { + ZSTD_RUST_DICT_MODE_EXT_DICT + } else if has_dict_match_state != 0 { + if dedicated_dict_search != 0 { + ZSTD_RUST_DICT_MODE_DEDICATED + } else { + ZSTD_RUST_DICT_MODE_MATCH_STATE + } + } else { + ZSTD_RUST_DICT_MODE_NO_DICT + } +} + /// Project the dictionary/window limit policy while C retains pointer-owned /// match-state invalidation and the private window layout. #[repr(C)] @@ -19417,6 +19443,15 @@ mod tests { assert_eq!(ZSTD_rust_windowCheckDictValidity(70, 64, 8, 10), 1); } + #[test] + fn match_state_dictionary_mode_uses_window_before_match_state_policy() { + assert_eq!(ZSTD_rust_matchStateDictMode(10, 2, 0, 0), 1); + assert_eq!(ZSTD_rust_matchStateDictMode(10, 10, 0, 0), 0); + assert_eq!(ZSTD_rust_matchStateDictMode(10, 10, 1, 0), 2); + assert_eq!(ZSTD_rust_matchStateDictMode(10, 10, 1, 1), 3); + assert_eq!(ZSTD_rust_matchStateDictMode(10, 2, 1, 1), 1); + } + #[test] fn window_dictionary_pointer_projection_applies_invalidation_side_effects() { let mut low_limit = 2;