diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 238b98308..c9a85e6cc 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -48,7 +48,9 @@ int ZSTD_rust_updateFrameProgression(unsigned long long* consumedSrcSize, unsigned long long pledgedSrcSizePlusOne, size_t srcSize, size_t cSize, size_t fhSize); -U64 ZSTD_rust_frameProgressionIngested(U64 consumedSrcSize, size_t buffered); +ZSTD_frameProgression ZSTD_rust_frameProgression(U64 consumedSrcSize, + size_t buffered, + U64 producedCSize); size_t ZSTD_rust_resetCCtxForSimpleCompression(void* cctx); size_t ZSTD_rust_prepareCCtxForSimpleCompression(void* cctx, size_t srcSize, @@ -1436,19 +1438,14 @@ ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx) return ZSTDMT_getFrameProgression(cctx->mtctx); } #endif - { ZSTD_frameProgression fp; + { size_t const buffered = (cctx->inBuff == NULL) ? 0 : cctx->inBuffPos - cctx->inToCompress; if (buffered) assert(cctx->inBuffPos >= cctx->inToCompress); assert(buffered <= ZSTD_BLOCKSIZE_MAX); - fp.ingested = ZSTD_rust_frameProgressionIngested(cctx->consumedSrcSize, buffered); - fp.consumed = cctx->consumedSrcSize; - fp.produced = cctx->producedCSize; - fp.flushed = cctx->producedCSize; /* simplified; some data might still be left within streaming output buffer */ - fp.currentJobID = 0; - fp.nbActiveWorkers = 0; - return fp; -} } + return ZSTD_rust_frameProgression(cctx->consumedSrcSize, buffered, + cctx->producedCSize); + } } /*! ZSTD_toFlushNow() * Only useful for multithreading scenarios currently (nbWorkers >= 1). diff --git a/rust/src/zstd_compress.rs b/rust/src/zstd_compress.rs index d282938af..a2f1a6e1c 100644 --- a/rust/src/zstd_compress.rs +++ b/rust/src/zstd_compress.rs @@ -29,7 +29,7 @@ use crate::zstd_compress_stats::{SeqStore_t, ZSTD_compressedBlockState_t}; use crate::zstd_compress_superblock::ZSTD_rust_compressSuperBlock; use std::ffi::c_void; use std::mem::{size_of, MaybeUninit}; -use std::os::raw::c_int; +use std::os::raw::{c_int, c_uint}; use std::ptr; #[cfg(not(test))] @@ -345,19 +345,43 @@ pub unsafe extern "C" fn ZSTD_rust_updateFrameProgression( ) as c_int } -#[inline] -fn frame_progression_ingested(consumed_src_size: u64, buffered: usize) -> u64 { - // C's usual arithmetic conversions promote size_t to U64 before wrapping. - consumed_src_size.wrapping_add(buffered as u64) +/// ABI-compatible representation of `ZSTD_frameProgression` from `zstd.h`. +#[repr(C)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub struct ZSTD_frameProgression { + pub ingested: u64, + pub consumed: u64, + pub produced: u64, + pub flushed: u64, + pub currentJobID: c_uint, + pub nbActiveWorkers: c_uint, } -/// Calculate single-threaded frame input progression from consumed and buffered input. -#[no_mangle] -pub extern "C" fn ZSTD_rust_frameProgressionIngested( +#[inline] +fn frame_progression( consumed_src_size: u64, buffered: usize, -) -> u64 { - frame_progression_ingested(consumed_src_size, buffered) + produced_c_size: u64, +) -> ZSTD_frameProgression { + ZSTD_frameProgression { + // C's usual arithmetic conversions promote size_t to U64 before wrapping. + ingested: consumed_src_size.wrapping_add(buffered as u64), + consumed: consumed_src_size, + produced: produced_c_size, + flushed: produced_c_size, + currentJobID: 0, + nbActiveWorkers: 0, + } +} + +/// Construct single-threaded frame progression from C-owned scalar state. +#[no_mangle] +pub extern "C" fn ZSTD_rust_frameProgression( + consumed_src_size: u64, + buffered: usize, + produced_c_size: u64, +) -> ZSTD_frameProgression { + frame_progression(consumed_src_size, buffered, produced_c_size) } #[inline] @@ -1435,35 +1459,38 @@ mod tests { } #[test] - fn frame_progression_ingested_handles_zero() { - assert_eq!(frame_progression_ingested(0, 0), 0); - assert_eq!(ZSTD_rust_frameProgressionIngested(0, 0), 0); - } - - #[test] - fn frame_progression_ingested_adds_consumed_and_buffered_input() { + fn frame_progression_constructs_single_thread_values() { let consumed = 11_u64; let buffered = 37_usize; - let expected = consumed + buffered as u64; + let produced = 53_u64; + let expected = ZSTD_frameProgression { + ingested: consumed + buffered as u64, + consumed, + produced, + flushed: produced, + currentJobID: 0, + nbActiveWorkers: 0, + }; - assert_eq!(frame_progression_ingested(consumed, buffered), expected); + assert_eq!(frame_progression(consumed, buffered, produced), expected); assert_eq!( - ZSTD_rust_frameProgressionIngested(consumed, buffered), + ZSTD_rust_frameProgression(consumed, buffered, produced), expected ); } #[test] - fn frame_progression_ingested_wraps_u64() { + fn frame_progression_wraps_buffered_input_to_u64() { let consumed = u64::MAX - 3; let buffered = 8_usize; - let expected = consumed.wrapping_add(buffered as u64); + let progression = ZSTD_rust_frameProgression(consumed, buffered, 17); - assert_eq!(frame_progression_ingested(consumed, buffered), expected); - assert_eq!( - ZSTD_rust_frameProgressionIngested(consumed, buffered), - expected - ); + assert_eq!(progression.ingested, consumed.wrapping_add(buffered as u64)); + assert_eq!(progression.consumed, consumed); + assert_eq!(progression.produced, 17); + assert_eq!(progression.flushed, 17); + assert_eq!(progression.currentJobID, 0); + assert_eq!(progression.nbActiveWorkers, 0); } #[test]