feat(compress): move streaming size helpers to Rust

The public streaming-size functions still calculated their values in the C
compressor entry point. Keep those public symbols and their size_t ABI in C,
but route the pure formulas through zstd_compress_api.rs. Rust uses usize for
the C size_t-equivalent constants and reuses its compressBound implementation;
the fixed block and header sizes make the output helper exactly 131591 bytes.

Test Plan:
- Focused Rust cstream size test -- passed (1 test)
- 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 staged diff checks -- passed
This commit is contained in:
2026-07-18 09:26:44 +02:00
parent 7a345bd2f7
commit da84c8ff95
2 changed files with 28 additions and 2 deletions
+24
View File
@@ -14,6 +14,8 @@ const ZSTD_MAX_INPUT_SIZE: usize = 0xFF00_FF00;
const SMALL_INPUT_THRESHOLD: usize = 128 << 10;
const ZSTD_MINMATCH_MIN: usize = 3;
const ZSTD_BLOCKSIZE_MAX_MIN: usize = 1 << 10;
const ZSTD_BLOCKSIZE_MAX: usize = 1 << 17;
const ZSTD_BLOCK_HEADER_SIZE: usize = 3;
/// ABI-compatible `ZSTD_Sequence` from `zstd.h`.
#[repr(C)]
@@ -41,6 +43,18 @@ pub extern "C" fn ZSTD_compressBound(src_size: usize) -> usize {
src_size.wrapping_add(src_size >> 8).wrapping_add(margin)
}
/// Returns the recommended input buffer size for the public streaming API.
#[no_mangle]
pub extern "C" fn ZSTD_rust_CStreamInSize() -> usize {
ZSTD_BLOCKSIZE_MAX
}
/// Returns the recommended output buffer size for the public streaming API.
#[no_mangle]
pub extern "C" fn ZSTD_rust_CStreamOutSize() -> usize {
ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_BLOCK_HEADER_SIZE + 4
}
/// Returns the maximum number of public sequences generated for an input.
#[no_mangle]
pub extern "C" fn ZSTD_sequenceBound(src_size: usize) -> usize {
@@ -89,6 +103,16 @@ mod tests {
assert!(ERR_isError(ZSTD_compressBound(ZSTD_MAX_INPUT_SIZE)));
}
#[test]
fn cstream_sizes_match_the_public_formulas() {
assert_eq!(ZSTD_rust_CStreamInSize(), 128 * 1024);
assert_eq!(
ZSTD_rust_CStreamOutSize(),
ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_BLOCK_HEADER_SIZE + 4
);
assert_eq!(ZSTD_rust_CStreamOutSize(), 131_591);
}
#[test]
fn sequence_bound_matches_the_public_formula() {
assert_eq!(ZSTD_sequenceBound(0), 2);