diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index d0754fdfe..7709d6981 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -2304,7 +2304,7 @@ typedef struct { ZSTD_rust_resetCCtxStorageCallback_f resetHash; void* compressedBlockState; ZSTD_rust_resetCCtxTailCallback_f resetMatchState; - ZSTD_rust_resetCCtxTailCallback_f resetStorage; + const ZSTD_rust_resetCCtxStorageState* storageState; ZSTD_compressionParameters* matchStateCParams; int* matchStatePrefetchCDictTables; unsigned long long* pledgedSrcSizePlusOne; @@ -2327,7 +2327,7 @@ typedef char ZSTD_rust_reset_cctx_tail_state_layout[ == 2 * sizeof(void*) && offsetof(ZSTD_rust_resetCCtxTailState, resetMatchState) == 3 * sizeof(void*) - && offsetof(ZSTD_rust_resetCCtxTailState, resetStorage) + && offsetof(ZSTD_rust_resetCCtxTailState, storageState) == 4 * sizeof(void*) && offsetof(ZSTD_rust_resetCCtxTailState, matchStateCParams) == 5 * sizeof(void*) @@ -5389,13 +5389,6 @@ static size_t ZSTD_rust_resetCCtxTail_resetMatchState(void* opaque) ZSTD_resetTarget_CCtx); } -static size_t ZSTD_rust_resetCCtxTail_resetStorage(void* opaque) -{ - ZSTD_rust_resetCCtxTailContext* const context = - (ZSTD_rust_resetCCtxTailContext*)opaque; - return ZSTD_rust_resetCCtxStorage(context->storageState); -} - /*! ZSTD_resetCCtx_internal() : * @param loadedDictSize The size of the dictionary to be loaded * into the context, if any. If no dictionary is used, or the @@ -5534,7 +5527,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, tailState.resetHash = ZSTD_rust_resetCCtxTail_resetHash; tailState.compressedBlockState = NULL; tailState.resetMatchState = ZSTD_rust_resetCCtxTail_resetMatchState; - tailState.resetStorage = ZSTD_rust_resetCCtxTail_resetStorage; + tailState.storageState = &storageState; tailState.matchStateCParams = &zc->blockState.matchState.cParams; tailState.matchStatePrefetchCDictTables = &zc->blockState.matchState.prefetchCDictTables; diff --git a/rust/src/zstd_compress.rs b/rust/src/zstd_compress.rs index e654c5698..7d3db5f49 100644 --- a/rust/src/zstd_compress.rs +++ b/rust/src/zstd_compress.rs @@ -9930,15 +9930,15 @@ const _: () = { /// C-owned operations used by the post-workspace CCtx reset tail. /// /// Rust owns the operation order, compressed-block reset, and error -/// propagation. C retains the private context initialization, match-state -/// reset, and storage publication operations. +/// propagation. C retains the private context initialization and match-state +/// reset; the storage policy is called directly through its projected state. #[repr(C)] pub struct ZSTD_rust_resetCCtxTailState { callbackContext: *mut c_void, resetHash: Option, compressedBlockState: *mut ZSTD_compressedBlockState_t, resetMatchState: Option, - resetStorage: Option, + storageState: *const ZSTD_rust_resetCCtxStorageState, matchStateCParams: *mut ZSTD_compressionParameters, matchStatePrefetchCDictTables: *mut c_int, pledgedSrcSizePlusOne: *mut u64, @@ -9962,7 +9962,7 @@ const _: () = { offset_of!(ZSTD_rust_resetCCtxTailState, compressedBlockState) == 2 * size_of::() ); assert!(offset_of!(ZSTD_rust_resetCCtxTailState, resetMatchState) == 3 * size_of::()); - assert!(offset_of!(ZSTD_rust_resetCCtxTailState, resetStorage) == 4 * size_of::()); + assert!(offset_of!(ZSTD_rust_resetCCtxTailState, storageState) == 4 * size_of::()); assert!( offset_of!(ZSTD_rust_resetCCtxTailState, matchStateCParams) == 5 * size_of::() ); @@ -10462,9 +10462,9 @@ pub unsafe extern "C" fn ZSTD_rust_resetCCtxTail( let Some(reset_match_state) = state.resetMatchState else { return ERROR(ZstdErrorCode::Generic); }; - let Some(reset_storage) = state.resetStorage else { + if state.storageState.is_null() { return ERROR(ZstdErrorCode::Generic); - }; + } if state.compressedBlockState.is_null() { return ERROR(ZstdErrorCode::Generic); } @@ -10502,7 +10502,7 @@ pub unsafe extern "C" fn ZSTD_rust_resetCCtxTail( if ERR_isError(result) { return result; } - let result = reset_storage(state.callbackContext); + let result = ZSTD_rust_resetCCtxStorage(state.storageState); if ERR_isError(result) { return result; } @@ -23436,6 +23436,8 @@ mod tests { #[derive(Default)] struct ResetCCtxTailTestContext { events: Vec<&'static str>, + storage_allocations: Vec>, + storage_error_armed: bool, match_result: usize, storage_result: usize, c_params: ZSTD_compressionParameters, @@ -23471,22 +23473,110 @@ mod tests { context.match_result } - unsafe extern "C" fn reset_cctx_tail_test_reset_storage(context: *mut c_void) -> usize { + unsafe extern "C" fn reset_cctx_tail_storage_set_pointer( + _context: *mut c_void, + _pointer_kind: c_int, + _pointer: *mut c_void, + ) { + } + + unsafe extern "C" fn reset_cctx_tail_storage_set_size( + _context: *mut c_void, + _size_kind: c_int, + _value: usize, + ) { + } + + unsafe extern "C" fn reset_cctx_tail_storage_set_int( + _context: *mut c_void, + _int_kind: c_int, + _value: c_int, + ) { + } + + unsafe extern "C" fn reset_cctx_tail_storage_reserve( + context: *mut c_void, + _reserve_kind: c_int, + size: usize, + ) -> *mut c_void { + let context = unsafe { reset_cctx_tail_test_context(context) }; + let allocation = vec![0u8; size.max(1)].into_boxed_slice(); + let pointer = allocation.as_ptr() as *mut c_void; + context.storage_allocations.push(allocation); + pointer + } + + unsafe extern "C" fn reset_cctx_tail_storage_reserve_failed( + context: *mut c_void, + ) -> c_int { + let context = unsafe { reset_cctx_tail_test_context(context) }; + c_int::from(context.storage_error_armed) + } + + unsafe extern "C" fn reset_cctx_tail_storage_zero( + _context: *mut c_void, + pointer: *mut c_void, + size: usize, + ) { + if !pointer.is_null() { + unsafe { ptr::write_bytes(pointer.cast::(), 0, size) }; + } + } + + unsafe extern "C" fn reset_cctx_tail_storage_window_init(_context: *mut c_void) {} + + unsafe extern "C" fn reset_cctx_tail_storage_reset_external_sequences( + context: *mut c_void, + ) { let context = unsafe { reset_cctx_tail_test_context(context) }; context.events.push("reset-storage"); - context.storage_result + context.storage_error_armed = context.storage_result != 0; + } + + fn reset_cctx_tail_test_storage_state( + context: &mut ResetCCtxTailTestContext, + ) -> ZSTD_rust_resetCCtxStorageState { + ZSTD_rust_resetCCtxStorageState { + callbackContext: (context as *mut ResetCCtxTailTestContext).cast(), + ldmEnable: ZSTD_RUST_PS_DISABLE, + hasExtSeqProd: 0, + hashLog: 0, + bucketSizeLog: 0, + blockSize: 1, + maxNbSeq: 1, + maxNbLdmSeq: 0, + maxNbExternalSeq: 0, + buffInSize: 0, + buffOutSize: 0, + seqDefSize: 1, + ldmEntrySize: 1, + rawSeqSize: 1, + externalSequenceSize: 1, + byteSize: 1, + wildcopyOverlength: 0, + bufferedPolicy: 0, + setPointer: Some(reset_cctx_tail_storage_set_pointer), + setSize: Some(reset_cctx_tail_storage_set_size), + setInt: Some(reset_cctx_tail_storage_set_int), + reserve: Some(reset_cctx_tail_storage_reserve), + reserveFailed: Some(reset_cctx_tail_storage_reserve_failed), + zero: Some(reset_cctx_tail_storage_zero), + windowInit: Some(reset_cctx_tail_storage_window_init), + resetExternalSequences: Some(reset_cctx_tail_storage_reset_external_sequences), + } } fn reset_cctx_tail_test_state( context: &mut ResetCCtxTailTestContext, compressed_block_state: *mut ZSTD_compressedBlockState_t, + storage_state: &mut ZSTD_rust_resetCCtxStorageState, ) -> ZSTD_rust_resetCCtxTailState { ZSTD_rust_resetCCtxTailState { callbackContext: (context as *mut ResetCCtxTailTestContext).cast(), resetHash: Some(reset_cctx_tail_test_reset_hash), compressedBlockState: compressed_block_state, resetMatchState: Some(reset_cctx_tail_test_reset_match_state), - resetStorage: Some(reset_cctx_tail_test_reset_storage), + storageState: storage_state, matchStateCParams: ptr::addr_of_mut!(context.match_state_cparams), matchStatePrefetchCDictTables: ptr::addr_of_mut!( context.match_state_prefetch_cdict_tables @@ -23511,7 +23601,8 @@ mod tests { let mut context = ResetCCtxTailTestContext::default(); let mut block_state = unsafe { MaybeUninit::::zeroed().assume_init() }; - let state = reset_cctx_tail_test_state(&mut context, &mut block_state); + let mut storage_state = reset_cctx_tail_test_storage_state(&mut context); + let state = reset_cctx_tail_test_state(&mut context, &mut block_state, &mut storage_state); assert_eq!(unsafe { ZSTD_rust_resetCCtxTail(&state) }, 0); assert_eq!( @@ -23551,7 +23642,8 @@ mod tests { }; let mut block_state = unsafe { MaybeUninit::::zeroed().assume_init() }; - let state = reset_cctx_tail_test_state(&mut context, &mut block_state); + let mut storage_state = reset_cctx_tail_test_storage_state(&mut context); + let state = reset_cctx_tail_test_state(&mut context, &mut block_state, &mut storage_state); assert_eq!(unsafe { ZSTD_rust_resetCCtxTail(&state) }, 0); assert_eq!(context.match_state_cparams, c_params); @@ -23574,7 +23666,8 @@ mod tests { }; let mut block_state = unsafe { MaybeUninit::::zeroed().assume_init() }; - let state = reset_cctx_tail_test_state(&mut context, &mut block_state); + let mut storage_state = reset_cctx_tail_test_storage_state(&mut context); + let state = reset_cctx_tail_test_state(&mut context, &mut block_state, &mut storage_state); assert_eq!( unsafe { ZSTD_rust_resetCCtxTail(&state) }, @@ -23591,7 +23684,8 @@ mod tests { }; let mut block_state = unsafe { MaybeUninit::::zeroed().assume_init() }; - let state = reset_cctx_tail_test_state(&mut context, &mut block_state); + let mut storage_state = reset_cctx_tail_test_storage_state(&mut context); + let state = reset_cctx_tail_test_state(&mut context, &mut block_state, &mut storage_state); assert_eq!( unsafe { ZSTD_rust_resetCCtxTail(&state) },