feat(compress): move end-flush input policy to Rust
Keep ZSTD_CStream context access and caller-specific streaming behavior in C, while moving the pure stable-versus-buffered input-buffer policy to a scalar Rust ABI helper. The helper returns the public repr(C) buffer layout, preserves stable-mode source, size, and position values including NULL sources, and returns a zeroed buffer for every other mode. Test Plan: - `cargo clippy --manifest-path rust/Cargo.toml --no-default-features --features compression` -- passed before and after formatting - the same clippy command with `--benches` and `--tests` -- passed before and after formatting - `cargo +nightly fmt --manifest-path rust/Cargo.toml` -- passed - `cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression` -- 274 passed - `make -B -C lib -j2 lib` -- passed - `make -C tests test-rust-lib-smoke` -- passed - `make -B -C tests -j2 fuzzer` and `tests/fuzzer -s4560 -t56 -i57 -v` -- passed - `make -C tests -j2 test-zstream` -- 84 named tests and 7,400 plus 8,519 randomized cases passed - `git diff --check` and `git diff --cached --check` -- passed
This commit is contained in:
@@ -90,6 +90,10 @@ size_t ZSTD_rust_CStreamInSize(void);
|
||||
size_t ZSTD_rust_CStreamOutSize(void);
|
||||
size_t ZSTD_rust_sizeofLocalDict(int dictBufferPresent, size_t dictSize,
|
||||
size_t cdictSize);
|
||||
ZSTD_inBuffer ZSTD_rust_inBufferForEndFlush(int inBufferMode,
|
||||
const void* expectedSrc,
|
||||
size_t expectedSize,
|
||||
size_t expectedPos);
|
||||
|
||||
/* Context-free compression-parameter selection and sizing leaves live in
|
||||
* Rust (rust/src/zstd_compress_params.rs). This file retains
|
||||
@@ -5615,9 +5619,10 @@ ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
|
||||
|
||||
static ZSTD_inBuffer inBuffer_forEndFlush(const ZSTD_CStream* zcs)
|
||||
{
|
||||
const ZSTD_inBuffer nullInput = { NULL, 0, 0 };
|
||||
const int stableInput = (zcs->appliedParams.inBufferMode == ZSTD_bm_stable);
|
||||
return stableInput ? zcs->expectedInBuffer : nullInput;
|
||||
return ZSTD_rust_inBufferForEndFlush(zcs->appliedParams.inBufferMode,
|
||||
zcs->expectedInBuffer.src,
|
||||
zcs->expectedInBuffer.size,
|
||||
zcs->expectedInBuffer.pos);
|
||||
}
|
||||
|
||||
/*! ZSTD_flushStream() :
|
||||
|
||||
@@ -159,7 +159,6 @@ pub extern "C" fn ZSTD_rust_targetCBlockSizeAction(
|
||||
) as c_int
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[repr(C)]
|
||||
pub struct ZSTD_inBuffer {
|
||||
src: *const c_void,
|
||||
@@ -175,6 +174,28 @@ pub struct ZSTD_outBuffer {
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ZSTD_rust_inBufferForEndFlush(
|
||||
in_buffer_mode: c_int,
|
||||
expected_src: *const c_void,
|
||||
expected_size: usize,
|
||||
expected_pos: usize,
|
||||
) -> ZSTD_inBuffer {
|
||||
if in_buffer_mode == ZSTD_BM_STABLE {
|
||||
ZSTD_inBuffer {
|
||||
src: expected_src,
|
||||
size: expected_size,
|
||||
pos: expected_pos,
|
||||
}
|
||||
} else {
|
||||
ZSTD_inBuffer {
|
||||
src: ptr::null(),
|
||||
size: 0,
|
||||
pos: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* HUF_WORKSPACE_SIZE + (MaxSeq + 2) * sizeof(unsigned), rounded up. The
|
||||
* superblock leaf also accepts the larger pre-split workspace, so a fixed
|
||||
* 16 KiB buffer is sufficient for this first non-splitting path on both
|
||||
@@ -1147,6 +1168,35 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn in_buffer_for_end_flush_returns_stable_expected_buffer() {
|
||||
let expected_src = b"input".as_ptr().cast::<c_void>();
|
||||
let result = ZSTD_rust_inBufferForEndFlush(ZSTD_BM_STABLE, expected_src, 37, 11);
|
||||
|
||||
assert_eq!(result.src, expected_src);
|
||||
assert_eq!(result.size, 37);
|
||||
assert_eq!(result.pos, 11);
|
||||
|
||||
let null_result = ZSTD_rust_inBufferForEndFlush(ZSTD_BM_STABLE, ptr::null(), 37, 11);
|
||||
|
||||
assert!(null_result.src.is_null());
|
||||
assert_eq!(null_result.size, 37);
|
||||
assert_eq!(null_result.pos, 11);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn in_buffer_for_end_flush_clears_buffered_and_other_modes() {
|
||||
let expected_src = b"input".as_ptr().cast::<c_void>();
|
||||
|
||||
for mode in [ZSTD_BM_BUFFERED, 42] {
|
||||
let result = ZSTD_rust_inBufferForEndFlush(mode, expected_src, 37, 11);
|
||||
|
||||
assert!(result.src.is_null());
|
||||
assert_eq!(result.size, 0);
|
||||
assert_eq!(result.pos, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalidate_rep_codes_clears_all_entries() {
|
||||
let mut rep = [11u32, 22, 33];
|
||||
|
||||
Reference in New Issue
Block a user