feat(fileio): move buffer helpers to Rust
Route file-I/O input/output buffer construction and the LZ4 block-size mapping through Rust ABI leaves while preserving the existing C helper names and public buffer layouts. Add layout, field, and formula coverage. Test Plan: cargo test --manifest-path rust/cli/Cargo.toml --no-default-features --features cli,compression,decompression,benchmark; cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets --no-default-features --features cli,compression,decompression,benchmark; make -B -C programs -j2 zstd zstd-small zstd-frugal; make -B -C tests -j2 test-cli-tests
This commit is contained in:
+11
-7
@@ -309,6 +309,11 @@ static int FIO_shouldDisplayMultipleFileSummary(FIO_ctx_t const* fCtx)
|
|||||||
int FIO_rust_checkFilenameCollisions(const char** filenameTable, unsigned nbFiles);
|
int FIO_rust_checkFilenameCollisions(const char** filenameTable, unsigned nbFiles);
|
||||||
unsigned FIO_rust_highbit64(unsigned long long v);
|
unsigned FIO_rust_highbit64(unsigned long long v);
|
||||||
unsigned long long FIO_rust_getLargestFileSize(const char** inFileNames, unsigned nbFiles);
|
unsigned long long FIO_rust_getLargestFileSize(const char** inFileNames, unsigned nbFiles);
|
||||||
|
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);
|
||||||
|
#ifdef ZSTD_LZ4COMPRESS
|
||||||
|
int FIO_rust_LZ4_GetBlockSize_FromBlockId(int id);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
@@ -792,18 +797,14 @@ static int FIO_multiFilesConcatWarning(const FIO_ctx_t* fCtx, FIO_prefs_t* prefs
|
|||||||
static ZSTD_inBuffer setInBuffer(const void* buf, size_t s, size_t pos)
|
static ZSTD_inBuffer setInBuffer(const void* buf, size_t s, size_t pos)
|
||||||
{
|
{
|
||||||
ZSTD_inBuffer i;
|
ZSTD_inBuffer i;
|
||||||
i.src = buf;
|
FIO_rust_setInBuffer(&i, buf, s, pos);
|
||||||
i.size = s;
|
|
||||||
i.pos = pos;
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ZSTD_outBuffer setOutBuffer(void* buf, size_t s, size_t pos)
|
static ZSTD_outBuffer setOutBuffer(void* buf, size_t s, size_t pos)
|
||||||
{
|
{
|
||||||
ZSTD_outBuffer o;
|
ZSTD_outBuffer o;
|
||||||
o.dst = buf;
|
FIO_rust_setOutBuffer(&o, buf, s, pos);
|
||||||
o.size = s;
|
|
||||||
o.pos = pos;
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1140,7 +1141,10 @@ FIO_compressLzmaFrame(cRess_t* ress,
|
|||||||
#define LZ4F_max64KB max64KB
|
#define LZ4F_max64KB max64KB
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int FIO_LZ4_GetBlockSize_FromBlockId (int id) { return (1 << (8 + (2 * id))); }
|
static int FIO_LZ4_GetBlockSize_FromBlockId (int id)
|
||||||
|
{
|
||||||
|
return FIO_rust_LZ4_GetBlockSize_FromBlockId(id);
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned long long
|
static unsigned long long
|
||||||
FIO_compressLz4Frame(cRess_t* ress,
|
FIO_compressLz4Frame(cRess_t* ress,
|
||||||
|
|||||||
@@ -20,6 +20,20 @@ const FIO_ZSTD_COMPRESSION: c_int = 0;
|
|||||||
const FIO_OVERLAP_LOG_NOTSET: c_int = 9999;
|
const FIO_OVERLAP_LOG_NOTSET: c_int = 9999;
|
||||||
const FIO_LDM_PARAM_NOTSET: c_int = 9999;
|
const FIO_LDM_PARAM_NOTSET: c_int = 9999;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct FIO_inBuffer {
|
||||||
|
src: *const c_void,
|
||||||
|
size: usize,
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct FIO_outBuffer {
|
||||||
|
dst: *mut c_void,
|
||||||
|
size: usize,
|
||||||
|
pos: usize,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(target_vendor = "apple")]
|
||||||
const ZSTD_SPARSE_DEFAULT: c_int = 0;
|
const ZSTD_SPARSE_DEFAULT: c_int = 0;
|
||||||
#[cfg(not(target_vendor = "apple"))]
|
#[cfg(not(target_vendor = "apple"))]
|
||||||
@@ -517,6 +531,53 @@ pub unsafe extern "C" fn FIO_rust_getLargestFileSize(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fill a C-compatible input buffer through an output pointer.
|
||||||
|
///
|
||||||
|
/// The pointer form avoids relying on a cross-language struct return ABI while
|
||||||
|
/// retaining the public `ZSTD_inBuffer` field order and values.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn FIO_rust_setInBuffer(
|
||||||
|
output: *mut FIO_inBuffer,
|
||||||
|
buf: *const c_void,
|
||||||
|
size: usize,
|
||||||
|
pos: usize,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
output.write(FIO_inBuffer {
|
||||||
|
src: buf,
|
||||||
|
size,
|
||||||
|
pos,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fill a C-compatible output buffer through an output pointer.
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn FIO_rust_setOutBuffer(
|
||||||
|
output: *mut FIO_outBuffer,
|
||||||
|
buf: *mut c_void,
|
||||||
|
size: usize,
|
||||||
|
pos: usize,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
output.write(FIO_outBuffer {
|
||||||
|
dst: buf,
|
||||||
|
size,
|
||||||
|
pos,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn lz4_block_size_from_block_id(id: c_int) -> c_int {
|
||||||
|
1 << (8 + 2 * id)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn FIO_rust_LZ4_GetBlockSize_FromBlockId(id: c_int) -> c_int {
|
||||||
|
lz4_block_size_from_block_id(id)
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn filename_path_separator() -> u8 {
|
fn filename_path_separator() -> u8 {
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
@@ -650,6 +711,76 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn buffer_shims_preserve_fields_and_c_layout() {
|
||||||
|
let input_word = size_of::<*const c_void>();
|
||||||
|
let output_word = size_of::<*mut c_void>();
|
||||||
|
|
||||||
|
assert_eq!(offset_of!(FIO_inBuffer, src), 0);
|
||||||
|
assert_eq!(offset_of!(FIO_inBuffer, size), input_word);
|
||||||
|
assert_eq!(
|
||||||
|
offset_of!(FIO_inBuffer, pos),
|
||||||
|
input_word + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
size_of::<FIO_inBuffer>(),
|
||||||
|
input_word + 2 * size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert_eq!(offset_of!(FIO_outBuffer, dst), 0);
|
||||||
|
assert_eq!(offset_of!(FIO_outBuffer, size), output_word);
|
||||||
|
assert_eq!(
|
||||||
|
offset_of!(FIO_outBuffer, pos),
|
||||||
|
output_word + size_of::<usize>()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
size_of::<FIO_outBuffer>(),
|
||||||
|
output_word + 2 * size_of::<usize>()
|
||||||
|
);
|
||||||
|
|
||||||
|
let source = [1u8, 2, 3, 4];
|
||||||
|
let mut destination = [0u8; 8];
|
||||||
|
let mut input = FIO_inBuffer {
|
||||||
|
src: ptr::null(),
|
||||||
|
size: 0,
|
||||||
|
pos: 0,
|
||||||
|
};
|
||||||
|
let mut output = FIO_outBuffer {
|
||||||
|
dst: ptr::null_mut(),
|
||||||
|
size: 0,
|
||||||
|
pos: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
FIO_rust_setInBuffer(
|
||||||
|
&mut input,
|
||||||
|
source.as_ptr().cast::<c_void>(),
|
||||||
|
source.len(),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
FIO_rust_setOutBuffer(
|
||||||
|
&mut output,
|
||||||
|
destination.as_mut_ptr().cast::<c_void>(),
|
||||||
|
destination.len(),
|
||||||
|
2,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(input.src, source.as_ptr().cast::<c_void>());
|
||||||
|
assert_eq!(input.size, source.len());
|
||||||
|
assert_eq!(input.pos, 1);
|
||||||
|
assert_eq!(output.dst, destination.as_mut_ptr().cast::<c_void>());
|
||||||
|
assert_eq!(output.size, destination.len());
|
||||||
|
assert_eq!(output.pos, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lz4_block_size_shim_preserves_the_block_id_formula() {
|
||||||
|
assert_eq!(FIO_rust_LZ4_GetBlockSize_FromBlockId(0), 1 << 8);
|
||||||
|
assert_eq!(FIO_rust_LZ4_GetBlockSize_FromBlockId(1), 1 << 10);
|
||||||
|
assert_eq!(FIO_rust_LZ4_GetBlockSize_FromBlockId(3), 1 << 14);
|
||||||
|
assert_eq!(FIO_rust_LZ4_GetBlockSize_FromBlockId(4), 1 << 16);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn c_layouts_match_the_headers() {
|
fn c_layouts_match_the_headers() {
|
||||||
let word = size_of::<usize>();
|
let word = size_of::<usize>();
|
||||||
|
|||||||
Reference in New Issue
Block a user