feat(compress): move block header serialization to Rust
Keep the private writeBlockHeader signature and its debug logging in C while moving the pure block-type, size, and 24-bit little-endian encoding behind a narrow Rust ABI. The Rust leaf preserves the RLE blockSize path for cSize == 1 and the compressed cSize path for every other value. Test Plan: - `cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression block_header -- --nocapture` -- passed - `make -B -C lib -j2 lib` -- passed - `make -C tests -j2 fuzzer` -- passed - `./tests/fuzzer -s4560 -t47 -i48 -v` -- passed - Required clippy, nightly fmt, and diff checks -- passed
This commit is contained in:
@@ -37,6 +37,8 @@ size_t ZSTD_rust_writeFrameHeader(void* dst, size_t dstCapacity,
|
||||
int contentSizeFlag, int format,
|
||||
U32 windowLog, U64 pledgedSrcSize,
|
||||
U32 dictID);
|
||||
void ZSTD_rust_writeBlockHeader(void* op, size_t cSize, size_t blockSize,
|
||||
U32 lastBlock);
|
||||
size_t ZSTD_rust_writeEpilogue(void* dst, size_t dstCapacity, int* stage,
|
||||
int noDictIDFlag, int checksumFlag,
|
||||
int contentSizeFlag, int format, U32 windowLog,
|
||||
@@ -2592,10 +2594,7 @@ ZSTD_blockState_confirmRepcodesAndEntropyTables(ZSTD_blockState_t* const bs)
|
||||
static void
|
||||
writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock)
|
||||
{
|
||||
U32 const cBlockHeader = cSize == 1 ?
|
||||
lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
|
||||
lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
|
||||
MEM_writeLE24(op, cBlockHeader);
|
||||
ZSTD_rust_writeBlockHeader(op, cSize, blockSize, lastBlock);
|
||||
DEBUGLOG(5, "writeBlockHeader: cSize: %zu blockSize: %zu lastBlock: %u", cSize, blockSize, lastBlock);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ const ZSTD_F_ZSTD1: c_int = 0;
|
||||
const ZSTD_BLOCK_SIZE: usize = 128 << 10;
|
||||
const ZSTD_FAST: c_int = 1;
|
||||
const ZSTD_BTULTRA2: c_int = 9;
|
||||
const ZSTD_BT_COMPRESSED: u32 = 2;
|
||||
const SPLIT_LEVELS: [c_int; 10] = [0, 0, 1, 2, 2, 3, 3, 4, 4, 4];
|
||||
const ZSTD_BT_RLE: u32 = 1;
|
||||
const ZSTDCS_CREATED: c_int = 0;
|
||||
@@ -83,6 +84,31 @@ pub(crate) unsafe fn write_raw_block(
|
||||
needed
|
||||
}
|
||||
|
||||
/// Rust implementation of the private compressed-block header serializer.
|
||||
///
|
||||
/// The C wrapper retains the original static helper signature and keeps its
|
||||
/// debug logging at the call site. The helper itself only needs scalar
|
||||
/// values and writes the low 24 bits in little-endian order, as `MEM_writeLE24`
|
||||
/// does.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ZSTD_rust_writeBlockHeader(
|
||||
op: *mut c_void,
|
||||
c_size: usize,
|
||||
block_size: usize,
|
||||
last_block: c_uint,
|
||||
) {
|
||||
let block_type = if c_size == 1 {
|
||||
ZSTD_BT_RLE
|
||||
} else {
|
||||
ZSTD_BT_COMPRESSED
|
||||
};
|
||||
let size = if c_size == 1 { block_size } else { c_size };
|
||||
let header = last_block
|
||||
.wrapping_add(block_type << 1)
|
||||
.wrapping_add((size as u32).wrapping_shl(3));
|
||||
unsafe { write_le24(op.cast(), header) };
|
||||
}
|
||||
|
||||
/// Rust implementation of the private `ZSTD_writeFrameHeader()` leaf.
|
||||
///
|
||||
/// `no_dict_id_flag`, `checksum_flag`, `content_size_flag`, `format`, and
|
||||
@@ -604,6 +630,24 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn writes_rle_block_header() {
|
||||
let mut output = [0u8; ZSTD_BLOCKHEADERSIZE];
|
||||
unsafe {
|
||||
ZSTD_rust_writeBlockHeader(output.as_mut_ptr().cast(), 1, 0x12345, 1);
|
||||
}
|
||||
assert_eq!(output, [0x2b, 0x1a, 0x09]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn writes_compressed_block_header() {
|
||||
let mut output = [0u8; ZSTD_BLOCKHEADERSIZE];
|
||||
unsafe {
|
||||
ZSTD_rust_writeBlockHeader(output.as_mut_ptr().cast(), 0x23456, 0x54321, 1);
|
||||
}
|
||||
assert_eq!(output, [0xb5, 0xa2, 0x11]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optimal_block_size_keeps_small_blocks_intact() {
|
||||
let result = unsafe {
|
||||
|
||||
Reference in New Issue
Block a user