From 7eb70baec1a6c6503de4808d21128338b873d6bc Mon Sep 17 00:00:00 2001 From: ddidderr Date: Sun, 19 Jul 2026 22:48:30 +0200 Subject: [PATCH] feat(compress): move match-state copies into Rust Move the remaining CCtx and CDict copy match-state payloads into Rust. The Rust bridges now copy the window projection, nextToUpdate, and loadedDictEnd fields directly after the existing reset and table callbacks. C retains the private context layout, workspace ownership, and table-copy arithmetic. Test Plan: - ulimit -v 41943040 cargo fmt --manifest-path rust/Cargo.toml -- --check - ulimit -v 41943040 CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040 CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml - 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 --- lib/compress/zstd_compress.c | 68 ++++++++------- rust/src/zstd_compress.rs | 126 +++++++++++++++++++++++---- rust/src/zstd_compress_dictionary.rs | 119 +++++++++++++++++++++---- 3 files changed, 248 insertions(+), 65 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index ce6ee96ce..8d479b725 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -479,7 +479,12 @@ typedef struct { ZSTD_rust_copyCCtxMarkTables_f markTablesDirty; ZSTD_rust_copyCCtxCopyTables_f copyTables; ZSTD_rust_copyCCtxMarkTables_f markTablesClean; - ZSTD_rust_copyCCtxCopyState_f copyMatchState; + void* destinationWindow; + const void* sourceWindow; + U32* destinationNextToUpdate; + const U32* sourceNextToUpdate; + U32* destinationLoadedDictEnd; + const U32* sourceLoadedDictEnd; U32* destinationDictID; const U32* sourceDictID; size_t* destinationDictContentSize; @@ -488,6 +493,11 @@ typedef struct { const ZSTD_compressedBlockState_t* sourceBlockState; int zbuff; } ZSTD_rust_copyCCtxInternalState; +typedef char ZSTD_rust_copy_window_state_layout[ + sizeof(ZSTD_window_t) + == ((3 * sizeof(void*) + 3 * sizeof(U32) + sizeof(void*) - 1) + / sizeof(void*)) * sizeof(void*) + ? 1 : -1]; size_t ZSTD_rust_copyCCtxInternal( const ZSTD_rust_copyCCtxInternalState* state); typedef size_t (*ZSTD_rust_copyCCtxInternal_f)( @@ -526,7 +536,7 @@ typedef char ZSTD_rust_copy_cctx_internal_state_layout[ == 3 * sizeof(void*) + sizeof(U64) && offsetof(ZSTD_rust_copyCCtxInternalState, zbuff) == 3 * sizeof(void*) + sizeof(U64) - + 13 * sizeof(void*) + + 18 * sizeof(void*) && sizeof(ZSTD_rust_copyCCtxInternalState) == ((offsetof(ZSTD_rust_copyCCtxInternalState, zbuff) + sizeof(int) + sizeof(void*) - 1) / sizeof(void*)) @@ -2499,7 +2509,12 @@ typedef struct { ZSTD_rust_resetCCtxByCopyingCDictState_f copyTables; ZSTD_rust_resetCCtxByCopyingCDictState_f zeroHashTable3; ZSTD_rust_resetCCtxByCopyingCDictMarkTables_f markTablesClean; - ZSTD_rust_resetCCtxByCopyingCDictState_f copyMatchState; + void* destinationWindow; + const void* sourceWindow; + U32* destinationNextToUpdate; + const U32* sourceNextToUpdate; + U32* destinationLoadedDictEnd; + const U32* sourceLoadedDictEnd; U32* destinationDictID; const U32* sourceDictID; size_t* destinationDictContentSize; @@ -2521,7 +2536,7 @@ typedef char ZSTD_rust_reset_cctx_by_copying_cdict_state_layout[ && offsetof(ZSTD_rust_resetCCtxByCopyingCDictState, reset) == 3 * sizeof(void*) + sizeof(U64) && offsetof(ZSTD_rust_resetCCtxByCopyingCDictState, zbuff) - == 3 * sizeof(void*) + sizeof(U64) + 12 * sizeof(void*) + == 3 * sizeof(void*) + sizeof(U64) + 17 * sizeof(void*) && sizeof(ZSTD_rust_resetCCtxByCopyingCDictState) == ((offsetof(ZSTD_rust_resetCCtxByCopyingCDictState, zbuff) + sizeof(int) + sizeof(void*) - 1) / sizeof(void*)) @@ -4642,18 +4657,6 @@ static void ZSTD_rust_resetCCtx_byCopyingCDict_mark_tables_clean(void* context) ZSTD_cwksp_mark_tables_clean(&cctx->workspace); } -static void ZSTD_rust_resetCCtx_byCopyingCDict_copy_match_state( - void* context, const void* cdictOpaque) -{ - ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context; - const ZSTD_CDict* const cdict = (const ZSTD_CDict*)cdictOpaque; - const ZSTD_MatchState_t* const src = &cdict->matchState; - ZSTD_MatchState_t* const dst = &cctx->blockState.matchState; - dst->window = src->window; - dst->nextToUpdate = src->nextToUpdate; - dst->loadedDictEnd = src->loadedDictEnd; -} - static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, ZSTD_CCtx_params params, @@ -4673,8 +4676,12 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx, ZSTD_rust_resetCCtx_byCopyingCDict_zero_hash_table3; state.markTablesClean = ZSTD_rust_resetCCtx_byCopyingCDict_mark_tables_clean; - state.copyMatchState = - ZSTD_rust_resetCCtx_byCopyingCDict_copy_match_state; + state.destinationWindow = &cctx->blockState.matchState.window; + state.sourceWindow = &cdict->matchState.window; + state.destinationNextToUpdate = &cctx->blockState.matchState.nextToUpdate; + state.sourceNextToUpdate = &cdict->matchState.nextToUpdate; + state.destinationLoadedDictEnd = &cctx->blockState.matchState.loadedDictEnd; + state.sourceLoadedDictEnd = &cdict->matchState.loadedDictEnd; state.destinationDictID = &cctx->dictID; state.sourceDictID = &cdict->dictID; state.destinationDictContentSize = &cctx->dictContentSize; @@ -4828,18 +4835,6 @@ static void ZSTD_rust_copyCCtx_mark_tables_clean(void* context) ZSTD_cwksp_mark_tables_clean(&dst->workspace); } -static void ZSTD_rust_copyCCtx_copy_match_state( - void* context, const void* srcCCtx) -{ - ZSTD_CCtx* const dst = (ZSTD_CCtx*)context; - const ZSTD_CCtx* const src = (const ZSTD_CCtx*)srcCCtx; - const ZSTD_MatchState_t* const srcMatchState = &src->blockState.matchState; - ZSTD_MatchState_t* const dstMatchState = &dst->blockState.matchState; - dstMatchState->window = srcMatchState->window; - dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; - dstMatchState->loadedDictEnd = srcMatchState->loadedDictEnd; -} - static size_t ZSTD_rust_copyCCtx_internal_callback( void* context, const void* srcCCtx, const ZSTD_frameParameters* fParams, @@ -4856,7 +4851,18 @@ static size_t ZSTD_rust_copyCCtx_internal_callback( state.markTablesDirty = ZSTD_rust_copyCCtx_mark_tables_dirty; state.copyTables = ZSTD_rust_copyCCtx_copy_tables; state.markTablesClean = ZSTD_rust_copyCCtx_mark_tables_clean; - state.copyMatchState = ZSTD_rust_copyCCtx_copy_match_state; + state.destinationWindow = + &((ZSTD_CCtx*)context)->blockState.matchState.window; + state.sourceWindow = + &((const ZSTD_CCtx*)srcCCtx)->blockState.matchState.window; + state.destinationNextToUpdate = + &((ZSTD_CCtx*)context)->blockState.matchState.nextToUpdate; + state.sourceNextToUpdate = + &((const ZSTD_CCtx*)srcCCtx)->blockState.matchState.nextToUpdate; + state.destinationLoadedDictEnd = + &((ZSTD_CCtx*)context)->blockState.matchState.loadedDictEnd; + state.sourceLoadedDictEnd = + &((const ZSTD_CCtx*)srcCCtx)->blockState.matchState.loadedDictEnd; state.destinationDictID = &((ZSTD_CCtx*)context)->dictID; state.sourceDictID = &((const ZSTD_CCtx*)srcCCtx)->dictID; state.destinationDictContentSize = &((ZSTD_CCtx*)context)->dictContentSize; diff --git a/rust/src/zstd_compress.rs b/rust/src/zstd_compress.rs index ce4fa6eba..a6158ff42 100644 --- a/rust/src/zstd_compress.rs +++ b/rust/src/zstd_compress.rs @@ -1684,11 +1684,42 @@ type CopyCCtxResetFn = unsafe extern "C" fn( type CopyCCtxMarkTablesFn = unsafe extern "C" fn(*mut c_void); type CopyCCtxCopyTablesFn = unsafe extern "C" fn(*mut c_void, *const c_void); +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct ZSTD_rust_copyWindowState { + next_src: *const c_void, + base: *const c_void, + dict_base: *const c_void, + dict_limit: c_uint, + low_limit: c_uint, + nb_overflow_corrections: c_uint, +} + +const _: () = { + assert!(offset_of!(ZSTD_rust_copyWindowState, next_src) == 0); + assert!(offset_of!(ZSTD_rust_copyWindowState, base) == size_of::()); + assert!(offset_of!(ZSTD_rust_copyWindowState, dict_base) == 2 * size_of::()); + assert!(offset_of!(ZSTD_rust_copyWindowState, dict_limit) == 3 * size_of::()); + assert!( + offset_of!(ZSTD_rust_copyWindowState, low_limit) + == 3 * size_of::() + size_of::() + ); + assert!( + offset_of!(ZSTD_rust_copyWindowState, nb_overflow_corrections) + == 3 * size_of::() + 2 * size_of::() + ); + assert!( + size_of::() + == (3 * size_of::() + 3 * size_of::()).div_ceil(size_of::()) + * size_of::() + ); +}; + /// Projection for the private `ZSTD_copyCCtx_internal` operation. /// /// Rust owns the stage/error branch and the order of the reset, workspace, -/// table, dictionary, and block-state operations. C retains access to the -/// private `ZSTD_CCtx` layout behind callbacks. +/// table, window, dictionary, and block-state operations. C retains access to +/// the private `ZSTD_CCtx` layout behind callbacks. #[repr(C)] pub struct ZSTD_rust_copyCCtxInternalState { callback_context: *mut c_void, @@ -1701,7 +1732,12 @@ pub struct ZSTD_rust_copyCCtxInternalState { mark_tables_dirty: Option, copy_tables: Option, mark_tables_clean: Option, - copy_match_state: Option, + destination_window: *mut c_void, + source_window: *const c_void, + destination_next_to_update: *mut c_uint, + source_next_to_update: *const c_uint, + destination_loaded_dict_end: *mut c_uint, + source_loaded_dict_end: *const c_uint, destination_dict_id: *mut c_uint, source_dict_id: *const c_uint, destination_dict_content_size: *mut usize, @@ -1729,7 +1765,7 @@ const _: () = { ); assert!( offset_of!(ZSTD_rust_copyCCtxInternalState, zbuff) - == 3 * size_of::() + size_of::() + 13 * size_of::() + == 3 * size_of::() + size_of::() + 18 * size_of::() ); assert!( size_of::() @@ -1756,7 +1792,6 @@ pub unsafe extern "C" fn ZSTD_rust_copyCCtxInternal( Some(mark_tables_dirty), Some(copy_tables), Some(mark_tables_clean), - Some(copy_match_state), ) = ( state.check_stage, state.copy_custom_mem, @@ -1764,7 +1799,6 @@ pub unsafe extern "C" fn ZSTD_rust_copyCCtxInternal( state.mark_tables_dirty, state.copy_tables, state.mark_tables_clean, - state.copy_match_state, ) else { return ERROR(ZstdErrorCode::Generic); @@ -1772,6 +1806,12 @@ pub unsafe extern "C" fn ZSTD_rust_copyCCtxInternal( if state.callback_context.is_null() || state.src_cctx.is_null() || state.f_params.is_null() + || state.destination_window.is_null() + || state.source_window.is_null() + || state.destination_next_to_update.is_null() + || state.source_next_to_update.is_null() + || state.destination_loaded_dict_end.is_null() + || state.source_loaded_dict_end.is_null() || state.destination_dict_id.is_null() || state.source_dict_id.is_null() || state.destination_dict_content_size.is_null() @@ -1802,7 +1842,13 @@ pub unsafe extern "C" fn ZSTD_rust_copyCCtxInternal( mark_tables_dirty(state.callback_context); copy_tables(state.callback_context, state.src_cctx); mark_tables_clean(state.callback_context); - copy_match_state(state.callback_context, state.src_cctx); + ptr::copy( + state.source_window.cast::(), + state.destination_window.cast::(), + 1, + ); + *state.destination_next_to_update = *state.source_next_to_update; + *state.destination_loaded_dict_end = *state.source_loaded_dict_end; *state.destination_dict_id = *state.source_dict_id; *state.destination_dict_content_size = *state.source_dict_content_size; let destination_block_state = *state.destination_block_state; @@ -13873,13 +13919,9 @@ mod tests { context: *mut c_void, _src_cctx: *const c_void, ) { - let context = unsafe { copy_cctx_internal_test_context(context) }; - let event = match context.events.len() { - 1 => "custom", - 6 => "match", - _ => panic!("unexpected copy-state callback order"), - }; - context.events.push(event); + unsafe { copy_cctx_internal_test_context(context) } + .events + .push("custom"); } unsafe extern "C" fn copy_cctx_internal_test_reset( @@ -13921,6 +13963,12 @@ mod tests { context: &mut CopyCCtxInternalTestContext, src_cctx: *const c_void, f_params: &ZSTD_frameParameters, + destination_window: *mut c_void, + source_window: *const c_void, + destination_next_to_update: *mut c_uint, + source_next_to_update: *const c_uint, + destination_loaded_dict_end: *mut c_uint, + source_loaded_dict_end: *const c_uint, destination_dict_id: *mut c_uint, source_dict_id: *const c_uint, destination_dict_content_size: *mut usize, @@ -13939,7 +13987,12 @@ mod tests { mark_tables_dirty: Some(copy_cctx_internal_test_mark_tables_dirty), copy_tables: Some(copy_cctx_internal_test_copy_tables), mark_tables_clean: Some(copy_cctx_internal_test_mark_tables_clean), - copy_match_state: Some(copy_cctx_internal_test_copy_state), + destination_window, + source_window, + destination_next_to_update, + source_next_to_update, + destination_loaded_dict_end, + source_loaded_dict_end, destination_dict_id, source_dict_id, destination_dict_content_size, @@ -13963,6 +14016,26 @@ mod tests { source_block_state.rep = [15, 16, 17]; source_block_state.entropy.huf.repeatMode = 2; source_block_state.entropy.fse.offcode_repeatMode = FSE_REPEAT_VALID; + let source_window = ZSTD_rust_copyWindowState { + next_src: 0x1000usize as *const c_void, + base: 0x2000usize as *const c_void, + dict_base: 0x3000usize as *const c_void, + dict_limit: 21, + low_limit: 13, + nb_overflow_corrections: 8, + }; + let mut destination_window = ZSTD_rust_copyWindowState { + next_src: ptr::null(), + base: ptr::null(), + dict_base: ptr::null(), + dict_limit: 0, + low_limit: 0, + nb_overflow_corrections: 0, + }; + let source_next_to_update = 34; + let mut destination_next_to_update = 0; + let source_loaded_dict_end = 55; + let mut destination_loaded_dict_end = 0; let mut destination_block_state = unsafe { MaybeUninit::::zeroed().assume_init() }; let mut destination_block_state_slot = @@ -13975,6 +14048,12 @@ mod tests { &mut context, 0x5000usize as *const c_void, &f_params, + (&mut destination_window as *mut ZSTD_rust_copyWindowState).cast(), + (&source_window as *const ZSTD_rust_copyWindowState).cast(), + &mut destination_next_to_update, + &source_next_to_update, + &mut destination_loaded_dict_end, + &source_loaded_dict_end, &mut destination_dict_id, &source_dict_id, &mut destination_dict_content_size, @@ -13988,11 +14067,14 @@ mod tests { assert_eq!(result, 0); assert_eq!( context.events, - ["check", "custom", "reset", "dirty", "tables", "clean", "match"] + ["check", "custom", "reset", "dirty", "tables", "clean"] ); assert_eq!(context.frame_params, f_params); assert_eq!(context.pledged_src_size, 123); assert_eq!(context.zbuff, 7); + assert_eq!(destination_window, source_window); + assert_eq!(destination_next_to_update, source_next_to_update); + assert_eq!(destination_loaded_dict_end, source_loaded_dict_end); assert_eq!(destination_dict_id, source_dict_id); assert_eq!(destination_dict_content_size, source_dict_content_size); assert_eq!(destination_block_state.rep, source_block_state.rep); @@ -14027,6 +14109,12 @@ mod tests { &mut context, 0x5000usize as *const c_void, &f_params, + ptr::dangling_mut(), + ptr::dangling(), + ptr::dangling_mut(), + ptr::dangling(), + ptr::dangling_mut(), + ptr::dangling(), &mut destination_dict_id, &source_dict_id, &mut destination_dict_content_size, @@ -14062,6 +14150,12 @@ mod tests { &mut context, 0x5000usize as *const c_void, &f_params, + ptr::dangling_mut(), + ptr::dangling(), + ptr::dangling_mut(), + ptr::dangling(), + ptr::dangling_mut(), + ptr::dangling(), &mut destination_dict_id, &source_dict_id, &mut destination_dict_content_size, diff --git a/rust/src/zstd_compress_dictionary.rs b/rust/src/zstd_compress_dictionary.rs index d926248d8..b3cd1897e 100644 --- a/rust/src/zstd_compress_dictionary.rs +++ b/rust/src/zstd_compress_dictionary.rs @@ -1304,11 +1304,42 @@ type ResetCCtxByCopyingCDictResetFn = type ResetCCtxByCopyingCDictStateFn = unsafe extern "C" fn(*mut c_void, *const c_void); type ResetCCtxByCopyingCDictMarkTablesFn = unsafe extern "C" fn(*mut c_void); +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +struct ZSTD_rust_copyWindowState { + next_src: *const c_void, + base: *const c_void, + dict_base: *const c_void, + dict_limit: c_uint, + low_limit: c_uint, + nb_overflow_corrections: c_uint, +} + +const _: () = { + assert!(offset_of!(ZSTD_rust_copyWindowState, next_src) == 0); + assert!(offset_of!(ZSTD_rust_copyWindowState, base) == size_of::()); + assert!(offset_of!(ZSTD_rust_copyWindowState, dict_base) == 2 * size_of::()); + assert!(offset_of!(ZSTD_rust_copyWindowState, dict_limit) == 3 * size_of::()); + assert!( + offset_of!(ZSTD_rust_copyWindowState, low_limit) + == 3 * size_of::() + size_of::() + ); + assert!( + offset_of!(ZSTD_rust_copyWindowState, nb_overflow_corrections) + == 3 * size_of::() + 2 * size_of::() + ); + assert!( + size_of::() + == (3 * size_of::() + 3 * size_of::()).div_ceil(size_of::()) + * size_of::() + ); +}; + /// Projection for copying a prepared CDict into a working CCtx. /// /// Rust owns the reset/copy ordering and stops on reset allocation failure. -/// C retains the private CCtx/CDict layout, table-size policy, and pointer -/// arithmetic behind callbacks. +/// C retains the private CCtx/CDict layout, table-size policy, and table +/// pointer arithmetic behind callbacks. #[repr(C)] pub struct ZSTD_rust_resetCCtxByCopyingCDictState { callback_context: *mut c_void, @@ -1320,7 +1351,12 @@ pub struct ZSTD_rust_resetCCtxByCopyingCDictState { copy_tables: Option, zero_hash_table3: Option, mark_tables_clean: Option, - copy_match_state: Option, + destination_window: *mut c_void, + source_window: *const c_void, + destination_next_to_update: *mut c_uint, + source_next_to_update: *const c_uint, + destination_loaded_dict_end: *mut c_uint, + source_loaded_dict_end: *const c_uint, destination_dict_id: *mut c_uint, source_dict_id: *const c_uint, destination_dict_content_size: *mut usize, @@ -1347,7 +1383,7 @@ const _: () = { ); assert!( offset_of!(ZSTD_rust_resetCCtxByCopyingCDictState, zbuff) - == 3 * size_of::() + size_of::() + size_of::<[usize; 12]>() + == 3 * size_of::() + size_of::() + size_of::<[usize; 17]>() ); assert!( size_of::() @@ -1373,14 +1409,12 @@ pub unsafe extern "C" fn ZSTD_rust_resetCCtxByCopyingCDict( Some(copy_tables), Some(zero_hash_table3), Some(mark_tables_clean), - Some(copy_match_state), ) = ( state.reset, state.mark_tables_dirty, state.copy_tables, state.zero_hash_table3, state.mark_tables_clean, - state.copy_match_state, ) else { return ERROR(ZstdErrorCode::Generic); @@ -1388,6 +1422,12 @@ pub unsafe extern "C" fn ZSTD_rust_resetCCtxByCopyingCDict( if state.callback_context.is_null() || state.cdict.is_null() || state.params.is_null() + || state.destination_window.is_null() + || state.source_window.is_null() + || state.destination_next_to_update.is_null() + || state.source_next_to_update.is_null() + || state.destination_loaded_dict_end.is_null() + || state.source_loaded_dict_end.is_null() || state.destination_dict_id.is_null() || state.source_dict_id.is_null() || state.destination_dict_content_size.is_null() @@ -1413,7 +1453,13 @@ pub unsafe extern "C" fn ZSTD_rust_resetCCtxByCopyingCDict( copy_tables(state.callback_context, state.cdict); zero_hash_table3(state.callback_context, state.cdict); mark_tables_clean(state.callback_context); - copy_match_state(state.callback_context, state.cdict); + ptr::copy( + state.source_window.cast::(), + state.destination_window.cast::(), + 1, + ); + *state.destination_next_to_update = *state.source_next_to_update; + *state.destination_loaded_dict_end = *state.source_loaded_dict_end; *state.destination_dict_id = *state.source_dict_id; *state.destination_dict_content_size = *state.source_dict_content_size; let destination_block_state = *state.destination_block_state; @@ -2776,19 +2822,16 @@ mod tests { .push("clean"); } - unsafe extern "C" fn reset_cctx_by_copying_cdict_copy_match_state( - context: *mut c_void, - _cdict: *const c_void, - ) { - unsafe { reset_cctx_by_copying_cdict_probe(context) } - .events - .push("match"); - } - fn reset_cctx_by_copying_cdict_test_state( probe: &mut ResetCCtxByCopyingCDictProbe, cdict: *const c_void, params: *const c_void, + destination_window: *mut c_void, + source_window: *const c_void, + destination_next_to_update: *mut c_uint, + source_next_to_update: *const c_uint, + destination_loaded_dict_end: *mut c_uint, + source_loaded_dict_end: *const c_uint, destination_dict_id: *mut c_uint, source_dict_id: *const c_uint, destination_dict_content_size: *mut usize, @@ -2806,7 +2849,12 @@ mod tests { copy_tables: Some(reset_cctx_by_copying_cdict_copy_tables), zero_hash_table3: Some(reset_cctx_by_copying_cdict_zero_hash_table3), mark_tables_clean: Some(reset_cctx_by_copying_cdict_mark_clean), - copy_match_state: Some(reset_cctx_by_copying_cdict_copy_match_state), + destination_window, + source_window, + destination_next_to_update, + source_next_to_update, + destination_loaded_dict_end, + source_loaded_dict_end, destination_dict_id, source_dict_id, destination_dict_content_size, @@ -2827,6 +2875,26 @@ mod tests { source_block_state.rep = [9, 10, 11]; source_block_state.entropy.huf.repeatMode = HUF_REPEAT_VALID; source_block_state.entropy.fse.offcode_repeatMode = FSE_REPEAT_VALID; + let source_window = ZSTD_rust_copyWindowState { + next_src: 0x1000usize as *const c_void, + base: 0x2000usize as *const c_void, + dict_base: 0x3000usize as *const c_void, + dict_limit: 21, + low_limit: 13, + nb_overflow_corrections: 8, + }; + let mut destination_window = ZSTD_rust_copyWindowState { + next_src: ptr::null(), + base: ptr::null(), + dict_base: ptr::null(), + dict_limit: 0, + low_limit: 0, + nb_overflow_corrections: 0, + }; + let source_next_to_update = 34; + let mut destination_next_to_update = 0; + let source_loaded_dict_end = 55; + let mut destination_loaded_dict_end = 0; let source_dict_id = 0x1234_5678; let mut destination_dict_id = 0; let source_dict_content_size = 9876; @@ -2839,6 +2907,12 @@ mod tests { &mut probe, cdict, params, + (&mut destination_window as *mut ZSTD_rust_copyWindowState).cast(), + (&source_window as *const ZSTD_rust_copyWindowState).cast(), + &mut destination_next_to_update, + &source_next_to_update, + &mut destination_loaded_dict_end, + &source_loaded_dict_end, &mut destination_dict_id, &source_dict_id, &mut destination_dict_content_size, @@ -2852,12 +2926,15 @@ mod tests { assert_eq!(result, 0); assert_eq!( probe.events, - ["reset", "dirty", "tables", "zero-h3", "clean", "match"] + ["reset", "dirty", "tables", "zero-h3", "clean"] ); assert_eq!(probe.cdict, cdict); assert_eq!(probe.params, params); assert_eq!(probe.pledged_src_size, 123); assert_eq!(probe.zbuff, 7); + assert_eq!(destination_window, source_window); + assert_eq!(destination_next_to_update, source_next_to_update); + assert_eq!(destination_loaded_dict_end, source_loaded_dict_end); assert_eq!(destination_dict_id, source_dict_id); assert_eq!(destination_dict_content_size, source_dict_content_size); assert_eq!(destination_block_state.rep, source_block_state.rep); @@ -2891,6 +2968,12 @@ mod tests { &mut probe, 0x4000usize as *const c_void, 0x3000usize as *const c_void, + ptr::dangling_mut(), + ptr::dangling(), + ptr::dangling_mut(), + ptr::dangling(), + ptr::dangling_mut(), + ptr::dangling(), &mut destination_dict_id, &source_dict_id, &mut destination_dict_content_size,