feat(compress): move block-state confirmation to Rust
Keep C ownership of the block-state structure while delegating the confirmed-block pointer swap through a narrow two-pointer ABI leaf. Preserve every existing confirmation call site and add direct pointer-swap coverage. Test Plan: - cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression - cargo clippy --manifest-path rust/Cargo.toml --no-default-features --features compression --all-targets - cargo +nightly fmt --manifest-path rust/Cargo.toml - make -B -C lib -j2 lib - tests/fuzzer -s4560 -t47 -i48 -v - make -C tests -j2 test-zstream
This commit is contained in:
@@ -269,6 +269,9 @@ size_t ZSTD_rust_copyBlockSequences(
|
||||
SeqCollector* seqCollector, const SeqStore_t* seqStore,
|
||||
const U32 prevRepcodes[ZSTD_REP_NUM]);
|
||||
void ZSTD_rust_resetCompressedBlockState(ZSTD_compressedBlockState_t* bs);
|
||||
void ZSTD_rust_confirmRepcodesAndEntropyTables(
|
||||
ZSTD_compressedBlockState_t** prevCBlock,
|
||||
ZSTD_compressedBlockState_t** nextCBlock);
|
||||
void ZSTD_rust_storeLastLiterals(SeqStore_t* seqStorePtr,
|
||||
const BYTE* anchor, size_t lastLLSize);
|
||||
void ZSTD_rust_resetSeqStore(SeqStore_t* ssPtr);
|
||||
@@ -2596,9 +2599,8 @@ static int ZSTD_maybeRLE(SeqStore_t const* seqStore)
|
||||
static void
|
||||
ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t* const bs)
|
||||
{
|
||||
ZSTD_compressedBlockState_t* const tmp = bs->prevCBlock;
|
||||
bs->prevCBlock = bs->nextCBlock;
|
||||
bs->nextCBlock = tmp;
|
||||
ZSTD_rust_confirmRepcodesAndEntropyTables(
|
||||
&bs->prevCBlock, &bs->nextCBlock);
|
||||
}
|
||||
|
||||
/* Writes the block header */
|
||||
|
||||
@@ -1095,6 +1095,18 @@ pub unsafe extern "C" fn ZSTD_rust_resetCompressedBlockState(
|
||||
block_state.entropy.fse.litlength_repeatMode = FSE_REPEAT_NONE;
|
||||
}
|
||||
|
||||
/// Swaps the two C-owned block-state pointers after a block is confirmed.
|
||||
///
|
||||
/// The enclosing `ZSTD_blockState_t` contains C-only match-state storage, so
|
||||
/// the ABI deliberately passes only the two pointer fields separately.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_rust_confirmRepcodesAndEntropyTables(
|
||||
prev_c_block: *mut *mut ZSTD_compressedBlockState_t,
|
||||
next_c_block: *mut *mut ZSTD_compressedBlockState_t,
|
||||
) {
|
||||
unsafe { ptr::swap(prev_c_block, next_c_block) };
|
||||
}
|
||||
|
||||
/// Appends the final literals of a block to its sequence store.
|
||||
///
|
||||
/// The source and destination ranges must be valid and non-overlapping, as
|
||||
@@ -3258,6 +3270,23 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn confirm_repcodes_and_entropy_tables_swaps_block_state_pointers() {
|
||||
let mut previous_storage = std::mem::MaybeUninit::<ZSTD_compressedBlockState_t>::uninit();
|
||||
let mut next_storage = std::mem::MaybeUninit::<ZSTD_compressedBlockState_t>::uninit();
|
||||
let previous = previous_storage.as_mut_ptr();
|
||||
let next = next_storage.as_mut_ptr();
|
||||
let mut previous_ptr = previous;
|
||||
let mut next_ptr = next;
|
||||
|
||||
unsafe {
|
||||
ZSTD_rust_confirmRepcodesAndEntropyTables(&mut previous_ptr, &mut next_ptr);
|
||||
}
|
||||
|
||||
assert_eq!(previous_ptr, next);
|
||||
assert_eq!(next_ptr, previous);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn store_last_literals_copies_bytes_and_advances_only_the_literal_cursor() {
|
||||
let mut sequences = [SeqDef::default(); 2];
|
||||
|
||||
Reference in New Issue
Block a user