feat(cli): move shared-destination scheduling into Rust

Move the shared-output arm of FIO_compressMultipleFilenames into a Rust
scheduler. Rust now owns input-order iteration, processed-file accounting,
index advancement, and non-short-circuiting error aggregation while C retains
file validation, private resources, callbacks, diagnostics, and destination
lifetime.

Test Plan:
- cargo +nightly fmt --manifest-path rust/Cargo.toml
- cargo test --manifest-path rust/Cargo.toml compression_multiple_shared_destination -- --test-threads=1 (2 passed)
- cargo clippy --manifest-path rust/Cargo.toml --tests -- -D warnings
- make -B -C lib -j1 lib
- make -B -C programs -j1 zstd
- make -B -C tests -j1 test-cli-tests (41 passed)
- all commands used CARGO_BUILD_JOBS=1 where applicable and
  ulimit -v 41943040; no heavyweight jobs ran concurrently

Commit is intentionally unsigned because GPG pinentry hangs in this
non-interactive environment.
This commit is contained in:
2026-07-19 10:31:19 +02:00
parent 17cfedd56e
commit 035001b769
2 changed files with 226 additions and 5 deletions
+55 -5
View File
@@ -1125,6 +1125,35 @@ typedef struct {
FIO_rust_compress_status_display_fn display_status;
} FIO_rust_compress_callbacks_t;
typedef int (*FIO_rust_compress_multiple_file_fn)(
void* opaque, const char* dstFileName, const char* srcFileName);
typedef struct {
void* fCtx;
const char** inFileNamesTable;
const char* outFileName;
void* opaque;
FIO_rust_compress_multiple_file_fn compressFile;
} FIO_rust_compress_multiple_projection_t;
typedef char FIO_rust_compress_multiple_fctx_offset[
(offsetof(FIO_rust_compress_multiple_projection_t, fCtx) == 0) ? 1 : -1];
typedef char FIO_rust_compress_multiple_input_names_offset[
(offsetof(FIO_rust_compress_multiple_projection_t, inFileNamesTable)
== sizeof(void*)) ? 1 : -1];
typedef char FIO_rust_compress_multiple_output_name_offset[
(offsetof(FIO_rust_compress_multiple_projection_t, outFileName)
== 2 * sizeof(void*)) ? 1 : -1];
typedef char FIO_rust_compress_multiple_opaque_offset[
(offsetof(FIO_rust_compress_multiple_projection_t, opaque)
== 3 * sizeof(void*)) ? 1 : -1];
typedef char FIO_rust_compress_multiple_callback_offset[
(offsetof(FIO_rust_compress_multiple_projection_t, compressFile)
== 4 * sizeof(void*)) ? 1 : -1];
typedef char FIO_rust_compress_multiple_projection_size[
(sizeof(FIO_rust_compress_multiple_projection_t)
== 4 * sizeof(void*) + sizeof(FIO_rust_compress_multiple_file_fn)) ? 1 : -1];
int FIO_rust_compressMultipleFilenames(
const FIO_rust_compress_multiple_projection_t* projection);
enum {
FIO_RUST_ZSTD_OK = 0,
FIO_RUST_ZSTD_COMPRESS_ERROR = 1,
@@ -2897,6 +2926,24 @@ static unsigned long long FIO_getLargestFileSize(const char** inFileNames, unsig
return FIO_rust_getLargestFileSize(inFileNames, nbFiles);
}
typedef struct {
FIO_ctx_t* fCtx;
FIO_prefs_t* prefs;
cRess_t* ress;
int compressionLevel;
} FIO_rust_compress_multiple_context_t;
static int FIO_rust_compressMultipleFileCallback(void* opaque,
const char* dstFileName,
const char* srcFileName)
{
FIO_rust_compress_multiple_context_t* const context =
(FIO_rust_compress_multiple_context_t*)opaque;
return FIO_compressFilename_srcFile(
context->fCtx, context->prefs, *context->ress,
dstFileName, srcFileName, context->compressionLevel);
}
/* FIO_compressMultipleFilenames() :
* compress nbFiles files
* into either one destination (outFileName),
@@ -2930,12 +2977,15 @@ int FIO_compressMultipleFilenames(FIO_ctx_t* const fCtx,
if (dstFile == NULL) { /* could not open outFileName */
error = 1;
} else {
FIO_rust_compress_multiple_context_t callbackContext = {
fCtx, prefs, &ress, compressionLevel
};
FIO_rust_compress_multiple_projection_t projection = {
fCtx, inFileNamesTable, outFileName,
&callbackContext, FIO_rust_compressMultipleFileCallback
};
AIO_WritePool_setFile(ress.writeCtx, dstFile);
for (; fCtx->currFileIdx < fCtx->nbFilesTotal; ++fCtx->currFileIdx) {
status = FIO_compressFilename_srcFile(fCtx, prefs, ress, outFileName, inFileNamesTable[fCtx->currFileIdx], compressionLevel);
if (!status) fCtx->nbFilesProcessed++;
error |= status;
}
error = FIO_rust_compressMultipleFilenames(&projection);
if (AIO_WritePool_closeFile(ress.writeCtx))
EXM_THROW(29, "Write error (%s) : cannot properly close %s",
strerror(errno), outFileName);