feat(compress): move local dictionary sizing leaf to Rust

ZSTD_sizeof_localDict only combines the optional local dictionary buffer
size with the already-owned C dictionary size. Keep dictionary ownership and
workspace sizing in C, but pass the three scalar inputs to Rust so the leaf
uses explicit C size_t wrapping semantics. The CCtx NULL sizing guard and
surrounding ownership and call structure remain unchanged.

Test Plan:
- `cargo clippy --manifest-path rust/Cargo.toml --no-default-features --features compression` (before and after formatting) -- passed
- The same clippy command with `--benches` and `--tests` (before and after formatting) -- passed
- `cargo +nightly fmt --manifest-path rust/Cargo.toml` -- passed
- `cargo test --manifest-path rust/Cargo.toml --no-default-features --features compression` -- 272 passed
- `make -B -C lib -j2 lib` -- passed
- `make -C tests test-rust-lib-smoke` and direct `rustLibSmoke` execution -- passed
- `make -C tests -j2 fuzzer` -- passed
- `./fuzzer -s4560 -t56 -i57 -v` -- passed
- `git diff --check` and `git diff --cached --check` -- passed
This commit is contained in:
2026-07-18 10:22:36 +02:00
parent b581042717
commit faffd99d1c
2 changed files with 43 additions and 2 deletions
+4 -2
View File
@@ -88,6 +88,8 @@ size_t ZSTD_rust_nextInputSizeHint(int inBufferMode,
size_t inBuffPos);
size_t ZSTD_rust_CStreamInSize(void);
size_t ZSTD_rust_CStreamOutSize(void);
size_t ZSTD_rust_sizeofLocalDict(int dictBufferPresent, size_t dictSize,
size_t cdictSize);
/* Context-free compression-parameter selection and sizing leaves live in
* Rust (rust/src/zstd_compress_params.rs). This file retains
@@ -528,9 +530,9 @@ static void ZSTD_clearAllDicts(ZSTD_CCtx* cctx)
static size_t ZSTD_sizeof_localDict(ZSTD_localDict dict)
{
size_t const bufferSize = dict.dictBuffer != NULL ? dict.dictSize : 0;
size_t const cdictSize = ZSTD_sizeof_CDict(dict.cdict);
return bufferSize + cdictSize;
return ZSTD_rust_sizeofLocalDict(dict.dictBuffer != NULL, dict.dictSize,
cdictSize);
}
static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx)
+39
View File
@@ -301,6 +301,26 @@ pub extern "C" fn ZSTD_rust_dictTooBig(loaded_dict_size: usize) -> c_int {
dict_too_big(loaded_dict_size) as c_int
}
#[inline]
fn sizeof_local_dict(dict_buffer_present: c_int, dict_size: usize, cdict_size: usize) -> usize {
let buffer_size = if dict_buffer_present != 0 {
dict_size
} else {
0
};
buffer_size.wrapping_add(cdict_size)
}
/// Add the C-owned local-dictionary sizes with C `size_t` wrapping semantics.
#[no_mangle]
pub extern "C" fn ZSTD_rust_sizeofLocalDict(
dict_buffer_present: c_int,
dict_size: usize,
cdict_size: usize,
) -> usize {
sizeof_local_dict(dict_buffer_present, dict_size, cdict_size)
}
#[inline]
fn reduce_table_internal(table: &mut [u32], reducer_value: u32, preserve_mark: bool) {
debug_assert_eq!(table.len() % ZSTD_ROWSIZE, 0);
@@ -1136,6 +1156,25 @@ mod tests {
assert_eq!(rep, [0; ZSTD_REP_NUM]);
}
#[test]
fn sizeof_local_dict_ignores_size_without_a_buffer() {
assert_eq!(sizeof_local_dict(0, 37, 11), 11);
assert_eq!(ZSTD_rust_sizeofLocalDict(0, 37, 11), 11);
}
#[test]
fn sizeof_local_dict_adds_present_buffer_and_cdict_sizes() {
assert_eq!(sizeof_local_dict(1, 37, 11), 48);
assert_eq!(sizeof_local_dict(1, 0, 11), 11);
assert_eq!(ZSTD_rust_sizeofLocalDict(1, 37, 11), 48);
}
#[test]
fn sizeof_local_dict_wraps_like_c_size_t_addition() {
assert_eq!(sizeof_local_dict(1, usize::MAX, 1), 0);
assert_eq!(sizeof_local_dict(0, usize::MAX, usize::MAX), usize::MAX);
}
#[test]
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 =