feat(compress): move frame-block preparation order into Rust
Move the frame-chunk match-state preparation policy into Rust while keeping window and workspace mutations behind narrow C callbacks. Rust now guarantees the original overflow-correction, dictionary-validity, maximum-distance, and nextToUpdate-clamp order; the C side retains the private ZSTD_MatchState_t layout and exact primitive operations. Test Plan: - cargo fmt --manifest-path rust/Cargo.toml -- --check - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml frame_chunk --lib (3 passed) - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml --lib (691 passed) - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040 && MAKEFLAGS=-j1 make -B -C programs -j1 zstd - ulimit -v 41943040 && MAKEFLAGS=-j1 make -C tests -j1 test-zstream ZSTREAM_TESTTIME=-T1s (84 tests and both short fuzz rounds passed)
This commit is contained in:
@@ -673,12 +673,38 @@ typedef char ZSTD_rust_reset_match_state_layout[
|
||||
+ sizeof(void*))
|
||||
? 1 : -1];
|
||||
|
||||
/* The frame-chunk loop is Rust-owned. Its callbacks keep the private
|
||||
* ZSTD_CCtx and match-state layout in C: Rust only drives the block loop and
|
||||
* passes this context back to these C-owned state-preparation/dispatch seams. */
|
||||
typedef void (*ZSTD_rust_frameChunkPrepare_f)(void* context,
|
||||
const void* src,
|
||||
size_t blockSize);
|
||||
/* The frame-chunk loop and preparation ordering are Rust-owned. These
|
||||
* callbacks keep the private ZSTD_CCtx and match-state layout in C: Rust
|
||||
* passes the context back to the narrow window/workspace operations. */
|
||||
typedef void (*ZSTD_rust_frameChunkPrepareOverflow_f)(void* context,
|
||||
const void* src,
|
||||
size_t blockSize);
|
||||
typedef void (*ZSTD_rust_frameChunkPrepareWindow_f)(void* context,
|
||||
const void* src,
|
||||
size_t blockSize,
|
||||
U32 maxDist);
|
||||
typedef void (*ZSTD_rust_frameChunkPrepareClamp_f)(void* context);
|
||||
typedef struct {
|
||||
void* callbackContext;
|
||||
U32 maxDist;
|
||||
ZSTD_rust_frameChunkPrepareOverflow_f correctOverflow;
|
||||
ZSTD_rust_frameChunkPrepareWindow_f checkDictValidity;
|
||||
ZSTD_rust_frameChunkPrepareWindow_f enforceMaxDist;
|
||||
ZSTD_rust_frameChunkPrepareClamp_f clampNextToUpdate;
|
||||
} ZSTD_rust_frameChunkPrepareState;
|
||||
typedef char ZSTD_rust_frame_chunk_prepare_state_layout[
|
||||
(offsetof(ZSTD_rust_frameChunkPrepareState, callbackContext) == 0
|
||||
&& offsetof(ZSTD_rust_frameChunkPrepareState, maxDist) == sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_frameChunkPrepareState, correctOverflow)
|
||||
== 2 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_frameChunkPrepareState, checkDictValidity)
|
||||
== 3 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_frameChunkPrepareState, enforceMaxDist)
|
||||
== 4 * sizeof(void*)
|
||||
&& offsetof(ZSTD_rust_frameChunkPrepareState, clampNextToUpdate)
|
||||
== 5 * sizeof(void*)
|
||||
&& sizeof(ZSTD_rust_frameChunkPrepareState) == 6 * sizeof(void*))
|
||||
? 1 : -1];
|
||||
typedef size_t (*ZSTD_rust_frameChunkCompress_f)(void* context,
|
||||
void* dst,
|
||||
size_t dstCapacity,
|
||||
@@ -703,7 +729,7 @@ typedef struct {
|
||||
int blockSplitterEnabled;
|
||||
int checksumFlag;
|
||||
int endingStage;
|
||||
ZSTD_rust_frameChunkPrepare_f prepareBlock;
|
||||
const ZSTD_rust_frameChunkPrepareState* prepareState;
|
||||
ZSTD_rust_frameChunkCompress_f compressTarget;
|
||||
ZSTD_rust_frameChunkCompress_f compressSplit;
|
||||
ZSTD_rust_frameChunkCompress_f compressInternal;
|
||||
@@ -735,7 +761,7 @@ typedef char ZSTD_rust_frame_chunk_state_layout[
|
||||
== 7 * sizeof(void*) + sizeof(S64) + 4 * sizeof(int)
|
||||
&& offsetof(ZSTD_rust_frameChunkState, endingStage)
|
||||
== 7 * sizeof(void*) + sizeof(S64) + 5 * sizeof(int)
|
||||
&& offsetof(ZSTD_rust_frameChunkState, prepareBlock)
|
||||
&& offsetof(ZSTD_rust_frameChunkState, prepareState)
|
||||
== 7 * sizeof(void*) + sizeof(S64) + 6 * sizeof(int)
|
||||
&& sizeof(ZSTD_rust_frameChunkState)
|
||||
== 12 * sizeof(void*) + sizeof(S64) + 6 * sizeof(int))
|
||||
@@ -5053,24 +5079,46 @@ static void ZSTD_overflowCorrectIfNeeded(ZSTD_MatchState_t* ms,
|
||||
|
||||
#include "zstd_preSplit.h"
|
||||
|
||||
static void ZSTD_rust_frameChunk_prepareBlock(void* context,
|
||||
const void* src,
|
||||
size_t blockSize)
|
||||
static void ZSTD_rust_frameChunk_correctOverflow(void* context,
|
||||
const void* src,
|
||||
size_t blockSize)
|
||||
{
|
||||
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
|
||||
ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
|
||||
U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
|
||||
|
||||
ZSTD_overflowCorrectIfNeeded(
|
||||
ms, &cctx->workspace, &cctx->appliedParams,
|
||||
src, (const BYTE*)src + blockSize);
|
||||
}
|
||||
|
||||
static void ZSTD_rust_frameChunk_checkDictValidity(void* context,
|
||||
const void* src,
|
||||
size_t blockSize,
|
||||
U32 maxDist)
|
||||
{
|
||||
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
|
||||
ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
|
||||
ZSTD_checkDictValidity(
|
||||
&ms->window, (const BYTE*)src + blockSize, maxDist,
|
||||
&ms->loadedDictEnd, &ms->dictMatchState);
|
||||
}
|
||||
|
||||
static void ZSTD_rust_frameChunk_enforceMaxDist(void* context,
|
||||
const void* src,
|
||||
size_t blockSize,
|
||||
U32 maxDist)
|
||||
{
|
||||
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
|
||||
ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
|
||||
ZSTD_window_enforceMaxDist(
|
||||
&ms->window, src, maxDist,
|
||||
&ms->loadedDictEnd, &ms->dictMatchState);
|
||||
(void)blockSize;
|
||||
}
|
||||
|
||||
static void ZSTD_rust_frameChunk_clampNextToUpdate(void* context)
|
||||
{
|
||||
ZSTD_CCtx* const cctx = (ZSTD_CCtx*)context;
|
||||
ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
|
||||
/* Ensure hash/chain table insertion resumes no sooner than lowlimit. */
|
||||
if (ms->nextToUpdate < ms->window.lowLimit)
|
||||
ms->nextToUpdate = ms->window.lowLimit;
|
||||
@@ -5121,6 +5169,13 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
|
||||
U32 lastFrameChunk)
|
||||
{
|
||||
ZSTD_rust_frameChunkState state;
|
||||
ZSTD_rust_frameChunkPrepareState prepareState;
|
||||
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;
|
||||
prepareState.clampNextToUpdate = ZSTD_rust_frameChunk_clampNextToUpdate;
|
||||
state.callbackContext = cctx;
|
||||
state.tmpWorkspace = cctx->tmpWorkspace;
|
||||
state.checksumState = &cctx->xxhState;
|
||||
@@ -5135,7 +5190,7 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
|
||||
state.blockSplitterEnabled = ZSTD_blockSplitterEnabled(&cctx->appliedParams);
|
||||
state.checksumFlag = cctx->appliedParams.fParams.checksumFlag;
|
||||
state.endingStage = (int)ZSTDcs_ending;
|
||||
state.prepareBlock = ZSTD_rust_frameChunk_prepareBlock;
|
||||
state.prepareState = &prepareState;
|
||||
state.compressTarget = ZSTD_rust_frameChunk_compressTarget;
|
||||
state.compressSplit = ZSTD_rust_frameChunk_compressSplit;
|
||||
state.compressInternal = ZSTD_rust_frameChunk_compressInternal;
|
||||
|
||||
Reference in New Issue
Block a user