feat(cli): move shared decompression scheduling into Rust

Move the shared-destination branch of FIO_decompressMultipleFilenames into a Rust-owned scheduler. Preserve source order, destination propagation, cursor advancement, success counting, aggregate errors, and C-owned source/format/resource behavior including --rm and output close handling.

Test Plan:
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml decompression_multiple_shared_destination -- --test-threads=1
- ulimit -v 41943040; make -B -C programs -j1 zstd
- ulimit -v 41943040; make -B -C tests -j1 test-cli-tests
This commit is contained in:
2026-07-19 11:10:09 +02:00
parent 4dc6761e60
commit 802cb70184
2 changed files with 220 additions and 4 deletions
+55 -4
View File
@@ -1179,6 +1179,35 @@ typedef char FIO_rust_compress_multiple_separate_projection_size[
int FIO_rust_compressMultipleSeparateFilenames(
const FIO_rust_compress_multiple_separate_projection_t* projection);
typedef int (*FIO_rust_decompress_multiple_file_fn)(
void* opaque, const char* outFileName, const char* srcFileName);
typedef struct {
void* fCtx;
const char** srcNamesTable;
const char* outFileName;
void* opaque;
FIO_rust_decompress_multiple_file_fn decompressFile;
} FIO_rust_decompress_multiple_projection_t;
typedef char FIO_rust_decompress_multiple_fctx_offset[
(offsetof(FIO_rust_decompress_multiple_projection_t, fCtx) == 0) ? 1 : -1];
typedef char FIO_rust_decompress_multiple_input_names_offset[
(offsetof(FIO_rust_decompress_multiple_projection_t, srcNamesTable)
== sizeof(void*)) ? 1 : -1];
typedef char FIO_rust_decompress_multiple_output_name_offset[
(offsetof(FIO_rust_decompress_multiple_projection_t, outFileName)
== 2 * sizeof(void*)) ? 1 : -1];
typedef char FIO_rust_decompress_multiple_opaque_offset[
(offsetof(FIO_rust_decompress_multiple_projection_t, opaque)
== 3 * sizeof(void*)) ? 1 : -1];
typedef char FIO_rust_decompress_multiple_callback_offset[
(offsetof(FIO_rust_decompress_multiple_projection_t, decompressFile)
== 4 * sizeof(void*)) ? 1 : -1];
typedef char FIO_rust_decompress_multiple_projection_size[
(sizeof(FIO_rust_decompress_multiple_projection_t)
== 4 * sizeof(void*) + sizeof(FIO_rust_decompress_multiple_file_fn)) ? 1 : -1];
int FIO_rust_decompressMultipleFilenames(
const FIO_rust_decompress_multiple_projection_t* projection);
enum {
FIO_RUST_ZSTD_OK = 0,
FIO_RUST_ZSTD_COMPRESS_ERROR = 1,
@@ -3838,6 +3867,23 @@ static int FIO_decompressSrcFile(FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs
return result;
}
typedef struct {
FIO_ctx_t* fCtx;
FIO_prefs_t* prefs;
dRess_t* ress;
} FIO_rust_decompress_multiple_context_t;
/* Keep source opening, format dispatch, diagnostics, and --rm in C. */
static int FIO_rust_decompressMultipleFileCallback(void* opaque,
const char* outFileName,
const char* srcFileName)
{
FIO_rust_decompress_multiple_context_t* const context =
(FIO_rust_decompress_multiple_context_t*)opaque;
return FIO_decompressSrcFile(
context->fCtx, context->prefs, *context->ress, outFileName, srcFileName);
}
int FIO_decompressFilename(FIO_ctx_t* const fCtx, FIO_prefs_t* const prefs,
@@ -3921,10 +3967,15 @@ FIO_decompressMultipleFilenames(FIO_ctx_t* const fCtx,
if (dstFile == 0) EXM_THROW(19, "cannot open %s", outFileName);
AIO_WritePool_setFile(ress.writeCtx, dstFile);
}
for (; fCtx->currFileIdx < fCtx->nbFilesTotal; fCtx->currFileIdx++) {
status = FIO_decompressSrcFile(fCtx, prefs, ress, outFileName, srcNamesTable[fCtx->currFileIdx]);
if (!status) fCtx->nbFilesProcessed++;
error |= status;
{
FIO_rust_decompress_multiple_context_t callbackContext = {
fCtx, prefs, &ress
};
FIO_rust_decompress_multiple_projection_t projection = {
fCtx, srcNamesTable, outFileName,
&callbackContext, FIO_rust_decompressMultipleFileCallback
};
error = FIO_rust_decompressMultipleFilenames(&projection);
}
if ((!prefs->testMode) && (AIO_WritePool_closeFile(ress.writeCtx)))
EXM_THROW(72, "Write error : %s : cannot properly close output file",