From 7e5e226cbf296db0318dd707f7166866cb7ad9ba Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Fri, 23 Feb 2018 16:48:18 -0800 Subject: [PATCH] Split the window state into substructure --- lib/compress/zstd_compress.c | 120 ++++--------------- lib/compress/zstd_compress_internal.h | 165 +++++++++++++++++++++++++- lib/compress/zstd_double_fast.c | 14 +-- lib/compress/zstd_fast.c | 14 +-- lib/compress/zstd_lazy.c | 48 ++++---- lib/compress/zstd_ldm.c | 16 +-- lib/compress/zstd_opt.c | 26 ++-- 7 files changed, 241 insertions(+), 162 deletions(-) diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index 74a51c25e..467515370 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -883,13 +883,9 @@ static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs) */ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms) { - size_t const endT = (size_t)(ms->nextSrc - ms->base); - U32 const end = (U32)endT; - assert(endT < (3U<<30)); + ZSTD_window_clear(&ms->window); - ms->lowLimit = end; - ms->dictLimit = end; - ms->nextToUpdate = end + 1; + ms->nextToUpdate = ms->window.dictLimit + 1; ms->loadedDictEnd = 0; ms->opt.litLengthSum = 0; /* force reset of btopt stats */ } @@ -931,10 +927,8 @@ static void* ZSTD_reset_matchState(ZSTD_matchState_t* ms, void* ptr, ZSTD_compre assert(((size_t)ptr & 3) == 0); - ms->nextSrc = NULL; - ms->base = NULL; - ms->dictBase = NULL; ms->hashLog3 = hashLog3; + memset(&ms->window, 0, sizeof(ms->window)); ZSTD_invalidateMatchState(ms); /* opt parser space */ @@ -1114,7 +1108,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc, void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) { int i; for (i=0; iblockState.prevCBlock->rep[i] = 0; - assert(/* !extDict */ cctx->blockState.matchState.lowLimit == cctx->blockState.matchState.dictLimit); + assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window)); } static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx, @@ -1156,13 +1150,9 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx, { ZSTD_matchState_t const* srcMatchState = &cdict->matchState; ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState; + dstMatchState->window = srcMatchState->window; dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3; - dstMatchState->nextSrc = srcMatchState->nextSrc; - dstMatchState->base = srcMatchState->base; - dstMatchState->dictBase = srcMatchState->dictBase; - dstMatchState->dictLimit = srcMatchState->dictLimit; - dstMatchState->lowLimit = srcMatchState->lowLimit; dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; } cctx->dictID = cdict->dictID; @@ -1217,13 +1207,9 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, { ZSTD_matchState_t const* srcMatchState = &srcCCtx->blockState.matchState; ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState; + dstMatchState->window = srcMatchState->window; dstMatchState->nextToUpdate = srcMatchState->nextToUpdate; dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3; - dstMatchState->nextSrc = srcMatchState->nextSrc; - dstMatchState->base = srcMatchState->base; - dstMatchState->dictBase = srcMatchState->dictBase; - dstMatchState->dictLimit = srcMatchState->dictLimit; - dstMatchState->lowLimit = srcMatchState->lowLimit; dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd; } dstCCtx->dictID = srcCCtx->dictID; @@ -1826,13 +1812,13 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, { ZSTD_matchState_t* const ms = &zc->blockState.matchState; DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)", - (U32)dstCapacity, ms->dictLimit, ms->nextToUpdate); + (U32)dstCapacity, ms->window.dictLimit, ms->nextToUpdate); if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0; /* don't even attempt compression below a certain srcSize */ ZSTD_resetSeqStore(&(zc->seqStore)); /* limited update after a very long match */ - { const BYTE* const base = ms->base; + { const BYTE* const base = ms->window.base; const BYTE* const istart = (const BYTE*)src; const U32 current = (U32)(istart-base); if (current > ms->nextToUpdate + 384) @@ -1840,7 +1826,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, } /* select and store sequences */ - { U32 const extDict = ms->lowLimit < ms->dictLimit; + { U32 const extDict = ZSTD_window_hasExtDict(ms->window); size_t lastLLSize; { int i; for (i = 0; i < ZSTD_REP_NUM; ++i) zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i]; } if (zc->appliedParams.ldmParams.enableLdm) { @@ -1907,52 +1893,19 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx, return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */ if (remaining < blockSize) blockSize = remaining; - /* preemptive overflow correction: - * 1. correction is large enough: - * lowLimit > (3<<29) ==> current > 3<<29 + 1< (3<<29 + 1< (3<<29 - blockSize) - (1< (3<<29 - blockSize) - (1<<30) (NOTE: chainLog <= 30) - * > 1<<29 - 1<<17 - * - * 2. (ip+blockSize - cctx->base) doesn't overflow: - * In 32 bit mode we limit windowLog to 30 so we don't get - * differences larger than 1<<31-1. - * 3. cctx->lowLimit < 1<<32: - * windowLog <= 31 ==> 3<<29 + 1<lowLimit > (3U<<29)) { - U32 const cycleMask = ((U32)1 << ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy)) - 1; - U32 const current = (U32)(ip - cctx->blockState.matchState.base); - U32 const newCurrent = (current & cycleMask) + ((U32)1 << cctx->appliedParams.cParams.windowLog); - U32 const correction = current - newCurrent; + if (ZSTD_window_needOverflowCorrection(ms->window)) { + U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy); + U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip); ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30); ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30); ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31); - assert(current > newCurrent); - assert(correction > 1<<28); /* Loose bound, should be about 1<<29 */ + ZSTD_reduceIndex(cctx, correction); - ms->base += correction; - ms->dictBase += correction; - ms->lowLimit -= correction; - ms->dictLimit -= correction; if (ms->nextToUpdate < correction) ms->nextToUpdate = 0; else ms->nextToUpdate -= correction; - DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction, ms->lowLimit); - } - /* enforce maxDist */ - if ((U32)(ip+blockSize - ms->base) > ms->loadedDictEnd + maxDist) { - U32 const newLowLimit = (U32)(ip+blockSize - ms->base) - maxDist; - if (ms->lowLimit < newLowLimit) ms->lowLimit = newLowLimit; - if (ms->dictLimit < ms->lowLimit) - DEBUGLOG(5, "ZSTD_compress_frameChunk : update dictLimit from %u to %u ", - ms->dictLimit, ms->lowLimit); - if (ms->dictLimit < ms->lowLimit) ms->dictLimit = ms->lowLimit; - if (ms->nextToUpdate < ms->lowLimit) ms->nextToUpdate = ms->lowLimit; } + ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, ms->loadedDictEnd + maxDist); + if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit; { size_t cSize = ZSTD_compressBlock_internal(cctx, op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, @@ -2044,38 +1997,12 @@ size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity) } -static void ZSTD_manageWindowContinuity(ZSTD_matchState_t* ms, void const* src, size_t srcSize) -{ - const BYTE* const ip = (const BYTE*) src; - - /* Check if blocks follow each other */ - if (src != ms->nextSrc) { - /* not contiguous */ - size_t const distanceFromBase = (size_t)(ms->nextSrc - ms->base); - DEBUGLOG(5, "ZSTD_manageWindowContinuity: non contiguous blocks, new segment starts at %u", ms->dictLimit); - ms->lowLimit = ms->dictLimit; - assert(distanceFromBase == (size_t)(U32)distanceFromBase); /* should never overflow */ - ms->dictLimit = (U32)distanceFromBase; - ms->dictBase = ms->base; - ms->base = ip - distanceFromBase; - ms->nextToUpdate = ms->dictLimit; - if (ms->dictLimit - ms->lowLimit < HASH_READ_SIZE) ms->lowLimit = ms->dictLimit; /* too small extDict */ - } - ms->nextSrc = ip + srcSize; - /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */ - if ((ip+srcSize > ms->dictBase + ms->lowLimit) & (ip < ms->dictBase + ms->dictLimit)) { - ptrdiff_t const highInputIdx = (ip + srcSize) - ms->dictBase; - U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)ms->dictLimit) ? ms->dictLimit : (U32)highInputIdx; - ms->lowLimit = lowLimitMax; - } -} - - static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 frame, U32 lastFrameChunk) { + ZSTD_matchState_t* ms = &cctx->blockState.matchState; size_t fhSize = 0; DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u", @@ -2093,7 +2020,9 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx, if (!srcSize) return fhSize; /* do not generate an empty block if no input */ - ZSTD_manageWindowContinuity(&cctx->blockState.matchState, src, srcSize); + if (!ZSTD_window_update(&ms->window, src, srcSize)) { + ms->nextToUpdate = ms->window.dictLimit; + } DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (U32)cctx->blockSize); { size_t const cSize = frame ? @@ -2145,15 +2074,8 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, ZSTD_CCtx_params const BYTE* const iend = ip + srcSize; ZSTD_compressionParameters const* cParams = ¶ms->cParams; - /* input becomes current prefix */ - ms->lowLimit = ms->dictLimit; - ms->dictLimit = (U32)(ms->nextSrc - ms->base); - ms->dictBase = ms->base; - ms->base = ip - ms->dictLimit; - ms->nextToUpdate = ms->dictLimit; - ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->base); + ZSTD_window_update(&ms->window, src, srcSize); - ms->nextSrc = iend; if (srcSize <= HASH_READ_SIZE) return 0; switch(params->cParams.strategy) @@ -2183,7 +2105,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, ZSTD_CCtx_params assert(0); /* not possible : not a valid strategy id */ } - ms->nextToUpdate = (U32)(iend - ms->base); + ms->nextToUpdate = (U32)(iend - ms->window.base); return 0; } diff --git a/lib/compress/zstd_compress_internal.h b/lib/compress/zstd_compress_internal.h index 8a02f764e..98f866cde 100644 --- a/lib/compress/zstd_compress_internal.h +++ b/lib/compress/zstd_compress_internal.h @@ -110,10 +110,14 @@ typedef struct { BYTE const* dictBase; /* extDict indexes relative to this position */ U32 dictLimit; /* below that point, need extDict */ U32 lowLimit; /* below that point, no more data */ - U32 nextToUpdate; /* index from which to continue table update */ - U32 nextToUpdate3; /* index from which to continue table update */ - U32 hashLog3; /* dispatch table : larger == faster, more memory */ - U32 loadedDictEnd; /* index of end of dictionary */ +} ZSTD_window_t; + +typedef struct { + ZSTD_window_t window; /* State for window round buffer management */ + U32 loadedDictEnd; /* index of end of dictionary */ + U32 nextToUpdate; /* index from which to continue table update */ + U32 nextToUpdate3; /* index from which to continue table update */ + U32 hashLog3; /* dispatch table : larger == faster, more memory */ U32* hashTable; U32* hashTable3; U32* chainTable; @@ -441,6 +445,159 @@ MEM_STATIC size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls) } } +/*-************************************* +* Round buffer management +***************************************/ + +#define ZSTD_LOWLIMIT_MAX (3U << 29) /* Max lowLimit allowed */ +/* Maximum chunk size before overflow correction needs to be called again */ +#define ZSTD_CHUNKSIZE_MAX \ + ( ((U32)-1) /* Maximum ending current index */ \ + - (1U << ZSTD_WINDOWLOG_MAX) /* Max distance from lowLimit to current */ \ + - ZSTD_LOWLIMIT_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; +} + +/** + * ZSTD_window_hasExtDict(): + * Returns non-zero if the window has a non-empty extDict. + */ +MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window) +{ + return window.lowLimit < window.dictLimit; +} + +/** + * ZSTD_window_needOverflowCorrection(): + * Returns non-zero if the indices are getting too large and need overflow + * protection. + */ +MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window) +{ + return window.lowLimit > ZSTD_LOWLIMIT_MAX; +} + +/** + * ZSTD_window_correctOverflow(): + * Reduces the indices to protect from index overflow. + * Returns the correction made to the indices, which must be applied to every + * stored index. + * + * The least significant cycleLog bits of the indices must remain the same, + * which may be 0. Every index up to maxDist in the past must be valid. + * NOTE: (maxDist & cycleMask) must be zero. + */ +MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog, + U32 maxDist, void const* src) +{ + /* preemptive overflow correction: + * 1. correction is large enough: + * lowLimit > (3<<29) ==> current > 3<<29 + 1< (3<<29 + 1< (3<<29) - (1< (3<<29) - (1<<30) (NOTE: chainLog <= 30) + * > 1<<29 + * + * 2. (ip+ZSTD_CHUNKSIZE_MAX - cctx->base) doesn't overflow: + * After correction, current is less than (1<base < 1<<32. + * 3. (cctx->lowLimit + 1< 3<<29 + 1<base); + U32 const newCurrent = (current & cycleMask) + maxDist; + U32 const correction = current - newCurrent; + assert((maxDist & cycleMask) == 0); + assert(current > newCurrent); + /* Loose bound, should be around 1<<29 (see above) */ + assert(correction > 1<<28); + + window->base += correction; + window->dictBase += correction; + window->lowLimit -= correction; + window->dictLimit -= correction; + + DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction, + window->lowLimit); + return correction; +} + +/** + * ZSTD_window_enforceMaxDist(): + * Sets lowLimit such that indices earlier than (srcEnd - base) - lowLimit are + * invalid. This allows a simple check index >= lowLimit to see if it is valid. + * Source pointers past srcEnd are not guaranteed to be valid. + */ +MEM_STATIC void ZSTD_window_enforceMaxDist(ZSTD_window_t* window, + void const* srcEnd, U32 maxDist) +{ + U32 const current = (U32)((BYTE const*)srcEnd - window->base); + if (current > maxDist) { + U32 const newLowLimit = current - maxDist; + if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit; + if (window->dictLimit < window->lowLimit) { + DEBUGLOG(5, "Update dictLimit from %u to %u", window->dictLimit, + window->lowLimit); + window->dictLimit = window->lowLimit; + } + } +} + +/** + * ZSTD_window_update(): + * Updates the window by appending [src, src + srcSize) to the window. + * If it is not contiguous, the current prefix becomes the extDict, and we + * forget about the extDict. Handles overlap of the prefix and extDict. + * Returns non-zero if the segment is contiguous. + */ +MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window, + void const* src, size_t srcSize) +{ + BYTE const* const ip = (BYTE const*)src; + U32 contiguous = 1; + /* Check if blocks follow each other */ + if (src != window->nextSrc) { + /* not contiguous */ + size_t const distanceFromBase = (size_t)(window->nextSrc - window->base); + DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", + window->dictLimit); + window->lowLimit = window->dictLimit; + assert(distanceFromBase == (size_t)(U32)distanceFromBase); /* should never overflow */ + window->dictLimit = (U32)distanceFromBase; + window->dictBase = window->base; + window->base = ip - distanceFromBase; + // ms->nextToUpdate = window->dictLimit; + if (window->dictLimit - window->lowLimit < HASH_READ_SIZE) window->lowLimit = window->dictLimit; /* too small extDict */ + contiguous = 0; + } + window->nextSrc = ip + srcSize; + /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */ + if ( (ip+srcSize > window->dictBase + window->lowLimit) + & (ip < window->dictBase + window->dictLimit)) { + ptrdiff_t const highInputIdx = (ip + srcSize) - window->dictBase; + U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx; + window->lowLimit = lowLimitMax; + } + return contiguous; +} + #if defined (__cplusplus) } #endif diff --git a/lib/compress/zstd_double_fast.c b/lib/compress/zstd_double_fast.c index 6415480e2..86e6b3962 100644 --- a/lib/compress/zstd_double_fast.c +++ b/lib/compress/zstd_double_fast.c @@ -21,7 +21,7 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms, U32 const mls = cParams->searchLength; U32* const hashSmall = ms->chainTable; U32 const hBitsS = cParams->chainLog; - const BYTE* const base = ms->base; + const BYTE* const base = ms->window.base; const BYTE* ip = base + ms->nextToUpdate; const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; const U32 fastHashFillStep = 3; @@ -55,11 +55,11 @@ size_t ZSTD_compressBlock_doubleFast_generic( const U32 hBitsL = cParams->hashLog; U32* const hashSmall = ms->chainTable; const U32 hBitsS = cParams->chainLog; - const BYTE* const base = ms->base; + const BYTE* const base = ms->window.base; const BYTE* const istart = (const BYTE*)src; const BYTE* ip = istart; const BYTE* anchor = istart; - const U32 lowestIndex = ms->dictLimit; + const U32 lowestIndex = ms->window.dictLimit; const BYTE* const lowest = base + lowestIndex; const BYTE* const iend = istart + srcSize; const BYTE* const ilimit = iend - HASH_READ_SIZE; @@ -187,14 +187,14 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic( U32 const hBitsL = cParams->hashLog; U32* const hashSmall = ms->chainTable; U32 const hBitsS = cParams->chainLog; - const BYTE* const base = ms->base; - const BYTE* const dictBase = ms->dictBase; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; const BYTE* const istart = (const BYTE*)src; const BYTE* ip = istart; const BYTE* anchor = istart; - const U32 lowestIndex = ms->lowLimit; + const U32 lowestIndex = ms->window.lowLimit; const BYTE* const dictStart = dictBase + lowestIndex; - const U32 dictLimit = ms->dictLimit; + const U32 dictLimit = ms->window.dictLimit; const BYTE* const lowPrefixPtr = base + dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const iend = istart + srcSize; diff --git a/lib/compress/zstd_fast.c b/lib/compress/zstd_fast.c index b60f21580..d2f50488e 100644 --- a/lib/compress/zstd_fast.c +++ b/lib/compress/zstd_fast.c @@ -19,7 +19,7 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms, U32* const hashTable = ms->hashTable; U32 const hBits = cParams->hashLog; U32 const mls = cParams->searchLength; - const BYTE* const base = ms->base; + const BYTE* const base = ms->window.base; const BYTE* ip = base + ms->nextToUpdate; const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE; const U32 fastHashFillStep = 3; @@ -45,11 +45,11 @@ size_t ZSTD_compressBlock_fast_generic( U32 const hlog, U32 const mls) { U32* const hashTable = ms->hashTable; - const BYTE* const base = ms->base; + const BYTE* const base = ms->window.base; const BYTE* const istart = (const BYTE*)src; const BYTE* ip = istart; const BYTE* anchor = istart; - const U32 lowestIndex = ms->dictLimit; + const U32 lowestIndex = ms->window.dictLimit; const BYTE* const lowest = base + lowestIndex; const BYTE* const iend = istart + srcSize; const BYTE* const ilimit = iend - HASH_READ_SIZE; @@ -149,14 +149,14 @@ static size_t ZSTD_compressBlock_fast_extDict_generic( U32 const hlog, U32 const mls) { U32* hashTable = ms->hashTable; - const BYTE* const base = ms->base; - const BYTE* const dictBase = ms->dictBase; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; const BYTE* const istart = (const BYTE*)src; const BYTE* ip = istart; const BYTE* anchor = istart; - const U32 lowestIndex = ms->lowLimit; + const U32 lowestIndex = ms->window.lowLimit; const BYTE* const dictStart = dictBase + lowestIndex; - const U32 dictLimit = ms->dictLimit; + const U32 dictLimit = ms->window.dictLimit; const BYTE* const lowPrefixPtr = base + dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const iend = istart + srcSize; diff --git a/lib/compress/zstd_lazy.c b/lib/compress/zstd_lazy.c index 0dab117a3..9f158123f 100644 --- a/lib/compress/zstd_lazy.c +++ b/lib/compress/zstd_lazy.c @@ -28,17 +28,17 @@ void ZSTD_updateDUBT( U32 const btLog = cParams->chainLog - 1; U32 const btMask = (1 << btLog) - 1; - const BYTE* const base = ms->base; + const BYTE* const base = ms->window.base; U32 const target = (U32)(ip - base); U32 idx = ms->nextToUpdate; if (idx != target) DEBUGLOG(7, "ZSTD_updateDUBT, from %u to %u (dictLimit:%u)", - idx, target, ms->dictLimit); + idx, target, ms->window.dictLimit); assert(ip + 8 <= iend); /* condition for ZSTD_hashPtr */ (void)iend; - assert(idx >= ms->dictLimit); /* condition for valid base+idx */ + assert(idx >= ms->window.dictLimit); /* condition for valid base+idx */ for ( ; idx < target ; idx++) { size_t const h = ZSTD_hashPtr(base + idx, hashLog, mls); /* assumption : ip + 8 <= iend */ U32 const matchIndex = hashTable[h]; @@ -68,9 +68,9 @@ static void ZSTD_insertDUBT1( U32 const btLog = cParams->chainLog - 1; U32 const btMask = (1 << btLog) - 1; size_t commonLengthSmaller=0, commonLengthLarger=0; - const BYTE* const base = ms->base; - const BYTE* const dictBase = ms->dictBase; - const U32 dictLimit = ms->dictLimit; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; const BYTE* const ip = (current>=dictLimit) ? base + current : dictBase + current; const BYTE* const iend = (current>=dictLimit) ? inputEnd : dictBase + dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; @@ -80,7 +80,7 @@ static void ZSTD_insertDUBT1( U32* largerPtr = smallerPtr + 1; U32 matchIndex = *smallerPtr; U32 dummy32; /* to be nullified at the end */ - U32 const windowLow = ms->lowLimit; + U32 const windowLow = ms->window.lowLimit; DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)", current, dictLimit, windowLow); @@ -150,9 +150,9 @@ static size_t ZSTD_DUBT_findBestMatch ( size_t const h = ZSTD_hashPtr(ip, hashLog, mls); U32 matchIndex = hashTable[h]; - const BYTE* const base = ms->base; + const BYTE* const base = ms->window.base; U32 const current = (U32)(ip-base); - U32 const windowLow = ms->lowLimit; + U32 const windowLow = ms->window.lowLimit; U32* const bt = ms->chainTable; U32 const btLog = cParams->chainLog - 1; @@ -203,8 +203,8 @@ static size_t ZSTD_DUBT_findBestMatch ( /* find longest match */ { size_t commonLengthSmaller=0, commonLengthLarger=0; - const BYTE* const dictBase = ms->dictBase; - const U32 dictLimit = ms->dictLimit; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const prefixStart = base + dictLimit; U32* smallerPtr = bt + 2*(current&btMask); @@ -279,7 +279,7 @@ static size_t ZSTD_BtFindBestMatch ( const U32 mls /* template */) { DEBUGLOG(7, "ZSTD_BtFindBestMatch"); - if (ip < ms->base + ms->nextToUpdate) return 0; /* skipped area */ + if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */ ZSTD_updateDUBT(ms, cParams, ip, iLimit, mls); return ZSTD_DUBT_findBestMatch(ms, cParams, ip, iLimit, offsetPtr, mls, 0); } @@ -309,7 +309,7 @@ static size_t ZSTD_BtFindBestMatch_extDict ( const U32 mls) { DEBUGLOG(7, "ZSTD_BtFindBestMatch_extDict"); - if (ip < ms->base + ms->nextToUpdate) return 0; /* skipped area */ + if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */ ZSTD_updateDUBT(ms, cParams, ip, iLimit, mls); return ZSTD_DUBT_findBestMatch(ms, cParams, ip, iLimit, offsetPtr, mls, 1); } @@ -347,7 +347,7 @@ static U32 ZSTD_insertAndFindFirstIndex_internal( const U32 hashLog = cParams->hashLog; U32* const chainTable = ms->chainTable; const U32 chainMask = (1 << cParams->chainLog) - 1; - const BYTE* const base = ms->base; + const BYTE* const base = ms->window.base; const U32 target = (U32)(ip - base); U32 idx = ms->nextToUpdate; @@ -381,12 +381,12 @@ size_t ZSTD_HcFindBestMatch_generic ( U32* const chainTable = ms->chainTable; const U32 chainSize = (1 << cParams->chainLog); const U32 chainMask = chainSize-1; - const BYTE* const base = ms->base; - const BYTE* const dictBase = ms->dictBase; - const U32 dictLimit = ms->dictLimit; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; const BYTE* const prefixStart = base + dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; - const U32 lowLimit = ms->lowLimit; + const U32 lowLimit = ms->window.lowLimit; const U32 current = (U32)(ip-base); const U32 minChain = current > chainSize ? current - chainSize : 0; U32 nbAttempts = 1U << cParams->searchLog; @@ -471,7 +471,7 @@ size_t ZSTD_compressBlock_lazy_generic( const BYTE* anchor = istart; const BYTE* const iend = istart + srcSize; const BYTE* const ilimit = iend - 8; - const BYTE* const base = ms->base + ms->dictLimit; + const BYTE* const base = ms->window.base + ms->window.dictLimit; typedef size_t (*searchMax_f)( ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams, @@ -635,13 +635,13 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( const BYTE* anchor = istart; const BYTE* const iend = istart + srcSize; const BYTE* const ilimit = iend - 8; - const BYTE* const base = ms->base; - const U32 dictLimit = ms->dictLimit; - const U32 lowestIndex = ms->lowLimit; + const BYTE* const base = ms->window.base; + const U32 dictLimit = ms->window.dictLimit; + const U32 lowestIndex = ms->window.lowLimit; const BYTE* const prefixStart = base + dictLimit; - const BYTE* const dictBase = ms->dictBase; + const BYTE* const dictBase = ms->window.dictBase; const BYTE* const dictEnd = dictBase + dictLimit; - const BYTE* const dictStart = dictBase + ms->lowLimit; + const BYTE* const dictStart = dictBase + lowestIndex; typedef size_t (*searchMax_f)( ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams, diff --git a/lib/compress/zstd_ldm.c b/lib/compress/zstd_ldm.c index 2c304b38b..a043556b0 100644 --- a/lib/compress/zstd_ldm.c +++ b/lib/compress/zstd_ldm.c @@ -231,12 +231,12 @@ static size_t ZSTD_ldm_fillFastTables(ZSTD_matchState_t* ms, { case ZSTD_fast: ZSTD_fillHashTable(ms, cParams, iend); - ms->nextToUpdate = (U32)(iend - ms->base); + ms->nextToUpdate = (U32)(iend - ms->window.base); break; case ZSTD_dfast: ZSTD_fillDoubleHashTable(ms, cParams, iend); - ms->nextToUpdate = (U32)(iend - ms->base); + ms->nextToUpdate = (U32)(iend - ms->window.base); break; case ZSTD_greedy: @@ -287,7 +287,7 @@ static U64 ZSTD_ldm_fillLdmHashTable(ldmState_t* state, * (after a long match, only update tables a limited amount). */ static void ZSTD_ldm_limitTableUpdate(ZSTD_matchState_t* ms, const BYTE* anchor) { - U32 const current = (U32)(anchor - ms->base); + U32 const current = (U32)(anchor - ms->window.base); if (current > ms->nextToUpdate + 1024) { ms->nextToUpdate = current - MIN(512, current - ms->nextToUpdate - 1024); @@ -308,10 +308,10 @@ size_t ZSTD_ldm_generateSequences( U32 const hashEveryLog = params->hashEveryLog; U32 const ldmTagMask = (1U << params->hashEveryLog) - 1; /* Prefix and extDict parameters */ - U32 const dictLimit = ms->dictLimit; - U32 const lowestIndex = extDict ? ms->lowLimit : dictLimit; - BYTE const* const base = ms->base; - BYTE const* const dictBase = extDict ? ms->dictBase : NULL; + U32 const dictLimit = ms->window.dictLimit; + U32 const lowestIndex = extDict ? ms->window.lowLimit : dictLimit; + BYTE const* const base = ms->window.base; + BYTE const* const dictBase = extDict ? ms->window.dictBase : NULL; BYTE const* const dictStart = extDict ? dictBase + lowestIndex : NULL; BYTE const* const dictEnd = extDict ? dictBase + dictLimit : NULL; BYTE const* const lowPrefixPtr = base + dictLimit; @@ -514,7 +514,7 @@ size_t ZSTD_ldm_blockCompress(rawSeq const* sequences, size_t nbSeq, { ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(cParams->strategy, extDict); - BYTE const* const base = ms->base; + BYTE const* const base = ms->window.base; /* Input bounds */ BYTE const* const istart = (BYTE const*)src; BYTE const* const iend = istart + srcSize; diff --git a/lib/compress/zstd_opt.c b/lib/compress/zstd_opt.c index 149e63687..f63f0c585 100644 --- a/lib/compress/zstd_opt.c +++ b/lib/compress/zstd_opt.c @@ -247,7 +247,7 @@ static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms, const BYTE* { U32* const hashTable3 = ms->hashTable3; U32 const hashLog3 = ms->hashLog3; - const BYTE* const base = ms->base; + const BYTE* const base = ms->window.base; U32 idx = ms->nextToUpdate3; U32 const target = ms->nextToUpdate3 = (U32)(ip - base); size_t const hash3 = ZSTD_hash3Ptr(ip, hashLog3); @@ -281,9 +281,9 @@ static U32 ZSTD_insertBt1( U32 const btMask = (1 << btLog) - 1; U32 matchIndex = hashTable[h]; size_t commonLengthSmaller=0, commonLengthLarger=0; - const BYTE* const base = ms->base; - const BYTE* const dictBase = ms->dictBase; - const U32 dictLimit = ms->dictLimit; + const BYTE* const base = ms->window.base; + const BYTE* const dictBase = ms->window.dictBase; + const U32 dictLimit = ms->window.dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const prefixStart = base + dictLimit; const BYTE* match; @@ -292,7 +292,7 @@ static U32 ZSTD_insertBt1( U32* smallerPtr = bt + 2*(current&btMask); U32* largerPtr = smallerPtr + 1; U32 dummy32; /* to be nullified at the end */ - U32 const windowLow = ms->lowLimit; + U32 const windowLow = ms->window.lowLimit; U32 matchEndIdx = current+8+1; size_t bestLength = 8; U32 nbCompares = 1U << cParams->searchLog; @@ -383,7 +383,7 @@ void ZSTD_updateTree_internal( const BYTE* const ip, const BYTE* const iend, const U32 mls, const U32 extDict) { - const BYTE* const base = ms->base; + const BYTE* const base = ms->window.base; U32 const target = (U32)(ip - base); U32 idx = ms->nextToUpdate; DEBUGLOG(7, "ZSTD_updateTree_internal, from %u to %u (extDict:%u)", @@ -409,7 +409,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( ZSTD_match_t* matches, const U32 lengthToBeat, U32 const mls /* template */) { U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1); - const BYTE* const base = ms->base; + const BYTE* const base = ms->window.base; U32 const current = (U32)(ip-base); U32 const hashLog = cParams->hashLog; U32 const minMatch = (mls==3) ? 3 : 4; @@ -420,12 +420,12 @@ U32 ZSTD_insertBtAndGetAllMatches ( U32 const btLog = cParams->chainLog - 1; U32 const btMask= (1U << btLog) - 1; size_t commonLengthSmaller=0, commonLengthLarger=0; - const BYTE* const dictBase = ms->dictBase; - U32 const dictLimit = ms->dictLimit; + const BYTE* const dictBase = ms->window.dictBase; + U32 const dictLimit = ms->window.dictLimit; const BYTE* const dictEnd = dictBase + dictLimit; const BYTE* const prefixStart = base + dictLimit; U32 const btLow = btMask >= current ? 0 : current - btMask; - U32 const windowLow = ms->lowLimit; + U32 const windowLow = ms->window.lowLimit; U32* smallerPtr = bt + 2*(current&btMask); U32* largerPtr = bt + 2*(current&btMask) + 1; U32 matchEndIdx = current+8+1; /* farthest referenced position of any match => detects repetitive patterns */ @@ -566,7 +566,7 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches ( { U32 const matchLengthSearch = cParams->searchLength; DEBUGLOG(7, "ZSTD_BtGetAllMatches"); - if (ip < ms->base + ms->nextToUpdate) return 0; /* skipped area */ + if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */ ZSTD_updateTree_internal(ms, cParams, ip, iHighLimit, matchLengthSearch, extDict); switch(matchLengthSearch) { @@ -675,8 +675,8 @@ size_t ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,seqStore_t* seqStore const BYTE* anchor = istart; const BYTE* const iend = istart + srcSize; const BYTE* const ilimit = iend - 8; - const BYTE* const base = ms->base; - const BYTE* const prefixStart = base + ms->dictLimit; + const BYTE* const base = ms->window.base; + const BYTE* const prefixStart = base + ms->window.dictLimit; U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1); U32 const minMatch = (cParams->searchLength == 3) ? 3 : 4;