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)
This commit is contained in:
2026-07-18 05:06:48 +02:00
parent cba0373a2b
commit ce992fb0be
2 changed files with 29 additions and 2 deletions
+2 -2
View File
@@ -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,
+27
View File
@@ -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::<usize>() == 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<I>(sizes: I) -> u64
where
I: IntoIterator<Item = u64>,
@@ -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>();