feat(cli): move patch-from window policy to Rust
Keep patch-from orchestration in C while extracting only the bounded window selection and automatic-LDM decision into the Rust CLI leaf. The C caller still computes the raw file window with FIO_highbit64, obtains cParams, updates the memory limit, emits warnings and optimal-parser notes, and writes comprParams->windowLog and prefs->ldmFlag. Rust receives only scalar policy inputs and two output pointers, clamps the selected window to the target's 10..30/31 bounds, and compares the unclamped value strictly against cycleLog. This preserves equality as no-LDM and keeps values above the maximum eligible to trigger LDM. Focused unit tests cover both clamps and each comparison edge. Test Plan: - `cargo clippy --manifest-path rust/Cargo.toml --no-default-features --features compression` with library, `--benches`, and `--tests`, before and after formatting -- passed - `cargo +nightly fmt --manifest-path rust/Cargo.toml -- --config skip_children=true` and nightly rustfmt on the owned file -- passed - `cargo test --manifest-path rust/cli/Cargo.toml --no-default-features --features cli,compression,decompression,benchmark fileio_prefs` -- 36 passed - `make -C programs -j2 zstd` -- passed - `make -C tests -j2 test-cli-tests` -- 41 passed - Focused patch-from round trip and automatic long-mode trigger -- passed
This commit is contained in:
+12
-2
@@ -329,6 +329,10 @@ int FIO_rust_checkFilenameCollisions(const char** filenameTable, unsigned nbFile
|
||||
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_patchFromWindowPolicy(unsigned fileWindowLog,
|
||||
unsigned cycleLog,
|
||||
unsigned* windowLog,
|
||||
int* enableLdm);
|
||||
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);
|
||||
@@ -877,11 +881,17 @@ static void FIO_adjustParamsForPatchFromMode(FIO_prefs_t* const prefs,
|
||||
{
|
||||
unsigned const fileWindowLog = FIO_highbit64(maxSrcFileSize) + 1;
|
||||
ZSTD_compressionParameters const cParams = ZSTD_getCParams(cLevel, (size_t)maxSrcFileSize, (size_t)dictSize);
|
||||
unsigned windowLog;
|
||||
int enableLdm;
|
||||
FIO_adjustMemLimitForPatchFromMode(prefs, dictSize, maxSrcFileSize);
|
||||
FIO_rust_patchFromWindowPolicy(fileWindowLog,
|
||||
ZSTD_cycleLog(cParams.chainLog, cParams.strategy),
|
||||
&windowLog,
|
||||
&enableLdm);
|
||||
if (fileWindowLog > ZSTD_WINDOWLOG_MAX)
|
||||
DISPLAYLEVEL(1, "Max window log exceeded by file (compression ratio will suffer)\n");
|
||||
comprParams->windowLog = MAX(ZSTD_WINDOWLOG_MIN, MIN(ZSTD_WINDOWLOG_MAX, fileWindowLog));
|
||||
if (fileWindowLog > ZSTD_cycleLog(cParams.chainLog, cParams.strategy)) {
|
||||
comprParams->windowLog = windowLog;
|
||||
if (enableLdm) {
|
||||
if (!prefs->ldmFlag)
|
||||
DISPLAYLEVEL(2, "long mode automatically triggered\n");
|
||||
FIO_setLdmFlag(prefs, 1);
|
||||
|
||||
@@ -29,6 +29,7 @@ const FIO_MULTI_FILES_ACTION_DISABLE_REMOVE: c_int = 3;
|
||||
const FIO_MULTI_FILES_ACTION_QUIET_ABORT: c_int = 4;
|
||||
const FIO_MULTI_FILES_ACTION_CONFIRM: c_int = 5;
|
||||
const UTIL_FILESIZE_UNKNOWN: u64 = u64::MAX;
|
||||
const ZSTD_WINDOWLOG_MIN: u32 = 10;
|
||||
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";
|
||||
@@ -609,6 +610,20 @@ pub extern "C" fn FIO_rust_cycleLog(hash_log: c_uint, strategy: c_int) -> c_uint
|
||||
cycle_log(hash_log, strategy)
|
||||
}
|
||||
|
||||
/// Rust scalar ABI for patch-from window and automatic-LDM policy.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn FIO_rust_patchFromWindowPolicy(
|
||||
file_window_log: c_uint,
|
||||
cycle_log: c_uint,
|
||||
window_log: *mut c_uint,
|
||||
enable_ldm: *mut c_int,
|
||||
) {
|
||||
unsafe {
|
||||
window_log.write(file_window_log.clamp(ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX));
|
||||
enable_ldm.write(c_int::from(file_window_log > cycle_log));
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
#[inline]
|
||||
fn multi_files_concat_action(
|
||||
@@ -1179,6 +1194,54 @@ mod tests {
|
||||
assert_eq!(FIO_rust_cycleLog(20, ZSTD_BTLAZY2 + 3), 19);
|
||||
}
|
||||
|
||||
fn patch_from_window_policy(file_window_log: c_uint, cycle_log: c_uint) -> (c_uint, c_int) {
|
||||
let mut window_log = c_uint::MAX;
|
||||
let mut enable_ldm = -1;
|
||||
unsafe {
|
||||
FIO_rust_patchFromWindowPolicy(
|
||||
file_window_log,
|
||||
cycle_log,
|
||||
&mut window_log,
|
||||
&mut enable_ldm,
|
||||
);
|
||||
}
|
||||
(window_log, enable_ldm)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn patch_from_window_policy_clamps_to_lower_bound() {
|
||||
assert_eq!(
|
||||
patch_from_window_policy(ZSTD_WINDOWLOG_MIN - 1, ZSTD_WINDOWLOG_MIN),
|
||||
(ZSTD_WINDOWLOG_MIN, 0)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn patch_from_window_policy_clamps_to_upper_bound() {
|
||||
assert_eq!(
|
||||
patch_from_window_policy(ZSTD_WINDOWLOG_MAX + 1, ZSTD_WINDOWLOG_MAX + 1),
|
||||
(ZSTD_WINDOWLOG_MAX, 0)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn patch_from_window_policy_keeps_equal_cycle_log_out_of_ldm() {
|
||||
assert_eq!(patch_from_window_policy(20, 20), (20, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn patch_from_window_policy_enables_ldm_one_above_cycle_log() {
|
||||
assert_eq!(patch_from_window_policy(20, 19), (20, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn patch_from_window_policy_uses_raw_value_above_upper_bound_for_ldm() {
|
||||
assert_eq!(
|
||||
patch_from_window_policy(ZSTD_WINDOWLOG_MAX + 1, ZSTD_WINDOWLOG_MAX),
|
||||
(ZSTD_WINDOWLOG_MAX, 1)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_files_concat_policy_protects_stdout_and_test_mode_removal() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user