refactor(compress): move dictionary teardown ordering to Rust

The compression context still owns private dictionary storage and CDict
objects, but the teardown order is observable because each step can invoke an
allocator or clear state used by later steps. Keep those storage operations as
C callbacks while moving the sequencing policy into the Rust compression
module. The C bridge now contains only callback adapters and compile-time ABI
layout checks, and the Rust unit test pins the original five-step order.

Test Plan:
- `cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings` -- passed
- `cargo test --manifest-path rust/Cargo.toml --all-targets` -- 771 passed
- `cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings` -- passed
- `make -j1` under `ulimit -v 41943040` -- passed
- `make -j1 -C tests test` under `ulimit -v 41943040` -- passed
This commit is contained in:
2026-07-20 06:02:52 +02:00
parent 71a18ce315
commit 998c88c97b
2 changed files with 180 additions and 5 deletions
+62 -5
View File
@@ -444,6 +444,30 @@ typedef char ZSTD_rust_init_static_cdict_state_layout[
== 8 * sizeof(void*)
&& sizeof(ZSTD_rust_initStaticCDictState) == 9 * sizeof(void*))
? 1 : -1];
typedef void (*ZSTD_rust_clearAllDictsCallback_f)(void* context);
typedef struct {
void* callbackContext;
ZSTD_rust_clearAllDictsCallback_f freeLocalDictBuffer;
ZSTD_rust_clearAllDictsCallback_f freeLocalCDict;
ZSTD_rust_clearAllDictsCallback_f clearLocalDict;
ZSTD_rust_clearAllDictsCallback_f clearPrefixDict;
ZSTD_rust_clearAllDictsCallback_f clearCDict;
} ZSTD_rust_clearAllDictsState;
void ZSTD_rust_clearAllDicts(const ZSTD_rust_clearAllDictsState* state);
typedef char ZSTD_rust_clear_all_dicts_state_layout[
(offsetof(ZSTD_rust_clearAllDictsState, callbackContext) == 0
&& offsetof(ZSTD_rust_clearAllDictsState, freeLocalDictBuffer)
== sizeof(void*)
&& offsetof(ZSTD_rust_clearAllDictsState, freeLocalCDict)
== 2 * sizeof(void*)
&& offsetof(ZSTD_rust_clearAllDictsState, clearLocalDict)
== 3 * sizeof(void*)
&& offsetof(ZSTD_rust_clearAllDictsState, clearPrefixDict)
== 4 * sizeof(void*)
&& offsetof(ZSTD_rust_clearAllDictsState, clearCDict)
== 5 * sizeof(void*)
&& sizeof(ZSTD_rust_clearAllDictsState) == 6 * sizeof(void*))
? 1 : -1];
typedef void (*ZSTD_rust_resetCCtxClearAllDicts_f)(void* context);
typedef size_t (*ZSTD_rust_resetCCtxResetParams_f)(void* context);
typedef struct {
@@ -3214,13 +3238,46 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize)
/**
* Clears and frees all of the dictionaries in the CCtx.
*/
static void ZSTD_clearAllDicts_freeLocalDictBuffer(void* context)
{
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
ZSTD_customFree(cctx->localDict.dictBuffer, cctx->customMem);
}
static void ZSTD_clearAllDicts_freeLocalCDict(void* context)
{
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
ZSTD_freeCDict(cctx->localDict.cdict);
}
static void ZSTD_clearAllDicts_clearLocalDict(void* context)
{
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
ZSTD_memset(&cctx->localDict, 0, sizeof(cctx->localDict));
}
static void ZSTD_clearAllDicts_clearPrefixDict(void* context)
{
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));
}
static void ZSTD_clearAllDicts_clearCDict(void* context)
{
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
cctx->cdict = NULL;
}
static void ZSTD_clearAllDicts(ZSTD_CCtx* cctx)
{
ZSTD_customFree(cctx->localDict.dictBuffer, cctx->customMem);
ZSTD_freeCDict(cctx->localDict.cdict);
ZSTD_memset(&cctx->localDict, 0, sizeof(cctx->localDict));
ZSTD_memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));
cctx->cdict = NULL;
ZSTD_rust_clearAllDictsState state;
state.callbackContext = cctx;
state.freeLocalDictBuffer = ZSTD_clearAllDicts_freeLocalDictBuffer;
state.freeLocalCDict = ZSTD_clearAllDicts_freeLocalCDict;
state.clearLocalDict = ZSTD_clearAllDicts_clearLocalDict;
state.clearPrefixDict = ZSTD_clearAllDicts_clearPrefixDict;
state.clearCDict = ZSTD_clearAllDicts_clearCDict;
ZSTD_rust_clearAllDicts(&state);
}
static void ZSTD_clearAllDicts_callback(void* context)