From ce992fb0bed5cfc6deb43c8254cc4b5ee56e4d59 Mon Sep 17 00:00:00 2001 From: ddidderr Date: Sat, 18 Jul 2026 05:06:48 +0200 Subject: [PATCH] feat(cli): move cycle log policy to Rust Move the CLI's strategy-dependent cycle-log calculation behind a scalar Rust ABI shim while retaining the C assertion and call-site behavior. Test Plan: - cargo test --manifest-path rust/cli/Cargo.toml --no-default-features --features cli,compression,decompression,benchmark (116 tests) - cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets with the full CLI feature set - make -B -C programs -j2 zstd zstd-small zstd-frugal - make -C tests -j2 test-cli-tests (41 scenarios) --- programs/fileio.c | 4 ++-- rust/src/fileio_prefs.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 232c96d8e..a8ffcb50e 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -310,6 +310,7 @@ static int FIO_shouldDisplayMultipleFileSummary(FIO_ctx_t const* fCtx) int FIO_rust_checkFilenameCollisions(const char** filenameTable, unsigned nbFiles); unsigned FIO_rust_highbit64(unsigned long long v); unsigned long long FIO_rust_getLargestFileSize(const char** inFileNames, unsigned nbFiles); +unsigned FIO_rust_cycleLog(unsigned hashLog, int strategy); void FIO_rust_setInBuffer(ZSTD_inBuffer* output, const void* buf, size_t s, size_t pos); void FIO_rust_setOutBuffer(ZSTD_outBuffer* output, void* buf, size_t s, size_t pos); const char* FIO_rust_determineCompressedName(const char* srcFileName, const char* outDirName, const char* suffix); @@ -824,9 +825,8 @@ typedef struct { * condition for correct operation : hashLog > 1 */ static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat) { - U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2); assert(hashLog > 1); - return hashLog - btScale; + return FIO_rust_cycleLog(hashLog, (int)strat); } static void FIO_adjustParamsForPatchFromMode(FIO_prefs_t* const prefs, diff --git a/rust/src/fileio_prefs.rs b/rust/src/fileio_prefs.rs index d32e5d6bb..7c2002d2a 100644 --- a/rust/src/fileio_prefs.rs +++ b/rust/src/fileio_prefs.rs @@ -24,6 +24,7 @@ const FIO_PATCH_MEM_LIMIT_UNKNOWN_SIZE: c_int = 1; const FIO_PATCH_MEM_LIMIT_TOO_LARGE: c_int = 2; const UTIL_FILESIZE_UNKNOWN: u64 = u64::MAX; const ZSTD_WINDOWLOG_MAX: u32 = if size_of::() == 4 { 30 } else { 31 }; +const ZSTD_BTLAZY2: c_int = 6; static STDOUT_MARK: &[u8] = b"/*stdout*\\\0"; static mut COMPRESSED_NAME_CAPACITY: usize = 0; @@ -591,6 +592,17 @@ pub extern "C" fn FIO_rust_highbit64(value: u64) -> c_uint { (u64::BITS - 1 - value.leading_zeros()) as c_uint } +#[inline] +fn cycle_log(hash_log: c_uint, strategy: c_int) -> c_uint { + hash_log.wrapping_sub(c_uint::from(strategy >= ZSTD_BTLAZY2)) +} + +/// Rust scalar ABI for the `ZSTD_cycleLog()` policy in `programs/fileio.c`. +#[no_mangle] +pub extern "C" fn FIO_rust_cycleLog(hash_log: c_uint, strategy: c_int) -> c_uint { + cycle_log(hash_log, strategy) +} + fn largest_file_size(sizes: I) -> u64 where I: IntoIterator, @@ -1085,6 +1097,21 @@ mod tests { ); } + #[test] + fn cycle_log_keeps_lower_strategies_unchanged() { + assert_eq!(FIO_rust_cycleLog(20, ZSTD_BTLAZY2 - 1), 20); + } + + #[test] + fn cycle_log_subtracts_at_btlazy2_threshold() { + assert_eq!(FIO_rust_cycleLog(20, ZSTD_BTLAZY2), 19); + } + + #[test] + fn cycle_log_subtracts_for_upper_strategies() { + assert_eq!(FIO_rust_cycleLog(20, ZSTD_BTLAZY2 + 3), 19); + } + #[test] fn buffer_shims_preserve_fields_and_c_layout() { let input_word = size_of::<*const c_void>();