]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Split the window state into substructure
authorNick Terrell <terrelln@fb.com>
Sat, 24 Feb 2018 00:48:18 +0000 (16:48 -0800)
committerNick Terrell <terrelln@fb.com>
Mon, 26 Feb 2018 21:29:57 +0000 (13:29 -0800)
lib/compress/zstd_compress.c
lib/compress/zstd_compress_internal.h
lib/compress/zstd_double_fast.c
lib/compress/zstd_fast.c
lib/compress/zstd_lazy.c
lib/compress/zstd_ldm.c
lib/compress/zstd_opt.c

index 74a51c25e2248b806da8adab12dd3da168f8a2dc..46751537062650ec0cc270d25495773ce0f049ca 100644 (file)
@@ -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; i<ZSTD_REP_NUM; i++) cctx->blockState.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<<windowLog - blockSize
-         *    1<<windowLog <= newCurrent < 1<<chainLog + 1<<windowLog
-         *
-         *    current - newCurrent
-         *    > (3<<29 + 1<<windowLog - blockSize) - (1<<windowLog + 1<<chainLog)
-         *    > (3<<29 - blockSize) - (1<<chainLog)
-         *    > (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<<windowLog < 7<<29 < 1<<32.
-         */
-        if (ms->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 = &params->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;
 }
 
index 8a02f764e42cee70471f7d870c109a96bc921a19..98f866cdebb9a515b8002a1f65ba748fa449661e 100644 (file)
@@ -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<<windowLog
+     *    1<<windowLog <= newCurrent < 1<<chainLog + 1<<windowLog
+     *
+     *    current - newCurrent
+     *    > (3<<29 + 1<<windowLog) - (1<<windowLog + 1<<chainLog)
+     *    > (3<<29) - (1<<chainLog)
+     *    > (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<<chainLog + 1<<windowLog).
+     *    In 64-bit mode we are safe, because we have 64-bit ptrdiff_t.
+     *    In 32-bit mode we are safe, because (chainLog <= 29), so
+     *    ip+ZSTD_CHUNKSIZE_MAX - cctx->base < 1<<32.
+     * 3. (cctx->lowLimit + 1<<windowLog) < 1<<32:
+     *    windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.
+     */
+    U32 const cycleMask = (1U << cycleLog) - 1;
+    U32 const current = (U32)((BYTE const*)src - window->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
index 6415480e21d9d87d3a08ea8a02226e3cad64e882..86e6b39621b2a45cc425d03c5f9f1fcba655b2c7 100644 (file)
@@ -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;
index b60f21580d65ef6d384ccf739df91e189580d3d6..d2f50488e9c4c071edba93efea247a8e51c38323 100644 (file)
@@ -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;
index 0dab117a366b3bc61d33484d475c406ba02a25b6..9f158123f077cac1aa084ae4fd7d8184c81e9c90 100644 (file)
@@ -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,
index 2c304b38bdc0ef2bbb18c00ac0047f3952bf8508..a043556b0d333bfcf3e2633050f92a55d7b549b2 100644 (file)
@@ -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;
index 149e63687bd7bdecfd3798aac06afd720ea4380a..f63f0c585224d8111f5a7da032e2d39836972152 100644 (file)
@@ -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;