feat(ldm): move sequence-store emission into Rust

Remove the LDM-specific C sequence-store callback and reuse the existing Rust
sequence-store leaf from the fast matcher through a crate-local opaque wrapper.
The LDM C shim now retains only private match-state extraction and compressor
dispatch, with explicit SeqDef and SeqStore_t layout checks protecting the
cross-module pointer contract. The Rust boundary documentation now reflects
that sequence-store encoding is Rust-owned.

Test Plan:
- ulimit -v 41943040 && cargo fmt --manifest-path rust/Cargo.toml && git diff --check
- ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml zstd_ldm::tests --lib (7 passed)
- ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml store_seq_preserves_literal --lib (1 passed)
- ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml --lib (683 passed)
- ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings
- ulimit -v 41943040 && make -B -C programs -j1 zstd (passed; existing fileio const-cast warnings)
- ulimit -v 41943040 && make -C tests -j1 test-zstream ZSTREAM_TESTTIME=-T1s (84 tests and both short fuzz rounds passed; existing zstreamtest warning)
This commit is contained in:
2026-07-19 18:27:52 +02:00
parent db8c58ac97
commit d38c1e2a62
4 changed files with 121 additions and 32 deletions
+26 -4
View File
@@ -293,6 +293,28 @@ unsafe fn store_seq(
seq_store.sequences = sequence.wrapping_add(1);
}
/// Reuse the sequence-store leaf from another Rust compression module without
/// exposing this module's C-layout projection in its public API.
pub(crate) unsafe fn store_seq_opaque(
seq_store: *mut c_void,
lit_length: usize,
literals: *const c_void,
lit_limit: *const c_void,
off_base: u32,
match_length: usize,
) {
unsafe {
store_seq(
seq_store.cast::<SeqStore_t>(),
lit_length,
literals.cast::<u8>(),
lit_limit.cast::<u8>(),
off_base,
match_length,
)
}
}
#[inline]
unsafe fn match4_found(
current: *const u8,
@@ -1576,11 +1598,11 @@ mod tests {
};
unsafe {
store_seq(
&mut store,
store_seq_opaque(
(&mut store as *mut SeqStore_t).cast(),
source.len(),
source.as_ptr(),
source.as_ptr().add(source.len()),
source.as_ptr().cast(),
source.as_ptr().add(source.len()).cast(),
13,
3 + 0x1_0000,
);
+4 -11
View File
@@ -12,6 +12,7 @@
use crate::errors::{ERR_isError, ZstdErrorCode, ERROR};
use crate::mem::{MEM_64bits, MEM_isLittleEndian, MEM_read16, MEM_read32, MEM_readST};
use crate::xxhash::XXH64;
use crate::zstd_fast::store_seq_opaque;
use std::ffi::c_void;
use std::mem::size_of;
use std::os::raw::c_int;
@@ -98,14 +99,6 @@ unsafe extern "C" {
src: *const c_void,
src_size: usize,
) -> usize;
fn ZSTD_ldm_rust_storeSeq(
seq_store: *mut c_void,
lit_length: usize,
literals: *const c_void,
lit_limit: *const c_void,
off_base: u32,
match_length: usize,
);
fn ZSTD_ldm_rust_setLdmSeqStore(context: *mut c_void, raw_seq_store: *const c_void);
}
@@ -990,11 +983,11 @@ pub unsafe extern "C" fn ZSTD_rust_ldm_blockCompress(
*reps.add(2) = *reps.add(1);
*reps.add(1) = *reps;
*reps = sequence.offset;
ZSTD_ldm_rust_storeSeq(
store_seq_opaque(
seq_store,
new_lit_length,
input_position.wrapping_sub(new_lit_length).cast::<c_void>(),
input_end.cast::<c_void>(),
input_position.wrapping_sub(new_lit_length).cast(),
input_end.cast(),
sequence.offset.wrapping_add(ZSTD_REP_NUM as u32),
sequence.match_length as usize,
);