feat(compress): move workspace size aggregation to Rust
Keep all context-sensitive workspace sizing in C, including intermediate allocation calculations, match-state and LDM sizing, error propagation, and diagnostics. Move only the final nine-component neededSpace aggregation behind a scalar Rust ABI helper so its size_t wrapping behavior is explicit and independently tested. Test Plan: - `cargo clippy --manifest-path rust/Cargo.toml --no-default-features --features compression` -- passed before and after formatting. - The same command with `--benches` and `--tests` -- passed before and after formatting. - `cargo +nightly fmt --manifest-path rust/Cargo.toml` -- passed. - `cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression zstd_compress` -- 186 passed. - `make -B -C lib -j2 lib` -- passed. - `make -C tests test-rust-lib-smoke` -- passed. - `tests/fuzzer -s4560 -t56 -i57 -v` -- passed. - `make -C tests -j2 test-zstream` -- 84 named tests and 6,536 plus 7,961 randomized cases passed; the existing unterminated-string warning remains. - `git diff --cached --check` -- passed.
This commit is contained in:
@@ -92,6 +92,15 @@ size_t ZSTD_rust_sizeofLocalDict(int dictBufferPresent, size_t dictSize,
|
|||||||
size_t cdictSize);
|
size_t cdictSize);
|
||||||
size_t ZSTD_rust_sizeofCCtx(size_t objectSize, size_t workspaceSize,
|
size_t ZSTD_rust_sizeofCCtx(size_t objectSize, size_t workspaceSize,
|
||||||
size_t localDictSize, size_t mtctxSize);
|
size_t localDictSize, size_t mtctxSize);
|
||||||
|
size_t ZSTD_rust_estimateWorkspaceSize(size_t cctxSpace,
|
||||||
|
size_t tmpWorkSpace,
|
||||||
|
size_t blockStateSpace,
|
||||||
|
size_t ldmSpace,
|
||||||
|
size_t ldmSeqSpace,
|
||||||
|
size_t matchStateSize,
|
||||||
|
size_t tokenSpace,
|
||||||
|
size_t bufferSpace,
|
||||||
|
size_t externalSeqSpace);
|
||||||
ZSTD_inBuffer ZSTD_rust_inBufferForEndFlush(int inBufferMode,
|
ZSTD_inBuffer ZSTD_rust_inBufferForEndFlush(int inBufferMode,
|
||||||
const void* expectedSrc,
|
const void* expectedSrc,
|
||||||
size_t expectedSize,
|
size_t expectedSize,
|
||||||
@@ -1284,16 +1293,9 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
|||||||
? ZSTD_cwksp_aligned64_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence))
|
? ZSTD_cwksp_aligned64_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence))
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
size_t const neededSpace =
|
size_t const neededSpace = ZSTD_rust_estimateWorkspaceSize(
|
||||||
cctxSpace +
|
cctxSpace, tmpWorkSpace, blockStateSpace, ldmSpace, ldmSeqSpace,
|
||||||
tmpWorkSpace +
|
matchStateSize, tokenSpace, bufferSpace, externalSeqSpace);
|
||||||
blockStateSpace +
|
|
||||||
ldmSpace +
|
|
||||||
ldmSeqSpace +
|
|
||||||
matchStateSize +
|
|
||||||
tokenSpace +
|
|
||||||
bufferSpace +
|
|
||||||
externalSeqSpace;
|
|
||||||
|
|
||||||
DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
|
DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
|
||||||
return neededSpace;
|
return neededSpace;
|
||||||
|
|||||||
@@ -455,6 +455,55 @@ pub extern "C" fn ZSTD_rust_sizeofCCtx(
|
|||||||
sizeof_cctx(object_size, workspace_size, local_dict_size, mtctx_size)
|
sizeof_cctx(object_size, workspace_size, local_dict_size, mtctx_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn estimate_workspace_size(
|
||||||
|
cctx_space: usize,
|
||||||
|
tmp_work_space: usize,
|
||||||
|
block_state_space: usize,
|
||||||
|
ldm_space: usize,
|
||||||
|
ldm_seq_space: usize,
|
||||||
|
match_state_size: usize,
|
||||||
|
token_space: usize,
|
||||||
|
buffer_space: usize,
|
||||||
|
external_seq_space: usize,
|
||||||
|
) -> usize {
|
||||||
|
cctx_space
|
||||||
|
.wrapping_add(tmp_work_space)
|
||||||
|
.wrapping_add(block_state_space)
|
||||||
|
.wrapping_add(ldm_space)
|
||||||
|
.wrapping_add(ldm_seq_space)
|
||||||
|
.wrapping_add(match_state_size)
|
||||||
|
.wrapping_add(token_space)
|
||||||
|
.wrapping_add(buffer_space)
|
||||||
|
.wrapping_add(external_seq_space)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Aggregate workspace-size components with C `size_t` wrapping semantics.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn ZSTD_rust_estimateWorkspaceSize(
|
||||||
|
cctx_space: usize,
|
||||||
|
tmp_work_space: usize,
|
||||||
|
block_state_space: usize,
|
||||||
|
ldm_space: usize,
|
||||||
|
ldm_seq_space: usize,
|
||||||
|
match_state_size: usize,
|
||||||
|
token_space: usize,
|
||||||
|
buffer_space: usize,
|
||||||
|
external_seq_space: usize,
|
||||||
|
) -> usize {
|
||||||
|
estimate_workspace_size(
|
||||||
|
cctx_space,
|
||||||
|
tmp_work_space,
|
||||||
|
block_state_space,
|
||||||
|
ldm_space,
|
||||||
|
ldm_seq_space,
|
||||||
|
match_state_size,
|
||||||
|
token_space,
|
||||||
|
buffer_space,
|
||||||
|
external_seq_space,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn reduce_table_internal(table: &mut [u32], reducer_value: u32, preserve_mark: bool) {
|
fn reduce_table_internal(table: &mut [u32], reducer_value: u32, preserve_mark: bool) {
|
||||||
debug_assert_eq!(table.len() % ZSTD_ROWSIZE, 0);
|
debug_assert_eq!(table.len() % ZSTD_ROWSIZE, 0);
|
||||||
@@ -1452,6 +1501,44 @@ mod tests {
|
|||||||
assert_eq!(ZSTD_rust_sizeofCCtx(usize::MAX, 1, 2, 3), 5);
|
assert_eq!(ZSTD_rust_sizeofCCtx(usize::MAX, 1, 2, 3), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn estimate_workspace_size_handles_zero_components() {
|
||||||
|
assert_eq!(estimate_workspace_size(0, 0, 0, 0, 0, 0, 0, 0, 0), 0);
|
||||||
|
assert_eq!(
|
||||||
|
ZSTD_rust_estimateWorkspaceSize(0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn estimate_workspace_size_adds_components_in_order() {
|
||||||
|
assert_eq!(estimate_workspace_size(1, 2, 3, 4, 5, 6, 7, 8, 9), 45);
|
||||||
|
assert_eq!(
|
||||||
|
ZSTD_rust_estimateWorkspaceSize(1, 2, 3, 4, 5, 6, 7, 8, 9),
|
||||||
|
45
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn estimate_workspace_size_wraps_at_multiple_operand_positions() {
|
||||||
|
assert_eq!(
|
||||||
|
estimate_workspace_size(usize::MAX, 1, 0, 0, 0, 0, 0, 0, 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
estimate_workspace_size(0, usize::MAX, 1, 0, 0, 0, 0, 0, 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
estimate_workspace_size(0, 0, 0, 0, 0, usize::MAX, 1, 0, 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ZSTD_rust_estimateWorkspaceSize(0, 0, 0, 0, 0, 0, 0, usize::MAX, 1),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn public_one_shot_abi_is_c_compatible() {
|
fn public_one_shot_abi_is_c_compatible() {
|
||||||
let entry: unsafe extern "C" fn(*mut c_void, usize, *const c_void, usize, c_int) -> usize =
|
let entry: unsafe extern "C" fn(*mut c_void, usize, *const c_void, usize, c_int) -> usize =
|
||||||
|
|||||||
Reference in New Issue
Block a user