feat(compress): project CCtx reset-tail scalars

Move the scalar portion of the private CCtx reset tail behind the existing
Rust reset adapter. The C side now publishes explicit pointers to the fields
that Rust must initialize, while retaining workspace ownership, match-state
reset, storage reset, and the XXH64 reset callback that cannot cross the
boundary safely. This removes the last opaque C initializer from this reset
phase without exposing the private ZSTD_CCtx layout to Rust.

The ABI record has compile-time offset and size assertions on both sides, and
the Rust unit fixture now checks the resolved compression parameters,
prefetch policy, pledged-size sentinel handling, counters, content-size flag,
block-size limit, stage, and dictionary metadata. The callback-order tests
continue to verify that compressed-block state reset precedes match-state and
storage cleanup, and that failures stop the tail at the correct callback.

Test Plan:
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo check --manifest-path rust/cli/Cargo.toml --all-targets
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo check --manifest-path rust/Cargo.toml --tests
- 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
- ulimit -v 41943040; make -j1
- ulimit -v 41943040; make -j1 -C tests test
- git diff --check
This commit is contained in:
2026-07-21 15:48:15 +02:00
parent 13a271c420
commit cf8953eed2
2 changed files with 239 additions and 36 deletions
+69 -25
View File
@@ -2280,21 +2280,67 @@ typedef char ZSTD_rust_reset_cctx_workspace_state_layout[
? 1 : -1];
typedef struct {
void* callbackContext;
ZSTD_rust_resetCCtxStorageCallback_f initialize;
ZSTD_rust_resetCCtxStorageCallback_f resetHash;
void* compressedBlockState;
ZSTD_rust_resetCCtxTailCallback_f resetMatchState;
ZSTD_rust_resetCCtxTailCallback_f resetStorage;
ZSTD_compressionParameters* matchStateCParams;
int* matchStatePrefetchCDictTables;
unsigned long long* pledgedSrcSizePlusOne;
unsigned long long* consumedSrcSize;
unsigned long long* producedCSize;
int* contentSizeFlag;
size_t* blockSizeMax;
int* stage;
U32* dictID;
size_t* dictContentSize;
ZSTD_compressionParameters cParams;
int prefetchCDictTables;
U64 pledgedSrcSize;
size_t blockSize;
} ZSTD_rust_resetCCtxTailState;
typedef char ZSTD_rust_reset_cctx_tail_state_layout[
(offsetof(ZSTD_rust_resetCCtxTailState, callbackContext) == 0
&& offsetof(ZSTD_rust_resetCCtxTailState, initialize) == sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, resetHash) == sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, compressedBlockState)
== 2 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, resetMatchState)
== 3 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, resetStorage)
== 4 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, matchStateCParams)
== 5 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, matchStatePrefetchCDictTables)
== 6 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, pledgedSrcSizePlusOne)
== 7 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, consumedSrcSize)
== 8 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, producedCSize)
== 9 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, contentSizeFlag)
== 10 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, blockSizeMax)
== 11 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, stage)
== 12 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, dictID)
== 13 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, dictContentSize)
== 14 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, cParams)
== 15 * sizeof(void*)
&& offsetof(ZSTD_rust_resetCCtxTailState, prefetchCDictTables)
== offsetof(ZSTD_rust_resetCCtxTailState, cParams)
+ sizeof(ZSTD_compressionParameters)
&& offsetof(ZSTD_rust_resetCCtxTailState, pledgedSrcSize)
> offsetof(ZSTD_rust_resetCCtxTailState, prefetchCDictTables)
&& offsetof(ZSTD_rust_resetCCtxTailState, blockSize)
== offsetof(ZSTD_rust_resetCCtxTailState, pledgedSrcSize)
+ sizeof(U64)
&& sizeof(ZSTD_rust_resetCCtxTailState)
== offsetof(ZSTD_rust_resetCCtxTailState, resetStorage)
+ sizeof(void*))
== offsetof(ZSTD_rust_resetCCtxTailState, blockSize)
+ sizeof(size_t))
? 1 : -1];
typedef struct {
void* callbackContext;
@@ -5238,8 +5284,6 @@ static void ZSTD_rust_resetCCtxWorkspace_clear(void* opaque)
typedef struct {
ZSTD_CCtx* cctx;
const ZSTD_CCtx_params* params;
size_t blockSize;
U64 pledgedSrcSize;
ZSTD_cwksp* ws;
ZSTD_compResetPolicy_e compResetPolicy;
ZSTD_indexResetPolicy_e indexResetPolicy;
@@ -5270,34 +5314,21 @@ static void ZSTD_rust_resetCCtxTail_prepare(
{
ZSTD_rust_resetCCtxTailContext* const context =
(ZSTD_rust_resetCCtxTailContext*)opaque;
context->blockSize = blockSize;
context->indexResetPolicy = (ZSTD_indexResetPolicy_e)indexResetPolicy;
context->tailState->blockSize = blockSize;
context->tailState->compressedBlockState =
context->cctx->blockState.prevCBlock;
}
static void ZSTD_rust_resetCCtxTail_initialize(void* opaque)
static void ZSTD_rust_resetCCtxTail_resetHash(void* opaque)
{
ZSTD_rust_resetCCtxTailContext* const context =
(ZSTD_rust_resetCCtxTailContext*)opaque;
ZSTD_CCtx* const cctx = context->cctx;
cctx->blockState.matchState.cParams = context->params->cParams;
cctx->blockState.matchState.prefetchCDictTables =
context->params->prefetchCDictTables == ZSTD_ps_enable;
cctx->pledgedSrcSizePlusOne = context->pledgedSrcSize + 1;
cctx->consumedSrcSize = 0;
cctx->producedCSize = 0;
if (context->pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
cctx->appliedParams.fParams.contentSizeFlag = 0;
DEBUGLOG(4, "pledged content size : %u ; flag : %u",
(unsigned)context->pledgedSrcSize,
(unsigned)cctx->pledgedSrcSizePlusOne - 1,
cctx->appliedParams.fParams.contentSizeFlag);
cctx->blockSizeMax = context->blockSize;
XXH64_reset(&cctx->xxhState, 0);
cctx->stage = ZSTDcs_init;
cctx->dictID = 0;
cctx->dictContentSize = 0;
}
static size_t ZSTD_rust_resetCCtxTail_resetMatchState(void* opaque)
@@ -5450,18 +5481,31 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
tailContext.cctx = zc;
tailContext.params = params;
tailContext.blockSize = 0;
tailContext.pledgedSrcSize = pledgedSrcSize;
tailContext.ws = ws;
tailContext.compResetPolicy = crp;
tailContext.indexResetPolicy = needsIndexReset;
tailContext.storageState = &storageState;
tailContext.tailState = &tailState;
tailState.callbackContext = &tailContext;
tailState.initialize = ZSTD_rust_resetCCtxTail_initialize;
tailState.resetHash = ZSTD_rust_resetCCtxTail_resetHash;
tailState.compressedBlockState = NULL;
tailState.resetMatchState = ZSTD_rust_resetCCtxTail_resetMatchState;
tailState.resetStorage = ZSTD_rust_resetCCtxTail_resetStorage;
tailState.matchStateCParams = &zc->blockState.matchState.cParams;
tailState.matchStatePrefetchCDictTables =
&zc->blockState.matchState.prefetchCDictTables;
tailState.pledgedSrcSizePlusOne = &zc->pledgedSrcSizePlusOne;
tailState.consumedSrcSize = &zc->consumedSrcSize;
tailState.producedCSize = &zc->producedCSize;
tailState.contentSizeFlag = &zc->appliedParams.fParams.contentSizeFlag;
tailState.blockSizeMax = &zc->blockSizeMax;
tailState.stage = (int*)&zc->stage;
tailState.dictID = &zc->dictID;
tailState.dictContentSize = &zc->dictContentSize;
tailState.cParams = params->cParams;
tailState.prefetchCDictTables = (int)params->prefetchCDictTables;
tailState.pledgedSrcSize = pledgedSrcSize;
tailState.blockSize = 0;
internalState.callbackContext = &tailContext;
internalState.resetState = &resetState;