refactor(compress): move stable buffer policy to Rust
Move the stable input and output expectation update into the Rust compression module. Keep the private CCtx layout and debug logging in the C adapter while passing only the buffer-mode scalars and projected buffer fields across the ABI. Preserve C size_t wrapping for the output remainder and leave buffered modes unchanged. Test Plan: - rustfmt --edition 2021 --check rust/src/zstd_compress.rs - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040; make -j1 - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml --all-targets - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/cli/Cargo.toml --all-targets - ulimit -v 41943040; make -j1 -C tests test
This commit is contained in:
@@ -1792,6 +1792,10 @@ size_t ZSTD_rust_checkBufferStability(
|
||||
const void* expectedInSrc, size_t expectedInPos,
|
||||
const void* inputSrc, size_t inputPos,
|
||||
size_t expectedOutBufferSize, size_t outputSize, size_t outputPos);
|
||||
void ZSTD_rust_setBufferExpectations(
|
||||
int inBufferMode, int outBufferMode,
|
||||
ZSTD_inBuffer* expectedInBuffer, size_t* expectedOutBufferSize,
|
||||
const ZSTD_outBuffer* output, const ZSTD_inBuffer* input);
|
||||
|
||||
/* Context-free compression-parameter selection and sizing leaves live in
|
||||
* Rust (rust/src/zstd_compress_params.rs). This file retains
|
||||
@@ -7690,12 +7694,13 @@ static void
|
||||
ZSTD_setBufferExpectations(ZSTD_CCtx* cctx, const ZSTD_outBuffer* output, const ZSTD_inBuffer* input)
|
||||
{
|
||||
DEBUGLOG(5, "ZSTD_setBufferExpectations (for advanced stable in/out modes)");
|
||||
if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
|
||||
cctx->expectedInBuffer = *input;
|
||||
}
|
||||
if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) {
|
||||
cctx->expectedOutBufferSize = output->size - output->pos;
|
||||
}
|
||||
ZSTD_rust_setBufferExpectations(
|
||||
(int)cctx->appliedParams.inBufferMode,
|
||||
(int)cctx->appliedParams.outBufferMode,
|
||||
&cctx->expectedInBuffer,
|
||||
&cctx->expectedOutBufferSize,
|
||||
output,
|
||||
input);
|
||||
}
|
||||
|
||||
/* Validate that the input/output buffers match the expectations set by
|
||||
|
||||
@@ -6169,6 +6169,53 @@ pub extern "C" fn ZSTD_rust_checkBufferStability(
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn set_buffer_expectations(
|
||||
in_buffer_mode: c_int,
|
||||
out_buffer_mode: c_int,
|
||||
expected_in_buffer: *mut ZSTD_inBuffer,
|
||||
expected_out_buffer_size: *mut usize,
|
||||
output: *const ZSTD_outBuffer,
|
||||
input: *const ZSTD_inBuffer,
|
||||
) {
|
||||
if in_buffer_mode == ZSTD_BM_STABLE {
|
||||
unsafe {
|
||||
*expected_in_buffer = ptr::read(input);
|
||||
}
|
||||
}
|
||||
if out_buffer_mode == ZSTD_BM_STABLE {
|
||||
let output = unsafe { &*output };
|
||||
unsafe {
|
||||
*expected_out_buffer_size = output.size.wrapping_sub(output.pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the stable input/output expectations after a compression call.
|
||||
///
|
||||
/// C retains the private `ZSTD_CCtx` fields and passes only their projections;
|
||||
/// Rust owns the buffer-mode policy and C-size arithmetic.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_rust_setBufferExpectations(
|
||||
in_buffer_mode: c_int,
|
||||
out_buffer_mode: c_int,
|
||||
expected_in_buffer: *mut ZSTD_inBuffer,
|
||||
expected_out_buffer_size: *mut usize,
|
||||
output: *const ZSTD_outBuffer,
|
||||
input: *const ZSTD_inBuffer,
|
||||
) {
|
||||
unsafe {
|
||||
set_buffer_expectations(
|
||||
in_buffer_mode,
|
||||
out_buffer_mode,
|
||||
expected_in_buffer,
|
||||
expected_out_buffer_size,
|
||||
output,
|
||||
input,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn select_sequence_copier(mode: c_int) -> c_int {
|
||||
debug_assert!(
|
||||
@@ -14597,6 +14644,75 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_buffer_expectations_updates_only_enabled_stable_modes() {
|
||||
let expected_src = b"expected".as_ptr().cast::<c_void>();
|
||||
let input_src = b"input".as_ptr().cast::<c_void>();
|
||||
let mut expected_input = ZSTD_inBuffer {
|
||||
src: expected_src,
|
||||
size: 3,
|
||||
pos: 1,
|
||||
};
|
||||
let input = ZSTD_inBuffer {
|
||||
src: input_src,
|
||||
size: 11,
|
||||
pos: 7,
|
||||
};
|
||||
let output = ZSTD_outBuffer {
|
||||
dst: ptr::null_mut(),
|
||||
size: 40,
|
||||
pos: 9,
|
||||
};
|
||||
let mut expected_output_size = 5;
|
||||
|
||||
unsafe {
|
||||
ZSTD_rust_setBufferExpectations(
|
||||
ZSTD_BM_STABLE,
|
||||
ZSTD_BM_STABLE,
|
||||
&mut expected_input,
|
||||
&mut expected_output_size,
|
||||
&output,
|
||||
&input,
|
||||
);
|
||||
}
|
||||
|
||||
assert_eq!(expected_input.src, input.src);
|
||||
assert_eq!(expected_input.size, input.size);
|
||||
assert_eq!(expected_input.pos, input.pos);
|
||||
assert_eq!(expected_output_size, 31);
|
||||
|
||||
let original_input_src = expected_input.src;
|
||||
let original_input_size = expected_input.size;
|
||||
let original_input_pos = expected_input.pos;
|
||||
let original_output_size = expected_output_size;
|
||||
let other_input = ZSTD_inBuffer {
|
||||
src: expected_src,
|
||||
size: 99,
|
||||
pos: 22,
|
||||
};
|
||||
let other_output = ZSTD_outBuffer {
|
||||
dst: ptr::null_mut(),
|
||||
size: 3,
|
||||
pos: 8,
|
||||
};
|
||||
|
||||
unsafe {
|
||||
ZSTD_rust_setBufferExpectations(
|
||||
ZSTD_BM_BUFFERED,
|
||||
ZSTD_BM_BUFFERED,
|
||||
&mut expected_input,
|
||||
&mut expected_output_size,
|
||||
&other_output,
|
||||
&other_input,
|
||||
);
|
||||
}
|
||||
|
||||
assert_eq!(expected_input.src, original_input_src);
|
||||
assert_eq!(expected_input.size, original_input_size);
|
||||
assert_eq!(expected_input.pos, original_input_pos);
|
||||
assert_eq!(expected_output_size, original_output_size);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sequence_api_plan_places_input_and_frame_checksums_around_blocks() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user