feat(compress): move window dictionary policy into Rust

Move shared-window max-distance enforcement and dictionary-validity decisions into Rust. C keeps the private window pointer arithmetic, match-state pointer invalidation, and logging while applying the projected limit state returned by Rust.

Test Plan:
- ulimit -v 41943040; CARGO_BUILD_JOBS=1; cargo test --manifest-path rust/Cargo.toml
- ulimit -v 41943040; CARGO_BUILD_JOBS=1; cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings
- ulimit -v 41943040; make -B -C programs -j1 zstd
- ulimit -v 41943040; make -C tests -j1 test-zstream ZSTREAM_TESTTIME=-T1s
This commit is contained in:
2026-07-19 20:05:29 +02:00
parent f8cabd39a4
commit 2557319583
2 changed files with 121 additions and 8 deletions
+29 -8
View File
@@ -669,10 +669,26 @@ typedef char ZSTD_rust_window_update_state_layout[
&& offsetof(ZSTD_rust_windowUpdateState, dictLimit) == 3 * sizeof(void*)
&& offsetof(ZSTD_rust_windowUpdateState, lowLimit) == 3 * sizeof(void*) + sizeof(U32)
&& sizeof(ZSTD_rust_windowUpdateState) == 3 * sizeof(void*) + 2 * sizeof(U32)) ? 1 : -1];
typedef struct {
U32 lowLimit;
U32 dictLimit;
U32 loadedDictEnd;
U32 invalidate;
} ZSTD_rust_windowDictState;
typedef char ZSTD_rust_window_dict_state_layout[
(offsetof(ZSTD_rust_windowDictState, lowLimit) == 0
&& offsetof(ZSTD_rust_windowDictState, dictLimit) == sizeof(U32)
&& offsetof(ZSTD_rust_windowDictState, loadedDictEnd) == 2 * sizeof(U32)
&& offsetof(ZSTD_rust_windowDictState, invalidate) == 3 * sizeof(U32)
&& sizeof(ZSTD_rust_windowDictState) == 4 * sizeof(U32)) ? 1 : -1];
void ZSTD_rust_windowInit(ZSTD_rust_windowUpdateState* state);
U32 ZSTD_rust_windowIsEmpty(const void* nextSrc, const void* base,
U32 dictLimit, U32 lowLimit);
U32 ZSTD_rust_windowHasExtDict(U32 dictLimit, U32 lowLimit);
ZSTD_rust_windowDictState ZSTD_rust_windowEnforceMaxDist(
U32 blockEndIdx, U32 maxDist, ZSTD_rust_windowDictState state);
U32 ZSTD_rust_windowCheckDictValidity(U32 blockEndIdx, U32 maxDist,
U32 loadedDictEnd, U32 dictLimit);
U32 ZSTD_rust_windowUpdate(ZSTD_rust_windowUpdateState* state,
const void* src, size_t srcSize,
int forceNonContiguous);
@@ -1237,6 +1253,10 @@ ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
{
U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
U32 const oldDictLimit = window->dictLimit;
ZSTD_rust_windowDictState state = {
window->lowLimit, window->dictLimit, loadedDictEnd, 0
};
DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
(unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
@@ -1253,16 +1273,16 @@ ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
loadedDictEnd is expressed within the referential of the context,
so it can be directly compared against blockEndIdx.
*/
if (blockEndIdx > maxDist + loadedDictEnd) {
U32 const newLowLimit = blockEndIdx - maxDist;
if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit;
if (window->dictLimit < window->lowLimit) {
state = ZSTD_rust_windowEnforceMaxDist(blockEndIdx, maxDist, state);
window->lowLimit = state.lowLimit;
window->dictLimit = state.dictLimit;
if (state.invalidate) {
if (oldDictLimit < window->lowLimit) {
DEBUGLOG(5, "Update dictLimit to match lowLimit, from %u to %u",
(unsigned)window->dictLimit, (unsigned)window->lowLimit);
window->dictLimit = window->lowLimit;
(unsigned)oldDictLimit, (unsigned)window->lowLimit);
}
/* On reaching window size, dictionaries are invalidated */
if (loadedDictEndPtr) *loadedDictEndPtr = 0;
if (loadedDictEndPtr) *loadedDictEndPtr = state.loadedDictEnd;
if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
}
}
@@ -1288,7 +1308,8 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window,
(unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
assert(blockEndIdx >= loadedDictEnd);
if (blockEndIdx > loadedDictEnd + maxDist || loadedDictEnd != window->dictLimit) {
if (ZSTD_rust_windowCheckDictValidity(
blockEndIdx, maxDist, loadedDictEnd, window->dictLimit)) {
/* On reaching window size, dictionaries are invalidated.
* For simplification, if window size is reached anywhere within next block,
* the dictionary is invalidated for the full block.