feat(cli): port file I/O preferences to Rust
Move fileio preference and context allocation, defaults, setters, and small query helpers into Rust while keeping the actual file operations in C. Keep the C structs and ABI declarations as anchors, and make the CLI build track the new Rust source. Test Plan: - rustfmt +nightly --check --edition 2021 rust/src/fileio_prefs.rs rust/cli/src/lib.rs - RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= cargo test --manifest-path rust/cli/Cargo.toml - RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings - git diff --cached --check
This commit is contained in:
+31
-227
@@ -28,6 +28,7 @@
|
||||
#include <stdio.h> /* fprintf, open, fdopen, fread, _fileno, stdin, stdout */
|
||||
#include <stdlib.h> /* malloc, free */
|
||||
#include <string.h> /* strcmp, strlen */
|
||||
#include <stddef.h> /* offsetof */
|
||||
#include <time.h> /* clock_t, to measure process time */
|
||||
#include <fcntl.h> /* O_WRONLY */
|
||||
#include <assert.h>
|
||||
@@ -254,6 +255,34 @@ struct FIO_ctx_s {
|
||||
size_t totalBytesOutput;
|
||||
};
|
||||
|
||||
/* Keep the Rust preference/context layouts in lock-step with these C
|
||||
* definitions. The Rust side uses the same #[repr(C)] field order. */
|
||||
typedef char FIO_rust_prefs_compression_type_offset[
|
||||
(offsetof(FIO_prefs_t, compressionType) == 0) ? 1 : -1];
|
||||
typedef char FIO_rust_prefs_stream_size_offset[
|
||||
(offsetof(FIO_prefs_t, streamSrcSize) == 16 * sizeof(int)) ? 1 : -1];
|
||||
typedef char FIO_rust_prefs_target_size_offset[
|
||||
(offsetof(FIO_prefs_t, targetCBlockSize)
|
||||
== 16 * sizeof(int) + sizeof(size_t)) ? 1 : -1];
|
||||
typedef char FIO_rust_prefs_src_hint_offset[
|
||||
(offsetof(FIO_prefs_t, srcSizeHint)
|
||||
== 16 * sizeof(int) + 2 * sizeof(size_t)) ? 1 : -1];
|
||||
typedef char FIO_rust_prefs_mmap_dict_offset[
|
||||
(offsetof(FIO_prefs_t, mmapDict)
|
||||
== 16 * sizeof(int) + 2 * sizeof(size_t) + 13 * sizeof(int)) ? 1 : -1];
|
||||
typedef char FIO_rust_prefs_size[
|
||||
(sizeof(FIO_prefs_t)
|
||||
== 16 * sizeof(int) + 2 * sizeof(size_t) + 14 * sizeof(int)) ? 1 : -1];
|
||||
typedef char FIO_rust_ctx_total_input_offset[
|
||||
(offsetof(FIO_ctx_t, totalBytesInput)
|
||||
== ((5 * sizeof(int) + sizeof(size_t) - 1) / sizeof(size_t)) * sizeof(size_t)) ? 1 : -1];
|
||||
typedef char FIO_rust_ctx_total_output_offset[
|
||||
(offsetof(FIO_ctx_t, totalBytesOutput)
|
||||
== offsetof(FIO_ctx_t, totalBytesInput) + sizeof(size_t)) ? 1 : -1];
|
||||
typedef char FIO_rust_ctx_size[
|
||||
(sizeof(FIO_ctx_t)
|
||||
== offsetof(FIO_ctx_t, totalBytesOutput) + sizeof(size_t)) ? 1 : -1];
|
||||
|
||||
static int FIO_shouldDisplayFileSummary(FIO_ctx_t const* fCtx)
|
||||
{
|
||||
return fCtx->nbFilesTotal <= 1 || g_display_prefs.displayLevel >= 3;
|
||||
@@ -275,75 +304,14 @@ static int FIO_shouldDisplayMultipleFileSummary(FIO_ctx_t const* fCtx)
|
||||
#define FIO_LDM_PARAM_NOTSET 9999
|
||||
|
||||
|
||||
FIO_prefs_t* FIO_createPreferences(void)
|
||||
{
|
||||
FIO_prefs_t* const ret = (FIO_prefs_t*)malloc(sizeof(FIO_prefs_t));
|
||||
if (!ret) EXM_THROW(21, "Allocation error : not enough memory");
|
||||
|
||||
ret->compressionType = FIO_zstdCompression;
|
||||
ret->overwrite = 0;
|
||||
ret->sparseFileSupport = ZSTD_SPARSE_DEFAULT;
|
||||
ret->dictIDFlag = 1;
|
||||
ret->checksumFlag = 1;
|
||||
ret->removeSrcFile = 0;
|
||||
ret->memLimit = 0;
|
||||
ret->nbWorkers = 1;
|
||||
ret->blockSize = 0;
|
||||
ret->overlapLog = FIO_OVERLAP_LOG_NOTSET;
|
||||
ret->adaptiveMode = 0;
|
||||
ret->rsyncable = 0;
|
||||
ret->minAdaptLevel = -50; /* initializing this value requires a constant, so ZSTD_minCLevel() doesn't work */
|
||||
ret->maxAdaptLevel = 22; /* initializing this value requires a constant, so ZSTD_maxCLevel() doesn't work */
|
||||
ret->ldmFlag = 0;
|
||||
ret->ldmHashLog = 0;
|
||||
ret->ldmMinMatch = 0;
|
||||
ret->ldmBucketSizeLog = FIO_LDM_PARAM_NOTSET;
|
||||
ret->ldmHashRateLog = FIO_LDM_PARAM_NOTSET;
|
||||
ret->streamSrcSize = 0;
|
||||
ret->targetCBlockSize = 0;
|
||||
ret->srcSizeHint = 0;
|
||||
ret->testMode = 0;
|
||||
ret->literalCompressionMode = ZSTD_ps_auto;
|
||||
ret->excludeCompressedFiles = 0;
|
||||
ret->allowBlockDevices = 0;
|
||||
ret->asyncIO = AIO_supported();
|
||||
ret->passThrough = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
FIO_ctx_t* FIO_createContext(void)
|
||||
{
|
||||
FIO_ctx_t* const ret = (FIO_ctx_t*)malloc(sizeof(FIO_ctx_t));
|
||||
if (!ret) EXM_THROW(21, "Allocation error : not enough memory");
|
||||
|
||||
ret->currFileIdx = 0;
|
||||
ret->hasStdinInput = 0;
|
||||
ret->hasStdoutOutput = 0;
|
||||
ret->nbFilesTotal = 1;
|
||||
ret->nbFilesProcessed = 0;
|
||||
ret->totalBytesInput = 0;
|
||||
ret->totalBytesOutput = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FIO_freePreferences(FIO_prefs_t* const prefs)
|
||||
{
|
||||
free(prefs);
|
||||
}
|
||||
|
||||
void FIO_freeContext(FIO_ctx_t* const fCtx)
|
||||
{
|
||||
free(fCtx);
|
||||
}
|
||||
/* These symbols are implemented by rust/src/fileio_prefs.rs. The declarations
|
||||
* in fileio.h remain the C ABI shims while all actual file I/O stays here. */
|
||||
|
||||
|
||||
/*-*************************************
|
||||
* Parameters: Display Options
|
||||
***************************************/
|
||||
|
||||
void FIO_setNotificationLevel(int level) { g_display_prefs.displayLevel=level; }
|
||||
|
||||
void FIO_setProgressSetting(FIO_progressSetting_e setting) { g_display_prefs.progressSetting = setting; }
|
||||
|
||||
|
||||
/*-*************************************
|
||||
@@ -352,170 +320,6 @@ void FIO_setProgressSetting(FIO_progressSetting_e setting) { g_display_prefs.pro
|
||||
|
||||
/* FIO_prefs_t functions */
|
||||
|
||||
void FIO_setCompressionType(FIO_prefs_t* const prefs, FIO_compressionType_t compressionType) { prefs->compressionType = compressionType; }
|
||||
|
||||
void FIO_overwriteMode(FIO_prefs_t* const prefs) { prefs->overwrite = 1; }
|
||||
|
||||
void FIO_setSparseWrite(FIO_prefs_t* const prefs, int sparse) { prefs->sparseFileSupport = sparse; }
|
||||
|
||||
void FIO_setDictIDFlag(FIO_prefs_t* const prefs, int dictIDFlag) { prefs->dictIDFlag = dictIDFlag; }
|
||||
|
||||
void FIO_setChecksumFlag(FIO_prefs_t* const prefs, int checksumFlag) { prefs->checksumFlag = checksumFlag; }
|
||||
|
||||
void FIO_setRemoveSrcFile(FIO_prefs_t* const prefs, int flag) { prefs->removeSrcFile = (flag!=0); }
|
||||
|
||||
void FIO_setMemLimit(FIO_prefs_t* const prefs, unsigned memLimit) { prefs->memLimit = memLimit; }
|
||||
|
||||
void FIO_setNbWorkers(FIO_prefs_t* const prefs, int nbWorkers) {
|
||||
#ifndef ZSTD_MULTITHREAD
|
||||
if (nbWorkers > 0) DISPLAYLEVEL(2, "Note : multi-threading is disabled \n");
|
||||
#endif
|
||||
prefs->nbWorkers = nbWorkers;
|
||||
}
|
||||
|
||||
void FIO_setExcludeCompressedFile(FIO_prefs_t* const prefs, int excludeCompressedFiles) { prefs->excludeCompressedFiles = excludeCompressedFiles; }
|
||||
|
||||
void FIO_setAllowBlockDevices(FIO_prefs_t* const prefs, int allowBlockDevices) { prefs->allowBlockDevices = allowBlockDevices; }
|
||||
|
||||
void FIO_setBlockSize(FIO_prefs_t* const prefs, int blockSize) {
|
||||
if (blockSize && prefs->nbWorkers==0)
|
||||
DISPLAYLEVEL(2, "Setting block size is useless in single-thread mode \n");
|
||||
prefs->blockSize = blockSize;
|
||||
}
|
||||
|
||||
void FIO_setOverlapLog(FIO_prefs_t* const prefs, int overlapLog){
|
||||
if (overlapLog && prefs->nbWorkers==0)
|
||||
DISPLAYLEVEL(2, "Setting overlapLog is useless in single-thread mode \n");
|
||||
prefs->overlapLog = overlapLog;
|
||||
}
|
||||
|
||||
void FIO_setAdaptiveMode(FIO_prefs_t* const prefs, int adapt) {
|
||||
if ((adapt>0) && (prefs->nbWorkers==0))
|
||||
EXM_THROW(1, "Adaptive mode is not compatible with single thread mode \n");
|
||||
prefs->adaptiveMode = adapt;
|
||||
}
|
||||
|
||||
void FIO_setUseRowMatchFinder(FIO_prefs_t* const prefs, int useRowMatchFinder) {
|
||||
prefs->useRowMatchFinder = useRowMatchFinder;
|
||||
}
|
||||
|
||||
void FIO_setRsyncable(FIO_prefs_t* const prefs, int rsyncable) {
|
||||
if ((rsyncable>0) && (prefs->nbWorkers==0))
|
||||
EXM_THROW(1, "Rsyncable mode is not compatible with single thread mode \n");
|
||||
prefs->rsyncable = rsyncable;
|
||||
}
|
||||
|
||||
void FIO_setStreamSrcSize(FIO_prefs_t* const prefs, size_t streamSrcSize) {
|
||||
prefs->streamSrcSize = streamSrcSize;
|
||||
}
|
||||
|
||||
void FIO_setTargetCBlockSize(FIO_prefs_t* const prefs, size_t targetCBlockSize) {
|
||||
prefs->targetCBlockSize = targetCBlockSize;
|
||||
}
|
||||
|
||||
void FIO_setSrcSizeHint(FIO_prefs_t* const prefs, size_t srcSizeHint) {
|
||||
prefs->srcSizeHint = (int)MIN((size_t)INT_MAX, srcSizeHint);
|
||||
}
|
||||
|
||||
void FIO_setTestMode(FIO_prefs_t* const prefs, int testMode) {
|
||||
prefs->testMode = (testMode!=0);
|
||||
}
|
||||
|
||||
void FIO_setLiteralCompressionMode(
|
||||
FIO_prefs_t* const prefs,
|
||||
ZSTD_ParamSwitch_e mode) {
|
||||
prefs->literalCompressionMode = mode;
|
||||
}
|
||||
|
||||
void FIO_setAdaptMin(FIO_prefs_t* const prefs, int minCLevel)
|
||||
{
|
||||
#ifndef ZSTD_NOCOMPRESS
|
||||
assert(minCLevel >= ZSTD_minCLevel());
|
||||
#endif
|
||||
prefs->minAdaptLevel = minCLevel;
|
||||
}
|
||||
|
||||
void FIO_setAdaptMax(FIO_prefs_t* const prefs, int maxCLevel)
|
||||
{
|
||||
prefs->maxAdaptLevel = maxCLevel;
|
||||
}
|
||||
|
||||
void FIO_setLdmFlag(FIO_prefs_t* const prefs, unsigned ldmFlag) {
|
||||
prefs->ldmFlag = (ldmFlag>0);
|
||||
}
|
||||
|
||||
void FIO_setLdmHashLog(FIO_prefs_t* const prefs, int ldmHashLog) {
|
||||
prefs->ldmHashLog = ldmHashLog;
|
||||
}
|
||||
|
||||
void FIO_setLdmMinMatch(FIO_prefs_t* const prefs, int ldmMinMatch) {
|
||||
prefs->ldmMinMatch = ldmMinMatch;
|
||||
}
|
||||
|
||||
void FIO_setLdmBucketSizeLog(FIO_prefs_t* const prefs, int ldmBucketSizeLog) {
|
||||
prefs->ldmBucketSizeLog = ldmBucketSizeLog;
|
||||
}
|
||||
|
||||
|
||||
void FIO_setLdmHashRateLog(FIO_prefs_t* const prefs, int ldmHashRateLog) {
|
||||
prefs->ldmHashRateLog = ldmHashRateLog;
|
||||
}
|
||||
|
||||
void FIO_setPatchFromMode(FIO_prefs_t* const prefs, int value)
|
||||
{
|
||||
prefs->patchFromMode = value != 0;
|
||||
}
|
||||
|
||||
void FIO_setContentSize(FIO_prefs_t* const prefs, int value)
|
||||
{
|
||||
prefs->contentSize = value != 0;
|
||||
}
|
||||
|
||||
void FIO_setAsyncIOFlag(FIO_prefs_t* const prefs, int value) {
|
||||
#ifdef ZSTD_MULTITHREAD
|
||||
prefs->asyncIO = value;
|
||||
#else
|
||||
(void) prefs;
|
||||
(void) value;
|
||||
DISPLAYLEVEL(2, "Note : asyncio is disabled (lack of multithreading support) \n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void FIO_setPassThroughFlag(FIO_prefs_t* const prefs, int value) {
|
||||
prefs->passThrough = (value != 0);
|
||||
}
|
||||
|
||||
void FIO_setMMapDict(FIO_prefs_t* const prefs, ZSTD_ParamSwitch_e value)
|
||||
{
|
||||
prefs->mmapDict = value;
|
||||
}
|
||||
|
||||
/* FIO_ctx_t functions */
|
||||
|
||||
void FIO_setHasStdoutOutput(FIO_ctx_t* const fCtx, int value) {
|
||||
fCtx->hasStdoutOutput = value;
|
||||
}
|
||||
|
||||
void FIO_setNbFilesTotal(FIO_ctx_t* const fCtx, int value)
|
||||
{
|
||||
fCtx->nbFilesTotal = value;
|
||||
}
|
||||
|
||||
void FIO_setHasStdinInput(FIO_ctx_t* const fCtx, int value)
|
||||
{
|
||||
fCtx->hasStdinInput = value != 0;
|
||||
}
|
||||
|
||||
void FIO_determineHasStdinInput(FIO_ctx_t* const fCtx, const FileNamesTable* const filenames) {
|
||||
size_t i = 0;
|
||||
for ( ; i < filenames->tableSize; ++i) {
|
||||
if (!strcmp(stdinmark, filenames->fileNames[i])) {
|
||||
fCtx->hasStdinInput = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-*************************************
|
||||
* Functions
|
||||
***************************************/
|
||||
|
||||
Reference in New Issue
Block a user