extzstd 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +28 -14
 - data/contrib/zstd/CHANGELOG +114 -56
 - data/contrib/zstd/CONTRIBUTING.md +14 -0
 - data/contrib/zstd/Makefile +37 -31
 - data/contrib/zstd/README.md +6 -0
 - data/contrib/zstd/appveyor.yml +4 -1
 - data/contrib/zstd/lib/Makefile +231 -134
 - data/contrib/zstd/lib/README.md +28 -0
 - data/contrib/zstd/lib/common/bitstream.h +24 -15
 - data/contrib/zstd/lib/common/compiler.h +116 -3
 - data/contrib/zstd/lib/common/cpu.h +0 -2
 - data/contrib/zstd/lib/common/debug.h +11 -18
 - data/contrib/zstd/lib/common/entropy_common.c +188 -42
 - data/contrib/zstd/lib/common/error_private.c +1 -0
 - data/contrib/zstd/lib/common/error_private.h +1 -1
 - data/contrib/zstd/lib/common/fse.h +38 -11
 - data/contrib/zstd/lib/common/fse_decompress.c +123 -16
 - data/contrib/zstd/lib/common/huf.h +26 -5
 - data/contrib/zstd/lib/common/mem.h +66 -93
 - data/contrib/zstd/lib/common/pool.c +22 -16
 - data/contrib/zstd/lib/common/pool.h +1 -1
 - data/contrib/zstd/lib/common/threading.c +6 -5
 - data/contrib/zstd/lib/common/xxhash.c +18 -56
 - data/contrib/zstd/lib/common/xxhash.h +1 -1
 - data/contrib/zstd/lib/common/zstd_common.c +9 -9
 - data/contrib/zstd/lib/common/zstd_deps.h +111 -0
 - data/contrib/zstd/lib/common/zstd_errors.h +1 -0
 - data/contrib/zstd/lib/common/zstd_internal.h +89 -58
 - data/contrib/zstd/lib/compress/fse_compress.c +30 -23
 - data/contrib/zstd/lib/compress/hist.c +26 -28
 - data/contrib/zstd/lib/compress/hist.h +1 -1
 - data/contrib/zstd/lib/compress/huf_compress.c +210 -95
 - data/contrib/zstd/lib/compress/zstd_compress.c +1339 -409
 - data/contrib/zstd/lib/compress/zstd_compress_internal.h +119 -41
 - data/contrib/zstd/lib/compress/zstd_compress_literals.c +4 -4
 - data/contrib/zstd/lib/compress/zstd_compress_sequences.c +17 -3
 - data/contrib/zstd/lib/compress/zstd_compress_superblock.c +23 -19
 - data/contrib/zstd/lib/compress/zstd_cwksp.h +60 -24
 - data/contrib/zstd/lib/compress/zstd_double_fast.c +22 -22
 - data/contrib/zstd/lib/compress/zstd_fast.c +19 -19
 - data/contrib/zstd/lib/compress/zstd_lazy.c +351 -77
 - data/contrib/zstd/lib/compress/zstd_lazy.h +20 -0
 - data/contrib/zstd/lib/compress/zstd_ldm.c +59 -18
 - data/contrib/zstd/lib/compress/zstd_ldm.h +6 -0
 - data/contrib/zstd/lib/compress/zstd_opt.c +190 -45
 - data/contrib/zstd/lib/compress/zstdmt_compress.c +74 -406
 - data/contrib/zstd/lib/compress/zstdmt_compress.h +26 -108
 - data/contrib/zstd/lib/decompress/huf_decompress.c +302 -200
 - data/contrib/zstd/lib/decompress/zstd_ddict.c +8 -8
 - data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
 - data/contrib/zstd/lib/decompress/zstd_decompress.c +125 -80
 - data/contrib/zstd/lib/decompress/zstd_decompress_block.c +145 -37
 - data/contrib/zstd/lib/decompress/zstd_decompress_block.h +5 -2
 - data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +11 -10
 - data/contrib/zstd/lib/dictBuilder/cover.c +29 -20
 - data/contrib/zstd/lib/dictBuilder/cover.h +1 -1
 - data/contrib/zstd/lib/dictBuilder/fastcover.c +20 -19
 - data/contrib/zstd/lib/dictBuilder/zdict.c +15 -16
 - data/contrib/zstd/lib/dictBuilder/zdict.h +1 -1
 - data/contrib/zstd/lib/legacy/zstd_v01.c +5 -1
 - data/contrib/zstd/lib/legacy/zstd_v02.c +5 -1
 - data/contrib/zstd/lib/legacy/zstd_v03.c +5 -1
 - data/contrib/zstd/lib/legacy/zstd_v04.c +6 -2
 - data/contrib/zstd/lib/legacy/zstd_v05.c +5 -1
 - data/contrib/zstd/lib/legacy/zstd_v06.c +5 -1
 - data/contrib/zstd/lib/legacy/zstd_v07.c +5 -1
 - data/contrib/zstd/lib/libzstd.pc.in +3 -3
 - data/contrib/zstd/lib/zstd.h +348 -47
 - data/ext/extzstd.c +6 -0
 - data/ext/extzstd.h +6 -0
 - data/gemstub.rb +3 -21
 - data/lib/extzstd.rb +0 -2
 - data/lib/extzstd/version.rb +6 -1
 - data/test/test_basic.rb +0 -5
 - metadata +5 -4
 
| 
         @@ -58,11 +58,11 @@ ZSTD_updateDUBT(ZSTD_matchState_t* ms, 
     | 
|
| 
       58 
58 
     | 
    
         | 
| 
       59 
59 
     | 
    
         
             
            /** ZSTD_insertDUBT1() :
         
     | 
| 
       60 
60 
     | 
    
         
             
             *  sort one already inserted but unsorted position
         
     | 
| 
       61 
     | 
    
         
            -
             *  assumption :  
     | 
| 
      
 61 
     | 
    
         
            +
             *  assumption : curr >= btlow == (curr - btmask)
         
     | 
| 
       62 
62 
     | 
    
         
             
             *  doesn't fail */
         
     | 
| 
       63 
63 
     | 
    
         
             
            static void
         
     | 
| 
       64 
64 
     | 
    
         
             
            ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
         
     | 
| 
       65 
     | 
    
         
            -
                             U32  
     | 
| 
      
 65 
     | 
    
         
            +
                             U32 curr, const BYTE* inputEnd,
         
     | 
| 
       66 
66 
     | 
    
         
             
                             U32 nbCompares, U32 btLow,
         
     | 
| 
       67 
67 
     | 
    
         
             
                             const ZSTD_dictMode_e dictMode)
         
     | 
| 
       68 
68 
     | 
    
         
             
            {
         
     | 
| 
         @@ -74,41 +74,41 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms, 
     | 
|
| 
       74 
74 
     | 
    
         
             
                const BYTE* const base = ms->window.base;
         
     | 
| 
       75 
75 
     | 
    
         
             
                const BYTE* const dictBase = ms->window.dictBase;
         
     | 
| 
       76 
76 
     | 
    
         
             
                const U32 dictLimit = ms->window.dictLimit;
         
     | 
| 
       77 
     | 
    
         
            -
                const BYTE* const ip = ( 
     | 
| 
       78 
     | 
    
         
            -
                const BYTE* const iend = ( 
     | 
| 
      
 77 
     | 
    
         
            +
                const BYTE* const ip = (curr>=dictLimit) ? base + curr : dictBase + curr;
         
     | 
| 
      
 78 
     | 
    
         
            +
                const BYTE* const iend = (curr>=dictLimit) ? inputEnd : dictBase + dictLimit;
         
     | 
| 
       79 
79 
     | 
    
         
             
                const BYTE* const dictEnd = dictBase + dictLimit;
         
     | 
| 
       80 
80 
     | 
    
         
             
                const BYTE* const prefixStart = base + dictLimit;
         
     | 
| 
       81 
81 
     | 
    
         
             
                const BYTE* match;
         
     | 
| 
       82 
     | 
    
         
            -
                U32* smallerPtr = bt + 2*( 
     | 
| 
      
 82 
     | 
    
         
            +
                U32* smallerPtr = bt + 2*(curr&btMask);
         
     | 
| 
       83 
83 
     | 
    
         
             
                U32* largerPtr  = smallerPtr + 1;
         
     | 
| 
       84 
84 
     | 
    
         
             
                U32 matchIndex = *smallerPtr;   /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */
         
     | 
| 
       85 
85 
     | 
    
         
             
                U32 dummy32;   /* to be nullified at the end */
         
     | 
| 
       86 
86 
     | 
    
         
             
                U32 const windowValid = ms->window.lowLimit;
         
     | 
| 
       87 
87 
     | 
    
         
             
                U32 const maxDistance = 1U << cParams->windowLog;
         
     | 
| 
       88 
     | 
    
         
            -
                U32 const windowLow = ( 
     | 
| 
      
 88 
     | 
    
         
            +
                U32 const windowLow = (curr - windowValid > maxDistance) ? curr - maxDistance : windowValid;
         
     | 
| 
       89 
89 
     | 
    
         | 
| 
       90 
90 
     | 
    
         | 
| 
       91 
91 
     | 
    
         
             
                DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)",
         
     | 
| 
       92 
     | 
    
         
            -
                             
     | 
| 
       93 
     | 
    
         
            -
                assert( 
     | 
| 
      
 92 
     | 
    
         
            +
                            curr, dictLimit, windowLow);
         
     | 
| 
      
 93 
     | 
    
         
            +
                assert(curr >= btLow);
         
     | 
| 
       94 
94 
     | 
    
         
             
                assert(ip < iend);   /* condition for ZSTD_count */
         
     | 
| 
       95 
95 
     | 
    
         | 
| 
       96 
96 
     | 
    
         
             
                while (nbCompares-- && (matchIndex > windowLow)) {
         
     | 
| 
       97 
97 
     | 
    
         
             
                    U32* const nextPtr = bt + 2*(matchIndex & btMask);
         
     | 
| 
       98 
98 
     | 
    
         
             
                    size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
         
     | 
| 
       99 
     | 
    
         
            -
                    assert(matchIndex <  
     | 
| 
      
 99 
     | 
    
         
            +
                    assert(matchIndex < curr);
         
     | 
| 
       100 
100 
     | 
    
         
             
                    /* note : all candidates are now supposed sorted,
         
     | 
| 
       101 
101 
     | 
    
         
             
                     * but it's still possible to have nextPtr[1] == ZSTD_DUBT_UNSORTED_MARK
         
     | 
| 
       102 
102 
     | 
    
         
             
                     * when a real index has the same value as ZSTD_DUBT_UNSORTED_MARK */
         
     | 
| 
       103 
103 
     | 
    
         | 
| 
       104 
104 
     | 
    
         
             
                    if ( (dictMode != ZSTD_extDict)
         
     | 
| 
       105 
105 
     | 
    
         
             
                      || (matchIndex+matchLength >= dictLimit)  /* both in current segment*/
         
     | 
| 
       106 
     | 
    
         
            -
                      || ( 
     | 
| 
      
 106 
     | 
    
         
            +
                      || (curr < dictLimit) /* both in extDict */) {
         
     | 
| 
       107 
107 
     | 
    
         
             
                        const BYTE* const mBase = ( (dictMode != ZSTD_extDict)
         
     | 
| 
       108 
108 
     | 
    
         
             
                                                 || (matchIndex+matchLength >= dictLimit)) ?
         
     | 
| 
       109 
109 
     | 
    
         
             
                                                    base : dictBase;
         
     | 
| 
       110 
110 
     | 
    
         
             
                        assert( (matchIndex+matchLength >= dictLimit)   /* might be wrong if extDict is incorrectly set to 0 */
         
     | 
| 
       111 
     | 
    
         
            -
                             || ( 
     | 
| 
      
 111 
     | 
    
         
            +
                             || (curr < dictLimit) );
         
     | 
| 
       112 
112 
     | 
    
         
             
                        match = mBase + matchIndex;
         
     | 
| 
       113 
113 
     | 
    
         
             
                        matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
         
     | 
| 
       114 
114 
     | 
    
         
             
                    } else {
         
     | 
| 
         @@ -119,7 +119,7 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms, 
     | 
|
| 
       119 
119 
     | 
    
         
             
                    }
         
     | 
| 
       120 
120 
     | 
    
         | 
| 
       121 
121 
     | 
    
         
             
                    DEBUGLOG(8, "ZSTD_insertDUBT1: comparing %u with %u : found %u common bytes ",
         
     | 
| 
       122 
     | 
    
         
            -
                                 
     | 
| 
      
 122 
     | 
    
         
            +
                                curr, matchIndex, (U32)matchLength);
         
     | 
| 
       123 
123 
     | 
    
         | 
| 
       124 
124 
     | 
    
         
             
                    if (ip+matchLength == iend) {   /* equal : no way to know if inf or sup */
         
     | 
| 
       125 
125 
     | 
    
         
             
                        break;   /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */
         
     | 
| 
         @@ -168,7 +168,7 @@ ZSTD_DUBT_findBetterDictMatch ( 
     | 
|
| 
       168 
168 
     | 
    
         | 
| 
       169 
169 
     | 
    
         
             
                const BYTE* const base = ms->window.base;
         
     | 
| 
       170 
170 
     | 
    
         
             
                const BYTE* const prefixStart = base + ms->window.dictLimit;
         
     | 
| 
       171 
     | 
    
         
            -
                U32         const  
     | 
| 
      
 171 
     | 
    
         
            +
                U32         const curr = (U32)(ip-base);
         
     | 
| 
       172 
172 
     | 
    
         
             
                const BYTE* const dictBase = dms->window.base;
         
     | 
| 
       173 
173 
     | 
    
         
             
                const BYTE* const dictEnd = dms->window.nextSrc;
         
     | 
| 
       174 
174 
     | 
    
         
             
                U32         const dictHighLimit = (U32)(dms->window.nextSrc - dms->window.base);
         
     | 
| 
         @@ -195,10 +195,10 @@ ZSTD_DUBT_findBetterDictMatch ( 
     | 
|
| 
       195 
195 
     | 
    
         | 
| 
       196 
196 
     | 
    
         
             
                    if (matchLength > bestLength) {
         
     | 
| 
       197 
197 
     | 
    
         
             
                        U32 matchIndex = dictMatchIndex + dictIndexDelta;
         
     | 
| 
       198 
     | 
    
         
            -
                        if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32( 
     | 
| 
      
 198 
     | 
    
         
            +
                        if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) {
         
     | 
| 
       199 
199 
     | 
    
         
             
                            DEBUGLOG(9, "ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)",
         
     | 
| 
       200 
     | 
    
         
            -
                                 
     | 
| 
       201 
     | 
    
         
            -
                            bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE +  
     | 
| 
      
 200 
     | 
    
         
            +
                                curr, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, ZSTD_REP_MOVE + curr - matchIndex, dictMatchIndex, matchIndex);
         
     | 
| 
      
 201 
     | 
    
         
            +
                            bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
         
     | 
| 
       202 
202 
     | 
    
         
             
                        }
         
     | 
| 
       203 
203 
     | 
    
         
             
                        if (ip+matchLength == iend) {   /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */
         
     | 
| 
       204 
204 
     | 
    
         
             
                            break;   /* drop, to guarantee consistency (miss a little bit of compression) */
         
     | 
| 
         @@ -218,9 +218,9 @@ ZSTD_DUBT_findBetterDictMatch ( 
     | 
|
| 
       218 
218 
     | 
    
         
             
                }
         
     | 
| 
       219 
219 
     | 
    
         | 
| 
       220 
220 
     | 
    
         
             
                if (bestLength >= MINMATCH) {
         
     | 
| 
       221 
     | 
    
         
            -
                    U32 const mIndex =  
     | 
| 
      
 221 
     | 
    
         
            +
                    U32 const mIndex = curr - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
         
     | 
| 
       222 
222 
     | 
    
         
             
                    DEBUGLOG(8, "ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
         
     | 
| 
       223 
     | 
    
         
            -
                                 
     | 
| 
      
 223 
     | 
    
         
            +
                                curr, (U32)bestLength, (U32)*offsetPtr, mIndex);
         
     | 
| 
       224 
224 
     | 
    
         
             
                }
         
     | 
| 
       225 
225 
     | 
    
         
             
                return bestLength;
         
     | 
| 
       226 
226 
     | 
    
         | 
| 
         @@ -241,13 +241,13 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, 
     | 
|
| 
       241 
241 
     | 
    
         
             
                U32          matchIndex  = hashTable[h];
         
     | 
| 
       242 
242 
     | 
    
         | 
| 
       243 
243 
     | 
    
         
             
                const BYTE* const base = ms->window.base;
         
     | 
| 
       244 
     | 
    
         
            -
                U32    const  
     | 
| 
       245 
     | 
    
         
            -
                U32    const windowLow = ZSTD_getLowestMatchIndex(ms,  
     | 
| 
      
 244 
     | 
    
         
            +
                U32    const curr = (U32)(ip-base);
         
     | 
| 
      
 245 
     | 
    
         
            +
                U32    const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog);
         
     | 
| 
       246 
246 
     | 
    
         | 
| 
       247 
247 
     | 
    
         
             
                U32*   const bt = ms->chainTable;
         
     | 
| 
       248 
248 
     | 
    
         
             
                U32    const btLog  = cParams->chainLog - 1;
         
     | 
| 
       249 
249 
     | 
    
         
             
                U32    const btMask = (1 << btLog) - 1;
         
     | 
| 
       250 
     | 
    
         
            -
                U32    const btLow = (btMask >=  
     | 
| 
      
 250 
     | 
    
         
            +
                U32    const btLow = (btMask >= curr) ? 0 : curr - btMask;
         
     | 
| 
       251 
251 
     | 
    
         
             
                U32    const unsortLimit = MAX(btLow, windowLow);
         
     | 
| 
       252 
252 
     | 
    
         | 
| 
       253 
253 
     | 
    
         
             
                U32*         nextCandidate = bt + 2*(matchIndex&btMask);
         
     | 
| 
         @@ -256,8 +256,9 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, 
     | 
|
| 
       256 
256 
     | 
    
         
             
                U32          nbCandidates = nbCompares;
         
     | 
| 
       257 
257 
     | 
    
         
             
                U32          previousCandidate = 0;
         
     | 
| 
       258 
258 
     | 
    
         | 
| 
       259 
     | 
    
         
            -
                DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ",  
     | 
| 
      
 259 
     | 
    
         
            +
                DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", curr);
         
     | 
| 
       260 
260 
     | 
    
         
             
                assert(ip <= iend-8);   /* required for h calculation */
         
     | 
| 
      
 261 
     | 
    
         
            +
                assert(dictMode != ZSTD_dedicatedDictSearch);
         
     | 
| 
       261 
262 
     | 
    
         | 
| 
       262 
263 
     | 
    
         
             
                /* reach end of unsorted candidates list */
         
     | 
| 
       263 
264 
     | 
    
         
             
                while ( (matchIndex > unsortLimit)
         
     | 
| 
         @@ -299,14 +300,14 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, 
     | 
|
| 
       299 
300 
     | 
    
         
             
                    const U32 dictLimit = ms->window.dictLimit;
         
     | 
| 
       300 
301 
     | 
    
         
             
                    const BYTE* const dictEnd = dictBase + dictLimit;
         
     | 
| 
       301 
302 
     | 
    
         
             
                    const BYTE* const prefixStart = base + dictLimit;
         
     | 
| 
       302 
     | 
    
         
            -
                    U32* smallerPtr = bt + 2*( 
     | 
| 
       303 
     | 
    
         
            -
                    U32* largerPtr  = bt + 2*( 
     | 
| 
       304 
     | 
    
         
            -
                    U32 matchEndIdx =  
     | 
| 
      
 303 
     | 
    
         
            +
                    U32* smallerPtr = bt + 2*(curr&btMask);
         
     | 
| 
      
 304 
     | 
    
         
            +
                    U32* largerPtr  = bt + 2*(curr&btMask) + 1;
         
     | 
| 
      
 305 
     | 
    
         
            +
                    U32 matchEndIdx = curr + 8 + 1;
         
     | 
| 
       305 
306 
     | 
    
         
             
                    U32 dummy32;   /* to be nullified at the end */
         
     | 
| 
       306 
307 
     | 
    
         
             
                    size_t bestLength = 0;
         
     | 
| 
       307 
308 
     | 
    
         | 
| 
       308 
309 
     | 
    
         
             
                    matchIndex  = hashTable[h];
         
     | 
| 
       309 
     | 
    
         
            -
                    hashTable[h] =  
     | 
| 
      
 310 
     | 
    
         
            +
                    hashTable[h] = curr;   /* Update Hash Table */
         
     | 
| 
       310 
311 
     | 
    
         | 
| 
       311 
312 
     | 
    
         
             
                    while (nbCompares-- && (matchIndex > windowLow)) {
         
     | 
| 
       312 
313 
     | 
    
         
             
                        U32* const nextPtr = bt + 2*(matchIndex & btMask);
         
     | 
| 
         @@ -326,8 +327,8 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, 
     | 
|
| 
       326 
327 
     | 
    
         
             
                        if (matchLength > bestLength) {
         
     | 
| 
       327 
328 
     | 
    
         
             
                            if (matchLength > matchEndIdx - matchIndex)
         
     | 
| 
       328 
329 
     | 
    
         
             
                                matchEndIdx = matchIndex + (U32)matchLength;
         
     | 
| 
       329 
     | 
    
         
            -
                            if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32( 
     | 
| 
       330 
     | 
    
         
            -
                                bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE +  
     | 
| 
      
 330 
     | 
    
         
            +
                            if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
         
     | 
| 
      
 331 
     | 
    
         
            +
                                bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
         
     | 
| 
       331 
332 
     | 
    
         
             
                            if (ip+matchLength == iend) {   /* equal : no way to know if inf or sup */
         
     | 
| 
       332 
333 
     | 
    
         
             
                                if (dictMode == ZSTD_dictMatchState) {
         
     | 
| 
       333 
334 
     | 
    
         
             
                                    nbCompares = 0; /* in addition to avoiding checking any
         
     | 
| 
         @@ -363,12 +364,12 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms, 
     | 
|
| 
       363 
364 
     | 
    
         
             
                                mls, dictMode);
         
     | 
| 
       364 
365 
     | 
    
         
             
                    }
         
     | 
| 
       365 
366 
     | 
    
         | 
| 
       366 
     | 
    
         
            -
                    assert(matchEndIdx >  
     | 
| 
      
 367 
     | 
    
         
            +
                    assert(matchEndIdx > curr+8); /* ensure nextToUpdate is increased */
         
     | 
| 
       367 
368 
     | 
    
         
             
                    ms->nextToUpdate = matchEndIdx - 8;   /* skip repetitive patterns */
         
     | 
| 
       368 
369 
     | 
    
         
             
                    if (bestLength >= MINMATCH) {
         
     | 
| 
       369 
     | 
    
         
            -
                        U32 const mIndex =  
     | 
| 
      
 370 
     | 
    
         
            +
                        U32 const mIndex = curr - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
         
     | 
| 
       370 
371 
     | 
    
         
             
                        DEBUGLOG(8, "ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
         
     | 
| 
       371 
     | 
    
         
            -
                                     
     | 
| 
      
 372 
     | 
    
         
            +
                                    curr, (U32)bestLength, (U32)*offsetPtr, mIndex);
         
     | 
| 
       372 
373 
     | 
    
         
             
                    }
         
     | 
| 
       373 
374 
     | 
    
         
             
                    return bestLength;
         
     | 
| 
       374 
375 
     | 
    
         
             
                }
         
     | 
| 
         @@ -446,7 +447,7 @@ static size_t ZSTD_BtFindBestMatch_extDict_selectMLS ( 
     | 
|
| 
       446 
447 
     | 
    
         | 
| 
       447 
448 
     | 
    
         
             
            /* Update chains up to ip (excluded)
         
     | 
| 
       448 
449 
     | 
    
         
             
               Assumption : always within prefix (i.e. not within extDict) */
         
     | 
| 
       449 
     | 
    
         
            -
             
     | 
| 
      
 450 
     | 
    
         
            +
            FORCE_INLINE_TEMPLATE U32 ZSTD_insertAndFindFirstIndex_internal(
         
     | 
| 
       450 
451 
     | 
    
         
             
                                    ZSTD_matchState_t* ms,
         
     | 
| 
       451 
452 
     | 
    
         
             
                                    const ZSTD_compressionParameters* const cParams,
         
     | 
| 
       452 
453 
     | 
    
         
             
                                    const BYTE* ip, U32 const mls)
         
     | 
| 
         @@ -475,6 +476,121 @@ U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) { 
     | 
|
| 
       475 
476 
     | 
    
         
             
                return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch);
         
     | 
| 
       476 
477 
     | 
    
         
             
            }
         
     | 
| 
       477 
478 
     | 
    
         | 
| 
      
 479 
     | 
    
         
            +
            void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip)
         
     | 
| 
      
 480 
     | 
    
         
            +
            {
         
     | 
| 
      
 481 
     | 
    
         
            +
                const BYTE* const base = ms->window.base;
         
     | 
| 
      
 482 
     | 
    
         
            +
                U32 const target = (U32)(ip - base);
         
     | 
| 
      
 483 
     | 
    
         
            +
                U32* const hashTable = ms->hashTable;
         
     | 
| 
      
 484 
     | 
    
         
            +
                U32* const chainTable = ms->chainTable;
         
     | 
| 
      
 485 
     | 
    
         
            +
                U32 const chainSize = 1 << ms->cParams.chainLog;
         
     | 
| 
      
 486 
     | 
    
         
            +
                U32 idx = ms->nextToUpdate;
         
     | 
| 
      
 487 
     | 
    
         
            +
                U32 const minChain = chainSize < target ? target - chainSize : idx;
         
     | 
| 
      
 488 
     | 
    
         
            +
                U32 const bucketSize = 1 << ZSTD_LAZY_DDSS_BUCKET_LOG;
         
     | 
| 
      
 489 
     | 
    
         
            +
                U32 const cacheSize = bucketSize - 1;
         
     | 
| 
      
 490 
     | 
    
         
            +
                U32 const chainAttempts = (1 << ms->cParams.searchLog) - cacheSize;
         
     | 
| 
      
 491 
     | 
    
         
            +
                U32 const chainLimit = chainAttempts > 255 ? 255 : chainAttempts;
         
     | 
| 
      
 492 
     | 
    
         
            +
             
     | 
| 
      
 493 
     | 
    
         
            +
                /* We know the hashtable is oversized by a factor of `bucketSize`.
         
     | 
| 
      
 494 
     | 
    
         
            +
                 * We are going to temporarily pretend `bucketSize == 1`, keeping only a
         
     | 
| 
      
 495 
     | 
    
         
            +
                 * single entry. We will use the rest of the space to construct a temporary
         
     | 
| 
      
 496 
     | 
    
         
            +
                 * chaintable.
         
     | 
| 
      
 497 
     | 
    
         
            +
                 */
         
     | 
| 
      
 498 
     | 
    
         
            +
                U32 const hashLog = ms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG;
         
     | 
| 
      
 499 
     | 
    
         
            +
                U32* const tmpHashTable = hashTable;
         
     | 
| 
      
 500 
     | 
    
         
            +
                U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog);
         
     | 
| 
      
 501 
     | 
    
         
            +
                U32 const tmpChainSize = ((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog;
         
     | 
| 
      
 502 
     | 
    
         
            +
                U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx;
         
     | 
| 
      
 503 
     | 
    
         
            +
             
     | 
| 
      
 504 
     | 
    
         
            +
                U32 hashIdx;
         
     | 
| 
      
 505 
     | 
    
         
            +
             
     | 
| 
      
 506 
     | 
    
         
            +
                assert(ms->cParams.chainLog <= 24);
         
     | 
| 
      
 507 
     | 
    
         
            +
                assert(ms->cParams.hashLog >= ms->cParams.chainLog);
         
     | 
| 
      
 508 
     | 
    
         
            +
                assert(idx != 0);
         
     | 
| 
      
 509 
     | 
    
         
            +
                assert(tmpMinChain <= minChain);
         
     | 
| 
      
 510 
     | 
    
         
            +
             
     | 
| 
      
 511 
     | 
    
         
            +
                /* fill conventional hash table and conventional chain table */
         
     | 
| 
      
 512 
     | 
    
         
            +
                for ( ; idx < target; idx++) {
         
     | 
| 
      
 513 
     | 
    
         
            +
                    U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch);
         
     | 
| 
      
 514 
     | 
    
         
            +
                    if (idx >= tmpMinChain) {
         
     | 
| 
      
 515 
     | 
    
         
            +
                        tmpChainTable[idx - tmpMinChain] = hashTable[h];
         
     | 
| 
      
 516 
     | 
    
         
            +
                    }
         
     | 
| 
      
 517 
     | 
    
         
            +
                    tmpHashTable[h] = idx;
         
     | 
| 
      
 518 
     | 
    
         
            +
                }
         
     | 
| 
      
 519 
     | 
    
         
            +
             
     | 
| 
      
 520 
     | 
    
         
            +
                /* sort chains into ddss chain table */
         
     | 
| 
      
 521 
     | 
    
         
            +
                {
         
     | 
| 
      
 522 
     | 
    
         
            +
                    U32 chainPos = 0;
         
     | 
| 
      
 523 
     | 
    
         
            +
                    for (hashIdx = 0; hashIdx < (1U << hashLog); hashIdx++) {
         
     | 
| 
      
 524 
     | 
    
         
            +
                        U32 count;
         
     | 
| 
      
 525 
     | 
    
         
            +
                        U32 countBeyondMinChain = 0;
         
     | 
| 
      
 526 
     | 
    
         
            +
                        U32 i = tmpHashTable[hashIdx];
         
     | 
| 
      
 527 
     | 
    
         
            +
                        for (count = 0; i >= tmpMinChain && count < cacheSize; count++) {
         
     | 
| 
      
 528 
     | 
    
         
            +
                            /* skip through the chain to the first position that won't be
         
     | 
| 
      
 529 
     | 
    
         
            +
                             * in the hash cache bucket */
         
     | 
| 
      
 530 
     | 
    
         
            +
                            if (i < minChain) {
         
     | 
| 
      
 531 
     | 
    
         
            +
                                countBeyondMinChain++;
         
     | 
| 
      
 532 
     | 
    
         
            +
                            }
         
     | 
| 
      
 533 
     | 
    
         
            +
                            i = tmpChainTable[i - tmpMinChain];
         
     | 
| 
      
 534 
     | 
    
         
            +
                        }
         
     | 
| 
      
 535 
     | 
    
         
            +
                        if (count == cacheSize) {
         
     | 
| 
      
 536 
     | 
    
         
            +
                            for (count = 0; count < chainLimit;) {
         
     | 
| 
      
 537 
     | 
    
         
            +
                                if (i < minChain) {
         
     | 
| 
      
 538 
     | 
    
         
            +
                                    if (!i || countBeyondMinChain++ > cacheSize) {
         
     | 
| 
      
 539 
     | 
    
         
            +
                                        /* only allow pulling `cacheSize` number of entries
         
     | 
| 
      
 540 
     | 
    
         
            +
                                         * into the cache or chainTable beyond `minChain`,
         
     | 
| 
      
 541 
     | 
    
         
            +
                                         * to replace the entries pulled out of the
         
     | 
| 
      
 542 
     | 
    
         
            +
                                         * chainTable into the cache. This lets us reach
         
     | 
| 
      
 543 
     | 
    
         
            +
                                         * back further without increasing the total number
         
     | 
| 
      
 544 
     | 
    
         
            +
                                         * of entries in the chainTable, guaranteeing the
         
     | 
| 
      
 545 
     | 
    
         
            +
                                         * DDSS chain table will fit into the space
         
     | 
| 
      
 546 
     | 
    
         
            +
                                         * allocated for the regular one. */
         
     | 
| 
      
 547 
     | 
    
         
            +
                                        break;
         
     | 
| 
      
 548 
     | 
    
         
            +
                                    }
         
     | 
| 
      
 549 
     | 
    
         
            +
                                }
         
     | 
| 
      
 550 
     | 
    
         
            +
                                chainTable[chainPos++] = i;
         
     | 
| 
      
 551 
     | 
    
         
            +
                                count++;
         
     | 
| 
      
 552 
     | 
    
         
            +
                                if (i < tmpMinChain) {
         
     | 
| 
      
 553 
     | 
    
         
            +
                                    break;
         
     | 
| 
      
 554 
     | 
    
         
            +
                                }
         
     | 
| 
      
 555 
     | 
    
         
            +
                                i = tmpChainTable[i - tmpMinChain];
         
     | 
| 
      
 556 
     | 
    
         
            +
                            }
         
     | 
| 
      
 557 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 558 
     | 
    
         
            +
                            count = 0;
         
     | 
| 
      
 559 
     | 
    
         
            +
                        }
         
     | 
| 
      
 560 
     | 
    
         
            +
                        if (count) {
         
     | 
| 
      
 561 
     | 
    
         
            +
                            tmpHashTable[hashIdx] = ((chainPos - count) << 8) + count;
         
     | 
| 
      
 562 
     | 
    
         
            +
                        } else {
         
     | 
| 
      
 563 
     | 
    
         
            +
                            tmpHashTable[hashIdx] = 0;
         
     | 
| 
      
 564 
     | 
    
         
            +
                        }
         
     | 
| 
      
 565 
     | 
    
         
            +
                    }
         
     | 
| 
      
 566 
     | 
    
         
            +
                    assert(chainPos <= chainSize); /* I believe this is guaranteed... */
         
     | 
| 
      
 567 
     | 
    
         
            +
                }
         
     | 
| 
      
 568 
     | 
    
         
            +
             
     | 
| 
      
 569 
     | 
    
         
            +
                /* move chain pointers into the last entry of each hash bucket */
         
     | 
| 
      
 570 
     | 
    
         
            +
                for (hashIdx = (1 << hashLog); hashIdx; ) {
         
     | 
| 
      
 571 
     | 
    
         
            +
                    U32 const bucketIdx = --hashIdx << ZSTD_LAZY_DDSS_BUCKET_LOG;
         
     | 
| 
      
 572 
     | 
    
         
            +
                    U32 const chainPackedPointer = tmpHashTable[hashIdx];
         
     | 
| 
      
 573 
     | 
    
         
            +
                    U32 i;
         
     | 
| 
      
 574 
     | 
    
         
            +
                    for (i = 0; i < cacheSize; i++) {
         
     | 
| 
      
 575 
     | 
    
         
            +
                        hashTable[bucketIdx + i] = 0;
         
     | 
| 
      
 576 
     | 
    
         
            +
                    }
         
     | 
| 
      
 577 
     | 
    
         
            +
                    hashTable[bucketIdx + bucketSize - 1] = chainPackedPointer;
         
     | 
| 
      
 578 
     | 
    
         
            +
                }
         
     | 
| 
      
 579 
     | 
    
         
            +
             
     | 
| 
      
 580 
     | 
    
         
            +
                /* fill the buckets of the hash table */
         
     | 
| 
      
 581 
     | 
    
         
            +
                for (idx = ms->nextToUpdate; idx < target; idx++) {
         
     | 
| 
      
 582 
     | 
    
         
            +
                    U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch)
         
     | 
| 
      
 583 
     | 
    
         
            +
                               << ZSTD_LAZY_DDSS_BUCKET_LOG;
         
     | 
| 
      
 584 
     | 
    
         
            +
                    U32 i;
         
     | 
| 
      
 585 
     | 
    
         
            +
                    /* Shift hash cache down 1. */
         
     | 
| 
      
 586 
     | 
    
         
            +
                    for (i = cacheSize - 1; i; i--)
         
     | 
| 
      
 587 
     | 
    
         
            +
                        hashTable[h + i] = hashTable[h + i - 1];
         
     | 
| 
      
 588 
     | 
    
         
            +
                    hashTable[h] = idx;
         
     | 
| 
      
 589 
     | 
    
         
            +
                }
         
     | 
| 
      
 590 
     | 
    
         
            +
             
     | 
| 
      
 591 
     | 
    
         
            +
                ms->nextToUpdate = target;
         
     | 
| 
      
 592 
     | 
    
         
            +
            }
         
     | 
| 
      
 593 
     | 
    
         
            +
             
     | 
| 
       478 
594 
     | 
    
         | 
| 
       479 
595 
     | 
    
         
             
            /* inlining is important to hardwire a hot branch (template emulation) */
         
     | 
| 
       480 
596 
     | 
    
         
             
            FORCE_INLINE_TEMPLATE
         
     | 
| 
         @@ -493,20 +609,33 @@ size_t ZSTD_HcFindBestMatch_generic ( 
     | 
|
| 
       493 
609 
     | 
    
         
             
                const U32 dictLimit = ms->window.dictLimit;
         
     | 
| 
       494 
610 
     | 
    
         
             
                const BYTE* const prefixStart = base + dictLimit;
         
     | 
| 
       495 
611 
     | 
    
         
             
                const BYTE* const dictEnd = dictBase + dictLimit;
         
     | 
| 
       496 
     | 
    
         
            -
                const U32  
     | 
| 
      
 612 
     | 
    
         
            +
                const U32 curr = (U32)(ip-base);
         
     | 
| 
       497 
613 
     | 
    
         
             
                const U32 maxDistance = 1U << cParams->windowLog;
         
     | 
| 
       498 
614 
     | 
    
         
             
                const U32 lowestValid = ms->window.lowLimit;
         
     | 
| 
       499 
     | 
    
         
            -
                const U32 withinMaxDistance = ( 
     | 
| 
      
 615 
     | 
    
         
            +
                const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
         
     | 
| 
       500 
616 
     | 
    
         
             
                const U32 isDictionary = (ms->loadedDictEnd != 0);
         
     | 
| 
       501 
617 
     | 
    
         
             
                const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance;
         
     | 
| 
       502 
     | 
    
         
            -
                const U32 minChain =  
     | 
| 
      
 618 
     | 
    
         
            +
                const U32 minChain = curr > chainSize ? curr - chainSize : 0;
         
     | 
| 
       503 
619 
     | 
    
         
             
                U32 nbAttempts = 1U << cParams->searchLog;
         
     | 
| 
       504 
620 
     | 
    
         
             
                size_t ml=4-1;
         
     | 
| 
       505 
621 
     | 
    
         | 
| 
      
 622 
     | 
    
         
            +
                const ZSTD_matchState_t* const dms = ms->dictMatchState;
         
     | 
| 
      
 623 
     | 
    
         
            +
                const U32 ddsHashLog = dictMode == ZSTD_dedicatedDictSearch
         
     | 
| 
      
 624 
     | 
    
         
            +
                                     ? dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG : 0;
         
     | 
| 
      
 625 
     | 
    
         
            +
                const size_t ddsIdx = dictMode == ZSTD_dedicatedDictSearch
         
     | 
| 
      
 626 
     | 
    
         
            +
                                    ? ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG : 0;
         
     | 
| 
      
 627 
     | 
    
         
            +
             
     | 
| 
      
 628 
     | 
    
         
            +
                U32 matchIndex;
         
     | 
| 
      
 629 
     | 
    
         
            +
             
     | 
| 
      
 630 
     | 
    
         
            +
                if (dictMode == ZSTD_dedicatedDictSearch) {
         
     | 
| 
      
 631 
     | 
    
         
            +
                    const U32* entry = &dms->hashTable[ddsIdx];
         
     | 
| 
      
 632 
     | 
    
         
            +
                    PREFETCH_L1(entry);
         
     | 
| 
      
 633 
     | 
    
         
            +
                }
         
     | 
| 
      
 634 
     | 
    
         
            +
             
     | 
| 
       506 
635 
     | 
    
         
             
                /* HC4 match finder */
         
     | 
| 
       507 
     | 
    
         
            -
                 
     | 
| 
      
 636 
     | 
    
         
            +
                matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls);
         
     | 
| 
       508 
637 
     | 
    
         | 
| 
       509 
     | 
    
         
            -
                for ( ; (matchIndex 
     | 
| 
      
 638 
     | 
    
         
            +
                for ( ; (matchIndex>=lowLimit) & (nbAttempts>0) ; nbAttempts--) {
         
     | 
| 
       510 
639 
     | 
    
         
             
                    size_t currentMl=0;
         
     | 
| 
       511 
640 
     | 
    
         
             
                    if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {
         
     | 
| 
       512 
641 
     | 
    
         
             
                        const BYTE* const match = base + matchIndex;
         
     | 
| 
         @@ -523,7 +652,7 @@ size_t ZSTD_HcFindBestMatch_generic ( 
     | 
|
| 
       523 
652 
     | 
    
         
             
                    /* save best solution */
         
     | 
| 
       524 
653 
     | 
    
         
             
                    if (currentMl > ml) {
         
     | 
| 
       525 
654 
     | 
    
         
             
                        ml = currentMl;
         
     | 
| 
       526 
     | 
    
         
            -
                        *offsetPtr =  
     | 
| 
      
 655 
     | 
    
         
            +
                        *offsetPtr = curr - matchIndex + ZSTD_REP_MOVE;
         
     | 
| 
       527 
656 
     | 
    
         
             
                        if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
         
     | 
| 
       528 
657 
     | 
    
         
             
                    }
         
     | 
| 
       529 
658 
     | 
    
         | 
| 
         @@ -531,8 +660,92 @@ size_t ZSTD_HcFindBestMatch_generic ( 
     | 
|
| 
       531 
660 
     | 
    
         
             
                    matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
         
     | 
| 
       532 
661 
     | 
    
         
             
                }
         
     | 
| 
       533 
662 
     | 
    
         | 
| 
       534 
     | 
    
         
            -
                if (dictMode ==  
     | 
| 
       535 
     | 
    
         
            -
                    const  
     | 
| 
      
 663 
     | 
    
         
            +
                if (dictMode == ZSTD_dedicatedDictSearch) {
         
     | 
| 
      
 664 
     | 
    
         
            +
                    const U32 ddsLowestIndex  = dms->window.dictLimit;
         
     | 
| 
      
 665 
     | 
    
         
            +
                    const BYTE* const ddsBase = dms->window.base;
         
     | 
| 
      
 666 
     | 
    
         
            +
                    const BYTE* const ddsEnd  = dms->window.nextSrc;
         
     | 
| 
      
 667 
     | 
    
         
            +
                    const U32 ddsSize         = (U32)(ddsEnd - ddsBase);
         
     | 
| 
      
 668 
     | 
    
         
            +
                    const U32 ddsIndexDelta   = dictLimit - ddsSize;
         
     | 
| 
      
 669 
     | 
    
         
            +
                    const U32 bucketSize      = (1 << ZSTD_LAZY_DDSS_BUCKET_LOG);
         
     | 
| 
      
 670 
     | 
    
         
            +
                    const U32 bucketLimit     = nbAttempts < bucketSize - 1 ? nbAttempts : bucketSize - 1;
         
     | 
| 
      
 671 
     | 
    
         
            +
                    U32 ddsAttempt;
         
     | 
| 
      
 672 
     | 
    
         
            +
             
     | 
| 
      
 673 
     | 
    
         
            +
                    for (ddsAttempt = 0; ddsAttempt < bucketSize - 1; ddsAttempt++) {
         
     | 
| 
      
 674 
     | 
    
         
            +
                        PREFETCH_L1(ddsBase + dms->hashTable[ddsIdx + ddsAttempt]);
         
     | 
| 
      
 675 
     | 
    
         
            +
                    }
         
     | 
| 
      
 676 
     | 
    
         
            +
             
     | 
| 
      
 677 
     | 
    
         
            +
                    {
         
     | 
| 
      
 678 
     | 
    
         
            +
                        U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
         
     | 
| 
      
 679 
     | 
    
         
            +
                        U32 const chainIndex = chainPackedPointer >> 8;
         
     | 
| 
      
 680 
     | 
    
         
            +
             
     | 
| 
      
 681 
     | 
    
         
            +
                        PREFETCH_L1(&dms->chainTable[chainIndex]);
         
     | 
| 
      
 682 
     | 
    
         
            +
                    }
         
     | 
| 
      
 683 
     | 
    
         
            +
             
     | 
| 
      
 684 
     | 
    
         
            +
                    for (ddsAttempt = 0; ddsAttempt < bucketLimit; ddsAttempt++) {
         
     | 
| 
      
 685 
     | 
    
         
            +
                        size_t currentMl=0;
         
     | 
| 
      
 686 
     | 
    
         
            +
                        const BYTE* match;
         
     | 
| 
      
 687 
     | 
    
         
            +
                        matchIndex = dms->hashTable[ddsIdx + ddsAttempt];
         
     | 
| 
      
 688 
     | 
    
         
            +
                        match = ddsBase + matchIndex;
         
     | 
| 
      
 689 
     | 
    
         
            +
             
     | 
| 
      
 690 
     | 
    
         
            +
                        if (!matchIndex) {
         
     | 
| 
      
 691 
     | 
    
         
            +
                            return ml;
         
     | 
| 
      
 692 
     | 
    
         
            +
                        }
         
     | 
| 
      
 693 
     | 
    
         
            +
             
     | 
| 
      
 694 
     | 
    
         
            +
                        /* guaranteed by table construction */
         
     | 
| 
      
 695 
     | 
    
         
            +
                        (void)ddsLowestIndex;
         
     | 
| 
      
 696 
     | 
    
         
            +
                        assert(matchIndex >= ddsLowestIndex);
         
     | 
| 
      
 697 
     | 
    
         
            +
                        assert(match+4 <= ddsEnd);
         
     | 
| 
      
 698 
     | 
    
         
            +
                        if (MEM_read32(match) == MEM_read32(ip)) {
         
     | 
| 
      
 699 
     | 
    
         
            +
                            /* assumption : matchIndex <= dictLimit-4 (by table construction) */
         
     | 
| 
      
 700 
     | 
    
         
            +
                            currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
         
     | 
| 
      
 701 
     | 
    
         
            +
                        }
         
     | 
| 
      
 702 
     | 
    
         
            +
             
     | 
| 
      
 703 
     | 
    
         
            +
                        /* save best solution */
         
     | 
| 
      
 704 
     | 
    
         
            +
                        if (currentMl > ml) {
         
     | 
| 
      
 705 
     | 
    
         
            +
                            ml = currentMl;
         
     | 
| 
      
 706 
     | 
    
         
            +
                            *offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
         
     | 
| 
      
 707 
     | 
    
         
            +
                            if (ip+currentMl == iLimit) {
         
     | 
| 
      
 708 
     | 
    
         
            +
                                /* best possible, avoids read overflow on next attempt */
         
     | 
| 
      
 709 
     | 
    
         
            +
                                return ml;
         
     | 
| 
      
 710 
     | 
    
         
            +
                            }
         
     | 
| 
      
 711 
     | 
    
         
            +
                        }
         
     | 
| 
      
 712 
     | 
    
         
            +
                    }
         
     | 
| 
      
 713 
     | 
    
         
            +
             
     | 
| 
      
 714 
     | 
    
         
            +
                    {
         
     | 
| 
      
 715 
     | 
    
         
            +
                        U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
         
     | 
| 
      
 716 
     | 
    
         
            +
                        U32 chainIndex = chainPackedPointer >> 8;
         
     | 
| 
      
 717 
     | 
    
         
            +
                        U32 const chainLength = chainPackedPointer & 0xFF;
         
     | 
| 
      
 718 
     | 
    
         
            +
                        U32 const chainAttempts = nbAttempts - ddsAttempt;
         
     | 
| 
      
 719 
     | 
    
         
            +
                        U32 const chainLimit = chainAttempts > chainLength ? chainLength : chainAttempts;
         
     | 
| 
      
 720 
     | 
    
         
            +
                        U32 chainAttempt;
         
     | 
| 
      
 721 
     | 
    
         
            +
             
     | 
| 
      
 722 
     | 
    
         
            +
                        for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++) {
         
     | 
| 
      
 723 
     | 
    
         
            +
                            PREFETCH_L1(ddsBase + dms->chainTable[chainIndex + chainAttempt]);
         
     | 
| 
      
 724 
     | 
    
         
            +
                        }
         
     | 
| 
      
 725 
     | 
    
         
            +
             
     | 
| 
      
 726 
     | 
    
         
            +
                        for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++, chainIndex++) {
         
     | 
| 
      
 727 
     | 
    
         
            +
                            size_t currentMl=0;
         
     | 
| 
      
 728 
     | 
    
         
            +
                            const BYTE* match;
         
     | 
| 
      
 729 
     | 
    
         
            +
                            matchIndex = dms->chainTable[chainIndex];
         
     | 
| 
      
 730 
     | 
    
         
            +
                            match = ddsBase + matchIndex;
         
     | 
| 
      
 731 
     | 
    
         
            +
             
     | 
| 
      
 732 
     | 
    
         
            +
                            /* guaranteed by table construction */
         
     | 
| 
      
 733 
     | 
    
         
            +
                            assert(matchIndex >= ddsLowestIndex);
         
     | 
| 
      
 734 
     | 
    
         
            +
                            assert(match+4 <= ddsEnd);
         
     | 
| 
      
 735 
     | 
    
         
            +
                            if (MEM_read32(match) == MEM_read32(ip)) {
         
     | 
| 
      
 736 
     | 
    
         
            +
                                /* assumption : matchIndex <= dictLimit-4 (by table construction) */
         
     | 
| 
      
 737 
     | 
    
         
            +
                                currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
         
     | 
| 
      
 738 
     | 
    
         
            +
                            }
         
     | 
| 
      
 739 
     | 
    
         
            +
             
     | 
| 
      
 740 
     | 
    
         
            +
                            /* save best solution */
         
     | 
| 
      
 741 
     | 
    
         
            +
                            if (currentMl > ml) {
         
     | 
| 
      
 742 
     | 
    
         
            +
                                ml = currentMl;
         
     | 
| 
      
 743 
     | 
    
         
            +
                                *offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
         
     | 
| 
      
 744 
     | 
    
         
            +
                                if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
         
     | 
| 
      
 745 
     | 
    
         
            +
                            }
         
     | 
| 
      
 746 
     | 
    
         
            +
                        }
         
     | 
| 
      
 747 
     | 
    
         
            +
                    }
         
     | 
| 
      
 748 
     | 
    
         
            +
                } else if (dictMode == ZSTD_dictMatchState) {
         
     | 
| 
       536 
749 
     | 
    
         
             
                    const U32* const dmsChainTable = dms->chainTable;
         
     | 
| 
       537 
750 
     | 
    
         
             
                    const U32 dmsChainSize         = (1 << dms->cParams.chainLog);
         
     | 
| 
       538 
751 
     | 
    
         
             
                    const U32 dmsChainMask         = dmsChainSize - 1;
         
     | 
| 
         @@ -545,7 +758,7 @@ size_t ZSTD_HcFindBestMatch_generic ( 
     | 
|
| 
       545 
758 
     | 
    
         | 
| 
       546 
759 
     | 
    
         
             
                    matchIndex = dms->hashTable[ZSTD_hashPtr(ip, dms->cParams.hashLog, mls)];
         
     | 
| 
       547 
760 
     | 
    
         | 
| 
       548 
     | 
    
         
            -
                    for ( ; (matchIndex 
     | 
| 
      
 761 
     | 
    
         
            +
                    for ( ; (matchIndex>=dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) {
         
     | 
| 
       549 
762 
     | 
    
         
             
                        size_t currentMl=0;
         
     | 
| 
       550 
763 
     | 
    
         
             
                        const BYTE* const match = dmsBase + matchIndex;
         
     | 
| 
       551 
764 
     | 
    
         
             
                        assert(match+4 <= dmsEnd);
         
     | 
| 
         @@ -555,11 +768,12 @@ size_t ZSTD_HcFindBestMatch_generic ( 
     | 
|
| 
       555 
768 
     | 
    
         
             
                        /* save best solution */
         
     | 
| 
       556 
769 
     | 
    
         
             
                        if (currentMl > ml) {
         
     | 
| 
       557 
770 
     | 
    
         
             
                            ml = currentMl;
         
     | 
| 
       558 
     | 
    
         
            -
                            *offsetPtr =  
     | 
| 
      
 771 
     | 
    
         
            +
                            *offsetPtr = curr - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE;
         
     | 
| 
       559 
772 
     | 
    
         
             
                            if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
         
     | 
| 
       560 
773 
     | 
    
         
             
                        }
         
     | 
| 
       561 
774 
     | 
    
         | 
| 
       562 
775 
     | 
    
         
             
                        if (matchIndex <= dmsMinChain) break;
         
     | 
| 
      
 776 
     | 
    
         
            +
             
     | 
| 
       563 
777 
     | 
    
         
             
                        matchIndex = dmsChainTable[matchIndex & dmsChainMask];
         
     | 
| 
       564 
778 
     | 
    
         
             
                    }
         
     | 
| 
       565 
779 
     | 
    
         
             
                }
         
     | 
| 
         @@ -600,6 +814,22 @@ static size_t ZSTD_HcFindBestMatch_dictMatchState_selectMLS ( 
     | 
|
| 
       600 
814 
     | 
    
         
             
            }
         
     | 
| 
       601 
815 
     | 
    
         | 
| 
       602 
816 
     | 
    
         | 
| 
      
 817 
     | 
    
         
            +
            static size_t ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS (
         
     | 
| 
      
 818 
     | 
    
         
            +
                                    ZSTD_matchState_t* ms,
         
     | 
| 
      
 819 
     | 
    
         
            +
                                    const BYTE* ip, const BYTE* const iLimit,
         
     | 
| 
      
 820 
     | 
    
         
            +
                                    size_t* offsetPtr)
         
     | 
| 
      
 821 
     | 
    
         
            +
            {
         
     | 
| 
      
 822 
     | 
    
         
            +
                switch(ms->cParams.minMatch)
         
     | 
| 
      
 823 
     | 
    
         
            +
                {
         
     | 
| 
      
 824 
     | 
    
         
            +
                default : /* includes case 3 */
         
     | 
| 
      
 825 
     | 
    
         
            +
                case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_dedicatedDictSearch);
         
     | 
| 
      
 826 
     | 
    
         
            +
                case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_dedicatedDictSearch);
         
     | 
| 
      
 827 
     | 
    
         
            +
                case 7 :
         
     | 
| 
      
 828 
     | 
    
         
            +
                case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_dedicatedDictSearch);
         
     | 
| 
      
 829 
     | 
    
         
            +
                }
         
     | 
| 
      
 830 
     | 
    
         
            +
            }
         
     | 
| 
      
 831 
     | 
    
         
            +
             
     | 
| 
      
 832 
     | 
    
         
            +
             
     | 
| 
       603 
833 
     | 
    
         
             
            FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
         
     | 
| 
       604 
834 
     | 
    
         
             
                                    ZSTD_matchState_t* ms,
         
     | 
| 
       605 
835 
     | 
    
         
             
                                    const BYTE* ip, const BYTE* const iLimit,
         
     | 
| 
         @@ -641,39 +871,62 @@ ZSTD_compressBlock_lazy_generic( 
     | 
|
| 
       641 
871 
     | 
    
         
             
                typedef size_t (*searchMax_f)(
         
     | 
| 
       642 
872 
     | 
    
         
             
                                    ZSTD_matchState_t* ms,
         
     | 
| 
       643 
873 
     | 
    
         
             
                                    const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
         
     | 
| 
       644 
     | 
    
         
            -
             
     | 
| 
       645 
     | 
    
         
            -
             
     | 
| 
       646 
     | 
    
         
            -
             
     | 
| 
       647 
     | 
    
         
            -
             
     | 
| 
       648 
     | 
    
         
            -
             
     | 
| 
      
 874 
     | 
    
         
            +
             
     | 
| 
      
 875 
     | 
    
         
            +
                /**
         
     | 
| 
      
 876 
     | 
    
         
            +
                 * This table is indexed first by the four ZSTD_dictMode_e values, and then
         
     | 
| 
      
 877 
     | 
    
         
            +
                 * by the two searchMethod_e values. NULLs are placed for configurations
         
     | 
| 
      
 878 
     | 
    
         
            +
                 * that should never occur (extDict modes go to the other implementation
         
     | 
| 
      
 879 
     | 
    
         
            +
                 * below and there is no DDSS for binary tree search yet).
         
     | 
| 
      
 880 
     | 
    
         
            +
                 */
         
     | 
| 
      
 881 
     | 
    
         
            +
                const searchMax_f searchFuncs[4][2] = {
         
     | 
| 
      
 882 
     | 
    
         
            +
                    {
         
     | 
| 
      
 883 
     | 
    
         
            +
                        ZSTD_HcFindBestMatch_selectMLS,
         
     | 
| 
      
 884 
     | 
    
         
            +
                        ZSTD_BtFindBestMatch_selectMLS
         
     | 
| 
      
 885 
     | 
    
         
            +
                    },
         
     | 
| 
      
 886 
     | 
    
         
            +
                    {
         
     | 
| 
      
 887 
     | 
    
         
            +
                        NULL,
         
     | 
| 
      
 888 
     | 
    
         
            +
                        NULL
         
     | 
| 
      
 889 
     | 
    
         
            +
                    },
         
     | 
| 
      
 890 
     | 
    
         
            +
                    {
         
     | 
| 
      
 891 
     | 
    
         
            +
                        ZSTD_HcFindBestMatch_dictMatchState_selectMLS,
         
     | 
| 
      
 892 
     | 
    
         
            +
                        ZSTD_BtFindBestMatch_dictMatchState_selectMLS
         
     | 
| 
      
 893 
     | 
    
         
            +
                    },
         
     | 
| 
      
 894 
     | 
    
         
            +
                    {
         
     | 
| 
      
 895 
     | 
    
         
            +
                        ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS,
         
     | 
| 
      
 896 
     | 
    
         
            +
                        NULL
         
     | 
| 
      
 897 
     | 
    
         
            +
                    }
         
     | 
| 
      
 898 
     | 
    
         
            +
                };
         
     | 
| 
      
 899 
     | 
    
         
            +
             
     | 
| 
      
 900 
     | 
    
         
            +
                searchMax_f const searchMax = searchFuncs[dictMode][searchMethod == search_binaryTree];
         
     | 
| 
       649 
901 
     | 
    
         
             
                U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
         
     | 
| 
       650 
902 
     | 
    
         | 
| 
      
 903 
     | 
    
         
            +
                const int isDMS = dictMode == ZSTD_dictMatchState;
         
     | 
| 
      
 904 
     | 
    
         
            +
                const int isDDS = dictMode == ZSTD_dedicatedDictSearch;
         
     | 
| 
      
 905 
     | 
    
         
            +
                const int isDxS = isDMS || isDDS;
         
     | 
| 
       651 
906 
     | 
    
         
             
                const ZSTD_matchState_t* const dms = ms->dictMatchState;
         
     | 
| 
       652 
     | 
    
         
            -
                const U32 dictLowestIndex      =  
     | 
| 
       653 
     | 
    
         
            -
             
     | 
| 
       654 
     | 
    
         
            -
                const BYTE* const  
     | 
| 
       655 
     | 
    
         
            -
             
     | 
| 
       656 
     | 
    
         
            -
                const  
     | 
| 
       657 
     | 
    
         
            -
                                                 dictBase + dictLowestIndex : NULL;
         
     | 
| 
       658 
     | 
    
         
            -
                const BYTE* const dictEnd      = dictMode == ZSTD_dictMatchState ?
         
     | 
| 
       659 
     | 
    
         
            -
                                                 dms->window.nextSrc : NULL;
         
     | 
| 
       660 
     | 
    
         
            -
                const U32 dictIndexDelta       = dictMode == ZSTD_dictMatchState ?
         
     | 
| 
      
 907 
     | 
    
         
            +
                const U32 dictLowestIndex      = isDxS ? dms->window.dictLimit : 0;
         
     | 
| 
      
 908 
     | 
    
         
            +
                const BYTE* const dictBase     = isDxS ? dms->window.base : NULL;
         
     | 
| 
      
 909 
     | 
    
         
            +
                const BYTE* const dictLowest   = isDxS ? dictBase + dictLowestIndex : NULL;
         
     | 
| 
      
 910 
     | 
    
         
            +
                const BYTE* const dictEnd      = isDxS ? dms->window.nextSrc : NULL;
         
     | 
| 
      
 911 
     | 
    
         
            +
                const U32 dictIndexDelta       = isDxS ?
         
     | 
| 
       661 
912 
     | 
    
         
             
                                                 prefixLowestIndex - (U32)(dictEnd - dictBase) :
         
     | 
| 
       662 
913 
     | 
    
         
             
                                                 0;
         
     | 
| 
       663 
914 
     | 
    
         
             
                const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest));
         
     | 
| 
       664 
915 
     | 
    
         | 
| 
      
 916 
     | 
    
         
            +
                assert(searchMax != NULL);
         
     | 
| 
      
 917 
     | 
    
         
            +
             
     | 
| 
       665 
918 
     | 
    
         
             
                DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u)", (U32)dictMode);
         
     | 
| 
       666 
919 
     | 
    
         | 
| 
       667 
920 
     | 
    
         
             
                /* init */
         
     | 
| 
       668 
921 
     | 
    
         
             
                ip += (dictAndPrefixLength == 0);
         
     | 
| 
       669 
922 
     | 
    
         
             
                if (dictMode == ZSTD_noDict) {
         
     | 
| 
       670 
     | 
    
         
            -
                    U32 const  
     | 
| 
       671 
     | 
    
         
            -
                    U32 const windowLow = ZSTD_getLowestPrefixIndex(ms,  
     | 
| 
       672 
     | 
    
         
            -
                    U32 const maxRep =  
     | 
| 
      
 923 
     | 
    
         
            +
                    U32 const curr = (U32)(ip - base);
         
     | 
| 
      
 924 
     | 
    
         
            +
                    U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, ms->cParams.windowLog);
         
     | 
| 
      
 925 
     | 
    
         
            +
                    U32 const maxRep = curr - windowLow;
         
     | 
| 
       673 
926 
     | 
    
         
             
                    if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
         
     | 
| 
       674 
927 
     | 
    
         
             
                    if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
         
     | 
| 
       675 
928 
     | 
    
         
             
                }
         
     | 
| 
       676 
     | 
    
         
            -
                if ( 
     | 
| 
      
 929 
     | 
    
         
            +
                if (isDxS) {
         
     | 
| 
       677 
930 
     | 
    
         
             
                    /* dictMatchState repCode checks don't currently handle repCode == 0
         
     | 
| 
       678 
931 
     | 
    
         
             
                     * disabling. */
         
     | 
| 
       679 
932 
     | 
    
         
             
                    assert(offset_1 <= dictAndPrefixLength);
         
     | 
| 
         @@ -693,9 +946,9 @@ ZSTD_compressBlock_lazy_generic( 
     | 
|
| 
       693 
946 
     | 
    
         
             
                    const BYTE* start=ip+1;
         
     | 
| 
       694 
947 
     | 
    
         | 
| 
       695 
948 
     | 
    
         
             
                    /* check repCode */
         
     | 
| 
       696 
     | 
    
         
            -
                    if ( 
     | 
| 
      
 949 
     | 
    
         
            +
                    if (isDxS) {
         
     | 
| 
       697 
950 
     | 
    
         
             
                        const U32 repIndex = (U32)(ip - base) + 1 - offset_1;
         
     | 
| 
       698 
     | 
    
         
            -
                        const BYTE* repMatch = (dictMode == ZSTD_dictMatchState
         
     | 
| 
      
 951 
     | 
    
         
            +
                        const BYTE* repMatch = ((dictMode == ZSTD_dictMatchState || dictMode == ZSTD_dedicatedDictSearch)
         
     | 
| 
       699 
952 
     | 
    
         
             
                                            && repIndex < prefixLowestIndex) ?
         
     | 
| 
       700 
953 
     | 
    
         
             
                                               dictBase + (repIndex - dictIndexDelta) :
         
     | 
| 
       701 
954 
     | 
    
         
             
                                               base + repIndex;
         
     | 
| 
         @@ -736,7 +989,7 @@ ZSTD_compressBlock_lazy_generic( 
     | 
|
| 
       736 
989 
     | 
    
         
             
                            if ((mlRep >= 4) && (gain2 > gain1))
         
     | 
| 
       737 
990 
     | 
    
         
             
                                matchLength = mlRep, offset = 0, start = ip;
         
     | 
| 
       738 
991 
     | 
    
         
             
                        }
         
     | 
| 
       739 
     | 
    
         
            -
                        if ( 
     | 
| 
      
 992 
     | 
    
         
            +
                        if (isDxS) {
         
     | 
| 
       740 
993 
     | 
    
         
             
                            const U32 repIndex = (U32)(ip - base) - offset_1;
         
     | 
| 
       741 
994 
     | 
    
         
             
                            const BYTE* repMatch = repIndex < prefixLowestIndex ?
         
     | 
| 
       742 
995 
     | 
    
         
             
                                           dictBase + (repIndex - dictIndexDelta) :
         
     | 
| 
         @@ -771,7 +1024,7 @@ ZSTD_compressBlock_lazy_generic( 
     | 
|
| 
       771 
1024 
     | 
    
         
             
                                if ((mlRep >= 4) && (gain2 > gain1))
         
     | 
| 
       772 
1025 
     | 
    
         
             
                                    matchLength = mlRep, offset = 0, start = ip;
         
     | 
| 
       773 
1026 
     | 
    
         
             
                            }
         
     | 
| 
       774 
     | 
    
         
            -
                            if ( 
     | 
| 
      
 1027 
     | 
    
         
            +
                            if (isDxS) {
         
     | 
| 
       775 
1028 
     | 
    
         
             
                                const U32 repIndex = (U32)(ip - base) - offset_1;
         
     | 
| 
       776 
1029 
     | 
    
         
             
                                const BYTE* repMatch = repIndex < prefixLowestIndex ?
         
     | 
| 
       777 
1030 
     | 
    
         
             
                                               dictBase + (repIndex - dictIndexDelta) :
         
     | 
| 
         @@ -809,7 +1062,7 @@ ZSTD_compressBlock_lazy_generic( 
     | 
|
| 
       809 
1062 
     | 
    
         
             
                                 && (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) )  /* only search for offset within prefix */
         
     | 
| 
       810 
1063 
     | 
    
         
             
                                { start--; matchLength++; }
         
     | 
| 
       811 
1064 
     | 
    
         
             
                        }
         
     | 
| 
       812 
     | 
    
         
            -
                        if ( 
     | 
| 
      
 1065 
     | 
    
         
            +
                        if (isDxS) {
         
     | 
| 
       813 
1066 
     | 
    
         
             
                            U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
         
     | 
| 
       814 
1067 
     | 
    
         
             
                            const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex;
         
     | 
| 
       815 
1068 
     | 
    
         
             
                            const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest;
         
     | 
| 
         @@ -825,12 +1078,11 @@ _storeSequence: 
     | 
|
| 
       825 
1078 
     | 
    
         
             
                    }
         
     | 
| 
       826 
1079 
     | 
    
         | 
| 
       827 
1080 
     | 
    
         
             
                    /* check immediate repcode */
         
     | 
| 
       828 
     | 
    
         
            -
                    if ( 
     | 
| 
      
 1081 
     | 
    
         
            +
                    if (isDxS) {
         
     | 
| 
       829 
1082 
     | 
    
         
             
                        while (ip <= ilimit) {
         
     | 
| 
       830 
1083 
     | 
    
         
             
                            U32 const current2 = (U32)(ip-base);
         
     | 
| 
       831 
1084 
     | 
    
         
             
                            U32 const repIndex = current2 - offset_2;
         
     | 
| 
       832 
     | 
    
         
            -
                            const BYTE* repMatch =  
     | 
| 
       833 
     | 
    
         
            -
                                && repIndex < prefixLowestIndex ?
         
     | 
| 
      
 1085 
     | 
    
         
            +
                            const BYTE* repMatch = repIndex < prefixLowestIndex ?
         
     | 
| 
       834 
1086 
     | 
    
         
             
                                    dictBase - dictIndexDelta + repIndex :
         
     | 
| 
       835 
1087 
     | 
    
         
             
                                    base + repIndex;
         
     | 
| 
       836 
1088 
     | 
    
         
             
                            if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex) >= 3 /* intentional overflow */)
         
     | 
| 
         @@ -925,6 +1177,28 @@ size_t ZSTD_compressBlock_greedy_dictMatchState( 
     | 
|
| 
       925 
1177 
     | 
    
         
             
            }
         
     | 
| 
       926 
1178 
     | 
    
         | 
| 
       927 
1179 
     | 
    
         | 
| 
      
 1180 
     | 
    
         
            +
            size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch(
         
     | 
| 
      
 1181 
     | 
    
         
            +
                    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         
     | 
| 
      
 1182 
     | 
    
         
            +
                    void const* src, size_t srcSize)
         
     | 
| 
      
 1183 
     | 
    
         
            +
            {
         
     | 
| 
      
 1184 
     | 
    
         
            +
                return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dedicatedDictSearch);
         
     | 
| 
      
 1185 
     | 
    
         
            +
            }
         
     | 
| 
      
 1186 
     | 
    
         
            +
             
     | 
| 
      
 1187 
     | 
    
         
            +
            size_t ZSTD_compressBlock_lazy_dedicatedDictSearch(
         
     | 
| 
      
 1188 
     | 
    
         
            +
                    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         
     | 
| 
      
 1189 
     | 
    
         
            +
                    void const* src, size_t srcSize)
         
     | 
| 
      
 1190 
     | 
    
         
            +
            {
         
     | 
| 
      
 1191 
     | 
    
         
            +
                return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dedicatedDictSearch);
         
     | 
| 
      
 1192 
     | 
    
         
            +
            }
         
     | 
| 
      
 1193 
     | 
    
         
            +
             
     | 
| 
      
 1194 
     | 
    
         
            +
            size_t ZSTD_compressBlock_greedy_dedicatedDictSearch(
         
     | 
| 
      
 1195 
     | 
    
         
            +
                    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         
     | 
| 
      
 1196 
     | 
    
         
            +
                    void const* src, size_t srcSize)
         
     | 
| 
      
 1197 
     | 
    
         
            +
            {
         
     | 
| 
      
 1198 
     | 
    
         
            +
                return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dedicatedDictSearch);
         
     | 
| 
      
 1199 
     | 
    
         
            +
            }
         
     | 
| 
      
 1200 
     | 
    
         
            +
             
     | 
| 
      
 1201 
     | 
    
         
            +
             
     | 
| 
       928 
1202 
     | 
    
         
             
            FORCE_INLINE_TEMPLATE
         
     | 
| 
       929 
1203 
     | 
    
         
             
            size_t ZSTD_compressBlock_lazy_extDict_generic(
         
     | 
| 
       930 
1204 
     | 
    
         
             
                                    ZSTD_matchState_t* ms, seqStore_t* seqStore,
         
     | 
| 
         @@ -968,11 +1242,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( 
     | 
|
| 
       968 
1242 
     | 
    
         
             
                    size_t matchLength=0;
         
     | 
| 
       969 
1243 
     | 
    
         
             
                    size_t offset=0;
         
     | 
| 
       970 
1244 
     | 
    
         
             
                    const BYTE* start=ip+1;
         
     | 
| 
       971 
     | 
    
         
            -
                    U32  
     | 
| 
      
 1245 
     | 
    
         
            +
                    U32 curr = (U32)(ip-base);
         
     | 
| 
       972 
1246 
     | 
    
         | 
| 
       973 
1247 
     | 
    
         
             
                    /* check repCode */
         
     | 
| 
       974 
     | 
    
         
            -
                    {   const U32 windowLow = ZSTD_getLowestMatchIndex(ms,  
     | 
| 
       975 
     | 
    
         
            -
                        const U32 repIndex = (U32)( 
     | 
| 
      
 1248 
     | 
    
         
            +
                    {   const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr+1, windowLog);
         
     | 
| 
      
 1249 
     | 
    
         
            +
                        const U32 repIndex = (U32)(curr+1 - offset_1);
         
     | 
| 
       976 
1250 
     | 
    
         
             
                        const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
         
     | 
| 
       977 
1251 
     | 
    
         
             
                        const BYTE* const repMatch = repBase + repIndex;
         
     | 
| 
       978 
1252 
     | 
    
         
             
                        if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow))   /* intentional overflow */
         
     | 
| 
         @@ -999,11 +1273,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( 
     | 
|
| 
       999 
1273 
     | 
    
         
             
                    if (depth>=1)
         
     | 
| 
       1000 
1274 
     | 
    
         
             
                    while (ip<ilimit) {
         
     | 
| 
       1001 
1275 
     | 
    
         
             
                        ip ++;
         
     | 
| 
       1002 
     | 
    
         
            -
                         
     | 
| 
      
 1276 
     | 
    
         
            +
                        curr++;
         
     | 
| 
       1003 
1277 
     | 
    
         
             
                        /* check repCode */
         
     | 
| 
       1004 
1278 
     | 
    
         
             
                        if (offset) {
         
     | 
| 
       1005 
     | 
    
         
            -
                            const U32 windowLow = ZSTD_getLowestMatchIndex(ms,  
     | 
| 
       1006 
     | 
    
         
            -
                            const U32 repIndex = (U32)( 
     | 
| 
      
 1279 
     | 
    
         
            +
                            const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog);
         
     | 
| 
      
 1280 
     | 
    
         
            +
                            const U32 repIndex = (U32)(curr - offset_1);
         
     | 
| 
       1007 
1281 
     | 
    
         
             
                            const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
         
     | 
| 
       1008 
1282 
     | 
    
         
             
                            const BYTE* const repMatch = repBase + repIndex;
         
     | 
| 
       1009 
1283 
     | 
    
         
             
                            if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow))  /* intentional overflow */
         
     | 
| 
         @@ -1030,11 +1304,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic( 
     | 
|
| 
       1030 
1304 
     | 
    
         
             
                        /* let's find an even better one */
         
     | 
| 
       1031 
1305 
     | 
    
         
             
                        if ((depth==2) && (ip<ilimit)) {
         
     | 
| 
       1032 
1306 
     | 
    
         
             
                            ip ++;
         
     | 
| 
       1033 
     | 
    
         
            -
                             
     | 
| 
      
 1307 
     | 
    
         
            +
                            curr++;
         
     | 
| 
       1034 
1308 
     | 
    
         
             
                            /* check repCode */
         
     | 
| 
       1035 
1309 
     | 
    
         
             
                            if (offset) {
         
     | 
| 
       1036 
     | 
    
         
            -
                                const U32 windowLow = ZSTD_getLowestMatchIndex(ms,  
     | 
| 
       1037 
     | 
    
         
            -
                                const U32 repIndex = (U32)( 
     | 
| 
      
 1310 
     | 
    
         
            +
                                const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog);
         
     | 
| 
      
 1311 
     | 
    
         
            +
                                const U32 repIndex = (U32)(curr - offset_1);
         
     | 
| 
       1038 
1312 
     | 
    
         
             
                                const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
         
     | 
| 
       1039 
1313 
     | 
    
         
             
                                const BYTE* const repMatch = repBase + repIndex;
         
     | 
| 
       1040 
1314 
     | 
    
         
             
                                if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow))  /* intentional overflow */
         
     |