refactor(compress): move CDict construction policy to Rust

Move advanced and static CDict construction ordering into Rust while keeping
private workspace layout, object initialization, dictionary loading, and
allocator leaves in C callbacks.  The Rust policy now validates parameters and
memory, computes the workspace contract, sequences allocation/reservation and
initialization, and preserves failure cleanup for both dynamic and static
workspaces.  Add callback-order, allocation-failure, reservation-failure, and
initializer-failure tests around the ABI projections.

Test Plan:
- `cargo fmt --manifest-path rust/Cargo.toml --all -- --check`
- `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml --all-targets`
- `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings`
- `ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo build --manifest-path rust/Cargo.toml --release`
This commit is contained in:
2026-07-20 04:05:14 +02:00
parent 371451d69c
commit 1c3bf6b708
2 changed files with 414 additions and 157 deletions
+164 -79
View File
@@ -404,12 +404,23 @@ typedef char ZSTD_rust_free_cdict_state_layout[
== 3 * sizeof(void*) == 3 * sizeof(void*)
&& sizeof(ZSTD_rust_freeCDictState) == 4 * sizeof(void*)) && sizeof(ZSTD_rust_freeCDictState) == 4 * sizeof(void*))
? 1 : -1]; ? 1 : -1];
typedef void* (*ZSTD_rust_initStaticCDictInit_f)(void* context); typedef void (*ZSTD_rust_initStaticCDictCreateWorkspace_f)(void* context);
typedef void* (*ZSTD_rust_initStaticCDictReserveObject_f)(void* context);
typedef void (*ZSTD_rust_initStaticCDictMoveWorkspace_f)(
void* context, void* cdict);
typedef void (*ZSTD_rust_initStaticCDictInitialize_f)(
void* context, void* cdict);
typedef void* (*ZSTD_rust_initStaticCDictInit_f)(
void* context, void* cdict);
typedef struct { typedef struct {
void* callbackContext; void* callbackContext;
void* workspace; void* workspace;
size_t workspaceSize; size_t workspaceSize;
size_t neededSize; size_t neededSize;
ZSTD_rust_initStaticCDictCreateWorkspace_f createWorkspace;
ZSTD_rust_initStaticCDictReserveObject_f reserveObject;
ZSTD_rust_initStaticCDictMoveWorkspace_f moveWorkspace;
ZSTD_rust_initStaticCDictInitialize_f initialize;
ZSTD_rust_initStaticCDictInit_f init; ZSTD_rust_initStaticCDictInit_f init;
} ZSTD_rust_initStaticCDictState; } ZSTD_rust_initStaticCDictState;
void* ZSTD_rust_initStaticCDict(const ZSTD_rust_initStaticCDictState* state); void* ZSTD_rust_initStaticCDict(const ZSTD_rust_initStaticCDictState* state);
@@ -421,9 +432,17 @@ typedef char ZSTD_rust_init_static_cdict_state_layout[
== 2 * sizeof(void*) == 2 * sizeof(void*)
&& offsetof(ZSTD_rust_initStaticCDictState, neededSize) && offsetof(ZSTD_rust_initStaticCDictState, neededSize)
== 3 * sizeof(void*) == 3 * sizeof(void*)
&& offsetof(ZSTD_rust_initStaticCDictState, init) && offsetof(ZSTD_rust_initStaticCDictState, createWorkspace)
== 4 * sizeof(void*) == 4 * sizeof(void*)
&& sizeof(ZSTD_rust_initStaticCDictState) == 5 * sizeof(void*)) && offsetof(ZSTD_rust_initStaticCDictState, reserveObject)
== 5 * sizeof(void*)
&& offsetof(ZSTD_rust_initStaticCDictState, moveWorkspace)
== 6 * sizeof(void*)
&& offsetof(ZSTD_rust_initStaticCDictState, initialize)
== 7 * sizeof(void*)
&& offsetof(ZSTD_rust_initStaticCDictState, init)
== 8 * sizeof(void*)
&& sizeof(ZSTD_rust_initStaticCDictState) == 9 * sizeof(void*))
? 1 : -1]; ? 1 : -1];
typedef void (*ZSTD_rust_resetCCtxClearAllDicts_f)(void* context); typedef void (*ZSTD_rust_resetCCtxClearAllDicts_f)(void* context);
typedef size_t (*ZSTD_rust_resetCCtxResetParams_f)(void* context); typedef size_t (*ZSTD_rust_resetCCtxResetParams_f)(void* context);
@@ -2531,11 +2550,14 @@ typedef size_t (*ZSTD_rust_createCDictAdvancedWorkspaceSize_f)(
int useRowMatchFinder, int enableDedicatedDictSearch); int useRowMatchFinder, int enableDedicatedDictSearch);
typedef void* (*ZSTD_rust_createCDictAdvancedAllocate_f)( typedef void* (*ZSTD_rust_createCDictAdvancedAllocate_f)(
void* context, size_t workspaceSize); void* context, size_t workspaceSize);
typedef void* (*ZSTD_rust_createCDictAdvancedCreate_f)( typedef void (*ZSTD_rust_createCDictAdvancedCreateWorkspace_f)(
void* context, void* workspace, size_t workspaceSize, void* context, void* workspace, size_t workspaceSize);
size_t dictSize, int dictLoadMethod, typedef void* (*ZSTD_rust_createCDictAdvancedReserveObject_f)(
const ZSTD_compressionParameters* cParams, void* context);
int useRowMatchFinder, int enableDedicatedDictSearch); typedef void (*ZSTD_rust_createCDictAdvancedMoveWorkspace_f)(
void* context, void* cdict);
typedef void (*ZSTD_rust_createCDictAdvancedInitialize_f)(
void* context, void* cdict, int useRowMatchFinder);
typedef size_t (*ZSTD_rust_createCDictAdvancedInit_f)( typedef size_t (*ZSTD_rust_createCDictAdvancedInit_f)(
void* context, void* cdict, const void* dict, size_t dictSize, void* context, void* cdict, const void* dict, size_t dictSize,
int dictLoadMethod, int dictContentType, int dictLoadMethod, int dictContentType,
@@ -2555,7 +2577,10 @@ typedef struct {
ZSTD_rust_createCDictAdvancedValidateCustomMem_f validateCustomMem; ZSTD_rust_createCDictAdvancedValidateCustomMem_f validateCustomMem;
ZSTD_rust_createCDictAdvancedWorkspaceSize_f workspaceSize; ZSTD_rust_createCDictAdvancedWorkspaceSize_f workspaceSize;
ZSTD_rust_createCDictAdvancedAllocate_f allocate; ZSTD_rust_createCDictAdvancedAllocate_f allocate;
ZSTD_rust_createCDictAdvancedCreate_f create; ZSTD_rust_createCDictAdvancedCreateWorkspace_f createWorkspace;
ZSTD_rust_createCDictAdvancedReserveObject_f reserveObject;
ZSTD_rust_createCDictAdvancedMoveWorkspace_f moveWorkspace;
ZSTD_rust_createCDictAdvancedInitialize_f initialize;
ZSTD_rust_createCDictAdvancedInit_f init; ZSTD_rust_createCDictAdvancedInit_f init;
ZSTD_rust_createCDictAdvancedFreeWorkspace_f freeWorkspace; ZSTD_rust_createCDictAdvancedFreeWorkspace_f freeWorkspace;
ZSTD_rust_createCDictAdvancedFree_f free; ZSTD_rust_createCDictAdvancedFree_f free;
@@ -2584,16 +2609,22 @@ typedef char ZSTD_rust_create_cdict_advanced_state_layout[
== 6 * sizeof(void*) + 2 * sizeof(U32) == 6 * sizeof(void*) + 2 * sizeof(U32)
&& offsetof(ZSTD_rust_createCDictAdvancedState, allocate) && offsetof(ZSTD_rust_createCDictAdvancedState, allocate)
== 7 * sizeof(void*) + 2 * sizeof(U32) == 7 * sizeof(void*) + 2 * sizeof(U32)
&& offsetof(ZSTD_rust_createCDictAdvancedState, create) && offsetof(ZSTD_rust_createCDictAdvancedState, createWorkspace)
== 8 * sizeof(void*) + 2 * sizeof(U32) == 8 * sizeof(void*) + 2 * sizeof(U32)
&& offsetof(ZSTD_rust_createCDictAdvancedState, init) && offsetof(ZSTD_rust_createCDictAdvancedState, reserveObject)
== 9 * sizeof(void*) + 2 * sizeof(U32) == 9 * sizeof(void*) + 2 * sizeof(U32)
&& offsetof(ZSTD_rust_createCDictAdvancedState, freeWorkspace) && offsetof(ZSTD_rust_createCDictAdvancedState, moveWorkspace)
== 10 * sizeof(void*) + 2 * sizeof(U32) == 10 * sizeof(void*) + 2 * sizeof(U32)
&& offsetof(ZSTD_rust_createCDictAdvancedState, free) && offsetof(ZSTD_rust_createCDictAdvancedState, initialize)
== 11 * sizeof(void*) + 2 * sizeof(U32) == 11 * sizeof(void*) + 2 * sizeof(U32)
&& offsetof(ZSTD_rust_createCDictAdvancedState, init)
== 12 * sizeof(void*) + 2 * sizeof(U32)
&& offsetof(ZSTD_rust_createCDictAdvancedState, freeWorkspace)
== 13 * sizeof(void*) + 2 * sizeof(U32)
&& offsetof(ZSTD_rust_createCDictAdvancedState, free)
== 14 * sizeof(void*) + 2 * sizeof(U32)
&& sizeof(ZSTD_rust_createCDictAdvancedState) && sizeof(ZSTD_rust_createCDictAdvancedState)
== 12 * sizeof(void*) + 2 * sizeof(U32)) == 15 * sizeof(void*) + 2 * sizeof(U32))
? 1 : -1]; ? 1 : -1];
typedef size_t (*ZSTD_rust_compressBeginResetInternal_f)( typedef size_t (*ZSTD_rust_compressBeginResetInternal_f)(
@@ -6710,9 +6741,16 @@ static size_t ZSTD_initCDict_internal(
(int)dictLoadMethod, (int)dictContentType); (int)dictLoadMethod, (int)dictContentType);
} }
typedef struct {
ZSTD_customMem customMem;
ZSTD_cwksp workspace;
} ZSTD_rust_createCDictAdvancedContext;
static int ZSTD_rust_createCDictAdvanced_validateCustomMem(void* context) static int ZSTD_rust_createCDictAdvanced_validateCustomMem(void* context)
{ {
ZSTD_customMem const* const customMem = (const ZSTD_customMem*)context; ZSTD_rust_createCDictAdvancedContext const* const createContext =
(const ZSTD_rust_createCDictAdvancedContext*)context;
ZSTD_customMem const* const customMem = &createContext->customMem;
return ((!customMem->customAlloc) ^ (!customMem->customFree)) == 0; return ((!customMem->customAlloc) ^ (!customMem->customFree)) == 0;
} }
@@ -6741,59 +6779,54 @@ static size_t ZSTD_rust_createCDictAdvanced_workspaceSize(
static void* ZSTD_rust_createCDictAdvanced_allocate( static void* ZSTD_rust_createCDictAdvanced_allocate(
void* context, size_t workspaceSize) void* context, size_t workspaceSize)
{ {
return ZSTD_customMalloc(workspaceSize, *(const ZSTD_customMem*)context); ZSTD_rust_createCDictAdvancedContext const* const createContext =
(const ZSTD_rust_createCDictAdvancedContext*)context;
return ZSTD_customMalloc(workspaceSize, createContext->customMem);
} }
static void* ZSTD_rust_createCDictAdvanced_create( static void ZSTD_rust_createCDictAdvanced_createWorkspace(
void* context, void* workspace, size_t workspaceSize, void* context, void* workspace, size_t workspaceSize)
size_t dictSize, int dictLoadMethod,
const ZSTD_compressionParameters* cParams,
int useRowMatchFinder, int enableDedicatedDictSearch)
{ {
ZSTD_customMem const customMem = *(const ZSTD_customMem*)context; ZSTD_rust_createCDictAdvancedContext* const createContext =
ZSTD_cwksp ws; (ZSTD_rust_createCDictAdvancedContext*)context;
ZSTD_CDict* cdict;
(void)dictSize;
(void)dictLoadMethod;
(void)cParams;
(void)enableDedicatedDictSearch;
DEBUGLOG(3, "ZSTD_createCDict_advanced_internal (workspaceSize=%u)", DEBUGLOG(3, "ZSTD_createCDict_advanced_internal (workspaceSize=%u)",
(unsigned)workspaceSize); (unsigned)workspaceSize);
if (workspace == NULL) return NULL; ZSTD_cwksp_init(&createContext->workspace, workspace, workspaceSize,
ZSTD_cwksp_dynamic_alloc);
}
ZSTD_cwksp_init(&ws, workspace, workspaceSize, ZSTD_cwksp_dynamic_alloc); static void* ZSTD_rust_createCDictAdvanced_reserveObject(void* context)
cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict)); {
if (cdict == NULL) return NULL; ZSTD_rust_createCDictAdvancedContext* const createContext =
ZSTD_cwksp_move(&cdict->workspace, &ws); (ZSTD_rust_createCDictAdvancedContext*)context;
cdict->customMem = customMem; return ZSTD_cwksp_reserve_object(&createContext->workspace, sizeof(ZSTD_CDict));
cdict->compressionLevel = ZSTD_NO_CLEVEL; /* signals advanced API usage */ }
cdict->useRowMatchFinder = (ZSTD_ParamSwitch_e)useRowMatchFinder;
return cdict; static void ZSTD_rust_createCDictAdvanced_moveWorkspace(
void* context, void* cdict)
{
ZSTD_rust_createCDictAdvancedContext* const createContext =
(ZSTD_rust_createCDictAdvancedContext*)context;
ZSTD_cwksp_move(&((ZSTD_CDict*)cdict)->workspace, &createContext->workspace);
}
static void ZSTD_rust_createCDictAdvanced_initialize(
void* context, void* cdict, int useRowMatchFinder)
{
ZSTD_rust_createCDictAdvancedContext const* const createContext =
(const ZSTD_rust_createCDictAdvancedContext*)context;
ZSTD_CDict* const dictionary = (ZSTD_CDict*)cdict;
dictionary->customMem = createContext->customMem;
dictionary->compressionLevel = ZSTD_NO_CLEVEL; /* signals advanced API usage */
dictionary->useRowMatchFinder = (ZSTD_ParamSwitch_e)useRowMatchFinder;
} }
static void ZSTD_rust_createCDictAdvanced_freeWorkspace( static void ZSTD_rust_createCDictAdvanced_freeWorkspace(
void* context, void* workspace) void* context, void* workspace)
{ {
ZSTD_customFree(workspace, *(const ZSTD_customMem*)context); ZSTD_rust_createCDictAdvancedContext const* const createContext =
} (const ZSTD_rust_createCDictAdvancedContext*)context;
ZSTD_customFree(workspace, createContext->customMem);
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_dictContentType_e dictContentType,
ZSTD_compressionParameters cParams,
ZSTD_customMem customMem)
{
ZSTD_CCtx_params cctxParams;
ZSTD_memset(&cctxParams, 0, sizeof(cctxParams));
DEBUGLOG(3, "ZSTD_createCDict_advanced, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType);
ZSTD_CCtxParams_init(&cctxParams, 0);
cctxParams.cParams = cParams;
cctxParams.customMem = customMem;
return ZSTD_createCDict_advanced2(
dictBuffer, dictSize,
dictLoadMethod, dictContentType,
&cctxParams, customMem);
} }
static size_t ZSTD_rust_createCDictAdvanced_init( static size_t ZSTD_rust_createCDictAdvanced_init(
@@ -6814,6 +6847,24 @@ static void ZSTD_rust_createCDictAdvanced_free(void* context, void* cdict)
ZSTD_freeCDict((ZSTD_CDict*)cdict); ZSTD_freeCDict((ZSTD_CDict*)cdict);
} }
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod,
ZSTD_dictContentType_e dictContentType,
ZSTD_compressionParameters cParams,
ZSTD_customMem customMem)
{
ZSTD_CCtx_params cctxParams;
ZSTD_memset(&cctxParams, 0, sizeof(cctxParams));
DEBUGLOG(3, "ZSTD_createCDict_advanced, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType);
ZSTD_CCtxParams_init(&cctxParams, 0);
cctxParams.cParams = cParams;
cctxParams.customMem = customMem;
return ZSTD_createCDict_advanced2(
dictBuffer, dictSize,
dictLoadMethod, dictContentType,
&cctxParams, customMem);
}
ZSTD_CDict* ZSTD_createCDict_advanced2( ZSTD_CDict* ZSTD_createCDict_advanced2(
const void* dict, size_t dictSize, const void* dict, size_t dictSize,
ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictLoadMethod_e dictLoadMethod,
@@ -6822,13 +6873,15 @@ ZSTD_CDict* ZSTD_createCDict_advanced2(
ZSTD_customMem customMem) ZSTD_customMem customMem)
{ {
ZSTD_CCtx_params cctxParams; ZSTD_CCtx_params cctxParams;
ZSTD_rust_createCDictAdvancedContext context;
ZSTD_rust_createCDictAdvancedState state; ZSTD_rust_createCDictAdvancedState state;
DEBUGLOG(3, "ZSTD_createCDict_advanced2, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType); DEBUGLOG(3, "ZSTD_createCDict_advanced2, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType);
if (originalCctxParams == NULL) return NULL; if (originalCctxParams == NULL) return NULL;
cctxParams = *originalCctxParams; cctxParams = *originalCctxParams;
state.callbackContext = &customMem; context.customMem = customMem;
state.callbackContext = &context;
state.cctxParams = &cctxParams; state.cctxParams = &cctxParams;
state.cParams = &cctxParams.cParams; state.cParams = &cctxParams.cParams;
state.enableDedicatedDictSearch = &cctxParams.enableDedicatedDictSearch; state.enableDedicatedDictSearch = &cctxParams.enableDedicatedDictSearch;
@@ -6838,7 +6891,10 @@ ZSTD_CDict* ZSTD_createCDict_advanced2(
state.validateCustomMem = ZSTD_rust_createCDictAdvanced_validateCustomMem; state.validateCustomMem = ZSTD_rust_createCDictAdvanced_validateCustomMem;
state.workspaceSize = ZSTD_rust_createCDictAdvanced_workspaceSize; state.workspaceSize = ZSTD_rust_createCDictAdvanced_workspaceSize;
state.allocate = ZSTD_rust_createCDictAdvanced_allocate; state.allocate = ZSTD_rust_createCDictAdvanced_allocate;
state.create = ZSTD_rust_createCDictAdvanced_create; state.createWorkspace = ZSTD_rust_createCDictAdvanced_createWorkspace;
state.reserveObject = ZSTD_rust_createCDictAdvanced_reserveObject;
state.moveWorkspace = ZSTD_rust_createCDictAdvanced_moveWorkspace;
state.initialize = ZSTD_rust_createCDictAdvanced_initialize;
state.init = ZSTD_rust_createCDictAdvanced_init; state.init = ZSTD_rust_createCDictAdvanced_init;
state.freeWorkspace = ZSTD_rust_createCDictAdvanced_freeWorkspace; state.freeWorkspace = ZSTD_rust_createCDictAdvanced_freeWorkspace;
state.free = ZSTD_rust_createCDictAdvanced_free; state.free = ZSTD_rust_createCDictAdvanced_free;
@@ -6847,6 +6903,10 @@ ZSTD_CDict* ZSTD_createCDict_advanced2(
(int)dictLoadMethod, (int)dictContentType); (int)dictLoadMethod, (int)dictContentType);
} }
/* The implementation above intentionally keeps the private workspace and
* object operations in C. Rust only sequences those operations and handles
* the public construction policy. */
static void* ZSTD_rust_createCDict_create( static void* ZSTD_rust_createCDict_create(
void* context, const void* dict, size_t dictSize, void* context, const void* dict, size_t dictSize,
int dictLoadMethod, int dictContentType, int dictLoadMethod, int dictContentType,
@@ -6936,35 +6996,56 @@ typedef struct {
ZSTD_dictContentType_e dictContentType; ZSTD_dictContentType_e dictContentType;
ZSTD_compressionParameters cParams; ZSTD_compressionParameters cParams;
ZSTD_ParamSwitch_e useRowMatchFinder; ZSTD_ParamSwitch_e useRowMatchFinder;
ZSTD_cwksp workspaceState;
ZSTD_CCtx_params params;
} ZSTD_rust_initStaticCDictContext; } ZSTD_rust_initStaticCDictContext;
static void* ZSTD_rust_initStaticCDict_init(void* opaque) static void ZSTD_rust_initStaticCDict_createWorkspace(void* opaque)
{ {
ZSTD_rust_initStaticCDictContext* const context = ZSTD_rust_initStaticCDictContext* const context =
(ZSTD_rust_initStaticCDictContext*)opaque; (ZSTD_rust_initStaticCDictContext*)opaque;
ZSTD_cwksp ws; ZSTD_cwksp_init(&context->workspaceState, context->workspace, context->workspaceSize,
ZSTD_CDict* cdict;
ZSTD_CCtx_params params;
ZSTD_cwksp_init(&ws, context->workspace, context->workspaceSize,
ZSTD_cwksp_static_alloc); ZSTD_cwksp_static_alloc);
cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict)); }
if (cdict == NULL) return NULL;
ZSTD_cwksp_move(&cdict->workspace, &ws);
ZSTD_CCtxParams_init(&params, 0); static void* ZSTD_rust_initStaticCDict_reserveObject(void* opaque)
params.cParams = context->cParams; {
params.useRowMatchFinder = context->useRowMatchFinder; ZSTD_rust_initStaticCDictContext* const context =
cdict->useRowMatchFinder = context->useRowMatchFinder; (ZSTD_rust_initStaticCDictContext*)opaque;
cdict->compressionLevel = ZSTD_NO_CLEVEL; return ZSTD_cwksp_reserve_object(&context->workspaceState, sizeof(ZSTD_CDict));
}
if (ZSTD_isError( ZSTD_initCDict_internal(cdict, static void ZSTD_rust_initStaticCDict_moveWorkspace(
context->dict, context->dictSize, void* opaque, void* cdict)
context->dictLoadMethod, {
context->dictContentType, ZSTD_rust_initStaticCDictContext* const context =
params) )) (ZSTD_rust_initStaticCDictContext*)opaque;
ZSTD_cwksp_move(&((ZSTD_CDict*)cdict)->workspace, &context->workspaceState);
}
static void ZSTD_rust_initStaticCDict_initialize(void* opaque, void* cdict)
{
ZSTD_rust_initStaticCDictContext* const context =
(ZSTD_rust_initStaticCDictContext*)opaque;
ZSTD_CDict* const dictionary = (ZSTD_CDict*)cdict;
ZSTD_CCtx_params* const params = &context->params;
ZSTD_CCtxParams_init(params, 0);
params->cParams = context->cParams;
params->useRowMatchFinder = context->useRowMatchFinder;
dictionary->useRowMatchFinder = context->useRowMatchFinder;
dictionary->compressionLevel = ZSTD_NO_CLEVEL;
}
static void* ZSTD_rust_initStaticCDict_init(void* opaque, void* cdict)
{
ZSTD_rust_initStaticCDictContext const* const context =
(const ZSTD_rust_initStaticCDictContext*)opaque;
if (ZSTD_isError( ZSTD_initCDict_internal(
(ZSTD_CDict*)cdict, context->dict, context->dictSize,
context->dictLoadMethod, context->dictContentType,
context->params) ))
return NULL; return NULL;
return cdict; return cdict;
} }
@@ -7005,6 +7086,10 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
state.workspace = workspace; state.workspace = workspace;
state.workspaceSize = workspaceSize; state.workspaceSize = workspaceSize;
state.neededSize = neededSize; state.neededSize = neededSize;
state.createWorkspace = ZSTD_rust_initStaticCDict_createWorkspace;
state.reserveObject = ZSTD_rust_initStaticCDict_reserveObject;
state.moveWorkspace = ZSTD_rust_initStaticCDict_moveWorkspace;
state.initialize = ZSTD_rust_initStaticCDict_initialize;
state.init = ZSTD_rust_initStaticCDict_init; state.init = ZSTD_rust_initStaticCDict_init;
return (const ZSTD_CDict*)ZSTD_rust_initStaticCDict(&state); return (const ZSTD_CDict*)ZSTD_rust_initStaticCDict(&state);
} }
+250 -78
View File
@@ -835,16 +835,10 @@ type CreateCDictAdvancedWorkspaceSizeFn = unsafe extern "C" fn(
c_int, c_int,
) -> usize; ) -> usize;
type CreateCDictAdvancedAllocateFn = unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void; type CreateCDictAdvancedAllocateFn = unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void;
type CreateCDictAdvancedCreateFn = unsafe extern "C" fn( type CreateCDictAdvancedCreateWorkspaceFn = unsafe extern "C" fn(*mut c_void, *mut c_void, usize);
*mut c_void, type CreateCDictAdvancedReserveObjectFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void;
*mut c_void, type CreateCDictAdvancedMoveWorkspaceFn = unsafe extern "C" fn(*mut c_void, *mut c_void);
usize, type CreateCDictAdvancedInitializeFn = unsafe extern "C" fn(*mut c_void, *mut c_void, c_int);
usize,
c_int,
*const ZSTD_compressionParameters,
c_int,
c_int,
) -> *mut c_void;
type CreateCDictAdvancedInitFn = unsafe extern "C" fn( type CreateCDictAdvancedInitFn = unsafe extern "C" fn(
*mut c_void, *mut c_void,
*mut c_void, *mut c_void,
@@ -877,7 +871,10 @@ pub struct ZSTD_rust_createCDictAdvancedState {
validate_custom_mem: CreateCDictAdvancedValidateCustomMemFn, validate_custom_mem: CreateCDictAdvancedValidateCustomMemFn,
workspace_size: CreateCDictAdvancedWorkspaceSizeFn, workspace_size: CreateCDictAdvancedWorkspaceSizeFn,
allocate: CreateCDictAdvancedAllocateFn, allocate: CreateCDictAdvancedAllocateFn,
create: CreateCDictAdvancedCreateFn, create_workspace: CreateCDictAdvancedCreateWorkspaceFn,
reserve_object: CreateCDictAdvancedReserveObjectFn,
move_workspace: CreateCDictAdvancedMoveWorkspaceFn,
initialize: CreateCDictAdvancedInitializeFn,
init: CreateCDictAdvancedInitFn, init: CreateCDictAdvancedInitFn,
free_workspace: CreateCDictAdvancedFreeWorkspaceFn, free_workspace: CreateCDictAdvancedFreeWorkspaceFn,
free: CreateCDictAdvancedFreeFn, free: CreateCDictAdvancedFreeFn,
@@ -917,28 +914,41 @@ const _: () = {
== size_of::<[usize; 7]>() + size_of::<[u32; 2]>() == size_of::<[usize; 7]>() + size_of::<[u32; 2]>()
); );
assert!( assert!(
offset_of!(ZSTD_rust_createCDictAdvancedState, create) offset_of!(ZSTD_rust_createCDictAdvancedState, create_workspace)
== size_of::<[usize; 8]>() + size_of::<[u32; 2]>() == size_of::<[usize; 8]>() + size_of::<[u32; 2]>()
); );
assert!( assert!(
offset_of!(ZSTD_rust_createCDictAdvancedState, init) offset_of!(ZSTD_rust_createCDictAdvancedState, reserve_object)
== size_of::<[usize; 9]>() + size_of::<[u32; 2]>() == size_of::<[usize; 9]>() + size_of::<[u32; 2]>()
); );
assert!( assert!(
offset_of!(ZSTD_rust_createCDictAdvancedState, free_workspace) offset_of!(ZSTD_rust_createCDictAdvancedState, move_workspace)
== size_of::<[usize; 10]>() + size_of::<[u32; 2]>() == size_of::<[usize; 10]>() + size_of::<[u32; 2]>()
); );
assert!( assert!(
offset_of!(ZSTD_rust_createCDictAdvancedState, free) offset_of!(ZSTD_rust_createCDictAdvancedState, initialize)
== size_of::<[usize; 11]>() + size_of::<[u32; 2]>() == size_of::<[usize; 11]>() + size_of::<[u32; 2]>()
); );
assert!( assert!(
size_of::<ZSTD_rust_createCDictAdvancedState>() offset_of!(ZSTD_rust_createCDictAdvancedState, init)
== size_of::<[usize; 12]>() + size_of::<[u32; 2]>() == size_of::<[usize; 12]>() + size_of::<[u32; 2]>()
); );
assert!(
offset_of!(ZSTD_rust_createCDictAdvancedState, free_workspace)
== size_of::<[usize; 13]>() + size_of::<[u32; 2]>()
);
assert!(
offset_of!(ZSTD_rust_createCDictAdvancedState, free)
== size_of::<[usize; 14]>() + size_of::<[u32; 2]>()
);
assert!(
size_of::<ZSTD_rust_createCDictAdvancedState>()
== size_of::<[usize; 15]>() + size_of::<[u32; 2]>()
);
}; };
/// Prepare advanced-CDict parameters and run the C-owned construction path. /// Prepare advanced-CDict parameters and run the C-owned construction leaves
/// in their original allocation, workspace, and initialization order.
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn ZSTD_rust_createCDictAdvanced( pub unsafe extern "C" fn ZSTD_rust_createCDictAdvanced(
state: *const ZSTD_rust_createCDictAdvancedState, state: *const ZSTD_rust_createCDictAdvancedState,
@@ -991,23 +1001,20 @@ pub unsafe extern "C" fn ZSTD_rust_createCDictAdvanced(
return ptr::null_mut(); return ptr::null_mut();
} }
let cdict = unsafe { unsafe {
(state.create)( (state.create_workspace)(state.callback_context, workspace, workspace_size);
state.callback_context, }
workspace, let cdict = unsafe { (state.reserve_object)(state.callback_context) };
workspace_size,
dict_size,
dict_load_method,
state.cparams,
*state.use_row_match_finder,
*state.enable_dedicated_dict_search,
)
};
if cdict.is_null() { if cdict.is_null() {
unsafe { (state.free_workspace)(state.callback_context, workspace) }; unsafe { (state.free_workspace)(state.callback_context, workspace) };
return ptr::null_mut(); return ptr::null_mut();
} }
unsafe {
(state.move_workspace)(state.callback_context, cdict);
(state.initialize)(state.callback_context, cdict, *state.use_row_match_finder);
}
let init_result = unsafe { let init_result = unsafe {
(state.init)( (state.init)(
state.callback_context, state.callback_context,
@@ -1068,19 +1075,27 @@ pub unsafe extern "C" fn ZSTD_rust_freeCDict(state: *const ZSTD_rust_freeCDictSt
0 0
} }
type InitStaticCDictFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void; type InitStaticCDictCreateWorkspaceFn = unsafe extern "C" fn(*mut c_void);
type InitStaticCDictReserveObjectFn = unsafe extern "C" fn(*mut c_void) -> *mut c_void;
type InitStaticCDictMoveWorkspaceFn = unsafe extern "C" fn(*mut c_void, *mut c_void);
type InitStaticCDictInitializeFn = unsafe extern "C" fn(*mut c_void, *mut c_void);
type InitStaticCDictFn = unsafe extern "C" fn(*mut c_void, *mut c_void) -> *mut c_void;
/// Explicit projection for the public `ZSTD_initStaticCDict` wrapper. /// Explicit projection for the public `ZSTD_initStaticCDict` wrapper.
/// ///
/// Rust owns workspace pointer/alignment validation, minimum-size validation, /// Rust owns workspace pointer/alignment validation, minimum-size validation,
/// and callback ordering. C retains the private static-workspace layout and /// and callback ordering. C retains the private static-workspace layout and
/// dictionary initialization behind one callback. /// dictionary initialization behind narrow callbacks.
#[repr(C)] #[repr(C)]
pub struct ZSTD_rust_initStaticCDictState { pub struct ZSTD_rust_initStaticCDictState {
callback_context: *mut c_void, callback_context: *mut c_void,
workspace: *mut c_void, workspace: *mut c_void,
workspace_size: usize, workspace_size: usize,
needed_size: usize, needed_size: usize,
create_workspace: InitStaticCDictCreateWorkspaceFn,
reserve_object: InitStaticCDictReserveObjectFn,
move_workspace: InitStaticCDictMoveWorkspaceFn,
initialize: InitStaticCDictInitializeFn,
init: InitStaticCDictFn, init: InitStaticCDictFn,
} }
@@ -1089,8 +1104,12 @@ const _: () = {
assert!(offset_of!(ZSTD_rust_initStaticCDictState, workspace) == size_of::<usize>()); assert!(offset_of!(ZSTD_rust_initStaticCDictState, workspace) == size_of::<usize>());
assert!(offset_of!(ZSTD_rust_initStaticCDictState, workspace_size) == 2 * size_of::<usize>()); assert!(offset_of!(ZSTD_rust_initStaticCDictState, workspace_size) == 2 * size_of::<usize>());
assert!(offset_of!(ZSTD_rust_initStaticCDictState, needed_size) == 3 * size_of::<usize>()); assert!(offset_of!(ZSTD_rust_initStaticCDictState, needed_size) == 3 * size_of::<usize>());
assert!(offset_of!(ZSTD_rust_initStaticCDictState, init) == 4 * size_of::<usize>()); assert!(offset_of!(ZSTD_rust_initStaticCDictState, create_workspace) == 4 * size_of::<usize>());
assert!(size_of::<ZSTD_rust_initStaticCDictState>() == size_of::<[usize; 5]>()); assert!(offset_of!(ZSTD_rust_initStaticCDictState, reserve_object) == 5 * size_of::<usize>());
assert!(offset_of!(ZSTD_rust_initStaticCDictState, move_workspace) == 6 * size_of::<usize>());
assert!(offset_of!(ZSTD_rust_initStaticCDictState, initialize) == 7 * size_of::<usize>());
assert!(offset_of!(ZSTD_rust_initStaticCDictState, init) == usize::BITS as usize);
assert!(size_of::<ZSTD_rust_initStaticCDictState>() == size_of::<[usize; 9]>());
}; };
/// Validate static CDict workspace ownership before entering the C leaf. /// Validate static CDict workspace ownership before entering the C leaf.
@@ -1109,7 +1128,18 @@ pub unsafe extern "C" fn ZSTD_rust_initStaticCDict(
{ {
return ptr::null_mut(); return ptr::null_mut();
} }
unsafe { (state.init)(state.callback_context) } unsafe {
(state.create_workspace)(state.callback_context);
}
let cdict = unsafe { (state.reserve_object)(state.callback_context) };
if cdict.is_null() {
return ptr::null_mut();
}
unsafe {
(state.move_workspace)(state.callback_context, cdict);
(state.initialize)(state.callback_context, cdict);
(state.init)(state.callback_context, cdict)
}
} }
type CompressBeginUsingDictBeginFn = type CompressBeginUsingDictBeginFn =
@@ -4587,13 +4617,12 @@ mod tests {
workspace_size_enable_dedicated_dict_search: c_int, workspace_size_enable_dedicated_dict_search: c_int,
allocated_workspace: *mut c_void, allocated_workspace: *mut c_void,
allocated_workspace_size: usize, allocated_workspace_size: usize,
create_workspace: *mut c_void, created_workspace: *mut c_void,
create_workspace_size: usize, created_workspace_size: usize,
create_dict_size: usize, reserved_cdict: *mut c_void,
create_dict_load_method: c_int, moved_cdict: *mut c_void,
cparams: *const ZSTD_compressionParameters, initialized_cdict: *mut c_void,
use_row_match_finder: c_int, use_row_match_finder: c_int,
enable_dedicated_dict_search: c_int,
cdict_result: *mut c_void, cdict_result: *mut c_void,
init_cdict: *mut c_void, init_cdict: *mut c_void,
init_dict: *const c_void, init_dict: *const c_void,
@@ -4642,28 +4671,46 @@ mod tests {
probe.allocated_workspace probe.allocated_workspace
} }
unsafe extern "C" fn create_cdict_advanced_test_create( unsafe extern "C" fn create_cdict_advanced_test_create_workspace(
context: *mut c_void, context: *mut c_void,
workspace: *mut c_void, workspace: *mut c_void,
workspace_size: usize, workspace_size: usize,
dict_size: usize, ) {
dict_load_method: c_int, let probe = unsafe { &mut *context.cast::<CreateCDictAdvancedProbe>() };
cparams: *const ZSTD_compressionParameters, probe.events.push("create_workspace");
use_row_match_finder: c_int, probe.created_workspace = workspace;
enable_dedicated_dict_search: c_int, probe.created_workspace_size = workspace_size;
}
unsafe extern "C" fn create_cdict_advanced_test_reserve_object(
context: *mut c_void,
) -> *mut c_void { ) -> *mut c_void {
let probe = unsafe { &mut *context.cast::<CreateCDictAdvancedProbe>() }; let probe = unsafe { &mut *context.cast::<CreateCDictAdvancedProbe>() };
probe.events.push("create"); probe.events.push("reserve_object");
probe.create_workspace = workspace; probe.reserved_cdict = probe.cdict_result;
probe.create_workspace_size = workspace_size;
probe.create_dict_size = dict_size;
probe.create_dict_load_method = dict_load_method;
probe.cparams = cparams;
probe.use_row_match_finder = use_row_match_finder;
probe.enable_dedicated_dict_search = enable_dedicated_dict_search;
probe.cdict_result probe.cdict_result
} }
unsafe extern "C" fn create_cdict_advanced_test_move_workspace(
context: *mut c_void,
cdict: *mut c_void,
) {
let probe = unsafe { &mut *context.cast::<CreateCDictAdvancedProbe>() };
probe.events.push("move_workspace");
probe.moved_cdict = cdict;
}
unsafe extern "C" fn create_cdict_advanced_test_initialize(
context: *mut c_void,
cdict: *mut c_void,
use_row_match_finder: c_int,
) {
let probe = unsafe { &mut *context.cast::<CreateCDictAdvancedProbe>() };
probe.events.push("initialize");
probe.initialized_cdict = cdict;
probe.use_row_match_finder = use_row_match_finder;
}
unsafe extern "C" fn create_cdict_advanced_test_init( unsafe extern "C" fn create_cdict_advanced_test_init(
context: *mut c_void, context: *mut c_void,
cdict: *mut c_void, cdict: *mut c_void,
@@ -4731,7 +4778,10 @@ mod tests {
validate_custom_mem: create_cdict_advanced_test_validate_custom_mem, validate_custom_mem: create_cdict_advanced_test_validate_custom_mem,
workspace_size: create_cdict_advanced_test_workspace_size, workspace_size: create_cdict_advanced_test_workspace_size,
allocate: create_cdict_advanced_test_allocate, allocate: create_cdict_advanced_test_allocate,
create: create_cdict_advanced_test_create, create_workspace: create_cdict_advanced_test_create_workspace,
reserve_object: create_cdict_advanced_test_reserve_object,
move_workspace: create_cdict_advanced_test_move_workspace,
initialize: create_cdict_advanced_test_initialize,
init: create_cdict_advanced_test_init, init: create_cdict_advanced_test_init,
free_workspace: create_cdict_advanced_test_free_workspace, free_workspace: create_cdict_advanced_test_free_workspace,
free: create_cdict_advanced_test_free, free: create_cdict_advanced_test_free,
@@ -4782,7 +4832,16 @@ mod tests {
assert_eq!(result, probe.cdict_result); assert_eq!(result, probe.cdict_result);
assert_eq!( assert_eq!(
probe.events, probe.events,
["validate", "workspace_size", "allocate", "create", "init"] [
"validate",
"workspace_size",
"allocate",
"create_workspace",
"reserve_object",
"move_workspace",
"initialize",
"init"
]
); );
assert_eq!(probe.workspace_size_dict_size, dict.len()); assert_eq!(probe.workspace_size_dict_size, dict.len());
assert_eq!(probe.workspace_size_dict_load_method, ZSTD_DLM_BY_REF); assert_eq!(probe.workspace_size_dict_load_method, ZSTD_DLM_BY_REF);
@@ -4796,16 +4855,12 @@ mod tests {
enable_dedicated_dict_search enable_dedicated_dict_search
); );
assert_eq!(probe.allocated_workspace_size, 123); assert_eq!(probe.allocated_workspace_size, 123);
assert_eq!(probe.create_workspace, probe.allocated_workspace); assert_eq!(probe.created_workspace, probe.allocated_workspace);
assert_eq!(probe.create_workspace_size, 123); assert_eq!(probe.created_workspace_size, 123);
assert_eq!(probe.create_dict_size, dict.len()); assert_eq!(probe.reserved_cdict, probe.cdict_result);
assert_eq!(probe.create_dict_load_method, ZSTD_DLM_BY_REF); assert_eq!(probe.moved_cdict, probe.cdict_result);
assert_eq!(probe.cparams, &cparams); assert_eq!(probe.initialized_cdict, probe.cdict_result);
assert_eq!(probe.use_row_match_finder, use_row_match_finder); assert_eq!(probe.use_row_match_finder, use_row_match_finder);
assert_eq!(
probe.enable_dedicated_dict_search,
enable_dedicated_dict_search
);
assert_eq!(probe.init_cdict, probe.cdict_result); assert_eq!(probe.init_cdict, probe.cdict_result);
assert_eq!(probe.init_dict, dict.as_ptr().cast()); assert_eq!(probe.init_dict, dict.as_ptr().cast());
assert_eq!(probe.init_dict_size, dict.len()); assert_eq!(probe.init_dict_size, dict.len());
@@ -4838,7 +4893,7 @@ mod tests {
assert!(result.is_null()); assert!(result.is_null());
assert_eq!(probe.events, ["validate"]); assert_eq!(probe.events, ["validate"]);
assert!(probe.create_workspace.is_null()); assert!(probe.created_workspace.is_null());
assert!(probe.free_workspace.is_null()); assert!(probe.free_workspace.is_null());
assert!(probe.free_cdict.is_null()); assert!(probe.free_cdict.is_null());
} }
@@ -4870,13 +4925,13 @@ mod tests {
assert!(result.is_null()); assert!(result.is_null());
assert_eq!(probe.events, ["validate", "workspace_size", "allocate"]); assert_eq!(probe.events, ["validate", "workspace_size", "allocate"]);
assert_eq!(probe.allocated_workspace_size, 321); assert_eq!(probe.allocated_workspace_size, 321);
assert!(probe.create_workspace.is_null()); assert!(probe.created_workspace.is_null());
assert!(probe.free_workspace.is_null()); assert!(probe.free_workspace.is_null());
assert!(probe.free_cdict.is_null()); assert!(probe.free_cdict.is_null());
} }
#[test] #[test]
fn create_cdict_advanced_frees_workspace_after_creation_failure() { fn create_cdict_advanced_frees_workspace_after_reservation_failure() {
let workspace = ptr::dangling_mut::<c_void>(); let workspace = ptr::dangling_mut::<c_void>();
let mut probe = CreateCDictAdvancedProbe { let mut probe = CreateCDictAdvancedProbe {
custom_mem_valid: 1, custom_mem_valid: 1,
@@ -4908,13 +4963,13 @@ mod tests {
"validate", "validate",
"workspace_size", "workspace_size",
"allocate", "allocate",
"create", "create_workspace",
"reserve_object",
"free_workspace" "free_workspace"
] ]
); );
assert_eq!(probe.create_workspace, workspace); assert_eq!(probe.created_workspace, workspace);
assert_eq!(probe.create_workspace_size, 321); assert_eq!(probe.created_workspace_size, 321);
assert_eq!(probe.create_dict_size, 0);
assert_eq!(probe.free_workspace, workspace); assert_eq!(probe.free_workspace, workspace);
assert!(probe.free_cdict.is_null()); assert!(probe.free_cdict.is_null());
} }
@@ -4955,14 +5010,19 @@ mod tests {
"validate", "validate",
"workspace_size", "workspace_size",
"allocate", "allocate",
"create", "create_workspace",
"reserve_object",
"move_workspace",
"initialize",
"init", "init",
"free" "free"
] ]
); );
assert_eq!(probe.create_workspace, workspace); assert_eq!(probe.created_workspace, workspace);
assert_eq!(probe.create_workspace_size, 321); assert_eq!(probe.created_workspace_size, 321);
assert_eq!(probe.create_dict_size, 0); assert_eq!(probe.reserved_cdict, cdict);
assert_eq!(probe.moved_cdict, cdict);
assert_eq!(probe.initialized_cdict, cdict);
assert!(probe.free_workspace.is_null()); assert!(probe.free_workspace.is_null());
assert_eq!(probe.free_cdict, cdict); assert_eq!(probe.free_cdict, cdict);
} }
@@ -5033,12 +5093,53 @@ mod tests {
#[derive(Default)] #[derive(Default)]
struct InitStaticCDictProbe { struct InitStaticCDictProbe {
events: Vec<&'static str>, events: Vec<&'static str>,
reserved_cdict: *mut c_void,
moved_cdict: *mut c_void,
initialized_cdict: *mut c_void,
init_cdict: *mut c_void,
initialized: bool,
result: *mut c_void, result: *mut c_void,
} }
unsafe extern "C" fn init_static_cdict_test_init(context: *mut c_void) -> *mut c_void { unsafe extern "C" fn init_static_cdict_test_create_workspace(context: *mut c_void) {
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
probe.events.push("create_workspace");
}
unsafe extern "C" fn init_static_cdict_test_reserve_object(
context: *mut c_void,
) -> *mut c_void {
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
probe.events.push("reserve_object");
probe.reserved_cdict
}
unsafe extern "C" fn init_static_cdict_test_move_workspace(
context: *mut c_void,
cdict: *mut c_void,
) {
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
probe.events.push("move_workspace");
probe.moved_cdict = cdict;
}
unsafe extern "C" fn init_static_cdict_test_initialize(
context: *mut c_void,
cdict: *mut c_void,
) {
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
probe.events.push("initialize");
probe.initialized_cdict = cdict;
probe.initialized = true;
}
unsafe extern "C" fn init_static_cdict_test_init(
context: *mut c_void,
cdict: *mut c_void,
) -> *mut c_void {
let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() }; let probe = unsafe { &mut *context.cast::<InitStaticCDictProbe>() };
probe.events.push("init"); probe.events.push("init");
probe.init_cdict = cdict;
probe.result probe.result
} }
@@ -5053,6 +5154,10 @@ mod tests {
workspace, workspace,
workspace_size, workspace_size,
needed_size, needed_size,
create_workspace: init_static_cdict_test_create_workspace,
reserve_object: init_static_cdict_test_reserve_object,
move_workspace: init_static_cdict_test_move_workspace,
initialize: init_static_cdict_test_initialize,
init: init_static_cdict_test_init, init: init_static_cdict_test_init,
} }
} }
@@ -5095,7 +5200,9 @@ mod tests {
#[test] #[test]
fn init_static_cdict_calls_the_initializer_after_workspace_validation() { fn init_static_cdict_calls_the_initializer_after_workspace_validation() {
let cdict = ptr::dangling_mut::<c_void>();
let mut probe = InitStaticCDictProbe { let mut probe = InitStaticCDictProbe {
reserved_cdict: cdict,
result: ptr::dangling_mut(), result: ptr::dangling_mut(),
..Default::default() ..Default::default()
}; };
@@ -5110,7 +5217,72 @@ mod tests {
let result = unsafe { ZSTD_rust_initStaticCDict(&state) }; let result = unsafe { ZSTD_rust_initStaticCDict(&state) };
assert_eq!(result, probe.result); assert_eq!(result, probe.result);
assert_eq!(probe.events, ["init"]); assert_eq!(
probe.events,
[
"create_workspace",
"reserve_object",
"move_workspace",
"initialize",
"init"
]
);
assert_eq!(probe.moved_cdict, cdict);
assert_eq!(probe.initialized_cdict, cdict);
assert_eq!(probe.init_cdict, cdict);
assert!(probe.initialized);
}
#[test]
fn init_static_cdict_stops_after_object_reservation_failure() {
let mut probe = InitStaticCDictProbe::default();
let mut workspace = [0usize; 1];
let state = init_static_cdict_test_state(
&mut probe,
workspace.as_mut_ptr().cast(),
size_of_val(&workspace),
0,
);
let result = unsafe { ZSTD_rust_initStaticCDict(&state) };
assert!(result.is_null());
assert_eq!(probe.events, ["create_workspace", "reserve_object"]);
assert!(probe.moved_cdict.is_null());
assert!(!probe.initialized);
}
#[test]
fn init_static_cdict_propagates_initializer_failure_after_setup() {
let cdict = ptr::dangling_mut::<c_void>();
let mut probe = InitStaticCDictProbe {
reserved_cdict: cdict,
result: ptr::null_mut(),
..Default::default()
};
let mut workspace = [0usize; 1];
let state = init_static_cdict_test_state(
&mut probe,
workspace.as_mut_ptr().cast(),
size_of_val(&workspace),
size_of_val(&workspace),
);
let result = unsafe { ZSTD_rust_initStaticCDict(&state) };
assert!(result.is_null());
assert_eq!(probe.init_cdict, cdict);
assert!(probe.initialized);
assert_eq!(
probe.events,
[
"create_workspace",
"reserve_object",
"move_workspace",
"initialize",
"init"
]
);
} }
#[test] #[test]