feat(compress): move MT input size hint arithmetic to Rust

ZSTDMT_nextInputSizeHint only derives a size_t hint from targetSectionSize
and inBuff.filled. Keep the MT context, public/internal entry point, and
stream orchestration in C, but delegate those two scalars to Rust. The Rust
helper uses wrapping subtraction and preserves the zero-result fallback,
including C's wrapped behavior for invalid overfill.

Test Plan:
- The three compression clippy modes passed before and after
  `cargo +nightly fmt --manifest-path rust/Cargo.toml`.
- Focused Rust tests passed: 5 `mt_next_input_size_hint` tests.
- `make -B -C lib -j2 lib` passed.
- `make -C tests test-rust-lib-smoke` passed.
- `tests/fuzzer -s4560 -t56 -i57 -v` passed: 57 tests completed.
- `make -C tests -j2 test-zstream` passed: 84 named, 6,659, and 8,055
  randomized tests completed.
- `git diff --check` and `git diff --cached --check` passed.
This commit is contained in:
2026-07-18 11:19:43 +02:00
parent effef1b8b1
commit 564c82e70f
2 changed files with 50 additions and 3 deletions
+46
View File
@@ -303,6 +303,25 @@ pub extern "C" fn ZSTD_rust_nextInputSizeHint(
)
}
#[inline]
fn mt_next_input_size_hint(target_section_size: usize, in_buff_filled: usize) -> usize {
let hint_in_size = target_section_size.wrapping_sub(in_buff_filled);
if hint_in_size == 0 {
target_section_size
} else {
hint_in_size
}
}
/// Return the next input size required by the C multithreaded streaming state.
#[no_mangle]
pub extern "C" fn ZSTDMT_rust_nextInputSizeHint(
target_section_size: usize,
in_buff_filled: usize,
) -> usize {
mt_next_input_size_hint(target_section_size, in_buff_filled)
}
#[inline]
fn bitmix(mut val: u64, len: u64) -> u64 {
val ^= val.rotate_right(49) ^ val.rotate_right(24);
@@ -1191,6 +1210,33 @@ mod tests {
);
}
#[test]
fn mt_next_input_size_hint_handles_empty_input_buffer() {
assert_eq!(mt_next_input_size_hint(128, 0), 128);
assert_eq!(ZSTDMT_rust_nextInputSizeHint(128, 0), 128);
}
#[test]
fn mt_next_input_size_hint_returns_remaining_capacity() {
assert_eq!(mt_next_input_size_hint(128, 37), 91);
assert_eq!(ZSTDMT_rust_nextInputSizeHint(128, 37), 91);
}
#[test]
fn mt_next_input_size_hint_replaces_full_buffer_with_target_size() {
assert_eq!(ZSTDMT_rust_nextInputSizeHint(128, 128), 128);
}
#[test]
fn mt_next_input_size_hint_preserves_zero_target_behavior() {
assert_eq!(ZSTDMT_rust_nextInputSizeHint(0, 0), 0);
}
#[test]
fn mt_next_input_size_hint_preserves_wrapped_overfill() {
assert_eq!(ZSTDMT_rust_nextInputSizeHint(3, 4), usize::MAX);
}
#[test]
fn in_buffer_for_end_flush_returns_stable_expected_buffer() {
let expected_src = b"input".as_ptr().cast::<c_void>();