feat(cli): move compression resource orchestration to Rust
Make the Rust policy layer own the ordered compression-resource lifecycle: create the CCtx, prepare patch/dictionary state, create the write and read pools, validate the dictionary, apply general and multithreaded parameters, and finally load the dictionary. Keep cRess_t, FIO_Dict_t, file statistics, AIO pools, and CLI diagnostics in C callbacks so the existing resource ownership and error behavior remain local to the C backend. Preserve adaptive window defaults and patch-from parameter adjustment while adding ABI layout assertions and a lifecycle-order test for the new boundary. Test Plan: - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo +nightly fmt --manifest-path rust/cli/Cargo.toml --all - 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 (205 passed) - ulimit -v 41943040; CARGO_BUILD_JOBS=1 make -j1
This commit is contained in:
+120
-48
@@ -2063,11 +2063,29 @@ typedef size_t (*FIO_rust_createCResources_set_parameter_f)(void* context,
|
|||||||
int value);
|
int value);
|
||||||
typedef int (*FIO_rust_createCResources_is_error_f)(size_t result);
|
typedef int (*FIO_rust_createCResources_is_error_f)(size_t result);
|
||||||
typedef void (*FIO_rust_createCResources_display_overlap_f)(int overlapLog);
|
typedef void (*FIO_rust_createCResources_display_overlap_f)(int overlapLog);
|
||||||
|
typedef void (*FIO_rust_createCResources_create_cctx_f)(void* context);
|
||||||
|
typedef void (*FIO_rust_createCResources_prepare_dictionary_f)(
|
||||||
|
void* context, const FIO_prefs_t* prefs, const char* dictFileName,
|
||||||
|
U64 maxSrcFileSize, int cLevel, void* comprParams);
|
||||||
|
typedef void (*FIO_rust_createCResources_create_pool_f)(
|
||||||
|
void* context, const FIO_prefs_t* prefs);
|
||||||
|
typedef void (*FIO_rust_createCResources_validate_dictionary_f)(void* context);
|
||||||
|
typedef size_t (*FIO_rust_createCResources_load_dictionary_f)(
|
||||||
|
void* context, int patchFromMode);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void* callbackContext;
|
void* callbackContext;
|
||||||
const FIO_prefs_t* prefs;
|
const FIO_prefs_t* prefs;
|
||||||
ZSTD_compressionParameters comprParams;
|
ZSTD_compressionParameters comprParams;
|
||||||
int cLevel;
|
int cLevel;
|
||||||
|
const char* dictFileName;
|
||||||
|
U64 maxSrcFileSize;
|
||||||
|
int multithreaded;
|
||||||
|
FIO_rust_createCResources_create_cctx_f createCctx;
|
||||||
|
FIO_rust_createCResources_prepare_dictionary_f prepareDictionary;
|
||||||
|
FIO_rust_createCResources_create_pool_f createWritePool;
|
||||||
|
FIO_rust_createCResources_create_pool_f createReadPool;
|
||||||
|
FIO_rust_createCResources_validate_dictionary_f validateDictionary;
|
||||||
|
FIO_rust_createCResources_load_dictionary_f loadDictionary;
|
||||||
FIO_rust_createCResources_set_parameter_f setParameter;
|
FIO_rust_createCResources_set_parameter_f setParameter;
|
||||||
FIO_rust_createCResources_is_error_f isError;
|
FIO_rust_createCResources_is_error_f isError;
|
||||||
FIO_rust_createCResources_display_overlap_f displayOverlap;
|
FIO_rust_createCResources_display_overlap_f displayOverlap;
|
||||||
@@ -2081,10 +2099,21 @@ typedef char FIO_rust_create_c_resources_state_params_offset[
|
|||||||
typedef char FIO_rust_create_c_resources_state_level_offset[
|
typedef char FIO_rust_create_c_resources_state_level_offset[
|
||||||
(offsetof(FIO_rust_createCResourcesState, cLevel)
|
(offsetof(FIO_rust_createCResourcesState, cLevel)
|
||||||
== 2 * sizeof(void*) + sizeof(ZSTD_compressionParameters)) ? 1 : -1];
|
== 2 * sizeof(void*) + sizeof(ZSTD_compressionParameters)) ? 1 : -1];
|
||||||
typedef char FIO_rust_create_c_resources_state_set_parameter_offset[
|
typedef char FIO_rust_create_c_resources_state_dict_name_offset[
|
||||||
(offsetof(FIO_rust_createCResourcesState, setParameter)
|
(offsetof(FIO_rust_createCResourcesState, dictFileName)
|
||||||
== ((2 * sizeof(void*) + sizeof(ZSTD_compressionParameters) + sizeof(int)
|
== ((2 * sizeof(void*) + sizeof(ZSTD_compressionParameters) + sizeof(int)
|
||||||
+ sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*)) ? 1 : -1];
|
+ sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*)) ? 1 : -1];
|
||||||
|
typedef char FIO_rust_create_c_resources_state_max_src_offset[
|
||||||
|
(offsetof(FIO_rust_createCResourcesState, maxSrcFileSize)
|
||||||
|
== offsetof(FIO_rust_createCResourcesState, dictFileName) + sizeof(void*)) ? 1 : -1];
|
||||||
|
typedef char FIO_rust_create_c_resources_state_mt_offset[
|
||||||
|
(offsetof(FIO_rust_createCResourcesState, multithreaded)
|
||||||
|
== offsetof(FIO_rust_createCResourcesState, maxSrcFileSize) + sizeof(U64)) ? 1 : -1];
|
||||||
|
typedef char FIO_rust_create_c_resources_state_set_parameter_offset[
|
||||||
|
(offsetof(FIO_rust_createCResourcesState, setParameter)
|
||||||
|
== ((offsetof(FIO_rust_createCResourcesState, multithreaded) + sizeof(int)
|
||||||
|
+ sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*)
|
||||||
|
+ 6 * sizeof(void*)) ? 1 : -1];
|
||||||
typedef char FIO_rust_create_c_resources_state_is_error_offset[
|
typedef char FIO_rust_create_c_resources_state_is_error_offset[
|
||||||
(offsetof(FIO_rust_createCResourcesState, isError)
|
(offsetof(FIO_rust_createCResourcesState, isError)
|
||||||
== offsetof(FIO_rust_createCResourcesState, setParameter) + sizeof(void*)) ? 1 : -1];
|
== offsetof(FIO_rust_createCResourcesState, setParameter) + sizeof(void*)) ? 1 : -1];
|
||||||
@@ -2093,14 +2122,17 @@ typedef char FIO_rust_create_c_resources_state_display_overlap_offset[
|
|||||||
== offsetof(FIO_rust_createCResourcesState, isError) + sizeof(void*)) ? 1 : -1];
|
== offsetof(FIO_rust_createCResourcesState, isError) + sizeof(void*)) ? 1 : -1];
|
||||||
typedef char FIO_rust_create_c_resources_state_size[
|
typedef char FIO_rust_create_c_resources_state_size[
|
||||||
(sizeof(FIO_rust_createCResourcesState)
|
(sizeof(FIO_rust_createCResourcesState)
|
||||||
== offsetof(FIO_rust_createCResourcesState, setParameter) + 3 * sizeof(void*)) ? 1 : -1];
|
== offsetof(FIO_rust_createCResourcesState, displayOverlap) + sizeof(void*)) ? 1 : -1];
|
||||||
size_t FIO_rust_createCResources(const FIO_rust_createCResourcesState* state);
|
size_t FIO_rust_createCResources(const FIO_rust_createCResourcesState* state);
|
||||||
|
|
||||||
static size_t FIO_rust_createCResources_setParameter(void* context,
|
static size_t FIO_rust_createCResources_setParameter(void* context,
|
||||||
int parameter,
|
int parameter,
|
||||||
int value)
|
int value)
|
||||||
{
|
{
|
||||||
return ZSTD_CCtx_setParameter((ZSTD_CCtx*)context, (ZSTD_cParameter)parameter, value);
|
cRess_t* const ress = (cRess_t*)context;
|
||||||
|
if (parameter == ZSTD_c_nbWorkers)
|
||||||
|
DISPLAYLEVEL(5, "set nb workers = %u \n", (unsigned)value);
|
||||||
|
return ZSTD_CCtx_setParameter(ress->cctx, (ZSTD_cParameter)parameter, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int FIO_rust_createCResources_isError(size_t result)
|
static int FIO_rust_createCResources_isError(size_t result)
|
||||||
@@ -2113,67 +2145,107 @@ static void FIO_rust_createCResources_displayOverlap(int overlapLog)
|
|||||||
DISPLAYLEVEL(3,"set overlapLog = %u \n", overlapLog);
|
DISPLAYLEVEL(3,"set overlapLog = %u \n", overlapLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t FIO_rust_setCResourcesMtParameters(const FIO_rust_createCResourcesState* state);
|
static void FIO_rust_createCResources_createCctx(void* context)
|
||||||
|
{
|
||||||
|
cRess_t* const ress = (cRess_t*)context;
|
||||||
|
ress->cctx = ZSTD_createCCtx();
|
||||||
|
if (ress->cctx == NULL)
|
||||||
|
EXM_THROW(30, "allocation error (%s): can't create ZSTD_CCtx",
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_rust_createCResources_prepareDictionary(
|
||||||
|
void* context, const FIO_prefs_t* prefs, const char* dictFileName,
|
||||||
|
U64 maxSrcFileSize, int cLevel, void* comprParams)
|
||||||
|
{
|
||||||
|
cRess_t* const ress = (cRess_t*)context;
|
||||||
|
ZSTD_compressionParameters* const params =
|
||||||
|
(ZSTD_compressionParameters*)comprParams;
|
||||||
|
unsigned long long dictSize = 0;
|
||||||
|
unsigned long long ssSize = 0;
|
||||||
|
FIO_dictBufferType_t dictBufferType;
|
||||||
|
|
||||||
|
FIO_getDictFileStat(dictFileName, &ress->dictFileStat);
|
||||||
|
|
||||||
|
/* need to update memLimit before calling createDictBuffer
|
||||||
|
* because of memLimit check inside it */
|
||||||
|
if (prefs->patchFromMode) {
|
||||||
|
dictSize = (unsigned long long)UTIL_getFileSizeStat(&ress->dictFileStat);
|
||||||
|
ssSize = (unsigned long long)prefs->streamSrcSize;
|
||||||
|
FIO_adjustParamsForPatchFromMode(
|
||||||
|
(FIO_prefs_t*)prefs, params, dictSize,
|
||||||
|
ssSize > 0 ? ssSize : maxSrcFileSize, cLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
dictBufferType = (FIO_dictBufferType_t)FIO_rust_selectDictBufferType(
|
||||||
|
prefs->mmapDict, prefs->patchFromMode, dictSize, prefs->memLimit);
|
||||||
|
FIO_initDict(&ress->dict, dictFileName, (FIO_prefs_t*)prefs,
|
||||||
|
&ress->dictFileStat, dictBufferType);
|
||||||
|
ress->dictFileName = dictFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_rust_createCResources_createWritePool(
|
||||||
|
void* context, const FIO_prefs_t* prefs)
|
||||||
|
{
|
||||||
|
cRess_t* const ress = (cRess_t*)context;
|
||||||
|
ress->writeCtx = AIO_WritePool_create(prefs, ZSTD_CStreamOutSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_rust_createCResources_createReadPool(
|
||||||
|
void* context, const FIO_prefs_t* prefs)
|
||||||
|
{
|
||||||
|
cRess_t* const ress = (cRess_t*)context;
|
||||||
|
ress->readCtx = AIO_ReadPool_create(prefs, ZSTD_CStreamInSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FIO_rust_createCResources_validateDictionary(void* context)
|
||||||
|
{
|
||||||
|
cRess_t* const ress = (cRess_t*)context;
|
||||||
|
if (ress->dictFileName && (ress->dict.dictBuffer == NULL))
|
||||||
|
EXM_THROW(32, "allocation error : can't create dictBuffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t FIO_rust_createCResources_loadDictionary(
|
||||||
|
void* context, int patchFromMode)
|
||||||
|
{
|
||||||
|
cRess_t* const ress = (cRess_t*)context;
|
||||||
|
if (patchFromMode)
|
||||||
|
return ZSTD_CCtx_refPrefix(
|
||||||
|
ress->cctx, ress->dict.dictBuffer, ress->dict.dictBufferSize);
|
||||||
|
return ZSTD_CCtx_loadDictionary_byReference(
|
||||||
|
ress->cctx, ress->dict.dictBuffer, ress->dict.dictBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
static cRess_t FIO_createCResources(FIO_prefs_t* const prefs,
|
static cRess_t FIO_createCResources(FIO_prefs_t* const prefs,
|
||||||
const char* dictFileName, unsigned long long const maxSrcFileSize,
|
const char* dictFileName, unsigned long long const maxSrcFileSize,
|
||||||
int cLevel, ZSTD_compressionParameters comprParams) {
|
int cLevel, ZSTD_compressionParameters comprParams) {
|
||||||
unsigned long long dictSize = 0;
|
|
||||||
unsigned long long ssSize = 0;
|
|
||||||
FIO_dictBufferType_t dictBufferType;
|
|
||||||
cRess_t ress;
|
cRess_t ress;
|
||||||
FIO_rust_createCResourcesState policy;
|
FIO_rust_createCResourcesState policy;
|
||||||
memset(&ress, 0, sizeof(ress));
|
memset(&ress, 0, sizeof(ress));
|
||||||
|
|
||||||
DISPLAYLEVEL(6, "FIO_createCResources \n");
|
DISPLAYLEVEL(6, "FIO_createCResources \n");
|
||||||
ress.cctx = ZSTD_createCCtx();
|
policy.callbackContext = &ress;
|
||||||
if (ress.cctx == NULL)
|
|
||||||
EXM_THROW(30, "allocation error (%s): can't create ZSTD_CCtx",
|
|
||||||
strerror(errno));
|
|
||||||
|
|
||||||
FIO_getDictFileStat(dictFileName, &ress.dictFileStat);
|
|
||||||
|
|
||||||
/* need to update memLimit before calling createDictBuffer
|
|
||||||
* because of memLimit check inside it */
|
|
||||||
if (prefs->patchFromMode) {
|
|
||||||
dictSize = (unsigned long long)UTIL_getFileSizeStat(&ress.dictFileStat);
|
|
||||||
ssSize = (unsigned long long)prefs->streamSrcSize;
|
|
||||||
FIO_adjustParamsForPatchFromMode(prefs, &comprParams, dictSize, ssSize > 0 ? ssSize : maxSrcFileSize, cLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
dictBufferType = (FIO_dictBufferType_t)FIO_rust_selectDictBufferType(
|
|
||||||
prefs->mmapDict, prefs->patchFromMode, dictSize, prefs->memLimit);
|
|
||||||
FIO_initDict(&ress.dict, dictFileName, prefs, &ress.dictFileStat, dictBufferType); /* works with dictFileName==NULL */
|
|
||||||
|
|
||||||
ress.writeCtx = AIO_WritePool_create(prefs, ZSTD_CStreamOutSize());
|
|
||||||
ress.readCtx = AIO_ReadPool_create(prefs, ZSTD_CStreamInSize());
|
|
||||||
|
|
||||||
/* Advanced parameters, including dictionary */
|
|
||||||
if (dictFileName && (ress.dict.dictBuffer==NULL))
|
|
||||||
EXM_THROW(32, "allocation error : can't create dictBuffer");
|
|
||||||
ress.dictFileName = dictFileName;
|
|
||||||
|
|
||||||
policy.callbackContext = ress.cctx;
|
|
||||||
policy.prefs = prefs;
|
policy.prefs = prefs;
|
||||||
policy.comprParams = comprParams;
|
policy.comprParams = comprParams;
|
||||||
policy.cLevel = cLevel;
|
policy.cLevel = cLevel;
|
||||||
|
policy.dictFileName = dictFileName;
|
||||||
|
policy.maxSrcFileSize = maxSrcFileSize;
|
||||||
|
#ifdef ZSTD_MULTITHREAD
|
||||||
|
policy.multithreaded = 1;
|
||||||
|
#else
|
||||||
|
policy.multithreaded = 0;
|
||||||
|
#endif
|
||||||
|
policy.createCctx = FIO_rust_createCResources_createCctx;
|
||||||
|
policy.prepareDictionary = FIO_rust_createCResources_prepareDictionary;
|
||||||
|
policy.createWritePool = FIO_rust_createCResources_createWritePool;
|
||||||
|
policy.createReadPool = FIO_rust_createCResources_createReadPool;
|
||||||
|
policy.validateDictionary = FIO_rust_createCResources_validateDictionary;
|
||||||
|
policy.loadDictionary = FIO_rust_createCResources_loadDictionary;
|
||||||
policy.setParameter = FIO_rust_createCResources_setParameter;
|
policy.setParameter = FIO_rust_createCResources_setParameter;
|
||||||
policy.isError = FIO_rust_createCResources_isError;
|
policy.isError = FIO_rust_createCResources_isError;
|
||||||
policy.displayOverlap = FIO_rust_createCResources_displayOverlap;
|
policy.displayOverlap = FIO_rust_createCResources_displayOverlap;
|
||||||
CHECK( FIO_rust_createCResources(&policy) );
|
CHECK( FIO_rust_createCResources(&policy) );
|
||||||
|
|
||||||
/* multi-threading */
|
|
||||||
#ifdef ZSTD_MULTITHREAD
|
|
||||||
DISPLAYLEVEL(5,"set nb workers = %u \n", prefs->nbWorkers);
|
|
||||||
CHECK( FIO_rust_setCResourcesMtParameters(&policy) );
|
|
||||||
#endif
|
|
||||||
/* dictionary */
|
|
||||||
if (prefs->patchFromMode) {
|
|
||||||
CHECK( ZSTD_CCtx_refPrefix(ress.cctx, ress.dict.dictBuffer, ress.dict.dictBufferSize) );
|
|
||||||
} else {
|
|
||||||
CHECK( ZSTD_CCtx_loadDictionary_byReference(ress.cctx, ress.dict.dictBuffer, ress.dict.dictBufferSize) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return ress;
|
return ress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+244
-136
@@ -288,20 +288,14 @@ pub struct FIO_rust_freeCResourcesState {
|
|||||||
const _: () = {
|
const _: () = {
|
||||||
assert!(offset_of!(FIO_rust_freeCResourcesState, callback_context) == 0);
|
assert!(offset_of!(FIO_rust_freeCResourcesState, callback_context) == 0);
|
||||||
assert!(offset_of!(FIO_rust_freeCResourcesState, free_dict) == size_of::<usize>());
|
assert!(offset_of!(FIO_rust_freeCResourcesState, free_dict) == size_of::<usize>());
|
||||||
assert!(
|
assert!(offset_of!(FIO_rust_freeCResourcesState, free_write_pool) == 2 * size_of::<usize>());
|
||||||
offset_of!(FIO_rust_freeCResourcesState, free_write_pool) == 2 * size_of::<usize>()
|
assert!(offset_of!(FIO_rust_freeCResourcesState, free_read_pool) == 3 * size_of::<usize>());
|
||||||
);
|
|
||||||
assert!(
|
|
||||||
offset_of!(FIO_rust_freeCResourcesState, free_read_pool) == 3 * size_of::<usize>()
|
|
||||||
);
|
|
||||||
assert!(offset_of!(FIO_rust_freeCResourcesState, free_cctx) == 4 * size_of::<usize>());
|
assert!(offset_of!(FIO_rust_freeCResourcesState, free_cctx) == 4 * size_of::<usize>());
|
||||||
assert!(size_of::<FIO_rust_freeCResourcesState>() == 5 * size_of::<usize>());
|
assert!(size_of::<FIO_rust_freeCResourcesState>() == 5 * size_of::<usize>());
|
||||||
};
|
};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn FIO_rust_freeCResources(
|
pub unsafe extern "C" fn FIO_rust_freeCResources(state: *const FIO_rust_freeCResourcesState) {
|
||||||
state: *const FIO_rust_freeCResourcesState,
|
|
||||||
) {
|
|
||||||
if state.is_null() {
|
if state.is_null() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -439,15 +433,14 @@ fn ceil_log2_window_size(window_size: u64) -> c_uint {
|
|||||||
if window_size == 0 {
|
if window_size == 0 {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
highbit64(window_size)
|
highbit64(window_size) + c_uint::from((window_size & window_size.wrapping_sub(1)) != 0)
|
||||||
+ c_uint::from((window_size & window_size.wrapping_sub(1)) != 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "decompression")]
|
#[cfg(feature = "decompression")]
|
||||||
const _: () = {
|
const _: () = {
|
||||||
let callback_offset = (offset_of!(FIO_rust_zstdErrorHelpState, error_code)
|
let callback_offset = (offset_of!(FIO_rust_zstdErrorHelpState, error_code)
|
||||||
+ size_of::<c_int>())
|
+ size_of::<c_int>())
|
||||||
.div_ceil(size_of::<usize>())
|
.div_ceil(size_of::<usize>())
|
||||||
* size_of::<usize>();
|
* size_of::<usize>();
|
||||||
assert!(offset_of!(FIO_rust_zstdErrorHelpState, callback_context) == 0);
|
assert!(offset_of!(FIO_rust_zstdErrorHelpState, callback_context) == 0);
|
||||||
assert!(offset_of!(FIO_rust_zstdErrorHelpState, src_file_name) == size_of::<usize>());
|
assert!(offset_of!(FIO_rust_zstdErrorHelpState, src_file_name) == size_of::<usize>());
|
||||||
@@ -537,68 +530,105 @@ pub type FIO_createCResourcesSetParameterFn =
|
|||||||
unsafe extern "C" fn(*mut c_void, c_int, c_int) -> usize;
|
unsafe extern "C" fn(*mut c_void, c_int, c_int) -> usize;
|
||||||
pub type FIO_createCResourcesIsErrorFn = unsafe extern "C" fn(usize) -> c_int;
|
pub type FIO_createCResourcesIsErrorFn = unsafe extern "C" fn(usize) -> c_int;
|
||||||
pub type FIO_createCResourcesDisplayOverlapFn = unsafe extern "C" fn(c_int);
|
pub type FIO_createCResourcesDisplayOverlapFn = unsafe extern "C" fn(c_int);
|
||||||
|
pub type FIO_createCResourcesCreateCctxFn = unsafe extern "C" fn(*mut c_void);
|
||||||
|
pub type FIO_createCResourcesPrepareDictionaryFn =
|
||||||
|
unsafe extern "C" fn(*mut c_void, *const FIO_prefs_t, *const c_char, u64, c_int, *mut c_void);
|
||||||
|
pub type FIO_createCResourcesCreatePoolFn = unsafe extern "C" fn(*mut c_void, *const FIO_prefs_t);
|
||||||
|
pub type FIO_createCResourcesValidateDictionaryFn = unsafe extern "C" fn(*mut c_void);
|
||||||
|
pub type FIO_createCResourcesLoadDictionaryFn = unsafe extern "C" fn(*mut c_void, c_int) -> usize;
|
||||||
|
|
||||||
/// C-owned compression-resource parameter policy projection.
|
/// Compression-resource initialization projection.
|
||||||
///
|
///
|
||||||
/// Rust owns the ordered, short-circuiting parameter policy. C keeps the
|
/// Rust owns the resource lifecycle and parameter order. C keeps the
|
||||||
/// `ZSTD_CCtx` layout private and exposes parameter/diagnostic callbacks;
|
/// `cRess_t`, `ZSTD_CCtx`, dictionary, and asynchronous-pool layouts private
|
||||||
/// resource allocation, dictionary/pool setup, and dictionary loading remain
|
/// behind callbacks which retain the original diagnostics and side effects.
|
||||||
/// in C.
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct FIO_rust_createCResourcesState {
|
pub struct FIO_rust_createCResourcesState {
|
||||||
callback_context: *mut c_void,
|
callback_context: *mut c_void,
|
||||||
prefs: *const FIO_prefs_t,
|
prefs: *const FIO_prefs_t,
|
||||||
compression_params: FIO_compressionParameters,
|
compression_params: FIO_compressionParameters,
|
||||||
compression_level: c_int,
|
compression_level: c_int,
|
||||||
|
dict_file_name: *const c_char,
|
||||||
|
max_src_file_size: u64,
|
||||||
|
multithreaded: c_int,
|
||||||
|
create_cctx: FIO_createCResourcesCreateCctxFn,
|
||||||
|
prepare_dictionary: FIO_createCResourcesPrepareDictionaryFn,
|
||||||
|
create_write_pool: FIO_createCResourcesCreatePoolFn,
|
||||||
|
create_read_pool: FIO_createCResourcesCreatePoolFn,
|
||||||
|
validate_dictionary: FIO_createCResourcesValidateDictionaryFn,
|
||||||
|
load_dictionary: FIO_createCResourcesLoadDictionaryFn,
|
||||||
set_parameter: FIO_createCResourcesSetParameterFn,
|
set_parameter: FIO_createCResourcesSetParameterFn,
|
||||||
is_error: FIO_createCResourcesIsErrorFn,
|
is_error: FIO_createCResourcesIsErrorFn,
|
||||||
display_overlap: FIO_createCResourcesDisplayOverlapFn,
|
display_overlap: FIO_createCResourcesDisplayOverlapFn,
|
||||||
}
|
}
|
||||||
|
|
||||||
const _: () = {
|
const _: () = {
|
||||||
let callback_offset = (2 * size_of::<usize>()
|
let word = size_of::<usize>();
|
||||||
+ size_of::<FIO_compressionParameters>()
|
let dict_file_name_offset =
|
||||||
+ size_of::<c_int>())
|
(2 * word + size_of::<FIO_compressionParameters>() + size_of::<c_int>()).div_ceil(word)
|
||||||
.div_ceil(size_of::<usize>())
|
* word;
|
||||||
* size_of::<usize>();
|
let callback_offset = (dict_file_name_offset + word + size_of::<u64>() + size_of::<c_int>())
|
||||||
|
.div_ceil(word)
|
||||||
|
* word;
|
||||||
assert!(offset_of!(FIO_rust_createCResourcesState, callback_context) == 0);
|
assert!(offset_of!(FIO_rust_createCResourcesState, callback_context) == 0);
|
||||||
assert!(offset_of!(FIO_rust_createCResourcesState, prefs) == size_of::<usize>());
|
assert!(offset_of!(FIO_rust_createCResourcesState, prefs) == word);
|
||||||
assert!(
|
assert!(offset_of!(FIO_rust_createCResourcesState, compression_params) == 2 * word);
|
||||||
offset_of!(FIO_rust_createCResourcesState, compression_params)
|
|
||||||
== 2 * size_of::<usize>()
|
|
||||||
);
|
|
||||||
assert!(
|
assert!(
|
||||||
offset_of!(FIO_rust_createCResourcesState, compression_level)
|
offset_of!(FIO_rust_createCResourcesState, compression_level)
|
||||||
== 2 * size_of::<usize>() + size_of::<FIO_compressionParameters>()
|
== 2 * word + size_of::<FIO_compressionParameters>()
|
||||||
);
|
);
|
||||||
assert!(offset_of!(FIO_rust_createCResourcesState, set_parameter) == callback_offset);
|
assert!(offset_of!(FIO_rust_createCResourcesState, dict_file_name) == dict_file_name_offset);
|
||||||
assert!(offset_of!(FIO_rust_createCResourcesState, is_error) == callback_offset + size_of::<usize>());
|
|
||||||
assert!(
|
assert!(
|
||||||
offset_of!(FIO_rust_createCResourcesState, display_overlap)
|
offset_of!(FIO_rust_createCResourcesState, max_src_file_size)
|
||||||
== callback_offset + 2 * size_of::<usize>()
|
== dict_file_name_offset + word
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
size_of::<FIO_rust_createCResourcesState>() == callback_offset + 3 * size_of::<usize>()
|
offset_of!(FIO_rust_createCResourcesState, multithreaded)
|
||||||
|
== dict_file_name_offset + word + size_of::<u64>()
|
||||||
);
|
);
|
||||||
|
assert!(offset_of!(FIO_rust_createCResourcesState, create_cctx) == callback_offset);
|
||||||
|
assert!(
|
||||||
|
offset_of!(FIO_rust_createCResourcesState, prepare_dictionary) == callback_offset + word
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(FIO_rust_createCResourcesState, create_write_pool) == callback_offset + 2 * word
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(FIO_rust_createCResourcesState, create_read_pool) == callback_offset + 3 * word
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(FIO_rust_createCResourcesState, validate_dictionary)
|
||||||
|
== callback_offset + 4 * word
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(FIO_rust_createCResourcesState, load_dictionary) == callback_offset + 5 * word
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
offset_of!(FIO_rust_createCResourcesState, set_parameter) == callback_offset + 6 * word
|
||||||
|
);
|
||||||
|
assert!(offset_of!(FIO_rust_createCResourcesState, is_error) == callback_offset + 7 * word);
|
||||||
|
assert!(
|
||||||
|
offset_of!(FIO_rust_createCResourcesState, display_overlap) == callback_offset + 8 * word
|
||||||
|
);
|
||||||
|
assert!(size_of::<FIO_rust_createCResourcesState>() == callback_offset + 9 * word);
|
||||||
};
|
};
|
||||||
|
|
||||||
#[no_mangle]
|
#[inline]
|
||||||
pub unsafe extern "C" fn FIO_rust_createCResources(
|
unsafe fn set_c_resources_parameters(state: &FIO_rust_createCResourcesState) -> usize {
|
||||||
state: *const FIO_rust_createCResourcesState,
|
|
||||||
) -> usize {
|
|
||||||
if state.is_null() {
|
|
||||||
return usize::MAX;
|
|
||||||
}
|
|
||||||
let state = unsafe { &*state };
|
|
||||||
if state.prefs.is_null() {
|
if state.prefs.is_null() {
|
||||||
return usize::MAX;
|
return usize::MAX;
|
||||||
}
|
}
|
||||||
let prefs = unsafe { &*state.prefs };
|
let prefs = unsafe { &*state.prefs };
|
||||||
let mut compression_params = state.compression_params;
|
let compression_params = state.compression_params;
|
||||||
if prefs.adaptiveMode != 0 && prefs.ldmFlag == 0 && compression_params.windowLog == 0 {
|
let set_parameter = |parameter: c_int, value: c_int| {
|
||||||
compression_params.windowLog = FIO_ADAPT_WINDOWLOG_DEFAULT;
|
let result = unsafe { (state.set_parameter)(state.callback_context, parameter, value) };
|
||||||
}
|
if unsafe { (state.is_error)(result) } != 0 {
|
||||||
|
Some(result)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
let parameters = [
|
let parameters = [
|
||||||
(FIO_ZSTD_C_CONTENT_SIZE_FLAG, prefs.contentSize),
|
(FIO_ZSTD_C_CONTENT_SIZE_FLAG, prefs.contentSize),
|
||||||
(FIO_ZSTD_C_DICT_ID_FLAG, prefs.dictIDFlag),
|
(FIO_ZSTD_C_DICT_ID_FLAG, prefs.dictIDFlag),
|
||||||
@@ -614,33 +644,18 @@ pub unsafe extern "C" fn FIO_rust_createCResources(
|
|||||||
(FIO_ZSTD_C_LDM_MIN_MATCH, prefs.ldmMinMatch),
|
(FIO_ZSTD_C_LDM_MIN_MATCH, prefs.ldmMinMatch),
|
||||||
];
|
];
|
||||||
for (parameter, value) in parameters {
|
for (parameter, value) in parameters {
|
||||||
let result = unsafe { (state.set_parameter)(state.callback_context, parameter, value) };
|
if let Some(error) = set_parameter(parameter, value) {
|
||||||
if unsafe { (state.is_error)(result) } != 0 {
|
return error;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if prefs.ldmBucketSizeLog != FIO_LDM_PARAM_NOTSET {
|
if prefs.ldmBucketSizeLog != FIO_LDM_PARAM_NOTSET {
|
||||||
let result = unsafe {
|
if let Some(error) = set_parameter(FIO_ZSTD_C_LDM_BUCKET_SIZE_LOG, prefs.ldmBucketSizeLog) {
|
||||||
(state.set_parameter)(
|
return error;
|
||||||
state.callback_context,
|
|
||||||
FIO_ZSTD_C_LDM_BUCKET_SIZE_LOG,
|
|
||||||
prefs.ldmBucketSizeLog,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
if unsafe { (state.is_error)(result) } != 0 {
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if prefs.ldmHashRateLog != FIO_LDM_PARAM_NOTSET {
|
if prefs.ldmHashRateLog != FIO_LDM_PARAM_NOTSET {
|
||||||
let result = unsafe {
|
if let Some(error) = set_parameter(FIO_ZSTD_C_LDM_HASH_RATE_LOG, prefs.ldmHashRateLog) {
|
||||||
(state.set_parameter)(
|
return error;
|
||||||
state.callback_context,
|
|
||||||
FIO_ZSTD_C_LDM_HASH_RATE_LOG,
|
|
||||||
prefs.ldmHashRateLog,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
if unsafe { (state.is_error)(result) } != 0 {
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,11 +678,62 @@ pub unsafe extern "C" fn FIO_rust_createCResources(
|
|||||||
(FIO_ZSTD_C_ENABLE_DEDICATED_DICT_SEARCH, 1),
|
(FIO_ZSTD_C_ENABLE_DEDICATED_DICT_SEARCH, 1),
|
||||||
];
|
];
|
||||||
for (parameter, value) in parameters {
|
for (parameter, value) in parameters {
|
||||||
let result = unsafe { (state.set_parameter)(state.callback_context, parameter, value) };
|
if let Some(error) = set_parameter(parameter, value) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn FIO_rust_createCResources(
|
||||||
|
state: *const FIO_rust_createCResourcesState,
|
||||||
|
) -> usize {
|
||||||
|
let Some(state) = (unsafe { state.as_ref() }) else {
|
||||||
|
return usize::MAX;
|
||||||
|
};
|
||||||
|
if state.prefs.is_null() {
|
||||||
|
return usize::MAX;
|
||||||
|
}
|
||||||
|
let prefs = unsafe { &*state.prefs };
|
||||||
|
|
||||||
|
unsafe { (state.create_cctx)(state.callback_context) };
|
||||||
|
let mut policy = *state;
|
||||||
|
let mut compression_params = state.compression_params;
|
||||||
|
unsafe {
|
||||||
|
(state.prepare_dictionary)(
|
||||||
|
state.callback_context,
|
||||||
|
state.prefs,
|
||||||
|
state.dict_file_name,
|
||||||
|
state.max_src_file_size,
|
||||||
|
state.compression_level,
|
||||||
|
(&mut compression_params as *mut FIO_compressionParameters).cast(),
|
||||||
|
);
|
||||||
|
(state.create_write_pool)(state.callback_context, state.prefs);
|
||||||
|
(state.create_read_pool)(state.callback_context, state.prefs);
|
||||||
|
(state.validate_dictionary)(state.callback_context);
|
||||||
|
}
|
||||||
|
if prefs.adaptiveMode != 0 && prefs.ldmFlag == 0 && compression_params.windowLog == 0 {
|
||||||
|
compression_params.windowLog = FIO_ADAPT_WINDOWLOG_DEFAULT;
|
||||||
|
}
|
||||||
|
policy.compression_params = compression_params;
|
||||||
|
|
||||||
|
let result = unsafe { set_c_resources_parameters(&policy) };
|
||||||
|
if unsafe { (state.is_error)(result) } != 0 {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if state.multithreaded != 0 {
|
||||||
|
let result = unsafe { FIO_rust_setCResourcesMtParameters(&policy) };
|
||||||
if unsafe { (state.is_error)(result) } != 0 {
|
if unsafe { (state.is_error)(result) } != 0 {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let patch_from_mode = prefs.patchFromMode;
|
||||||
|
let result = unsafe { (state.load_dictionary)(state.callback_context, patch_from_mode) };
|
||||||
|
if unsafe { (state.is_error)(result) } != 0 {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,7 +777,11 @@ pub unsafe extern "C" fn FIO_rust_setCResourcesMtParameters(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let result = unsafe {
|
let result = unsafe {
|
||||||
(state.set_parameter)(state.callback_context, FIO_ZSTD_C_RSYNCABLE, prefs.rsyncable)
|
(state.set_parameter)(
|
||||||
|
state.callback_context,
|
||||||
|
FIO_ZSTD_C_RSYNCABLE,
|
||||||
|
prefs.rsyncable,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
if unsafe { (state.is_error)(result) } != 0 {
|
if unsafe { (state.is_error)(result) } != 0 {
|
||||||
return result;
|
return result;
|
||||||
@@ -730,19 +800,12 @@ pub type FIO_listMultipleFilesListFileFn = unsafe extern "C" fn(
|
|||||||
pub type FIO_listMultipleFilesDisplayTotalFn =
|
pub type FIO_listMultipleFilesDisplayTotalFn =
|
||||||
unsafe extern "C" fn(*mut c_void, *const FIO_listFileInfoProjection_t);
|
unsafe extern "C" fn(*mut c_void, *const FIO_listFileInfoProjection_t);
|
||||||
|
|
||||||
pub type FIO_listFileGetInfoFn = unsafe extern "C" fn(
|
pub type FIO_listFileGetInfoFn =
|
||||||
*mut c_void,
|
unsafe extern "C" fn(*mut c_void, *const c_char, *mut FIO_fileInfo_t) -> c_int;
|
||||||
*const c_char,
|
|
||||||
*mut FIO_fileInfo_t,
|
|
||||||
) -> c_int;
|
|
||||||
pub type FIO_listFileDisplayStatusFn =
|
pub type FIO_listFileDisplayStatusFn =
|
||||||
unsafe extern "C" fn(*mut c_void, c_int, *const c_char, c_int);
|
unsafe extern "C" fn(*mut c_void, c_int, *const c_char, c_int);
|
||||||
pub type FIO_listFileDisplayInfoFn = unsafe extern "C" fn(
|
pub type FIO_listFileDisplayInfoFn =
|
||||||
*mut c_void,
|
unsafe extern "C" fn(*mut c_void, *const c_char, *const FIO_fileInfo_t, c_int);
|
||||||
*const c_char,
|
|
||||||
*const FIO_fileInfo_t,
|
|
||||||
c_int,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Callbacks for the C-owned `--list` file operation.
|
/// Callbacks for the C-owned `--list` file operation.
|
||||||
///
|
///
|
||||||
@@ -902,11 +965,7 @@ pub extern "C" fn FIO_rust_compressDestinationTransferStat(
|
|||||||
destination_is_stdout: c_int,
|
destination_is_stdout: c_int,
|
||||||
source_is_regular: c_int,
|
source_is_regular: c_int,
|
||||||
) -> c_int {
|
) -> c_int {
|
||||||
compress_destination_transfer_stat(
|
compress_destination_transfer_stat(source_is_stdin, destination_is_stdout, source_is_regular)
|
||||||
source_is_stdin,
|
|
||||||
destination_is_stdout,
|
|
||||||
source_is_regular,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Callback projection for the C-owned `--list` file operations.
|
/// Callback projection for the C-owned `--list` file operations.
|
||||||
@@ -2895,18 +2954,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn list_file_status_action_preserves_cli_mapping_and_abi() {
|
fn list_file_status_action_preserves_cli_mapping_and_abi() {
|
||||||
for (status, action) in [
|
for (status, action) in [
|
||||||
(
|
(FIO_LIST_INFO_SUCCESS, FIO_RUST_LIST_FILE_ACTION_SUCCESS),
|
||||||
FIO_LIST_INFO_SUCCESS,
|
|
||||||
FIO_RUST_LIST_FILE_ACTION_SUCCESS,
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
FIO_LIST_INFO_FRAME_ERROR,
|
FIO_LIST_INFO_FRAME_ERROR,
|
||||||
FIO_RUST_LIST_FILE_ACTION_FRAME_ERROR,
|
FIO_RUST_LIST_FILE_ACTION_FRAME_ERROR,
|
||||||
),
|
),
|
||||||
(
|
(FIO_LIST_INFO_NOT_ZSTD, FIO_RUST_LIST_FILE_ACTION_NOT_ZSTD),
|
||||||
FIO_LIST_INFO_NOT_ZSTD,
|
|
||||||
FIO_RUST_LIST_FILE_ACTION_NOT_ZSTD,
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
FIO_LIST_INFO_FILE_ERROR,
|
FIO_LIST_INFO_FILE_ERROR,
|
||||||
FIO_RUST_LIST_FILE_ACTION_FILE_ERROR,
|
FIO_RUST_LIST_FILE_ACTION_FILE_ERROR,
|
||||||
@@ -2935,10 +2988,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn remove_file_action_preserves_status_mapping_and_unknown_failure_policy() {
|
fn remove_file_action_preserves_status_mapping_and_unknown_failure_policy() {
|
||||||
for (status, action) in [
|
for (status, action) in [
|
||||||
(
|
(FIO_REMOVE_SUCCESS, FIO_RUST_REMOVE_FILE_ACTION_SUCCESS),
|
||||||
FIO_REMOVE_SUCCESS,
|
|
||||||
FIO_RUST_REMOVE_FILE_ACTION_SUCCESS,
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
FIO_REMOVE_STAT_FAILED,
|
FIO_REMOVE_STAT_FAILED,
|
||||||
FIO_RUST_REMOVE_FILE_ACTION_STAT_FAILED,
|
FIO_RUST_REMOVE_FILE_ACTION_STAT_FAILED,
|
||||||
@@ -2947,10 +2997,7 @@ mod tests {
|
|||||||
FIO_REMOVE_NON_REGULAR,
|
FIO_REMOVE_NON_REGULAR,
|
||||||
FIO_RUST_REMOVE_FILE_ACTION_NON_REGULAR,
|
FIO_RUST_REMOVE_FILE_ACTION_NON_REGULAR,
|
||||||
),
|
),
|
||||||
(
|
(FIO_REMOVE_FAILED, FIO_RUST_REMOVE_FILE_ACTION_FAILED),
|
||||||
FIO_REMOVE_FAILED,
|
|
||||||
FIO_RUST_REMOVE_FILE_ACTION_FAILED,
|
|
||||||
),
|
|
||||||
(-1, FIO_RUST_REMOVE_FILE_ACTION_INVALID),
|
(-1, FIO_RUST_REMOVE_FILE_ACTION_INVALID),
|
||||||
(c_int::MAX, FIO_RUST_REMOVE_FILE_ACTION_INVALID),
|
(c_int::MAX, FIO_RUST_REMOVE_FILE_ACTION_INVALID),
|
||||||
] {
|
] {
|
||||||
@@ -3289,9 +3336,75 @@ mod tests {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct CreateCResourcesTestState {
|
struct CreateCResourcesTestState {
|
||||||
events: Vec<(c_int, c_int)>,
|
events: Vec<(c_int, c_int)>,
|
||||||
|
lifecycle: Vec<&'static str>,
|
||||||
fail_parameter: Option<c_int>,
|
fail_parameter: Option<c_int>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn create_c_resources_create_cctx_test(context: *mut c_void) {
|
||||||
|
unsafe {
|
||||||
|
(*context.cast::<CreateCResourcesTestState>())
|
||||||
|
.lifecycle
|
||||||
|
.push("create-cctx");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn create_c_resources_prepare_dictionary_test(
|
||||||
|
context: *mut c_void,
|
||||||
|
_prefs: *const FIO_prefs_t,
|
||||||
|
_dict_file_name: *const c_char,
|
||||||
|
_max_src_file_size: u64,
|
||||||
|
_compression_level: c_int,
|
||||||
|
_compression_params: *mut c_void,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
(*context.cast::<CreateCResourcesTestState>())
|
||||||
|
.lifecycle
|
||||||
|
.push("prepare-dictionary");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn create_c_resources_create_write_pool_test(
|
||||||
|
context: *mut c_void,
|
||||||
|
_prefs: *const FIO_prefs_t,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
(*context.cast::<CreateCResourcesTestState>())
|
||||||
|
.lifecycle
|
||||||
|
.push("create-write-pool");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn create_c_resources_create_read_pool_test(
|
||||||
|
context: *mut c_void,
|
||||||
|
_prefs: *const FIO_prefs_t,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
(*context.cast::<CreateCResourcesTestState>())
|
||||||
|
.lifecycle
|
||||||
|
.push("create-read-pool");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn create_c_resources_validate_dictionary_test(context: *mut c_void) {
|
||||||
|
unsafe {
|
||||||
|
(*context.cast::<CreateCResourcesTestState>())
|
||||||
|
.lifecycle
|
||||||
|
.push("validate-dictionary");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn create_c_resources_load_dictionary_test(
|
||||||
|
context: *mut c_void,
|
||||||
|
_patch_from_mode: c_int,
|
||||||
|
) -> usize {
|
||||||
|
unsafe {
|
||||||
|
(*context.cast::<CreateCResourcesTestState>())
|
||||||
|
.lifecycle
|
||||||
|
.push("load-dictionary");
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn create_c_resources_set_parameter_test(
|
unsafe extern "C" fn create_c_resources_set_parameter_test(
|
||||||
context: *mut c_void,
|
context: *mut c_void,
|
||||||
parameter: c_int,
|
parameter: c_int,
|
||||||
@@ -3342,6 +3455,15 @@ mod tests {
|
|||||||
strategy: 6,
|
strategy: 6,
|
||||||
},
|
},
|
||||||
compression_level: 7,
|
compression_level: 7,
|
||||||
|
dict_file_name: ptr::null(),
|
||||||
|
max_src_file_size: 0,
|
||||||
|
multithreaded: 0,
|
||||||
|
create_cctx: create_c_resources_create_cctx_test,
|
||||||
|
prepare_dictionary: create_c_resources_prepare_dictionary_test,
|
||||||
|
create_write_pool: create_c_resources_create_write_pool_test,
|
||||||
|
create_read_pool: create_c_resources_create_read_pool_test,
|
||||||
|
validate_dictionary: create_c_resources_validate_dictionary_test,
|
||||||
|
load_dictionary: create_c_resources_load_dictionary_test,
|
||||||
set_parameter: create_c_resources_set_parameter_test,
|
set_parameter: create_c_resources_set_parameter_test,
|
||||||
is_error: create_c_resources_is_error_test,
|
is_error: create_c_resources_is_error_test,
|
||||||
display_overlap: create_c_resources_display_overlap_test,
|
display_overlap: create_c_resources_display_overlap_test,
|
||||||
@@ -3357,6 +3479,17 @@ mod tests {
|
|||||||
let result = unsafe { FIO_rust_createCResources(&state) };
|
let result = unsafe { FIO_rust_createCResources(&state) };
|
||||||
|
|
||||||
assert_eq!(result, 0);
|
assert_eq!(result, 0);
|
||||||
|
assert_eq!(
|
||||||
|
context.lifecycle,
|
||||||
|
vec![
|
||||||
|
"create-cctx",
|
||||||
|
"prepare-dictionary",
|
||||||
|
"create-write-pool",
|
||||||
|
"create-read-pool",
|
||||||
|
"validate-dictionary",
|
||||||
|
"load-dictionary",
|
||||||
|
]
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
context.events,
|
context.events,
|
||||||
vec![
|
vec![
|
||||||
@@ -3464,10 +3597,7 @@ mod tests {
|
|||||||
assert_eq!(result, usize::MAX);
|
assert_eq!(result, usize::MAX);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
context.events,
|
context.events,
|
||||||
vec![
|
vec![(FIO_ZSTD_C_NB_WORKERS, 3), (FIO_ZSTD_C_JOB_SIZE, 4096),]
|
||||||
(FIO_ZSTD_C_NB_WORKERS, 3),
|
|
||||||
(FIO_ZSTD_C_JOB_SIZE, 4096),
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4564,12 +4694,7 @@ mod tests {
|
|||||||
let mut output = sentinel;
|
let mut output = sentinel;
|
||||||
|
|
||||||
let result = unsafe {
|
let result = unsafe {
|
||||||
FIO_rust_listFile(
|
FIO_rust_listFile(file_name.as_ptr(), display_level, &mut output, &callbacks)
|
||||||
file_name.as_ptr(),
|
|
||||||
display_level,
|
|
||||||
&mut output,
|
|
||||||
&callbacks,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(result, expected_return, "status {status}");
|
assert_eq!(result, expected_return, "status {status}");
|
||||||
@@ -4803,20 +4928,15 @@ mod tests {
|
|||||||
let output_dir = CString::new("out").unwrap();
|
let output_dir = CString::new("out").unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let name =
|
let name = FIO_determineCompressedName(source.as_ptr(), ptr::null(), suffix.as_ptr());
|
||||||
FIO_determineCompressedName(source.as_ptr(), ptr::null(), suffix.as_ptr());
|
|
||||||
assert_eq!(CStr::from_ptr(name).to_bytes(), b"input/nested/file.zst");
|
assert_eq!(CStr::from_ptr(name).to_bytes(), b"input/nested/file.zst");
|
||||||
|
|
||||||
let name = FIO_determineCompressedName(
|
let name =
|
||||||
source.as_ptr(),
|
FIO_determineCompressedName(source.as_ptr(), output_dir.as_ptr(), suffix.as_ptr());
|
||||||
output_dir.as_ptr(),
|
|
||||||
suffix.as_ptr(),
|
|
||||||
);
|
|
||||||
assert_eq!(CStr::from_ptr(name).to_bytes(), b"out/file.zst");
|
assert_eq!(CStr::from_ptr(name).to_bytes(), b"out/file.zst");
|
||||||
|
|
||||||
let stdin = CString::new("/*stdin*\\").unwrap();
|
let stdin = CString::new("/*stdin*\\").unwrap();
|
||||||
let name =
|
let name = FIO_determineCompressedName(stdin.as_ptr(), ptr::null(), suffix.as_ptr());
|
||||||
FIO_determineCompressedName(stdin.as_ptr(), ptr::null(), suffix.as_ptr());
|
|
||||||
assert_eq!(CStr::from_ptr(name).to_bytes(), b"/*stdout*\\");
|
assert_eq!(CStr::from_ptr(name).to_bytes(), b"/*stdout*\\");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5105,33 +5225,21 @@ mod tests {
|
|||||||
|
|
||||||
for display_level in [0, 2, 3] {
|
for display_level in [0, 2, 3] {
|
||||||
FIO_setNotificationLevel(display_level);
|
FIO_setNotificationLevel(display_level);
|
||||||
assert_eq!(
|
assert_eq!(unsafe { FIO_shouldDisplayMultipleFileSummary(&ctx) }, 0);
|
||||||
unsafe { FIO_shouldDisplayMultipleFileSummary(&ctx) },
|
|
||||||
0
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.nbFilesProcessed = 1;
|
ctx.nbFilesProcessed = 1;
|
||||||
for display_level in [0, 2, 3] {
|
for display_level in [0, 2, 3] {
|
||||||
FIO_setNotificationLevel(display_level);
|
FIO_setNotificationLevel(display_level);
|
||||||
assert_eq!(
|
assert_eq!(unsafe { FIO_shouldDisplayMultipleFileSummary(&ctx) }, 1);
|
||||||
unsafe { FIO_shouldDisplayMultipleFileSummary(&ctx) },
|
|
||||||
1
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.nbFilesProcessed = 2;
|
ctx.nbFilesProcessed = 2;
|
||||||
FIO_setNotificationLevel(0);
|
FIO_setNotificationLevel(0);
|
||||||
assert_eq!(
|
assert_eq!(unsafe { FIO_shouldDisplayMultipleFileSummary(&ctx) }, 1);
|
||||||
unsafe { FIO_shouldDisplayMultipleFileSummary(&ctx) },
|
|
||||||
1
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx.nbFilesTotal = 1;
|
ctx.nbFilesTotal = 1;
|
||||||
assert_eq!(
|
assert_eq!(unsafe { FIO_shouldDisplayMultipleFileSummary(&ctx) }, 0);
|
||||||
unsafe { FIO_shouldDisplayMultipleFileSummary(&ctx) },
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
FIO_setNotificationLevel(2);
|
FIO_setNotificationLevel(2);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user