refactor(mt): export window overlap policy from Rust
Move the MT LDM overlap predicate behind the original ZSTDMT_doesOverlapWindow() by-value ABI. Rust now owns the half-open range calculation through a checked representation of Buffer and ZSTD_window_t; C retains the synchronization and context orchestration around the callback. Test Plan: - `cc -fsyntax-only -Ilib -Ilib/common -Ilib/compress -Ilib/decompress -Ilib/dict -Ilib/legacy lib/compress/zstdmt_compress.c` -- passed. - `cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check` -- passed. - `git diff --check` and `git diff --cached --check` -- passed. - Heavy verification intentionally deferred until the combined seam set is ready.
This commit is contained in:
@@ -3420,6 +3420,27 @@ pub struct ZstdMtBuffer {
|
||||
pub capacity: usize,
|
||||
}
|
||||
|
||||
/// ABI-compatible representation of the private C `ZSTD_window_t` used by
|
||||
/// the MT LDM overlap callback.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
pub struct ZstdMtWindow {
|
||||
pub nextSrc: *const u8,
|
||||
pub base: *const u8,
|
||||
pub dictBase: *const u8,
|
||||
pub dictLimit: u32,
|
||||
pub lowLimit: u32,
|
||||
pub nbOverflowCorrections: u32,
|
||||
}
|
||||
|
||||
const _: () = {
|
||||
assert!(std::mem::offset_of!(ZstdMtWindow, nextSrc) == 0);
|
||||
assert!(std::mem::offset_of!(ZstdMtWindow, base) == size_of::<usize>());
|
||||
assert!(std::mem::offset_of!(ZstdMtWindow, dictBase) == 2 * size_of::<usize>());
|
||||
assert!(std::mem::offset_of!(ZstdMtWindow, dictLimit) == 3 * size_of::<usize>());
|
||||
assert!(size_of::<ZstdMtWindow>() == if size_of::<usize>() == 8 { 40 } else { 24 });
|
||||
};
|
||||
|
||||
/// ABI-compatible representation of `rawSeq` from `zstd_compress_internal.h`.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Default)]
|
||||
@@ -3548,6 +3569,24 @@ pub extern "C" fn ZSTDMT_rust_doesOverlapWindow(
|
||||
) != 0) as c_int
|
||||
}
|
||||
|
||||
/// Return non-zero when a buffer overlaps either range in a C window.
|
||||
///
|
||||
/// This keeps the original by-value internal ABI while the scalar helper
|
||||
/// above remains available to projections that cannot expose the private
|
||||
/// window layout.
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ZSTDMT_doesOverlapWindow(buffer: ZstdMtBuffer, window: ZstdMtWindow) -> c_int {
|
||||
ZSTDMT_rust_doesOverlapWindow(
|
||||
buffer.start as *const c_void,
|
||||
buffer.capacity,
|
||||
window.nextSrc.cast(),
|
||||
window.base.cast(),
|
||||
window.dictBase.cast(),
|
||||
window.dictLimit,
|
||||
window.lowLimit,
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct BufferPoolState {
|
||||
buffer_size: usize,
|
||||
@@ -7850,6 +7889,35 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn direct_overlap_window_abi_matches_scalar_policy() {
|
||||
let bytes = [0u8; 32];
|
||||
let base = bytes.as_ptr();
|
||||
let window = ZstdMtWindow {
|
||||
nextSrc: base.wrapping_add(16),
|
||||
base,
|
||||
dictBase: base.wrapping_add(16),
|
||||
dictLimit: 8,
|
||||
lowLimit: 4,
|
||||
nbOverflowCorrections: 0,
|
||||
};
|
||||
let buffer = ZstdMtBuffer {
|
||||
start: base.wrapping_add(20) as *mut c_void,
|
||||
capacity: 4,
|
||||
};
|
||||
assert_eq!(ZSTDMT_doesOverlapWindow(buffer, window), 1);
|
||||
assert_eq!(
|
||||
ZSTDMT_doesOverlapWindow(
|
||||
ZstdMtBuffer {
|
||||
start: base as *mut u8 as *mut c_void,
|
||||
capacity: 4,
|
||||
},
|
||||
window,
|
||||
),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn buffer_pool_reuses_and_resizes_buffers() {
|
||||
let pool = unsafe { ZSTDMT_rust_buffer_pool_create(2, DEFAULT_MEM) };
|
||||
|
||||
Reference in New Issue
Block a user