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
 
| 
         @@ -17,8 +17,18 @@ extern "C" { 
     | 
|
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
            #include "zstd_compress_internal.h"
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
      
 20 
     | 
    
         
            +
            /**
         
     | 
| 
      
 21 
     | 
    
         
            +
             * Dedicated Dictionary Search Structure bucket log. In the
         
     | 
| 
      
 22 
     | 
    
         
            +
             * ZSTD_dedicatedDictSearch mode, the hashTable has
         
     | 
| 
      
 23 
     | 
    
         
            +
             * 2 ** ZSTD_LAZY_DDSS_BUCKET_LOG entries in each bucket, rather than just
         
     | 
| 
      
 24 
     | 
    
         
            +
             * one.
         
     | 
| 
      
 25 
     | 
    
         
            +
             */
         
     | 
| 
      
 26 
     | 
    
         
            +
            #define ZSTD_LAZY_DDSS_BUCKET_LOG 2
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
       20 
28 
     | 
    
         
             
            U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip);
         
     | 
| 
       21 
29 
     | 
    
         | 
| 
      
 30 
     | 
    
         
            +
            void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip);
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
       22 
32 
     | 
    
         
             
            void ZSTD_preserveUnsortedMark (U32* const table, U32 const size, U32 const reducerValue);  /*! used in ZSTD_reduceIndex(). preemptively increase value of ZSTD_DUBT_UNSORTED_MARK */
         
     | 
| 
       23 
33 
     | 
    
         | 
| 
       24 
34 
     | 
    
         
             
            size_t ZSTD_compressBlock_btlazy2(
         
     | 
| 
         @@ -47,6 +57,16 @@ size_t ZSTD_compressBlock_greedy_dictMatchState( 
     | 
|
| 
       47 
57 
     | 
    
         
             
                    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         
     | 
| 
       48 
58 
     | 
    
         
             
                    void const* src, size_t srcSize);
         
     | 
| 
       49 
59 
     | 
    
         | 
| 
      
 60 
     | 
    
         
            +
            size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch(
         
     | 
| 
      
 61 
     | 
    
         
            +
                    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         
     | 
| 
      
 62 
     | 
    
         
            +
                    void const* src, size_t srcSize);
         
     | 
| 
      
 63 
     | 
    
         
            +
            size_t ZSTD_compressBlock_lazy_dedicatedDictSearch(
         
     | 
| 
      
 64 
     | 
    
         
            +
                    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         
     | 
| 
      
 65 
     | 
    
         
            +
                    void const* src, size_t srcSize);
         
     | 
| 
      
 66 
     | 
    
         
            +
            size_t ZSTD_compressBlock_greedy_dedicatedDictSearch(
         
     | 
| 
      
 67 
     | 
    
         
            +
                    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         
     | 
| 
      
 68 
     | 
    
         
            +
                    void const* src, size_t srcSize);
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
       50 
70 
     | 
    
         
             
            size_t ZSTD_compressBlock_greedy_extDict(
         
     | 
| 
       51 
71 
     | 
    
         
             
                    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         
     | 
| 
       52 
72 
     | 
    
         
             
                    void const* src, size_t srcSize);
         
     | 
| 
         @@ -27,13 +27,6 @@ void ZSTD_ldm_adjustParameters(ldmParams_t* params, 
     | 
|
| 
       27 
27 
     | 
    
         
             
                DEBUGLOG(4, "ZSTD_ldm_adjustParameters");
         
     | 
| 
       28 
28 
     | 
    
         
             
                if (!params->bucketSizeLog) params->bucketSizeLog = LDM_BUCKET_SIZE_LOG;
         
     | 
| 
       29 
29 
     | 
    
         
             
                if (!params->minMatchLength) params->minMatchLength = LDM_MIN_MATCH_LENGTH;
         
     | 
| 
       30 
     | 
    
         
            -
                if (cParams->strategy >= ZSTD_btopt) {
         
     | 
| 
       31 
     | 
    
         
            -
                  /* Get out of the way of the optimal parser */
         
     | 
| 
       32 
     | 
    
         
            -
                  U32 const minMatch = MAX(cParams->targetLength, params->minMatchLength);
         
     | 
| 
       33 
     | 
    
         
            -
                  assert(minMatch >= ZSTD_LDM_MINMATCH_MIN);
         
     | 
| 
       34 
     | 
    
         
            -
                  assert(minMatch <= ZSTD_LDM_MINMATCH_MAX);
         
     | 
| 
       35 
     | 
    
         
            -
                  params->minMatchLength = minMatch;
         
     | 
| 
       36 
     | 
    
         
            -
                }
         
     | 
| 
       37 
30 
     | 
    
         
             
                if (params->hashLog == 0) {
         
     | 
| 
       38 
31 
     | 
    
         
             
                    params->hashLog = MAX(ZSTD_HASHLOG_MIN, params->windowLog - LDM_HASH_RLOG);
         
     | 
| 
       39 
32 
     | 
    
         
             
                    assert(params->hashLog <= ZSTD_HASHLOG_MAX);
         
     | 
| 
         @@ -150,10 +143,10 @@ static void ZSTD_ldm_makeEntryAndInsertByTag(ldmState_t* ldmState, 
     | 
|
| 
       150 
143 
     | 
    
         
             
             *  We count only bytes where pMatch >= pBase and pIn >= pAnchor. */
         
     | 
| 
       151 
144 
     | 
    
         
             
            static size_t ZSTD_ldm_countBackwardsMatch(
         
     | 
| 
       152 
145 
     | 
    
         
             
                        const BYTE* pIn, const BYTE* pAnchor,
         
     | 
| 
       153 
     | 
    
         
            -
                        const BYTE* pMatch, const BYTE*  
     | 
| 
      
 146 
     | 
    
         
            +
                        const BYTE* pMatch, const BYTE* pMatchBase)
         
     | 
| 
       154 
147 
     | 
    
         
             
            {
         
     | 
| 
       155 
148 
     | 
    
         
             
                size_t matchLength = 0;
         
     | 
| 
       156 
     | 
    
         
            -
                while (pIn > pAnchor && pMatch >  
     | 
| 
      
 149 
     | 
    
         
            +
                while (pIn > pAnchor && pMatch > pMatchBase && pIn[-1] == pMatch[-1]) {
         
     | 
| 
       157 
150 
     | 
    
         
             
                    pIn--;
         
     | 
| 
       158 
151 
     | 
    
         
             
                    pMatch--;
         
     | 
| 
       159 
152 
     | 
    
         
             
                    matchLength++;
         
     | 
| 
         @@ -161,6 +154,27 @@ static size_t ZSTD_ldm_countBackwardsMatch( 
     | 
|
| 
       161 
154 
     | 
    
         
             
                return matchLength;
         
     | 
| 
       162 
155 
     | 
    
         
             
            }
         
     | 
| 
       163 
156 
     | 
    
         | 
| 
      
 157 
     | 
    
         
            +
            /** ZSTD_ldm_countBackwardsMatch_2segments() :
         
     | 
| 
      
 158 
     | 
    
         
            +
             *  Returns the number of bytes that match backwards from pMatch,
         
     | 
| 
      
 159 
     | 
    
         
            +
             *  even with the backwards match spanning 2 different segments.
         
     | 
| 
      
 160 
     | 
    
         
            +
             *
         
     | 
| 
      
 161 
     | 
    
         
            +
             *  On reaching `pMatchBase`, start counting from mEnd */
         
     | 
| 
      
 162 
     | 
    
         
            +
            static size_t ZSTD_ldm_countBackwardsMatch_2segments(
         
     | 
| 
      
 163 
     | 
    
         
            +
                                const BYTE* pIn, const BYTE* pAnchor,
         
     | 
| 
      
 164 
     | 
    
         
            +
                                const BYTE* pMatch, const BYTE* pMatchBase,
         
     | 
| 
      
 165 
     | 
    
         
            +
                                const BYTE* pExtDictStart, const BYTE* pExtDictEnd)
         
     | 
| 
      
 166 
     | 
    
         
            +
            {
         
     | 
| 
      
 167 
     | 
    
         
            +
                size_t matchLength = ZSTD_ldm_countBackwardsMatch(pIn, pAnchor, pMatch, pMatchBase);
         
     | 
| 
      
 168 
     | 
    
         
            +
                if (pMatch - matchLength != pMatchBase || pMatchBase == pExtDictStart) {
         
     | 
| 
      
 169 
     | 
    
         
            +
                    /* If backwards match is entirely in the extDict or prefix, immediately return */
         
     | 
| 
      
 170 
     | 
    
         
            +
                    return matchLength;
         
     | 
| 
      
 171 
     | 
    
         
            +
                }
         
     | 
| 
      
 172 
     | 
    
         
            +
                DEBUGLOG(7, "ZSTD_ldm_countBackwardsMatch_2segments: found 2-parts backwards match (length in prefix==%zu)", matchLength);
         
     | 
| 
      
 173 
     | 
    
         
            +
                matchLength += ZSTD_ldm_countBackwardsMatch(pIn - matchLength, pAnchor, pExtDictEnd, pExtDictStart);
         
     | 
| 
      
 174 
     | 
    
         
            +
                DEBUGLOG(7, "final backwards match length = %zu", matchLength);
         
     | 
| 
      
 175 
     | 
    
         
            +
                return matchLength;
         
     | 
| 
      
 176 
     | 
    
         
            +
            }
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
       164 
178 
     | 
    
         
             
            /** ZSTD_ldm_fillFastTables() :
         
     | 
| 
       165 
179 
     | 
    
         
             
             *
         
     | 
| 
       166 
180 
     | 
    
         
             
             *  Fills the relevant tables for the ZSTD_fast and ZSTD_dfast strategies.
         
     | 
| 
         @@ -246,10 +260,10 @@ void ZSTD_ldm_fillHashTable( 
     | 
|
| 
       246 
260 
     | 
    
         
             
             *  (after a long match, only update tables a limited amount). */
         
     | 
| 
       247 
261 
     | 
    
         
             
            static void ZSTD_ldm_limitTableUpdate(ZSTD_matchState_t* ms, const BYTE* anchor)
         
     | 
| 
       248 
262 
     | 
    
         
             
            {
         
     | 
| 
       249 
     | 
    
         
            -
                U32 const  
     | 
| 
       250 
     | 
    
         
            -
                if ( 
     | 
| 
      
 263 
     | 
    
         
            +
                U32 const curr = (U32)(anchor - ms->window.base);
         
     | 
| 
      
 264 
     | 
    
         
            +
                if (curr > ms->nextToUpdate + 1024) {
         
     | 
| 
       251 
265 
     | 
    
         
             
                    ms->nextToUpdate =
         
     | 
| 
       252 
     | 
    
         
            -
                         
     | 
| 
      
 266 
     | 
    
         
            +
                        curr - MIN(512, curr - ms->nextToUpdate - 1024);
         
     | 
| 
       253 
267 
     | 
    
         
             
                }
         
     | 
| 
       254 
268 
     | 
    
         
             
            }
         
     | 
| 
       255 
269 
     | 
    
         | 
| 
         @@ -286,7 +300,7 @@ static size_t ZSTD_ldm_generateSequences_internal( 
     | 
|
| 
       286 
300 
     | 
    
         | 
| 
       287 
301 
     | 
    
         
             
                while (ip <= ilimit) {
         
     | 
| 
       288 
302 
     | 
    
         
             
                    size_t mLength;
         
     | 
| 
       289 
     | 
    
         
            -
                    U32 const  
     | 
| 
      
 303 
     | 
    
         
            +
                    U32 const curr = (U32)(ip - base);
         
     | 
| 
       290 
304 
     | 
    
         
             
                    size_t forwardMatchLength = 0, backwardMatchLength = 0;
         
     | 
| 
       291 
305 
     | 
    
         
             
                    ldmEntry_t* bestEntry = NULL;
         
     | 
| 
       292 
306 
     | 
    
         
             
                    if (ip != istart) {
         
     | 
| 
         @@ -336,8 +350,9 @@ static size_t ZSTD_ldm_generateSequences_internal( 
     | 
|
| 
       336 
350 
     | 
    
         
             
                                    continue;
         
     | 
| 
       337 
351 
     | 
    
         
             
                                }
         
     | 
| 
       338 
352 
     | 
    
         
             
                                curBackwardMatchLength =
         
     | 
| 
       339 
     | 
    
         
            -
                                     
     | 
| 
       340 
     | 
    
         
            -
             
     | 
| 
      
 353 
     | 
    
         
            +
                                    ZSTD_ldm_countBackwardsMatch_2segments(ip, anchor,
         
     | 
| 
      
 354 
     | 
    
         
            +
                                                                           pMatch, lowMatchPtr,
         
     | 
| 
      
 355 
     | 
    
         
            +
                                                                           dictStart, dictEnd);
         
     | 
| 
       341 
356 
     | 
    
         
             
                                curTotalMatchLength = curForwardMatchLength +
         
     | 
| 
       342 
357 
     | 
    
         
             
                                                      curBackwardMatchLength;
         
     | 
| 
       343 
358 
     | 
    
         
             
                            } else { /* !extDict */
         
     | 
| 
         @@ -365,7 +380,7 @@ static size_t ZSTD_ldm_generateSequences_internal( 
     | 
|
| 
       365 
380 
     | 
    
         
             
                    /* No match found -- continue searching */
         
     | 
| 
       366 
381 
     | 
    
         
             
                    if (bestEntry == NULL) {
         
     | 
| 
       367 
382 
     | 
    
         
             
                        ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash,
         
     | 
| 
       368 
     | 
    
         
            -
                                                         hBits,  
     | 
| 
      
 383 
     | 
    
         
            +
                                                         hBits, curr,
         
     | 
| 
       369 
384 
     | 
    
         
             
                                                         *params);
         
     | 
| 
       370 
385 
     | 
    
         
             
                        ip++;
         
     | 
| 
       371 
386 
     | 
    
         
             
                        continue;
         
     | 
| 
         @@ -377,11 +392,11 @@ static size_t ZSTD_ldm_generateSequences_internal( 
     | 
|
| 
       377 
392 
     | 
    
         | 
| 
       378 
393 
     | 
    
         
             
                    {
         
     | 
| 
       379 
394 
     | 
    
         
             
                        /* Store the sequence:
         
     | 
| 
       380 
     | 
    
         
            -
                         * ip =  
     | 
| 
      
 395 
     | 
    
         
            +
                         * ip = curr - backwardMatchLength
         
     | 
| 
       381 
396 
     | 
    
         
             
                         * The match is at (bestEntry->offset - backwardMatchLength)
         
     | 
| 
       382 
397 
     | 
    
         
             
                         */
         
     | 
| 
       383 
398 
     | 
    
         
             
                        U32 const matchIndex = bestEntry->offset;
         
     | 
| 
       384 
     | 
    
         
            -
                        U32 const offset =  
     | 
| 
      
 399 
     | 
    
         
            +
                        U32 const offset = curr - matchIndex;
         
     | 
| 
       385 
400 
     | 
    
         
             
                        rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size;
         
     | 
| 
       386 
401 
     | 
    
         | 
| 
       387 
402 
     | 
    
         
             
                        /* Out of sequence storage */
         
     | 
| 
         @@ -562,6 +577,23 @@ static rawSeq maybeSplitSequence(rawSeqStore_t* rawSeqStore, 
     | 
|
| 
       562 
577 
     | 
    
         
             
                return sequence;
         
     | 
| 
       563 
578 
     | 
    
         
             
            }
         
     | 
| 
       564 
579 
     | 
    
         | 
| 
      
 580 
     | 
    
         
            +
            void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
         
     | 
| 
      
 581 
     | 
    
         
            +
                U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes);
         
     | 
| 
      
 582 
     | 
    
         
            +
                while (currPos && rawSeqStore->pos < rawSeqStore->size) {
         
     | 
| 
      
 583 
     | 
    
         
            +
                    rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
         
     | 
| 
      
 584 
     | 
    
         
            +
                    if (currPos >= currSeq.litLength + currSeq.matchLength) {
         
     | 
| 
      
 585 
     | 
    
         
            +
                        currPos -= currSeq.litLength + currSeq.matchLength;
         
     | 
| 
      
 586 
     | 
    
         
            +
                        rawSeqStore->pos++;
         
     | 
| 
      
 587 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 588 
     | 
    
         
            +
                        rawSeqStore->posInSequence = currPos;
         
     | 
| 
      
 589 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 590 
     | 
    
         
            +
                    }
         
     | 
| 
      
 591 
     | 
    
         
            +
                }
         
     | 
| 
      
 592 
     | 
    
         
            +
                if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) {
         
     | 
| 
      
 593 
     | 
    
         
            +
                    rawSeqStore->posInSequence = 0;
         
     | 
| 
      
 594 
     | 
    
         
            +
                }
         
     | 
| 
      
 595 
     | 
    
         
            +
            }
         
     | 
| 
      
 596 
     | 
    
         
            +
             
     | 
| 
       565 
597 
     | 
    
         
             
            size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
         
     | 
| 
       566 
598 
     | 
    
         
             
                ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         
     | 
| 
       567 
599 
     | 
    
         
             
                void const* src, size_t srcSize)
         
     | 
| 
         @@ -577,6 +609,15 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, 
     | 
|
| 
       577 
609 
     | 
    
         
             
                BYTE const* ip = istart;
         
     | 
| 
       578 
610 
     | 
    
         | 
| 
       579 
611 
     | 
    
         
             
                DEBUGLOG(5, "ZSTD_ldm_blockCompress: srcSize=%zu", srcSize);
         
     | 
| 
      
 612 
     | 
    
         
            +
                /* If using opt parser, use LDMs only as candidates rather than always accepting them */
         
     | 
| 
      
 613 
     | 
    
         
            +
                if (cParams->strategy >= ZSTD_btopt) {
         
     | 
| 
      
 614 
     | 
    
         
            +
                    size_t lastLLSize;
         
     | 
| 
      
 615 
     | 
    
         
            +
                    ms->ldmSeqStore = rawSeqStore;
         
     | 
| 
      
 616 
     | 
    
         
            +
                    lastLLSize = blockCompressor(ms, seqStore, rep, src, srcSize);
         
     | 
| 
      
 617 
     | 
    
         
            +
                    ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore, srcSize);
         
     | 
| 
      
 618 
     | 
    
         
            +
                    return lastLLSize;
         
     | 
| 
      
 619 
     | 
    
         
            +
                }
         
     | 
| 
      
 620 
     | 
    
         
            +
             
     | 
| 
       580 
621 
     | 
    
         
             
                assert(rawSeqStore->pos <= rawSeqStore->size);
         
     | 
| 
       581 
622 
     | 
    
         
             
                assert(rawSeqStore->size <= rawSeqStore->capacity);
         
     | 
| 
       582 
623 
     | 
    
         
             
                /* Loop through each sequence and apply the block compressor to the lits */
         
     | 
| 
         @@ -78,6 +78,12 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore, 
     | 
|
| 
       78 
78 
     | 
    
         
             
            void ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize,
         
     | 
| 
       79 
79 
     | 
    
         
             
                U32 const minMatch);
         
     | 
| 
       80 
80 
     | 
    
         | 
| 
      
 81 
     | 
    
         
            +
            /* ZSTD_ldm_skipRawSeqStoreBytes():
         
     | 
| 
      
 82 
     | 
    
         
            +
             * Moves forward in rawSeqStore by nbBytes, updating fields 'pos' and 'posInSequence'.
         
     | 
| 
      
 83 
     | 
    
         
            +
             * Not to be used in conjunction with ZSTD_ldm_skipSequences().
         
     | 
| 
      
 84 
     | 
    
         
            +
             * Must be called for data with is not passed to ZSTD_ldm_blockCompress().
         
     | 
| 
      
 85 
     | 
    
         
            +
             */
         
     | 
| 
      
 86 
     | 
    
         
            +
            void ZSTD_ldm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes);
         
     | 
| 
       81 
87 
     | 
    
         | 
| 
       82 
88 
     | 
    
         
             
            /** ZSTD_ldm_getTableSize() :
         
     | 
| 
       83 
89 
     | 
    
         
             
             *  Estimate the space needed for long distance matching tables or 0 if LDM is
         
     | 
| 
         @@ -386,32 +386,32 @@ static U32 ZSTD_insertBt1( 
     | 
|
| 
       386 
386 
     | 
    
         
             
                const BYTE* const dictEnd = dictBase + dictLimit;
         
     | 
| 
       387 
387 
     | 
    
         
             
                const BYTE* const prefixStart = base + dictLimit;
         
     | 
| 
       388 
388 
     | 
    
         
             
                const BYTE* match;
         
     | 
| 
       389 
     | 
    
         
            -
                const U32  
     | 
| 
       390 
     | 
    
         
            -
                const U32 btLow = btMask >=  
     | 
| 
       391 
     | 
    
         
            -
                U32* smallerPtr = bt + 2*( 
     | 
| 
      
 389 
     | 
    
         
            +
                const U32 curr = (U32)(ip-base);
         
     | 
| 
      
 390 
     | 
    
         
            +
                const U32 btLow = btMask >= curr ? 0 : curr - btMask;
         
     | 
| 
      
 391 
     | 
    
         
            +
                U32* smallerPtr = bt + 2*(curr&btMask);
         
     | 
| 
       392 
392 
     | 
    
         
             
                U32* largerPtr  = smallerPtr + 1;
         
     | 
| 
       393 
393 
     | 
    
         
             
                U32 dummy32;   /* to be nullified at the end */
         
     | 
| 
       394 
394 
     | 
    
         
             
                U32 const windowLow = ms->window.lowLimit;
         
     | 
| 
       395 
     | 
    
         
            -
                U32 matchEndIdx =  
     | 
| 
      
 395 
     | 
    
         
            +
                U32 matchEndIdx = curr+8+1;
         
     | 
| 
       396 
396 
     | 
    
         
             
                size_t bestLength = 8;
         
     | 
| 
       397 
397 
     | 
    
         
             
                U32 nbCompares = 1U << cParams->searchLog;
         
     | 
| 
       398 
398 
     | 
    
         
             
            #ifdef ZSTD_C_PREDICT
         
     | 
| 
       399 
     | 
    
         
            -
                U32 predictedSmall = *(bt + 2*(( 
     | 
| 
       400 
     | 
    
         
            -
                U32 predictedLarge = *(bt + 2*(( 
     | 
| 
      
 399 
     | 
    
         
            +
                U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0);
         
     | 
| 
      
 400 
     | 
    
         
            +
                U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1);
         
     | 
| 
       401 
401 
     | 
    
         
             
                predictedSmall += (predictedSmall>0);
         
     | 
| 
       402 
402 
     | 
    
         
             
                predictedLarge += (predictedLarge>0);
         
     | 
| 
       403 
403 
     | 
    
         
             
            #endif /* ZSTD_C_PREDICT */
         
     | 
| 
       404 
404 
     | 
    
         | 
| 
       405 
     | 
    
         
            -
                DEBUGLOG(8, "ZSTD_insertBt1 (%u)",  
     | 
| 
      
 405 
     | 
    
         
            +
                DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr);
         
     | 
| 
       406 
406 
     | 
    
         | 
| 
       407 
407 
     | 
    
         
             
                assert(ip <= iend-8);   /* required for h calculation */
         
     | 
| 
       408 
     | 
    
         
            -
                hashTable[h] =  
     | 
| 
      
 408 
     | 
    
         
            +
                hashTable[h] = curr;   /* Update Hash Table */
         
     | 
| 
       409 
409 
     | 
    
         | 
| 
       410 
410 
     | 
    
         
             
                assert(windowLow > 0);
         
     | 
| 
       411 
411 
     | 
    
         
             
                while (nbCompares-- && (matchIndex >= windowLow)) {
         
     | 
| 
       412 
412 
     | 
    
         
             
                    U32* const nextPtr = bt + 2*(matchIndex & btMask);
         
     | 
| 
       413 
413 
     | 
    
         
             
                    size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
         
     | 
| 
       414 
     | 
    
         
            -
                    assert(matchIndex <  
     | 
| 
      
 414 
     | 
    
         
            +
                    assert(matchIndex < curr);
         
     | 
| 
       415 
415 
     | 
    
         | 
| 
       416 
416 
     | 
    
         
             
            #ifdef ZSTD_C_PREDICT   /* note : can create issues when hlog small <= 11 */
         
     | 
| 
       417 
417 
     | 
    
         
             
                    const U32* predictPtr = bt + 2*((matchIndex-1) & btMask);   /* written this way, as bt is a roll buffer */
         
     | 
| 
         @@ -474,8 +474,8 @@ static U32 ZSTD_insertBt1( 
     | 
|
| 
       474 
474 
     | 
    
         
             
                *smallerPtr = *largerPtr = 0;
         
     | 
| 
       475 
475 
     | 
    
         
             
                {   U32 positions = 0;
         
     | 
| 
       476 
476 
     | 
    
         
             
                    if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384));   /* speed optimization */
         
     | 
| 
       477 
     | 
    
         
            -
                    assert(matchEndIdx >  
     | 
| 
       478 
     | 
    
         
            -
                    return MAX(positions, matchEndIdx - ( 
     | 
| 
      
 477 
     | 
    
         
            +
                    assert(matchEndIdx > curr + 8);
         
     | 
| 
      
 478 
     | 
    
         
            +
                    return MAX(positions, matchEndIdx - (curr + 8));
         
     | 
| 
       479 
479 
     | 
    
         
             
                }
         
     | 
| 
       480 
480 
     | 
    
         
             
            }
         
     | 
| 
       481 
481 
     | 
    
         | 
| 
         @@ -519,7 +519,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( 
     | 
|
| 
       519 
519 
     | 
    
         
             
                const ZSTD_compressionParameters* const cParams = &ms->cParams;
         
     | 
| 
       520 
520 
     | 
    
         
             
                U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
         
     | 
| 
       521 
521 
     | 
    
         
             
                const BYTE* const base = ms->window.base;
         
     | 
| 
       522 
     | 
    
         
            -
                U32 const  
     | 
| 
      
 522 
     | 
    
         
            +
                U32 const curr = (U32)(ip-base);
         
     | 
| 
       523 
523 
     | 
    
         
             
                U32 const hashLog = cParams->hashLog;
         
     | 
| 
       524 
524 
     | 
    
         
             
                U32 const minMatch = (mls==3) ? 3 : 4;
         
     | 
| 
       525 
525 
     | 
    
         
             
                U32* const hashTable = ms->hashTable;
         
     | 
| 
         @@ -533,12 +533,12 @@ U32 ZSTD_insertBtAndGetAllMatches ( 
     | 
|
| 
       533 
533 
     | 
    
         
             
                U32 const dictLimit = ms->window.dictLimit;
         
     | 
| 
       534 
534 
     | 
    
         
             
                const BYTE* const dictEnd = dictBase + dictLimit;
         
     | 
| 
       535 
535 
     | 
    
         
             
                const BYTE* const prefixStart = base + dictLimit;
         
     | 
| 
       536 
     | 
    
         
            -
                U32 const btLow = (btMask >=  
     | 
| 
       537 
     | 
    
         
            -
                U32 const windowLow = ZSTD_getLowestMatchIndex(ms,  
     | 
| 
      
 536 
     | 
    
         
            +
                U32 const btLow = (btMask >= curr) ? 0 : curr - btMask;
         
     | 
| 
      
 537 
     | 
    
         
            +
                U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog);
         
     | 
| 
       538 
538 
     | 
    
         
             
                U32 const matchLow = windowLow ? windowLow : 1;
         
     | 
| 
       539 
     | 
    
         
            -
                U32* smallerPtr = bt + 2*( 
     | 
| 
       540 
     | 
    
         
            -
                U32* largerPtr  = bt + 2*( 
     | 
| 
       541 
     | 
    
         
            -
                U32 matchEndIdx =  
     | 
| 
      
 539 
     | 
    
         
            +
                U32* smallerPtr = bt + 2*(curr&btMask);
         
     | 
| 
      
 540 
     | 
    
         
            +
                U32* largerPtr  = bt + 2*(curr&btMask) + 1;
         
     | 
| 
      
 541 
     | 
    
         
            +
                U32 matchEndIdx = curr+8+1;   /* farthest referenced position of any match => detects repetitive patterns */
         
     | 
| 
       542 
542 
     | 
    
         
             
                U32 dummy32;   /* to be nullified at the end */
         
     | 
| 
       543 
543 
     | 
    
         
             
                U32 mnum = 0;
         
     | 
| 
       544 
544 
     | 
    
         
             
                U32 nbCompares = 1U << cParams->searchLog;
         
     | 
| 
         @@ -557,7 +557,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( 
     | 
|
| 
       557 
557 
     | 
    
         
             
                U32         const dmsBtLow      = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit;
         
     | 
| 
       558 
558 
     | 
    
         | 
| 
       559 
559 
     | 
    
         
             
                size_t bestLength = lengthToBeat-1;
         
     | 
| 
       560 
     | 
    
         
            -
                DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u",  
     | 
| 
      
 560 
     | 
    
         
            +
                DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", curr);
         
     | 
| 
       561 
561 
     | 
    
         | 
| 
       562 
562 
     | 
    
         
             
                /* check repCode */
         
     | 
| 
       563 
563 
     | 
    
         
             
                assert(ll0 <= 1);   /* necessarily 1 or 0 */
         
     | 
| 
         @@ -565,29 +565,29 @@ U32 ZSTD_insertBtAndGetAllMatches ( 
     | 
|
| 
       565 
565 
     | 
    
         
             
                    U32 repCode;
         
     | 
| 
       566 
566 
     | 
    
         
             
                    for (repCode = ll0; repCode < lastR; repCode++) {
         
     | 
| 
       567 
567 
     | 
    
         
             
                        U32 const repOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
         
     | 
| 
       568 
     | 
    
         
            -
                        U32 const repIndex =  
     | 
| 
      
 568 
     | 
    
         
            +
                        U32 const repIndex = curr - repOffset;
         
     | 
| 
       569 
569 
     | 
    
         
             
                        U32 repLen = 0;
         
     | 
| 
       570 
     | 
    
         
            -
                        assert( 
     | 
| 
       571 
     | 
    
         
            -
                        if (repOffset-1 /* intentional overflow, discards 0 and -1 */ <  
     | 
| 
      
 570 
     | 
    
         
            +
                        assert(curr >= dictLimit);
         
     | 
| 
      
 571 
     | 
    
         
            +
                        if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < curr-dictLimit) {  /* equivalent to `curr > repIndex >= dictLimit` */
         
     | 
| 
       572 
572 
     | 
    
         
             
                            /* We must validate the repcode offset because when we're using a dictionary the
         
     | 
| 
       573 
573 
     | 
    
         
             
                             * valid offset range shrinks when the dictionary goes out of bounds.
         
     | 
| 
       574 
574 
     | 
    
         
             
                             */
         
     | 
| 
       575 
575 
     | 
    
         
             
                            if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) {
         
     | 
| 
       576 
576 
     | 
    
         
             
                                repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch;
         
     | 
| 
       577 
577 
     | 
    
         
             
                            }
         
     | 
| 
       578 
     | 
    
         
            -
                        } else {  /* repIndex < dictLimit || repIndex >=  
     | 
| 
      
 578 
     | 
    
         
            +
                        } else {  /* repIndex < dictLimit || repIndex >= curr */
         
     | 
| 
       579 
579 
     | 
    
         
             
                            const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ?
         
     | 
| 
       580 
580 
     | 
    
         
             
                                                         dmsBase + repIndex - dmsIndexDelta :
         
     | 
| 
       581 
581 
     | 
    
         
             
                                                         dictBase + repIndex;
         
     | 
| 
       582 
     | 
    
         
            -
                            assert( 
     | 
| 
      
 582 
     | 
    
         
            +
                            assert(curr >= windowLow);
         
     | 
| 
       583 
583 
     | 
    
         
             
                            if ( dictMode == ZSTD_extDict
         
     | 
| 
       584 
     | 
    
         
            -
                              && ( ((repOffset-1) /*intentional overflow*/ <  
     | 
| 
      
 584 
     | 
    
         
            +
                              && ( ((repOffset-1) /*intentional overflow*/ < curr - windowLow)  /* equivalent to `curr > repIndex >= windowLow` */
         
     | 
| 
       585 
585 
     | 
    
         
             
                                 & (((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */)
         
     | 
| 
       586 
586 
     | 
    
         
             
                              && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
         
     | 
| 
       587 
587 
     | 
    
         
             
                                repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch;
         
     | 
| 
       588 
588 
     | 
    
         
             
                            }
         
     | 
| 
       589 
589 
     | 
    
         
             
                            if (dictMode == ZSTD_dictMatchState
         
     | 
| 
       590 
     | 
    
         
            -
                              && ( ((repOffset-1) /*intentional overflow*/ <  
     | 
| 
      
 590 
     | 
    
         
            +
                              && ( ((repOffset-1) /*intentional overflow*/ < curr - (dmsLowLimit + dmsIndexDelta))  /* equivalent to `curr > repIndex >= dmsLowLimit` */
         
     | 
| 
       591 
591 
     | 
    
         
             
                                 & ((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */
         
     | 
| 
       592 
592 
     | 
    
         
             
                              && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
         
     | 
| 
       593 
593 
     | 
    
         
             
                                repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch;
         
     | 
| 
         @@ -609,7 +609,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( 
     | 
|
| 
       609 
609 
     | 
    
         
             
                if ((mls == 3) /*static*/ && (bestLength < mls)) {
         
     | 
| 
       610 
610 
     | 
    
         
             
                    U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip);
         
     | 
| 
       611 
611 
     | 
    
         
             
                    if ((matchIndex3 >= matchLow)
         
     | 
| 
       612 
     | 
    
         
            -
                      & ( 
     | 
| 
      
 612 
     | 
    
         
            +
                      & (curr - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {
         
     | 
| 
       613 
613 
     | 
    
         
             
                        size_t mlen;
         
     | 
| 
       614 
614 
     | 
    
         
             
                        if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) {
         
     | 
| 
       615 
615 
     | 
    
         
             
                            const BYTE* const match = base + matchIndex3;
         
     | 
| 
         @@ -624,26 +624,26 @@ U32 ZSTD_insertBtAndGetAllMatches ( 
     | 
|
| 
       624 
624 
     | 
    
         
             
                            DEBUGLOG(8, "found small match with hlog3, of length %u",
         
     | 
| 
       625 
625 
     | 
    
         
             
                                        (U32)mlen);
         
     | 
| 
       626 
626 
     | 
    
         
             
                            bestLength = mlen;
         
     | 
| 
       627 
     | 
    
         
            -
                            assert( 
     | 
| 
      
 627 
     | 
    
         
            +
                            assert(curr > matchIndex3);
         
     | 
| 
       628 
628 
     | 
    
         
             
                            assert(mnum==0);  /* no prior solution */
         
     | 
| 
       629 
     | 
    
         
            -
                            matches[0].off = ( 
     | 
| 
      
 629 
     | 
    
         
            +
                            matches[0].off = (curr - matchIndex3) + ZSTD_REP_MOVE;
         
     | 
| 
       630 
630 
     | 
    
         
             
                            matches[0].len = (U32)mlen;
         
     | 
| 
       631 
631 
     | 
    
         
             
                            mnum = 1;
         
     | 
| 
       632 
632 
     | 
    
         
             
                            if ( (mlen > sufficient_len) |
         
     | 
| 
       633 
633 
     | 
    
         
             
                                 (ip+mlen == iLimit) ) {  /* best possible length */
         
     | 
| 
       634 
     | 
    
         
            -
                                ms->nextToUpdate =  
     | 
| 
      
 634 
     | 
    
         
            +
                                ms->nextToUpdate = curr+1;  /* skip insertion */
         
     | 
| 
       635 
635 
     | 
    
         
             
                                return 1;
         
     | 
| 
       636 
636 
     | 
    
         
             
                    }   }   }
         
     | 
| 
       637 
637 
     | 
    
         
             
                    /* no dictMatchState lookup: dicts don't have a populated HC3 table */
         
     | 
| 
       638 
638 
     | 
    
         
             
                }
         
     | 
| 
       639 
639 
     | 
    
         | 
| 
       640 
     | 
    
         
            -
                hashTable[h] =  
     | 
| 
      
 640 
     | 
    
         
            +
                hashTable[h] = curr;   /* Update Hash Table */
         
     | 
| 
       641 
641 
     | 
    
         | 
| 
       642 
642 
     | 
    
         
             
                while (nbCompares-- && (matchIndex >= matchLow)) {
         
     | 
| 
       643 
643 
     | 
    
         
             
                    U32* const nextPtr = bt + 2*(matchIndex & btMask);
         
     | 
| 
       644 
644 
     | 
    
         
             
                    const BYTE* match;
         
     | 
| 
       645 
645 
     | 
    
         
             
                    size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
         
     | 
| 
       646 
     | 
    
         
            -
                    assert( 
     | 
| 
      
 646 
     | 
    
         
            +
                    assert(curr > matchIndex);
         
     | 
| 
       647 
647 
     | 
    
         | 
| 
       648 
648 
     | 
    
         
             
                    if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) {
         
     | 
| 
       649 
649 
     | 
    
         
             
                        assert(matchIndex+matchLength >= dictLimit);  /* ensure the condition is correct when !extDict */
         
     | 
| 
         @@ -660,12 +660,12 @@ U32 ZSTD_insertBtAndGetAllMatches ( 
     | 
|
| 
       660 
660 
     | 
    
         | 
| 
       661 
661 
     | 
    
         
             
                    if (matchLength > bestLength) {
         
     | 
| 
       662 
662 
     | 
    
         
             
                        DEBUGLOG(8, "found match of length %u at distance %u (offCode=%u)",
         
     | 
| 
       663 
     | 
    
         
            -
                                (U32)matchLength,  
     | 
| 
      
 663 
     | 
    
         
            +
                                (U32)matchLength, curr - matchIndex, curr - matchIndex + ZSTD_REP_MOVE);
         
     | 
| 
       664 
664 
     | 
    
         
             
                        assert(matchEndIdx > matchIndex);
         
     | 
| 
       665 
665 
     | 
    
         
             
                        if (matchLength > matchEndIdx - matchIndex)
         
     | 
| 
       666 
666 
     | 
    
         
             
                            matchEndIdx = matchIndex + (U32)matchLength;
         
     | 
| 
       667 
667 
     | 
    
         
             
                        bestLength = matchLength;
         
     | 
| 
       668 
     | 
    
         
            -
                        matches[mnum].off = ( 
     | 
| 
      
 668 
     | 
    
         
            +
                        matches[mnum].off = (curr - matchIndex) + ZSTD_REP_MOVE;
         
     | 
| 
       669 
669 
     | 
    
         
             
                        matches[mnum].len = (U32)matchLength;
         
     | 
| 
       670 
670 
     | 
    
         
             
                        mnum++;
         
     | 
| 
       671 
671 
     | 
    
         
             
                        if ( (matchLength > ZSTD_OPT_NUM)
         
     | 
| 
         @@ -708,11 +708,11 @@ U32 ZSTD_insertBtAndGetAllMatches ( 
     | 
|
| 
       708 
708 
     | 
    
         
             
                        if (matchLength > bestLength) {
         
     | 
| 
       709 
709 
     | 
    
         
             
                            matchIndex = dictMatchIndex + dmsIndexDelta;
         
     | 
| 
       710 
710 
     | 
    
         
             
                            DEBUGLOG(8, "found dms match of length %u at distance %u (offCode=%u)",
         
     | 
| 
       711 
     | 
    
         
            -
                                    (U32)matchLength,  
     | 
| 
      
 711 
     | 
    
         
            +
                                    (U32)matchLength, curr - matchIndex, curr - matchIndex + ZSTD_REP_MOVE);
         
     | 
| 
       712 
712 
     | 
    
         
             
                            if (matchLength > matchEndIdx - matchIndex)
         
     | 
| 
       713 
713 
     | 
    
         
             
                                matchEndIdx = matchIndex + (U32)matchLength;
         
     | 
| 
       714 
714 
     | 
    
         
             
                            bestLength = matchLength;
         
     | 
| 
       715 
     | 
    
         
            -
                            matches[mnum].off = ( 
     | 
| 
      
 715 
     | 
    
         
            +
                            matches[mnum].off = (curr - matchIndex) + ZSTD_REP_MOVE;
         
     | 
| 
       716 
716 
     | 
    
         
             
                            matches[mnum].len = (U32)matchLength;
         
     | 
| 
       717 
717 
     | 
    
         
             
                            mnum++;
         
     | 
| 
       718 
718 
     | 
    
         
             
                            if ( (matchLength > ZSTD_OPT_NUM)
         
     | 
| 
         @@ -733,7 +733,7 @@ U32 ZSTD_insertBtAndGetAllMatches ( 
     | 
|
| 
       733 
733 
     | 
    
         
             
                    }
         
     | 
| 
       734 
734 
     | 
    
         
             
                }
         
     | 
| 
       735 
735 
     | 
    
         | 
| 
       736 
     | 
    
         
            -
                assert(matchEndIdx >  
     | 
| 
      
 736 
     | 
    
         
            +
                assert(matchEndIdx > curr+8);
         
     | 
| 
       737 
737 
     | 
    
         
             
                ms->nextToUpdate = matchEndIdx - 8;  /* skip repetitive patterns */
         
     | 
| 
       738 
738 
     | 
    
         
             
                return mnum;
         
     | 
| 
       739 
739 
     | 
    
         
             
            }
         
     | 
| 
         @@ -764,6 +764,140 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches ( 
     | 
|
| 
       764 
764 
     | 
    
         
             
                }
         
     | 
| 
       765 
765 
     | 
    
         
             
            }
         
     | 
| 
       766 
766 
     | 
    
         | 
| 
      
 767 
     | 
    
         
            +
            /*************************
         
     | 
| 
      
 768 
     | 
    
         
            +
            *  LDM helper functions  *
         
     | 
| 
      
 769 
     | 
    
         
            +
            *************************/
         
     | 
| 
      
 770 
     | 
    
         
            +
             
     | 
| 
      
 771 
     | 
    
         
            +
            /* Struct containing info needed to make decision about ldm inclusion */
         
     | 
| 
      
 772 
     | 
    
         
            +
            typedef struct {
         
     | 
| 
      
 773 
     | 
    
         
            +
                rawSeqStore_t seqStore;         /* External match candidates store for this block */
         
     | 
| 
      
 774 
     | 
    
         
            +
                U32 startPosInBlock;            /* Start position of the current match candidate */
         
     | 
| 
      
 775 
     | 
    
         
            +
                U32 endPosInBlock;              /* End position of the current match candidate */
         
     | 
| 
      
 776 
     | 
    
         
            +
                U32 offset;                     /* Offset of the match candidate */
         
     | 
| 
      
 777 
     | 
    
         
            +
            } ZSTD_optLdm_t;
         
     | 
| 
      
 778 
     | 
    
         
            +
             
     | 
| 
      
 779 
     | 
    
         
            +
            /* ZSTD_optLdm_skipRawSeqStoreBytes():
         
     | 
| 
      
 780 
     | 
    
         
            +
             * Moves forward in rawSeqStore by nbBytes, which will update the fields 'pos' and 'posInSequence'.
         
     | 
| 
      
 781 
     | 
    
         
            +
             */
         
     | 
| 
      
 782 
     | 
    
         
            +
            static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes) {
         
     | 
| 
      
 783 
     | 
    
         
            +
                U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes);
         
     | 
| 
      
 784 
     | 
    
         
            +
                while (currPos && rawSeqStore->pos < rawSeqStore->size) {
         
     | 
| 
      
 785 
     | 
    
         
            +
                    rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
         
     | 
| 
      
 786 
     | 
    
         
            +
                    if (currPos >= currSeq.litLength + currSeq.matchLength) {
         
     | 
| 
      
 787 
     | 
    
         
            +
                        currPos -= currSeq.litLength + currSeq.matchLength;
         
     | 
| 
      
 788 
     | 
    
         
            +
                        rawSeqStore->pos++;
         
     | 
| 
      
 789 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 790 
     | 
    
         
            +
                        rawSeqStore->posInSequence = currPos;
         
     | 
| 
      
 791 
     | 
    
         
            +
                        break;
         
     | 
| 
      
 792 
     | 
    
         
            +
                    }
         
     | 
| 
      
 793 
     | 
    
         
            +
                }
         
     | 
| 
      
 794 
     | 
    
         
            +
                if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) {
         
     | 
| 
      
 795 
     | 
    
         
            +
                    rawSeqStore->posInSequence = 0;
         
     | 
| 
      
 796 
     | 
    
         
            +
                }
         
     | 
| 
      
 797 
     | 
    
         
            +
            }
         
     | 
| 
      
 798 
     | 
    
         
            +
             
     | 
| 
      
 799 
     | 
    
         
            +
            /* ZSTD_opt_getNextMatchAndUpdateSeqStore():
         
     | 
| 
      
 800 
     | 
    
         
            +
             * Calculates the beginning and end of the next match in the current block.
         
     | 
| 
      
 801 
     | 
    
         
            +
             * Updates 'pos' and 'posInSequence' of the ldmSeqStore.
         
     | 
| 
      
 802 
     | 
    
         
            +
             */
         
     | 
| 
      
 803 
     | 
    
         
            +
            static void ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 currPosInBlock,
         
     | 
| 
      
 804 
     | 
    
         
            +
                                                               U32 blockBytesRemaining) {
         
     | 
| 
      
 805 
     | 
    
         
            +
                rawSeq currSeq;
         
     | 
| 
      
 806 
     | 
    
         
            +
                U32 currBlockEndPos;
         
     | 
| 
      
 807 
     | 
    
         
            +
                U32 literalsBytesRemaining;
         
     | 
| 
      
 808 
     | 
    
         
            +
                U32 matchBytesRemaining;
         
     | 
| 
      
 809 
     | 
    
         
            +
             
     | 
| 
      
 810 
     | 
    
         
            +
                /* Setting match end position to MAX to ensure we never use an LDM during this block */
         
     | 
| 
      
 811 
     | 
    
         
            +
                if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
         
     | 
| 
      
 812 
     | 
    
         
            +
                    optLdm->startPosInBlock = UINT_MAX;
         
     | 
| 
      
 813 
     | 
    
         
            +
                    optLdm->endPosInBlock = UINT_MAX;
         
     | 
| 
      
 814 
     | 
    
         
            +
                    return;
         
     | 
| 
      
 815 
     | 
    
         
            +
                }
         
     | 
| 
      
 816 
     | 
    
         
            +
                /* Calculate appropriate bytes left in matchLength and litLength after adjusting
         
     | 
| 
      
 817 
     | 
    
         
            +
                   based on ldmSeqStore->posInSequence */
         
     | 
| 
      
 818 
     | 
    
         
            +
                currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos];
         
     | 
| 
      
 819 
     | 
    
         
            +
                assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength);
         
     | 
| 
      
 820 
     | 
    
         
            +
                currBlockEndPos = currPosInBlock + blockBytesRemaining;
         
     | 
| 
      
 821 
     | 
    
         
            +
                literalsBytesRemaining = (optLdm->seqStore.posInSequence < currSeq.litLength) ?
         
     | 
| 
      
 822 
     | 
    
         
            +
                        currSeq.litLength - (U32)optLdm->seqStore.posInSequence :
         
     | 
| 
      
 823 
     | 
    
         
            +
                        0;
         
     | 
| 
      
 824 
     | 
    
         
            +
                matchBytesRemaining = (literalsBytesRemaining == 0) ?
         
     | 
| 
      
 825 
     | 
    
         
            +
                        currSeq.matchLength - ((U32)optLdm->seqStore.posInSequence - currSeq.litLength) :
         
     | 
| 
      
 826 
     | 
    
         
            +
                        currSeq.matchLength;
         
     | 
| 
      
 827 
     | 
    
         
            +
             
     | 
| 
      
 828 
     | 
    
         
            +
                /* If there are more literal bytes than bytes remaining in block, no ldm is possible */
         
     | 
| 
      
 829 
     | 
    
         
            +
                if (literalsBytesRemaining >= blockBytesRemaining) {
         
     | 
| 
      
 830 
     | 
    
         
            +
                    optLdm->startPosInBlock = UINT_MAX;
         
     | 
| 
      
 831 
     | 
    
         
            +
                    optLdm->endPosInBlock = UINT_MAX;
         
     | 
| 
      
 832 
     | 
    
         
            +
                    ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, blockBytesRemaining);
         
     | 
| 
      
 833 
     | 
    
         
            +
                    return;
         
     | 
| 
      
 834 
     | 
    
         
            +
                }
         
     | 
| 
      
 835 
     | 
    
         
            +
             
     | 
| 
      
 836 
     | 
    
         
            +
                /* Matches may be < MINMATCH by this process. In that case, we will reject them
         
     | 
| 
      
 837 
     | 
    
         
            +
                   when we are deciding whether or not to add the ldm */
         
     | 
| 
      
 838 
     | 
    
         
            +
                optLdm->startPosInBlock = currPosInBlock + literalsBytesRemaining;
         
     | 
| 
      
 839 
     | 
    
         
            +
                optLdm->endPosInBlock = optLdm->startPosInBlock + matchBytesRemaining;
         
     | 
| 
      
 840 
     | 
    
         
            +
                optLdm->offset = currSeq.offset;
         
     | 
| 
      
 841 
     | 
    
         
            +
             
     | 
| 
      
 842 
     | 
    
         
            +
                if (optLdm->endPosInBlock > currBlockEndPos) {
         
     | 
| 
      
 843 
     | 
    
         
            +
                    /* Match ends after the block ends, we can't use the whole match */
         
     | 
| 
      
 844 
     | 
    
         
            +
                    optLdm->endPosInBlock = currBlockEndPos;
         
     | 
| 
      
 845 
     | 
    
         
            +
                    ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, currBlockEndPos - currPosInBlock);
         
     | 
| 
      
 846 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 847 
     | 
    
         
            +
                    /* Consume nb of bytes equal to size of sequence left */
         
     | 
| 
      
 848 
     | 
    
         
            +
                    ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, literalsBytesRemaining + matchBytesRemaining);
         
     | 
| 
      
 849 
     | 
    
         
            +
                }
         
     | 
| 
      
 850 
     | 
    
         
            +
            }
         
     | 
| 
      
 851 
     | 
    
         
            +
             
     | 
| 
      
 852 
     | 
    
         
            +
            /* ZSTD_optLdm_maybeAddMatch():
         
     | 
| 
      
 853 
     | 
    
         
            +
             * Adds a match if it's long enough, based on it's 'matchStartPosInBlock'
         
     | 
| 
      
 854 
     | 
    
         
            +
             * and 'matchEndPosInBlock', into 'matches'. Maintains the correct ordering of 'matches'
         
     | 
| 
      
 855 
     | 
    
         
            +
             */
         
     | 
| 
      
 856 
     | 
    
         
            +
            static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
         
     | 
| 
      
 857 
     | 
    
         
            +
                                                  ZSTD_optLdm_t* optLdm, U32 currPosInBlock) {
         
     | 
| 
      
 858 
     | 
    
         
            +
                U32 posDiff = currPosInBlock - optLdm->startPosInBlock;
         
     | 
| 
      
 859 
     | 
    
         
            +
                /* Note: ZSTD_match_t actually contains offCode and matchLength (before subtracting MINMATCH) */
         
     | 
| 
      
 860 
     | 
    
         
            +
                U32 candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff;
         
     | 
| 
      
 861 
     | 
    
         
            +
                U32 candidateOffCode = optLdm->offset + ZSTD_REP_MOVE;
         
     | 
| 
      
 862 
     | 
    
         
            +
             
     | 
| 
      
 863 
     | 
    
         
            +
                /* Ensure that current block position is not outside of the match */
         
     | 
| 
      
 864 
     | 
    
         
            +
                if (currPosInBlock < optLdm->startPosInBlock
         
     | 
| 
      
 865 
     | 
    
         
            +
                  || currPosInBlock >= optLdm->endPosInBlock
         
     | 
| 
      
 866 
     | 
    
         
            +
                  || candidateMatchLength < MINMATCH) {
         
     | 
| 
      
 867 
     | 
    
         
            +
                    return;
         
     | 
| 
      
 868 
     | 
    
         
            +
                }
         
     | 
| 
      
 869 
     | 
    
         
            +
             
     | 
| 
      
 870 
     | 
    
         
            +
                if (*nbMatches == 0 || ((candidateMatchLength > matches[*nbMatches-1].len) && *nbMatches < ZSTD_OPT_NUM)) {
         
     | 
| 
      
 871 
     | 
    
         
            +
                    DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offCode: %u matchLength %u) at block position=%u",
         
     | 
| 
      
 872 
     | 
    
         
            +
                             candidateOffCode, candidateMatchLength, currPosInBlock);
         
     | 
| 
      
 873 
     | 
    
         
            +
                    matches[*nbMatches].len = candidateMatchLength;
         
     | 
| 
      
 874 
     | 
    
         
            +
                    matches[*nbMatches].off = candidateOffCode;
         
     | 
| 
      
 875 
     | 
    
         
            +
                    (*nbMatches)++;
         
     | 
| 
      
 876 
     | 
    
         
            +
                }
         
     | 
| 
      
 877 
     | 
    
         
            +
            }
         
     | 
| 
      
 878 
     | 
    
         
            +
             
     | 
| 
      
 879 
     | 
    
         
            +
            /* ZSTD_optLdm_processMatchCandidate():
         
     | 
| 
      
 880 
     | 
    
         
            +
             * Wrapper function to update ldm seq store and call ldm functions as necessary.
         
     | 
| 
      
 881 
     | 
    
         
            +
             */
         
     | 
| 
      
 882 
     | 
    
         
            +
            static void ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm, ZSTD_match_t* matches, U32* nbMatches,
         
     | 
| 
      
 883 
     | 
    
         
            +
                                                          U32 currPosInBlock, U32 remainingBytes) {
         
     | 
| 
      
 884 
     | 
    
         
            +
                if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
         
     | 
| 
      
 885 
     | 
    
         
            +
                    return;
         
     | 
| 
      
 886 
     | 
    
         
            +
                }
         
     | 
| 
      
 887 
     | 
    
         
            +
             
     | 
| 
      
 888 
     | 
    
         
            +
                if (currPosInBlock >= optLdm->endPosInBlock) {
         
     | 
| 
      
 889 
     | 
    
         
            +
                    if (currPosInBlock > optLdm->endPosInBlock) {
         
     | 
| 
      
 890 
     | 
    
         
            +
                        /* The position at which ZSTD_optLdm_processMatchCandidate() is called is not necessarily
         
     | 
| 
      
 891 
     | 
    
         
            +
                         * at the end of a match from the ldm seq store, and will often be some bytes
         
     | 
| 
      
 892 
     | 
    
         
            +
                         * over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots"
         
     | 
| 
      
 893 
     | 
    
         
            +
                         */
         
     | 
| 
      
 894 
     | 
    
         
            +
                        U32 posOvershoot = currPosInBlock - optLdm->endPosInBlock;
         
     | 
| 
      
 895 
     | 
    
         
            +
                        ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot);
         
     | 
| 
      
 896 
     | 
    
         
            +
                    } 
         
     | 
| 
      
 897 
     | 
    
         
            +
                    ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes);
         
     | 
| 
      
 898 
     | 
    
         
            +
                }
         
     | 
| 
      
 899 
     | 
    
         
            +
                ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock);
         
     | 
| 
      
 900 
     | 
    
         
            +
            }
         
     | 
| 
       767 
901 
     | 
    
         | 
| 
       768 
902 
     | 
    
         
             
            /*-*******************************
         
     | 
| 
       769 
903 
     | 
    
         
             
            *  Optimal parser
         
     | 
| 
         @@ -817,6 +951,11 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, 
     | 
|
| 
       817 
951 
     | 
    
         
             
                ZSTD_optimal_t* const opt = optStatePtr->priceTable;
         
     | 
| 
       818 
952 
     | 
    
         
             
                ZSTD_match_t* const matches = optStatePtr->matchTable;
         
     | 
| 
       819 
953 
     | 
    
         
             
                ZSTD_optimal_t lastSequence;
         
     | 
| 
      
 954 
     | 
    
         
            +
                ZSTD_optLdm_t optLdm;
         
     | 
| 
      
 955 
     | 
    
         
            +
             
     | 
| 
      
 956 
     | 
    
         
            +
                optLdm.seqStore = ms->ldmSeqStore ? *ms->ldmSeqStore : kNullRawSeqStore;
         
     | 
| 
      
 957 
     | 
    
         
            +
                optLdm.endPosInBlock = optLdm.startPosInBlock = optLdm.offset = 0;
         
     | 
| 
      
 958 
     | 
    
         
            +
                ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip));
         
     | 
| 
       820 
959 
     | 
    
         | 
| 
       821 
960 
     | 
    
         
             
                /* init */
         
     | 
| 
       822 
961 
     | 
    
         
             
                DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u",
         
     | 
| 
         @@ -832,7 +971,9 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, 
     | 
|
| 
       832 
971 
     | 
    
         
             
                    /* find first match */
         
     | 
| 
       833 
972 
     | 
    
         
             
                    {   U32 const litlen = (U32)(ip - anchor);
         
     | 
| 
       834 
973 
     | 
    
         
             
                        U32 const ll0 = !litlen;
         
     | 
| 
       835 
     | 
    
         
            -
                        U32  
     | 
| 
      
 974 
     | 
    
         
            +
                        U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch);
         
     | 
| 
      
 975 
     | 
    
         
            +
                        ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
         
     | 
| 
      
 976 
     | 
    
         
            +
                                                          (U32)(ip-istart), (U32)(iend - ip));
         
     | 
| 
       836 
977 
     | 
    
         
             
                        if (!nbMatches) { ip++; continue; }
         
     | 
| 
       837 
978 
     | 
    
         | 
| 
       838 
979 
     | 
    
         
             
                        /* initialize opt[0] */
         
     | 
| 
         @@ -925,9 +1066,9 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, 
     | 
|
| 
       925 
1066 
     | 
    
         
             
                        if (opt[cur].mlen != 0) {
         
     | 
| 
       926 
1067 
     | 
    
         
             
                            U32 const prev = cur - opt[cur].mlen;
         
     | 
| 
       927 
1068 
     | 
    
         
             
                            repcodes_t newReps = ZSTD_updateRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0);
         
     | 
| 
       928 
     | 
    
         
            -
                             
     | 
| 
      
 1069 
     | 
    
         
            +
                            ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t));
         
     | 
| 
       929 
1070 
     | 
    
         
             
                        } else {
         
     | 
| 
       930 
     | 
    
         
            -
                             
     | 
| 
      
 1071 
     | 
    
         
            +
                            ZSTD_memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t));
         
     | 
| 
       931 
1072 
     | 
    
         
             
                        }
         
     | 
| 
       932 
1073 
     | 
    
         | 
| 
       933 
1074 
     | 
    
         
             
                        /* last match must start at a minimum distance of 8 from oend */
         
     | 
| 
         @@ -945,8 +1086,12 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms, 
     | 
|
| 
       945 
1086 
     | 
    
         
             
                            U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
         
     | 
| 
       946 
1087 
     | 
    
         
             
                            U32 const previousPrice = opt[cur].price;
         
     | 
| 
       947 
1088 
     | 
    
         
             
                            U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
         
     | 
| 
       948 
     | 
    
         
            -
                            U32  
     | 
| 
      
 1089 
     | 
    
         
            +
                            U32 nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch);
         
     | 
| 
       949 
1090 
     | 
    
         
             
                            U32 matchNb;
         
     | 
| 
      
 1091 
     | 
    
         
            +
             
     | 
| 
      
 1092 
     | 
    
         
            +
                            ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
         
     | 
| 
      
 1093 
     | 
    
         
            +
                                                              (U32)(inr-istart), (U32)(iend-inr));
         
     | 
| 
      
 1094 
     | 
    
         
            +
             
     | 
| 
       950 
1095 
     | 
    
         
             
                            if (!nbMatches) {
         
     | 
| 
       951 
1096 
     | 
    
         
             
                                DEBUGLOG(7, "rPos:%u : no match found", cur);
         
     | 
| 
       952 
1097 
     | 
    
         
             
                                continue;
         
     | 
| 
         @@ -1010,9 +1155,9 @@ _shortestPath:   /* cur, last_pos, best_mlen, best_off have to be set */ 
     | 
|
| 
       1010 
1155 
     | 
    
         
             
                     */
         
     | 
| 
       1011 
1156 
     | 
    
         
             
                    if (lastSequence.mlen != 0) {
         
     | 
| 
       1012 
1157 
     | 
    
         
             
                        repcodes_t reps = ZSTD_updateRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0);
         
     | 
| 
       1013 
     | 
    
         
            -
                         
     | 
| 
      
 1158 
     | 
    
         
            +
                        ZSTD_memcpy(rep, &reps, sizeof(reps));
         
     | 
| 
       1014 
1159 
     | 
    
         
             
                    } else {
         
     | 
| 
       1015 
     | 
    
         
            -
                         
     | 
| 
      
 1160 
     | 
    
         
            +
                        ZSTD_memcpy(rep, opt[cur].rep, sizeof(repcodes_t));
         
     | 
| 
       1016 
1161 
     | 
    
         
             
                    }
         
     | 
| 
       1017 
1162 
     | 
    
         | 
| 
       1018 
1163 
     | 
    
         
             
                    {   U32 const storeEnd = cur + 1;
         
     | 
| 
         @@ -1110,7 +1255,7 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms, 
     | 
|
| 
       1110 
1255 
     | 
    
         
             
                           const void* src, size_t srcSize)
         
     | 
| 
       1111 
1256 
     | 
    
         
             
            {
         
     | 
| 
       1112 
1257 
     | 
    
         
             
                U32 tmpRep[ZSTD_REP_NUM];  /* updated rep codes will sink here */
         
     | 
| 
       1113 
     | 
    
         
            -
                 
     | 
| 
      
 1258 
     | 
    
         
            +
                ZSTD_memcpy(tmpRep, rep, sizeof(tmpRep));
         
     | 
| 
       1114 
1259 
     | 
    
         | 
| 
       1115 
1260 
     | 
    
         
             
                DEBUGLOG(4, "ZSTD_initStats_ultra (srcSize=%zu)", srcSize);
         
     | 
| 
       1116 
1261 
     | 
    
         
             
                assert(ms->opt.litLengthSum == 0);    /* first block */
         
     | 
| 
         @@ -1143,7 +1288,7 @@ size_t ZSTD_compressBlock_btultra2( 
     | 
|
| 
       1143 
1288 
     | 
    
         
             
                    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
         
     | 
| 
       1144 
1289 
     | 
    
         
             
                    const void* src, size_t srcSize)
         
     | 
| 
       1145 
1290 
     | 
    
         
             
            {
         
     | 
| 
       1146 
     | 
    
         
            -
                U32 const  
     | 
| 
      
 1291 
     | 
    
         
            +
                U32 const curr = (U32)((const BYTE*)src - ms->window.base);
         
     | 
| 
       1147 
1292 
     | 
    
         
             
                DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize);
         
     | 
| 
       1148 
1293 
     | 
    
         | 
| 
       1149 
1294 
     | 
    
         
             
                /* 2-pass strategy:
         
     | 
| 
         @@ -1158,7 +1303,7 @@ size_t ZSTD_compressBlock_btultra2( 
     | 
|
| 
       1158 
1303 
     | 
    
         
             
                if ( (ms->opt.litLengthSum==0)   /* first block */
         
     | 
| 
       1159 
1304 
     | 
    
         
             
                  && (seqStore->sequences == seqStore->sequencesStart)  /* no ldm */
         
     | 
| 
       1160 
1305 
     | 
    
         
             
                  && (ms->window.dictLimit == ms->window.lowLimit)   /* no dictionary */
         
     | 
| 
       1161 
     | 
    
         
            -
                  && ( 
     | 
| 
      
 1306 
     | 
    
         
            +
                  && (curr == ms->window.dictLimit)   /* start of frame, nothing already loaded nor skipped */
         
     | 
| 
       1162 
1307 
     | 
    
         
             
                  && (srcSize > ZSTD_PREDEF_THRESHOLD)
         
     | 
| 
       1163 
1308 
     | 
    
         
             
                  ) {
         
     | 
| 
       1164 
1309 
     | 
    
         
             
                    ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize);
         
     |