From 2d2214eb1de732bbaed8c2a008edba9f6aa3c7ac Mon Sep 17 00:00:00 2001 From: ddidderr Date: Sun, 19 Jul 2026 21:08:02 +0200 Subject: [PATCH] feat(compress): move match-state salt update into Rust Move the row-matchfinder hash-salt field update behind a Rust in-place leaf. C retains the private match-state pointer and entropy field access, while Rust owns the scalar mutation and reuses the tested salt arithmetic. Test Plan: - cargo fmt --manifest-path rust/Cargo.toml -- --check - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml zstd_compress::tests::bitmix_and_hash_salt_match_the_c_arithmetic -- --nocapture - ulimit -v 41943040 && make -j1 - ulimit -v 41943040 && make -j1 -C tests test-fuzzer FUZZERTEST=-T3s FUZZER_FLAGS=--no-big-tests --- lib/compress/zstd_compress.c | 8 +++----- rust/src/zstd_compress.rs | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 1bc06c481..beb20b967 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -652,6 +652,7 @@ size_t ZSTD_compressStream2_c(ZSTD_CCtx* cctx, int ZSTD_rust_simpleCompress2Level(const void* cctx, size_t srcSize); int ZSTD_rust_simpleCompressStream2Level(const void* cctx, size_t srcSize); U32 ZSTD_rust_limitNextToUpdate(U32 curr, U32 nextToUpdate); +void ZSTD_rust_advanceHashSaltInPlace(U64* hashSalt, U64 hashSaltEntropy); void ZSTD_rust_reduceIndex(U32* hashTable, U32 hashSize, U32* chainTable, U32 chainSize, U32* hashTable3, U32 hashSize3, @@ -3756,10 +3757,6 @@ typedef enum { } ZSTD_resetTarget_e; /* Mixes in the hashSalt and hashSaltEntropy to create a new hashSalt */ -static void ZSTD_advanceHashSalt(ZSTD_MatchState_t* ms) { - ms->hashSalt = ZSTD_rust_advanceHashSalt(ms->hashSalt, (U64)ms->hashSaltEntropy); -} - typedef struct { ZSTD_MatchState_t* ms; ZSTD_cwksp* ws; @@ -3829,7 +3826,8 @@ static void ZSTD_rust_resetMatchState_advanceHashSalt(void* opaque) { ZSTD_rust_resetMatchStateContext* const context = (ZSTD_rust_resetMatchStateContext*)opaque; - ZSTD_advanceHashSalt(context->ms); + ZSTD_rust_advanceHashSaltInPlace( + &context->ms->hashSalt, (U64)context->ms->hashSaltEntropy); } static void* ZSTD_rust_resetMatchState_reserve( diff --git a/rust/src/zstd_compress.rs b/rust/src/zstd_compress.rs index 0461eb43e..576399e82 100644 --- a/rust/src/zstd_compress.rs +++ b/rust/src/zstd_compress.rs @@ -5599,6 +5599,19 @@ pub extern "C" fn ZSTD_rust_advanceHashSalt(hash_salt: u64, hash_salt_entropy: u advance_hash_salt(hash_salt, hash_salt_entropy) } +/// Advance a C-owned row-matchfinder salt in place while C retains the +/// private match-state layout. +#[no_mangle] +pub unsafe extern "C" fn ZSTD_rust_advanceHashSaltInPlace( + hash_salt: *mut u64, + hash_salt_entropy: u64, +) { + debug_assert!(!hash_salt.is_null()); + unsafe { + *hash_salt = advance_hash_salt(*hash_salt, hash_salt_entropy); + } +} + #[inline] fn index_too_close_to_max(next_src_base_offset: usize) -> bool { next_src_base_offset > ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN @@ -11243,6 +11256,9 @@ mod tests { ZSTD_rust_advanceHashSalt(0x0123_4567_89ab_cdef, 0xfedc_ba98_7654_3210), 0xe5ee_f172_e5ff_3e57 ); + let mut hash_salt = 0x0123_4567_89ab_cdef; + unsafe { ZSTD_rust_advanceHashSaltInPlace(&mut hash_salt, 0xfedc_ba98_7654_3210) }; + assert_eq!(hash_salt, 0xe5ee_f172_e5ff_3e57); } #[test]