refactor(cli): move dictionary buffer selection policy to Rust

Move the malloc-versus-mmap decision used by compression and decompression
resource construction into Rust.  The C adapter continues to own platform
loaders, allocation handles, diagnostics, and dictionary I/O; Rust only
combines the explicit mmap preference, patch-mode size threshold, and explicit
disable override.  Add enum-value ABI checks and focused policy coverage.

Also hoist the source-size declaration in the C adapter so the migration does
not introduce a C90 declaration-after-statement warning.

Test Plan:
- `ulimit -v 41943040; cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check`
- `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings`
- `ulimit -v 41943040; make -j1`
- `ulimit -v 41943040; make -j1 -C tests test`
- `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings`
- `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/cli/Cargo.toml --all-targets`

The integrated checks ran at the combined working-tree tip under a serial
40 GiB virtual-memory limit. Standalone root Rust unit linking remains
unavailable because the crate imports C-owned bridge symbols without a Cargo
build/link setup.
This commit is contained in:
2026-07-20 09:50:12 +02:00
parent 7ea0cbd96e
commit ac4b7afca8
2 changed files with 66 additions and 11 deletions
+48
View File
@@ -642,6 +642,30 @@ pub unsafe extern "C" fn FIO_rust_munmapDict(
const FIO_MALLOC_DICT: c_int = 0;
const FIO_MMAP_DICT: c_int = 1;
const FIO_MMAP_POLICY_ENABLE: c_int = 1;
const FIO_MMAP_POLICY_DISABLE: c_int = 2;
/// Selects the dictionary backing store without performing any filesystem I/O.
///
/// Explicit mmap enable wins for ordinary dictionaries, patch mode requests a
/// mapping when the dictionary exceeds the memory limit, and an explicit
/// disable always wins over both. The C adapter retains the platform-specific
/// loaders and all diagnostics; this function owns only that policy decision.
#[no_mangle]
pub extern "C" fn FIO_rust_selectDictBufferType(
mmap_dict: c_int,
patch_from_mode: c_int,
dict_size: u64,
mem_limit: u64,
) -> c_int {
let auto_mmap = patch_from_mode != 0 && dict_size > mem_limit;
let requested_mmap = mmap_dict == FIO_MMAP_POLICY_ENABLE || auto_mmap;
if requested_mmap && mmap_dict != FIO_MMAP_POLICY_DISABLE {
FIO_MMAP_DICT
} else {
FIO_MALLOC_DICT
}
}
/// Releases either kind of dictionary buffer and clears its C-visible fields.
///
@@ -716,6 +740,30 @@ mod tests {
}
}
#[test]
fn dict_buffer_selection_preserves_mmap_preference_and_patch_policy() {
assert_eq!(
FIO_rust_selectDictBufferType(0, 0, 4096, 1),
FIO_MALLOC_DICT
);
assert_eq!(
FIO_rust_selectDictBufferType(0, 1, 4096, 8192),
FIO_MALLOC_DICT
);
assert_eq!(
FIO_rust_selectDictBufferType(0, 1, 8193, 8192),
FIO_MMAP_DICT
);
assert_eq!(
FIO_rust_selectDictBufferType(FIO_MMAP_POLICY_ENABLE, 0, 0, 0),
FIO_MMAP_DICT
);
assert_eq!(
FIO_rust_selectDictBufferType(FIO_MMAP_POLICY_DISABLE, 1, u64::MAX, 0),
FIO_MALLOC_DICT
);
}
fn open_source(path: &Path) -> (c_int, *mut c_void) {
let path = c_path(path);
let mut stat_buf = MaybeUninit::<libc::stat>::uninit();