feat(cli): move compression preference formatting into Rust
The verbose compression-preference summary was still formatted by the C file-I/O orchestration layer even though the preference object and the rest of its policy helpers already lived in Rust. Move the option selection and exact summary formatting into the Rust CLI archive, keeping the public C function as a narrow assertion-and-dispatch shim. The Rust formatter preserves the legacy option spellings, default memory limit, integer casts, and stderr output, with a focused string-format regression test. Test Plan: - `cargo fmt --manifest-path rust/cli/Cargo.toml -- --check` -- passed - `cargo test --manifest-path rust/cli/Cargo.toml --lib fileio_prefs -- --test-threads=1` -- 46 passed - `git diff --check` -- passed
This commit is contained in:
@@ -712,6 +712,89 @@ fn display(level: c_int, message: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
fn checked_option(options: &[&'static str], index: c_int) -> &'static str {
|
||||
options
|
||||
.get(index as usize)
|
||||
.copied()
|
||||
.unwrap_or_else(|| std::process::abort())
|
||||
}
|
||||
|
||||
fn format_compression_parameters(prefs: &FIO_prefs_t) -> String {
|
||||
let format = checked_option(
|
||||
&[".zst", ".gz", ".xz", ".lzma", ".lz4"],
|
||||
prefs.compressionType,
|
||||
);
|
||||
let sparse = checked_option(&[" --no-sparse", "", " --sparse"], prefs.sparseFileSupport);
|
||||
let checksum = checked_option(&[" --no-check", "", " --check"], prefs.checksumFlag);
|
||||
let row_match_finder = checked_option(
|
||||
&["", " --no-row-match-finder", " --row-match-finder"],
|
||||
prefs.useRowMatchFinder,
|
||||
);
|
||||
let compress_literals = checked_option(
|
||||
&["", " --compress-literals", " --no-compress-literals"],
|
||||
prefs.literalCompressionMode,
|
||||
);
|
||||
|
||||
let mut result = format!("--format={format}{sparse}");
|
||||
if prefs.dictIDFlag == 0 {
|
||||
result.push_str(" --no-dictID");
|
||||
}
|
||||
result.push_str(checksum);
|
||||
result.push_str(&format!(" --block-size={}", prefs.blockSize));
|
||||
if prefs.adaptiveMode != 0 {
|
||||
result.push_str(&format!(
|
||||
" --adapt=min={},max={}",
|
||||
prefs.minAdaptLevel, prefs.maxAdaptLevel
|
||||
));
|
||||
}
|
||||
result.push_str(row_match_finder);
|
||||
if prefs.rsyncable != 0 {
|
||||
result.push_str(" --rsyncable");
|
||||
}
|
||||
if prefs.streamSrcSize != 0 {
|
||||
result.push_str(&format!(" --stream-size={}", prefs.streamSrcSize as c_uint));
|
||||
}
|
||||
if prefs.srcSizeHint != 0 {
|
||||
result.push_str(&format!(" --size-hint={}", prefs.srcSizeHint));
|
||||
}
|
||||
if prefs.targetCBlockSize != 0 {
|
||||
result.push_str(&format!(
|
||||
" --target-compressed-block-size={}",
|
||||
prefs.targetCBlockSize as c_uint
|
||||
));
|
||||
}
|
||||
result.push_str(compress_literals);
|
||||
result.push_str(&format!(
|
||||
" --memory={} --threads={}",
|
||||
if prefs.memLimit != 0 {
|
||||
prefs.memLimit
|
||||
} else {
|
||||
128 * 1024 * 1024
|
||||
},
|
||||
prefs.nbWorkers
|
||||
));
|
||||
if prefs.excludeCompressedFiles != 0 {
|
||||
result.push_str(" --exclude-compressed");
|
||||
}
|
||||
result.push_str(if prefs.contentSize != 0 {
|
||||
" --content-size"
|
||||
} else {
|
||||
" --no-content-size"
|
||||
});
|
||||
result.push('\n');
|
||||
result
|
||||
}
|
||||
|
||||
/// Rust implementation of the verbose preference summary used by CLI diagnostics.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn FIO_rust_displayCompressionParameters(prefs: *const FIO_prefs_t) {
|
||||
if prefs.is_null() {
|
||||
return;
|
||||
}
|
||||
let output = format_compression_parameters(unsafe { &*prefs });
|
||||
eprint!("{output}");
|
||||
}
|
||||
|
||||
fn throw(error: c_int, message: &str) -> ! {
|
||||
let enabled = unsafe { (*display_prefs()).displayLevel >= 1 };
|
||||
if enabled {
|
||||
@@ -2557,6 +2640,38 @@ mod tests {
|
||||
unsafe { FIO_freePreferences(prefs as *const FIO_prefs_t as *mut FIO_prefs_t) };
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compression_parameter_format_matches_fileio_c() {
|
||||
let mut prefs = unsafe { std::mem::zeroed::<FIO_prefs_t>() };
|
||||
prefs.compressionType = FIO_ZSTD_COMPRESSION;
|
||||
prefs.sparseFileSupport = 2;
|
||||
prefs.dictIDFlag = 0;
|
||||
prefs.checksumFlag = 2;
|
||||
prefs.blockSize = 131_072;
|
||||
prefs.adaptiveMode = 1;
|
||||
prefs.minAdaptLevel = 1;
|
||||
prefs.maxAdaptLevel = 9;
|
||||
prefs.useRowMatchFinder = 1;
|
||||
prefs.rsyncable = 1;
|
||||
prefs.streamSrcSize = 4096;
|
||||
prefs.srcSizeHint = 8192;
|
||||
prefs.targetCBlockSize = 16_384;
|
||||
prefs.literalCompressionMode = 2;
|
||||
prefs.memLimit = 64 * 1024 * 1024;
|
||||
prefs.nbWorkers = 3;
|
||||
prefs.excludeCompressedFiles = 1;
|
||||
prefs.contentSize = 0;
|
||||
|
||||
assert_eq!(
|
||||
format_compression_parameters(&prefs),
|
||||
"--format=.zst --sparse --no-dictID --check --block-size=131072 ".to_owned()
|
||||
+ "--adapt=min=1,max=9 --no-row-match-finder --rsyncable "
|
||||
+ "--stream-size=4096 --size-hint=8192 "
|
||||
+ "--target-compressed-block-size=16384 --no-compress-literals "
|
||||
+ "--memory=67108864 --threads=3 --exclude-compressed --no-content-size\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn context_defaults_and_setters_match_fileio_c() {
|
||||
let ctx = unsafe { FIO_createContext() };
|
||||
|
||||
Reference in New Issue
Block a user