feat(compress): move window clearing leaf into Rust

Keep the private ZSTD_window_t layout and pointer-difference calculation in C,
then route the size_t-to-U32 conversion and paired limit writes through a small
Rust ABI leaf. This removes the inline C window-clear implementation while
preserving its overflow behavior at both single-threaded and multithreaded
call sites.

Test Plan:
- cargo test --manifest-path rust/Cargo.toml --lib zstd_compress::tests (77 passed)
- make -C programs -j2 zstd
- rustfmt +nightly --edition 2021 rust/src/zstd_compress.rs --check
- make -C tests -j2 test-cli-tests (41 passed)
- make -C tests -j2 test-legacy test-invalidDictionaries test-decodecorpus test-rust-lib-smoke (passed)
- git diff --check
This commit is contained in:
2026-07-18 17:23:33 +02:00
parent 98cca9aa0f
commit c057bcbbdf
4 changed files with 54 additions and 16 deletions
+7 -2
View File
@@ -1486,7 +1486,8 @@ void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
*/
static void ZSTD_invalidateMatchState(ZSTD_MatchState_t* ms)
{
ZSTD_window_clear(&ms->window);
ZSTD_rust_windowClear((size_t)(ms->window.nextSrc - ms->window.base),
&ms->window.lowLimit, &ms->window.dictLimit);
ms->nextToUpdate = ms->window.dictLimit;
ms->loadedDictEnd = 0;
@@ -1893,7 +1894,11 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
if (cctx->blockState.matchState.window.dictLimit < cdictEnd) {
cctx->blockState.matchState.window.nextSrc =
cctx->blockState.matchState.window.base + cdictEnd;
ZSTD_window_clear(&cctx->blockState.matchState.window);
ZSTD_rust_windowClear(
(size_t)(cctx->blockState.matchState.window.nextSrc -
cctx->blockState.matchState.window.base),
&cctx->blockState.matchState.window.lowLimit,
&cctx->blockState.matchState.window.dictLimit);
}
/* loadedDictEnd is expressed within the referential of the active context */
cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit;
+1 -13
View File
@@ -654,6 +654,7 @@ size_t ZSTD_rust_noCompressBlock(void* dst, size_t dstCapacity,
const void* src, size_t srcSize, U32 lastBlock);
size_t ZSTD_rust_rleCompressBlock(void* dst, size_t dstCapacity, BYTE src,
size_t srcSize, U32 lastBlock);
void ZSTD_rust_windowClear(size_t endT, U32* lowLimit, U32* dictLimit);
U32 ZSTD_rust_windowCorrectOverflow(U32 curr, U32 cycleLog, U32 maxDist);
U32 ZSTD_rust_windowCanOverflowCorrect(U32 curr, U32 cycleLog, U32 maxDist,
U32 loadedDictEnd,
@@ -1025,19 +1026,6 @@ MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64
( ((U32)-1) /* Maximum ending current index */ \
- ZSTD_CURRENT_MAX) /* Maximum beginning lowLimit */
/**
* ZSTD_window_clear():
* Clears the window containing the history by simply setting it to empty.
*/
MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window)
{
size_t const endT = (size_t)(window->nextSrc - window->base);
U32 const end = (U32)endT;
window->lowLimit = end;
window->dictLimit = end;
}
MEM_STATIC U32 ZSTD_window_isEmpty(ZSTD_window_t const window)
{
return window.dictLimit == ZSTD_WINDOW_START_INDEX &&
+4 -1
View File
@@ -620,7 +620,10 @@ static void ZSTDMT_serialState_ensureFinished(SerialState* serialState,
ZSTD_pthread_cond_broadcast(&serialState->cond);
ZSTD_PTHREAD_MUTEX_LOCK(&serialState->ldmWindowMutex);
ZSTD_window_clear(&serialState->ldmWindow);
ZSTD_rust_windowClear((size_t)(serialState->ldmWindow.nextSrc -
serialState->ldmWindow.base),
&serialState->ldmWindow.lowLimit,
&serialState->ldmWindow.dictLimit);
ZSTD_pthread_cond_signal(&serialState->ldmWindowCond);
ZSTD_pthread_mutex_unlock(&serialState->ldmWindowMutex);
}