feat(compress): move continue frame chunks into Rust

Project the prepared frame-chunk state through the compressContinue ABI so
Rust invokes the existing frame-chunk loop directly. Remove the redundant C
frame-chunk forwarding wrapper while retaining C callbacks for the private
block-compression leaves and context-sensitive preparation operations.

Test Plan:
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo fmt --all -- --check
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --lib zstd_compress::tests::compress_continue -- --nocapture
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --all-targets -- -D warnings
- ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test
- ulimit -v 41943040; make -j1
- ulimit -v 41943040; make -j1 -C tests test-zstream ZSTREAM_TESTTIME=-T2s
- ulimit -v 41943040; make -j1 -C tests test-fuzzer FUZZERTEST=-T3s FUZZER_FLAGS=--no-big-tests
This commit is contained in:
2026-07-20 00:48:02 +02:00
parent 3ec8f03850
commit 58e6d2eef7
2 changed files with 115 additions and 69 deletions
+35 -60
View File
@@ -874,7 +874,8 @@ typedef char ZSTD_rust_frame_chunk_state_layout[
? 1 : -1];
/* The high-level continue/block entry points are Rust-owned. This projection
* carries frame-header scalars, mutable state, and C callbacks. Window
* carries frame-header scalars, the already-projected frame-chunk state, and
* the remaining C callback for context-sensitive block compression. Window
* advancement uses direct pointers to the C-owned fields; the private CCtx
* and match-state layout never crosses the ABI. */
typedef struct {
@@ -899,7 +900,7 @@ typedef struct {
ZSTD_rust_compressContinueWindowState* windowState;
ZSTD_rust_compressContinueWindowState* ldmWindowState;
const ZSTD_rust_overflowCorrectState* overflowState;
ZSTD_rust_compressContinueBlock_f compressFrameChunk;
const ZSTD_rust_frameChunkState* frameChunkState;
ZSTD_rust_compressContinueBlock_f compressBlock;
ZSTD_compressionStage_e* stage;
unsigned long long* consumedSrcSize;
@@ -925,7 +926,7 @@ typedef char ZSTD_rust_compress_continue_state_layout[
&& offsetof(ZSTD_rust_compressContinueState, windowState) == sizeof(void*)
&& offsetof(ZSTD_rust_compressContinueState, ldmWindowState) == 2 * sizeof(void*)
&& offsetof(ZSTD_rust_compressContinueState, overflowState) == 3 * sizeof(void*)
&& offsetof(ZSTD_rust_compressContinueState, compressFrameChunk) == 4 * sizeof(void*)
&& offsetof(ZSTD_rust_compressContinueState, frameChunkState) == 4 * sizeof(void*)
&& offsetof(ZSTD_rust_compressContinueState, compressBlock) == 5 * sizeof(void*)
&& offsetof(ZSTD_rust_compressContinueState, stage) == 6 * sizeof(void*)
&& offsetof(ZSTD_rust_compressContinueState, consumedSrcSize) == 7 * sizeof(void*)
@@ -5568,62 +5569,6 @@ static size_t ZSTD_rust_frameChunk_compressInternal(
1 /* frame */);
}
/*! ZSTD_compress_frameChunk() :
* Compress a chunk of data into one or multiple blocks.
* All blocks will be terminated, all input will be consumed.
* Function will issue an error if there is not enough `dstCapacity` to hold the compressed content.
* Frame is supposed already started (header already produced)
* @return : compressed size, or an error code
*/
static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
U32 lastFrameChunk)
{
ZSTD_rust_frameChunkState state;
ZSTD_rust_frameChunkPrepareState prepareState;
ZSTD_rust_frameChunkClampState clampState;
ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
prepareState.callbackContext = cctx;
prepareState.maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
prepareState.correctOverflow = ZSTD_rust_frameChunk_correctOverflow;
prepareState.checkDictValidity = ZSTD_rust_frameChunk_checkDictValidity;
prepareState.enforceMaxDist = ZSTD_rust_frameChunk_enforceMaxDist;
clampState.nextToUpdate = &ms->nextToUpdate;
clampState.lowLimit = &ms->window.lowLimit;
prepareState.clampState = &clampState;
state.callbackContext = cctx;
state.tmpWorkspace = cctx->tmpWorkspace;
state.checksumState = &cctx->xxhState;
state.isFirstBlock = &cctx->isFirstBlock;
state.stage = &cctx->stage;
state.tmpWkspSize = cctx->tmpWkspSize;
state.blockSizeMax = cctx->blockSizeMax;
state.savings = (S64)cctx->consumedSrcSize - (S64)cctx->producedCSize;
state.preBlockSplitterLevel = cctx->appliedParams.preBlockSplitter_level;
state.strategy = (int)cctx->appliedParams.cParams.strategy;
state.useTargetCBlockSize = ZSTD_useTargetCBlockSize(&cctx->appliedParams);
state.blockSplitterEnabled = ZSTD_blockSplitterEnabled(&cctx->appliedParams);
state.checksumFlag = cctx->appliedParams.fParams.checksumFlag;
state.endingStage = (int)ZSTDcs_ending;
state.prepareState = &prepareState;
state.compressTarget = ZSTD_rust_frameChunk_compressTarget;
state.compressSplit = ZSTD_rust_frameChunk_compressSplit;
state.compressInternal = ZSTD_rust_frameChunk_compressInternal;
return ZSTD_rust_compressFrameChunk(
&state, dst, dstCapacity, src, srcSize, lastFrameChunk);
}
static size_t ZSTD_rust_compressContinue_frameChunk(
void* context, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, U32 lastFrameChunk)
{
return ZSTD_compress_frameChunk(
(ZSTD_CCtx*)context, dst, dstCapacity, src, srcSize,
lastFrameChunk);
}
static size_t ZSTD_rust_compressContinue_block(
void* context, void* dst, size_t dstCapacity,
const void* src, size_t srcSize, U32 lastFrameChunk)
@@ -5643,6 +5588,9 @@ static size_t ZSTD_compressContinue_dispatch(
ZSTD_rust_compressContinueState state;
ZSTD_rust_compressContinueWindowState windowState;
ZSTD_rust_compressContinueWindowState ldmWindowState;
ZSTD_rust_frameChunkState frameChunkState;
ZSTD_rust_frameChunkPrepareState frameChunkPrepareState;
ZSTD_rust_frameChunkClampState frameChunkClampState;
ZSTD_rust_overflowCorrectContext overflowContext;
ZSTD_rust_overflowCorrectState overflowState;
ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
@@ -5664,6 +5612,33 @@ static size_t ZSTD_compressContinue_dispatch(
ldmWindowState.forceNonContiguous = NULL;
ldmWindowState.nextToUpdate = NULL;
frameChunkPrepareState.callbackContext = cctx;
frameChunkPrepareState.maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
frameChunkPrepareState.correctOverflow = ZSTD_rust_frameChunk_correctOverflow;
frameChunkPrepareState.checkDictValidity = ZSTD_rust_frameChunk_checkDictValidity;
frameChunkPrepareState.enforceMaxDist = ZSTD_rust_frameChunk_enforceMaxDist;
frameChunkClampState.nextToUpdate = &ms->nextToUpdate;
frameChunkClampState.lowLimit = &ms->window.lowLimit;
frameChunkPrepareState.clampState = &frameChunkClampState;
frameChunkState.callbackContext = cctx;
frameChunkState.tmpWorkspace = cctx->tmpWorkspace;
frameChunkState.checksumState = &cctx->xxhState;
frameChunkState.isFirstBlock = &cctx->isFirstBlock;
frameChunkState.stage = &cctx->stage;
frameChunkState.tmpWkspSize = cctx->tmpWkspSize;
frameChunkState.blockSizeMax = cctx->blockSizeMax;
frameChunkState.savings = (S64)cctx->consumedSrcSize - (S64)cctx->producedCSize;
frameChunkState.preBlockSplitterLevel = cctx->appliedParams.preBlockSplitter_level;
frameChunkState.strategy = (int)cctx->appliedParams.cParams.strategy;
frameChunkState.useTargetCBlockSize = ZSTD_useTargetCBlockSize(&cctx->appliedParams);
frameChunkState.blockSplitterEnabled = ZSTD_blockSplitterEnabled(&cctx->appliedParams);
frameChunkState.checksumFlag = cctx->appliedParams.fParams.checksumFlag;
frameChunkState.endingStage = (int)ZSTDcs_ending;
frameChunkState.prepareState = &frameChunkPrepareState;
frameChunkState.compressTarget = ZSTD_rust_frameChunk_compressTarget;
frameChunkState.compressSplit = ZSTD_rust_frameChunk_compressSplit;
frameChunkState.compressInternal = ZSTD_rust_frameChunk_compressInternal;
overflowContext.matchState = ms;
overflowContext.workspace = &cctx->workspace;
overflowContext.params = &cctx->appliedParams;
@@ -5681,7 +5656,7 @@ static size_t ZSTD_compressContinue_dispatch(
state.windowState = &windowState;
state.ldmWindowState = &ldmWindowState;
state.overflowState = &overflowState;
state.compressFrameChunk = ZSTD_rust_compressContinue_frameChunk;
state.frameChunkState = &frameChunkState;
state.compressBlock = ZSTD_rust_compressContinue_block;
state.stage = &cctx->stage;
state.consumedSrcSize = &cctx->consumedSrcSize;