feat(compress): project hash salt entropy into Rust

The row-matchfinder reset path only used its C callback to read the private
hashSaltEntropy scalar and invoke Rust. Replace that callback slot with the
existing 32-bit scalar, keep the ABI offsets pointer-sized on 32-bit and
64-bit targets, and update the salt directly in Rust at the row-table reset
point. Preserve the C workspace callbacks and verify the real salt transition
in the reset-policy test.

Test Plan:
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo check --manifest-path rust/Cargo.toml --tests
- ulimit -v 41943040; make -j1
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings
- ulimit -v 41943040; make -j1 -C tests test
This commit is contained in:
2026-07-21 19:45:07 +02:00
parent 5f965b7025
commit 8597c9c4aa
2 changed files with 30 additions and 26 deletions
+22 -14
View File
@@ -8843,7 +8843,7 @@ pub struct ZSTD_rust_resetMatchStateState {
invalidate_match_state: Option<ResetMatchStateCallback>,
clear_tables: Option<ResetMatchStateCallback>,
clean_tables: Option<ResetMatchStateCallback>,
advance_hash_salt: Option<ResetMatchStateCallback>,
hash_salt_entropy: c_uint,
reserve: Option<ResetMatchStateReserve>,
reserve_failed: Option<ResetMatchStateReserveFailed>,
zero: Option<ResetMatchStateZero>,
@@ -8865,6 +8865,15 @@ const _: () = {
offset_of!(ZSTD_rust_resetMatchStateState, hash_log3)
== offset_of!(ZSTD_rust_resetMatchStateState, optimal_size) + size_of::<usize>()
);
assert!(
offset_of!(ZSTD_rust_resetMatchStateState, hash_salt_entropy)
== offset_of!(ZSTD_rust_resetMatchStateState, clean_tables) + size_of::<usize>()
);
assert!(
offset_of!(ZSTD_rust_resetMatchStateState, reserve)
== offset_of!(ZSTD_rust_resetMatchStateState, hash_salt_entropy)
+ size_of::<usize>()
);
assert!(
offset_of!(ZSTD_rust_resetMatchStateState, set_pointer)
== offset_of!(ZSTD_rust_resetMatchStateState, c_params_out) + size_of::<usize>()
@@ -8911,9 +8920,6 @@ pub unsafe extern "C" fn ZSTD_rust_resetMatchState(
let Some(clean_tables) = state.clean_tables else {
return ERROR(ZstdErrorCode::Generic);
};
let Some(advance_hash_salt) = state.advance_hash_salt else {
return ERROR(ZstdErrorCode::Generic);
};
let Some(reserve) = state.reserve else {
return ERROR(ZstdErrorCode::Generic);
};
@@ -9038,7 +9044,10 @@ pub unsafe extern "C" fn ZSTD_rust_resetMatchState(
RESET_MATCH_POINTER_TAG_TABLE,
tag_table,
);
advance_hash_salt(state.callback_context);
*state.hash_salt = advance_hash_salt(
*state.hash_salt,
state.hash_salt_entropy as u64,
);
}
} else {
let tag_table = unsafe {
@@ -13051,6 +13060,7 @@ mod tests {
zeroed: Vec<(usize, usize)>,
storage: [usize; 32],
fail_after: usize,
hash_salt_entropy: c_uint,
}
unsafe fn reset_match_state_test_context(
@@ -13084,11 +13094,6 @@ mod tests {
context.events.push(5);
}
unsafe extern "C" fn reset_match_state_test_advance(context: *mut c_void) {
let context = unsafe { reset_match_state_test_context(context) };
context.events.push(6);
}
unsafe extern "C" fn reset_match_state_test_reserve(
context: *mut c_void,
reserve_kind: c_int,
@@ -13171,7 +13176,7 @@ mod tests {
invalidate_match_state: Some(reset_match_state_test_invalidate),
clear_tables: Some(reset_match_state_test_clear),
clean_tables: Some(reset_match_state_test_clean),
advance_hash_salt: Some(reset_match_state_test_advance),
hash_salt_entropy: context.hash_salt_entropy,
reserve: Some(reset_match_state_test_reserve),
reserve_failed: Some(reset_match_state_test_reserve_failed),
zero: Some(reset_match_state_test_zero),
@@ -13254,7 +13259,10 @@ mod tests {
#[test]
fn reset_match_state_salts_cctx_row_tables_without_zeroing() {
let c_params = reset_match_state_test_params(ZSTD_GREEDY, 6, 4);
let mut context = ResetMatchStateTestContext::default();
let mut context = ResetMatchStateTestContext {
hash_salt_entropy: 11,
..ResetMatchStateTestContext::default()
};
let mut hash_log3 = 99;
let mut row_hash_log = 99;
let mut hash_salt = 7;
@@ -13280,11 +13288,11 @@ mod tests {
assert_eq!(result, 0);
assert_eq!(hash_log3, 0);
assert_eq!(row_hash_log, 6);
assert_eq!(hash_salt, 7);
assert_eq!(hash_salt, advance_hash_salt(7, 11));
assert_eq!(c_params_out, c_params);
assert_eq!(
context.events,
[3, 4, 100, 200, 100, 201, 100, 202, 5, 101, 203, 6]
[3, 4, 100, 200, 100, 201, 100, 202, 5, 101, 203]
);
assert_eq!(
context.reserves,