feat(ldm): move limit-table scalar leaf to Rust

Keep the LDM limit-table update on the Rust compression path while leaving
match-state ownership in C. Previously, the C block wrapper combined pointer
subtraction, match-state access, and the bounded scalar update. The wrapper
now computes `curr` from `anchor - window.base`, passes `curr` and
`nextToUpdate` through the narrow U32 ABI, and stores Rust's result before the
existing fast-table dispatch.

The Rust leaf uses explicit wrapping arithmetic to preserve the C U32 behavior:
the strict `curr > nextToUpdate + 1024` threshold and the `MIN(512, ...)`
clamp. Focused tests cover the threshold, one-step update, clamp, nonzero
starting point, and arithmetic wraparound.

Test Plan:
- `cargo test zstd_ldm` -- default-feature test-binary link failed because
  existing dict-builder C symbols are not linked.
- `cargo test --no-default-features --features compression zstd_ldm` -- passed
  (7 tests).
- `make lib-nomt` -- passed.
- `make lib-mt` -- passed.
- `make -C tests test-zstream` -- passed; it emitted the existing
  `tests/zstreamtest.c` unterminated-string warning.
- `cargo clippy`, `cargo clippy --benches`, `cargo clippy --tests`,
  `cargo +nightly fmt`, then the same clippy sequence -- passed.
This commit is contained in:
2026-07-18 15:39:37 +02:00
parent 63ca375557
commit 66cb254532
2 changed files with 39 additions and 9 deletions
+35
View File
@@ -187,6 +187,16 @@ fn bounded(lower: u32, value: u32, upper: u32) -> u32 {
value.max(lower).min(upper)
}
/// Return the next match-table update point using the C scalar rule.
#[no_mangle]
pub extern "C" fn ZSTD_rust_ldm_limitTableUpdate(curr: u32, next_to_update: u32) -> u32 {
if curr > next_to_update.wrapping_add(1024) {
curr.wrapping_sub(512u32.min(curr.wrapping_sub(next_to_update).wrapping_sub(1024)))
} else {
next_to_update
}
}
#[inline]
unsafe fn ldm_bucket(hash_table: *mut LdmEntry, hash: u32, bucket_size_log: u32) -> *mut LdmEntry {
unsafe { hash_table.add((hash as usize) << bucket_size_log) }
@@ -1007,6 +1017,31 @@ pub unsafe extern "C" fn ZSTD_rust_ldm_blockCompress(
mod tests {
use super::*;
#[test]
fn limit_table_update_keeps_threshold_strict() {
assert_eq!(ZSTD_rust_ldm_limitTableUpdate(1024, 0), 0);
}
#[test]
fn limit_table_update_moves_one_step_past_threshold() {
assert_eq!(ZSTD_rust_ldm_limitTableUpdate(1025, 0), 1024);
}
#[test]
fn limit_table_update_clamps_to_512() {
assert_eq!(ZSTD_rust_ldm_limitTableUpdate(2048, 0), 1536);
}
#[test]
fn limit_table_update_preserves_nonzero_next_to_update() {
assert_eq!(ZSTD_rust_ldm_limitTableUpdate(2000, 500), 1524);
}
#[test]
fn limit_table_update_wraps_u32_arithmetic() {
assert_eq!(ZSTD_rust_ldm_limitTableUpdate(1000, u32::MAX - 511), 512);
}
#[test]
fn parameter_defaults_follow_the_c_rules() {
let mut params = LdmParams {