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* expectedInSrc, size_t expectedInPos,
|
||||||
const void* inputSrc, size_t inputPos,
|
const void* inputSrc, size_t inputPos,
|
||||||
size_t expectedOutBufferSize, size_t outputSize, size_t outputPos);
|
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
|
/* Context-free compression-parameter selection and sizing leaves live in
|
||||||
* Rust (rust/src/zstd_compress_params.rs). This file retains
|
* 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)
|
ZSTD_setBufferExpectations(ZSTD_CCtx* cctx, const ZSTD_outBuffer* output, const ZSTD_inBuffer* input)
|
||||||
{
|
{
|
||||||
DEBUGLOG(5, "ZSTD_setBufferExpectations (for advanced stable in/out modes)");
|
DEBUGLOG(5, "ZSTD_setBufferExpectations (for advanced stable in/out modes)");
|
||||||
if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
|
ZSTD_rust_setBufferExpectations(
|
||||||
cctx->expectedInBuffer = *input;
|
(int)cctx->appliedParams.inBufferMode,
|
||||||
}
|
(int)cctx->appliedParams.outBufferMode,
|
||||||
if (cctx->appliedParams.outBufferMode == ZSTD_bm_stable) {
|
&cctx->expectedInBuffer,
|
||||||
cctx->expectedOutBufferSize = output->size - output->pos;
|
&cctx->expectedOutBufferSize,
|
||||||
}
|
output,
|
||||||
|
input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate that the input/output buffers match the expectations set by
|
/* 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]
|
#[inline]
|
||||||
fn select_sequence_copier(mode: c_int) -> c_int {
|
fn select_sequence_copier(mode: c_int) -> c_int {
|
||||||
debug_assert!(
|
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]
|
#[test]
|
||||||
fn sequence_api_plan_places_input_and_frame_checksums_around_blocks() {
|
fn sequence_api_plan_places_input_and_frame_checksums_around_blocks() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
Reference in New Issue
Block a user