feat(compress): move continue frame chunks into Rust

Project the prepared frame-chunk state through the compressContinue ABI so
Rust invokes the existing frame-chunk loop directly. Remove the redundant C
frame-chunk forwarding wrapper while retaining C callbacks for the private
block-compression leaves and context-sensitive preparation operations.

Test Plan:
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo fmt --all -- --check
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --lib zstd_compress::tests::compress_continue -- --nocapture
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --all-targets -- -D warnings
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test
- ulimit -v 41943040; make -j1
- ulimit -v 41943040; make -j1 -C tests test-zstream ZSTREAM_TESTTIME=-T2s
- ulimit -v 41943040; make -j1 -C tests test-fuzzer FUZZERTEST=-T3s FUZZER_FLAGS=--no-big-tests
This commit is contained in:
2026-07-20 00:48:02 +02:00
parent 3ec8f03850
commit 58e6d2eef7
2 changed files with 115 additions and 69 deletions
+80 -9
View File
@@ -841,16 +841,17 @@ const _: () = {
///
/// Rust owns stage transitions, frame-header sequencing, input progression,
/// and dispatch between the already-migrated frame-chunk/block bodies. The
/// frame-header parameters are projected as scalars. The opaque callback
/// context remains in C for overflow-correction callbacks and context-sensitive
/// block operations; window advancement is projected directly into Rust.
/// frame-header parameters and frame-chunk state are projected explicitly.
/// The opaque callback context remains in C for overflow-correction callbacks
/// and context-sensitive block operations; window advancement is projected
/// directly into Rust.
#[repr(C)]
pub struct ZSTD_rust_compressContinueState {
callback_context: *mut c_void,
window_state: *const ZSTD_rust_compressContinueWindowProjection,
ldm_window_state: *const ZSTD_rust_compressContinueWindowProjection,
overflow_state: *const ZSTD_rust_overflowCorrectState,
compress_frame_chunk: CompressContinueBlockFn,
frame_chunk_state: *const ZSTD_rust_frameChunkState,
compress_block: CompressContinueBlockFn,
stage: *mut c_int,
consumed_src_size: *mut u64,
@@ -878,7 +879,7 @@ const _: () = {
);
assert!(offset_of!(ZSTD_rust_compressContinueState, overflow_state) == 3 * size_of::<usize>());
assert!(
offset_of!(ZSTD_rust_compressContinueState, compress_frame_chunk) == 4 * size_of::<usize>()
offset_of!(ZSTD_rust_compressContinueState, frame_chunk_state) == 4 * size_of::<usize>()
);
assert!(offset_of!(ZSTD_rust_compressContinueState, compress_block) == 5 * size_of::<usize>());
assert!(offset_of!(ZSTD_rust_compressContinueState, stage) == 6 * size_of::<usize>());
@@ -938,6 +939,8 @@ const _: () = {
const ZSTD_COMPRESSION_STAGE_CREATED: c_int = 0;
const ZSTD_COMPRESSION_STAGE_INIT: c_int = 1;
const ZSTD_COMPRESSION_STAGE_ONGOING: c_int = 2;
#[cfg(test)]
const ZSTD_COMPRESSION_STAGE_ENDING: c_int = 3;
unsafe fn compress_continue_update_window(
projection: *const ZSTD_rust_compressContinueWindowProjection,
@@ -1081,9 +1084,12 @@ unsafe fn compress_continue_body_with(
}
let compressed_size = if frame != 0 {
if state.frame_chunk_state.is_null() {
return ERROR(ZstdErrorCode::Generic);
}
unsafe {
(state.compress_frame_chunk)(
state.callback_context,
ZSTD_rust_compressFrameChunk(
state.frame_chunk_state,
dst,
dst_capacity,
src,
@@ -11174,6 +11180,10 @@ mod tests {
window_projection: ZSTD_rust_compressContinueWindowProjection,
ldm_window_projection: ZSTD_rust_compressContinueWindowProjection,
overflow_state: Option<ZSTD_rust_overflowCorrectState>,
is_first_block: c_int,
frame_chunk_clamp_state: Option<ZSTD_rust_frameChunkClampState>,
frame_chunk_prepare_state: Option<ZSTD_rust_frameChunkPrepareState>,
frame_chunk_state: Option<ZSTD_rust_frameChunkState>,
}
unsafe fn compress_continue_test_context(
@@ -11207,6 +11217,21 @@ mod tests {
) {
}
unsafe extern "C" fn compress_continue_test_frame_prepare_overflow(
_context: *mut c_void,
_src: *const c_void,
_block_size: usize,
) {
}
unsafe extern "C" fn compress_continue_test_frame_prepare_window(
_context: *mut c_void,
_src: *const c_void,
_block_size: usize,
_max_dist: c_uint,
) {
}
unsafe extern "C" fn compress_continue_test_frame(
context: *mut c_void,
_dst: *mut c_void,
@@ -11257,6 +11282,7 @@ mod tests {
context.next_to_update = ZSTD_WINDOW_START_INDEX;
context.loaded_dict_end = 0;
context.dict_match_state = ptr::null();
context.is_first_block = 1;
context.window_projection = ZSTD_rust_compressContinueWindowProjection {
next_src: ptr::addr_of_mut!(context.window.nextSrc),
base: ptr::addr_of_mut!(context.window.base),
@@ -11291,12 +11317,56 @@ mod tests {
.overflow_state
.as_ref()
.map_or(ptr::null(), |state| state as *const _);
context.frame_chunk_clamp_state = Some(ZSTD_rust_frameChunkClampState {
next_to_update: ptr::addr_of_mut!(context.next_to_update),
low_limit: ptr::addr_of!(context.window.lowLimit),
});
let frame_chunk_clamp_state = context
.frame_chunk_clamp_state
.as_ref()
.map_or(ptr::null(), |state| state as *const _);
context.frame_chunk_prepare_state = Some(ZSTD_rust_frameChunkPrepareState {
callback_context,
max_dist: 64,
correct_overflow: compress_continue_test_frame_prepare_overflow,
check_dict_validity: compress_continue_test_frame_prepare_window,
enforce_max_dist: compress_continue_test_frame_prepare_window,
clamp_state: frame_chunk_clamp_state,
});
let frame_chunk_prepare_state = context
.frame_chunk_prepare_state
.as_ref()
.map_or(ptr::null(), |state| state as *const _);
context.frame_chunk_state = Some(ZSTD_rust_frameChunkState {
callback_context,
tmp_workspace: ptr::null_mut(),
checksum_state: ptr::null_mut(),
is_first_block: ptr::addr_of_mut!(context.is_first_block),
stage,
tmp_wksp_size: 0,
block_size_max,
savings: 0,
pre_block_splitter_level: 1,
strategy: ZSTD_FAST,
use_target_c_block_size: 1,
block_splitter_enabled: 0,
checksum_flag: 0,
ending_stage: ZSTD_COMPRESSION_STAGE_ENDING,
prepare_state: frame_chunk_prepare_state,
compress_target: compress_continue_test_frame,
compress_split: compress_continue_test_frame,
compress_internal: compress_continue_test_frame,
});
let frame_chunk_state = context
.frame_chunk_state
.as_ref()
.map_or(ptr::null(), |state| state as *const _);
ZSTD_rust_compressContinueState {
callback_context,
window_state: &context.window_projection,
ldm_window_state: &context.ldm_window_projection,
overflow_state,
compress_frame_chunk: compress_continue_test_frame,
frame_chunk_state,
compress_block: compress_continue_test_block,
stage,
consumed_src_size,
@@ -11348,7 +11418,7 @@ mod tests {
};
assert_eq!(result, 12);
assert_eq!(stage, ZSTD_COMPRESSION_STAGE_ONGOING);
assert_eq!(stage, ZSTD_COMPRESSION_STAGE_ENDING);
assert_eq!(consumed, 12);
assert_eq!(produced, 23);
assert_eq!(context.window.nextSrc, unsafe {
@@ -11361,6 +11431,7 @@ mod tests {
assert_eq!(context.frame_calls, 1);
assert_eq!(context.block_calls, 0);
assert_eq!(context.last_frame_chunk, 1);
assert_eq!(context.is_first_block, 0);
}
#[test]