git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / lib / compress / zstd_opt.c
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  * All rights reserved.
4  *
5  * This source code is licensed under both the BSD-style license (found in the
6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7  * in the COPYING file in the root directory of this source tree).
8  * You may select, at your option, one of the above-listed licenses.
9  */
10
11 #include "zstd_compress_internal.h"
12 #include "hist.h"
13 #include "zstd_opt.h"
14
15
16 #define ZSTD_LITFREQ_ADD    2   /* scaling factor for litFreq, so that frequencies adapt faster to new stats */
17 #define ZSTD_MAX_PRICE     (1<<30)
18
19 #define ZSTD_PREDEF_THRESHOLD 8   /* if srcSize < ZSTD_PREDEF_THRESHOLD, symbols' cost is assumed static, directly determined by pre-defined distributions */
20
21
22 /*-*************************************
23 *  Price functions for optimal parser
24 ***************************************/
25
26 #if 0    /* approximation at bit level (for tests) */
27 #  define BITCOST_ACCURACY 0
28 #  define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
29 #  define WEIGHT(stat, opt) ((void)(opt), ZSTD_bitWeight(stat))
30 #elif 0  /* fractional bit accuracy (for tests) */
31 #  define BITCOST_ACCURACY 8
32 #  define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
33 #  define WEIGHT(stat,opt) ((void)(opt), ZSTD_fracWeight(stat))
34 #else    /* opt==approx, ultra==accurate */
35 #  define BITCOST_ACCURACY 8
36 #  define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)
37 #  define WEIGHT(stat,opt) ((opt) ? ZSTD_fracWeight(stat) : ZSTD_bitWeight(stat))
38 #endif
39
40 /* ZSTD_bitWeight() :
41  * provide estimated "cost" of a stat in full bits only */
42 MEM_STATIC U32 ZSTD_bitWeight(U32 stat)
43 {
44     return (ZSTD_highbit32(stat+1) * BITCOST_MULTIPLIER);
45 }
46
47 /* ZSTD_fracWeight() :
48  * provide fractional-bit "cost" of a stat,
49  * using linear interpolation approximation */
50 MEM_STATIC U32 ZSTD_fracWeight(U32 rawStat)
51 {
52     U32 const stat = rawStat + 1;
53     U32 const hb = ZSTD_highbit32(stat);
54     U32 const BWeight = hb * BITCOST_MULTIPLIER;
55     /* Fweight was meant for "Fractional weight"
56      * but it's effectively a value between 1 and 2
57      * using fixed point arithmetic */
58     U32 const FWeight = (stat << BITCOST_ACCURACY) >> hb;
59     U32 const weight = BWeight + FWeight;
60     assert(hb + BITCOST_ACCURACY < 31);
61     return weight;
62 }
63
64 #if (DEBUGLEVEL>=2)
65 /* debugging function,
66  * @return price in bytes as fractional value
67  * for debug messages only */
68 MEM_STATIC double ZSTD_fCost(int price)
69 {
70     return (double)price / (BITCOST_MULTIPLIER*8);
71 }
72 #endif
73
74 static int ZSTD_compressedLiterals(optState_t const* const optPtr)
75 {
76     return optPtr->literalCompressionMode != ZSTD_ps_disable;
77 }
78
79 static void ZSTD_setBasePrices(optState_t* optPtr, int optLevel)
80 {
81     if (ZSTD_compressedLiterals(optPtr))
82         optPtr->litSumBasePrice = WEIGHT(optPtr->litSum, optLevel);
83     optPtr->litLengthSumBasePrice = WEIGHT(optPtr->litLengthSum, optLevel);
84     optPtr->matchLengthSumBasePrice = WEIGHT(optPtr->matchLengthSum, optLevel);
85     optPtr->offCodeSumBasePrice = WEIGHT(optPtr->offCodeSum, optLevel);
86 }
87
88
89 static U32 sum_u32(const unsigned table[], size_t nbElts)
90 {
91     size_t n;
92     U32 total = 0;
93     for (n=0; n<nbElts; n++) {
94         total += table[n];
95     }
96     return total;
97 }
98
99 typedef enum { base_0possible=0, base_1guaranteed=1 } base_directive_e;
100
101 static U32
102 ZSTD_downscaleStats(unsigned* table, U32 lastEltIndex, U32 shift, base_directive_e base1)
103 {
104     U32 s, sum=0;
105     DEBUGLOG(5, "ZSTD_downscaleStats (nbElts=%u, shift=%u)",
106             (unsigned)lastEltIndex+1, (unsigned)shift );
107     assert(shift < 30);
108     for (s=0; s<lastEltIndex+1; s++) {
109         unsigned const base = base1 ? 1 : (table[s]>0);
110         unsigned const newStat = base + (table[s] >> shift);
111         sum += newStat;
112         table[s] = newStat;
113     }
114     return sum;
115 }
116
117 /* ZSTD_scaleStats() :
118  * reduce all elt frequencies in table if sum too large
119  * return the resulting sum of elements */
120 static U32 ZSTD_scaleStats(unsigned* table, U32 lastEltIndex, U32 logTarget)
121 {
122     U32 const prevsum = sum_u32(table, lastEltIndex+1);
123     U32 const factor = prevsum >> logTarget;
124     DEBUGLOG(5, "ZSTD_scaleStats (nbElts=%u, target=%u)", (unsigned)lastEltIndex+1, (unsigned)logTarget);
125     assert(logTarget < 30);
126     if (factor <= 1) return prevsum;
127     return ZSTD_downscaleStats(table, lastEltIndex, ZSTD_highbit32(factor), base_1guaranteed);
128 }
129
130 /* ZSTD_rescaleFreqs() :
131  * if first block (detected by optPtr->litLengthSum == 0) : init statistics
132  *    take hints from dictionary if there is one
133  *    and init from zero if there is none,
134  *    using src for literals stats, and baseline stats for sequence symbols
135  * otherwise downscale existing stats, to be used as seed for next block.
136  */
137 static void
138 ZSTD_rescaleFreqs(optState_t* const optPtr,
139             const BYTE* const src, size_t const srcSize,
140                   int const optLevel)
141 {
142     int const compressedLiterals = ZSTD_compressedLiterals(optPtr);
143     DEBUGLOG(5, "ZSTD_rescaleFreqs (srcSize=%u)", (unsigned)srcSize);
144     optPtr->priceType = zop_dynamic;
145
146     if (optPtr->litLengthSum == 0) {  /* no literals stats collected -> first block assumed -> init */
147
148         /* heuristic: use pre-defined stats for too small inputs */
149         if (srcSize <= ZSTD_PREDEF_THRESHOLD) {
150             DEBUGLOG(5, "srcSize <= %i : use predefined stats", ZSTD_PREDEF_THRESHOLD);
151             optPtr->priceType = zop_predef;
152         }
153
154         assert(optPtr->symbolCosts != NULL);
155         if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) {
156
157             /* huffman stats covering the full value set : table presumed generated by dictionary */
158             optPtr->priceType = zop_dynamic;
159
160             if (compressedLiterals) {
161                 /* generate literals statistics from huffman table */
162                 unsigned lit;
163                 assert(optPtr->litFreq != NULL);
164                 optPtr->litSum = 0;
165                 for (lit=0; lit<=MaxLit; lit++) {
166                     U32 const scaleLog = 11;   /* scale to 2K */
167                     U32 const bitCost = HUF_getNbBitsFromCTable(optPtr->symbolCosts->huf.CTable, lit);
168                     assert(bitCost <= scaleLog);
169                     optPtr->litFreq[lit] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;
170                     optPtr->litSum += optPtr->litFreq[lit];
171             }   }
172
173             {   unsigned ll;
174                 FSE_CState_t llstate;
175                 FSE_initCState(&llstate, optPtr->symbolCosts->fse.litlengthCTable);
176                 optPtr->litLengthSum = 0;
177                 for (ll=0; ll<=MaxLL; ll++) {
178                     U32 const scaleLog = 10;   /* scale to 1K */
179                     U32 const bitCost = FSE_getMaxNbBits(llstate.symbolTT, ll);
180                     assert(bitCost < scaleLog);
181                     optPtr->litLengthFreq[ll] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;
182                     optPtr->litLengthSum += optPtr->litLengthFreq[ll];
183             }   }
184
185             {   unsigned ml;
186                 FSE_CState_t mlstate;
187                 FSE_initCState(&mlstate, optPtr->symbolCosts->fse.matchlengthCTable);
188                 optPtr->matchLengthSum = 0;
189                 for (ml=0; ml<=MaxML; ml++) {
190                     U32 const scaleLog = 10;
191                     U32 const bitCost = FSE_getMaxNbBits(mlstate.symbolTT, ml);
192                     assert(bitCost < scaleLog);
193                     optPtr->matchLengthFreq[ml] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;
194                     optPtr->matchLengthSum += optPtr->matchLengthFreq[ml];
195             }   }
196
197             {   unsigned of;
198                 FSE_CState_t ofstate;
199                 FSE_initCState(&ofstate, optPtr->symbolCosts->fse.offcodeCTable);
200                 optPtr->offCodeSum = 0;
201                 for (of=0; of<=MaxOff; of++) {
202                     U32 const scaleLog = 10;
203                     U32 const bitCost = FSE_getMaxNbBits(ofstate.symbolTT, of);
204                     assert(bitCost < scaleLog);
205                     optPtr->offCodeFreq[of] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;
206                     optPtr->offCodeSum += optPtr->offCodeFreq[of];
207             }   }
208
209         } else {  /* first block, no dictionary */
210
211             assert(optPtr->litFreq != NULL);
212             if (compressedLiterals) {
213                 /* base initial cost of literals on direct frequency within src */
214                 unsigned lit = MaxLit;
215                 HIST_count_simple(optPtr->litFreq, &lit, src, srcSize);   /* use raw first block to init statistics */
216                 optPtr->litSum = ZSTD_downscaleStats(optPtr->litFreq, MaxLit, 8, base_0possible);
217             }
218
219             {   unsigned const baseLLfreqs[MaxLL+1] = {
220                     4, 2, 1, 1, 1, 1, 1, 1,
221                     1, 1, 1, 1, 1, 1, 1, 1,
222                     1, 1, 1, 1, 1, 1, 1, 1,
223                     1, 1, 1, 1, 1, 1, 1, 1,
224                     1, 1, 1, 1
225                 };
226                 ZSTD_memcpy(optPtr->litLengthFreq, baseLLfreqs, sizeof(baseLLfreqs));
227                 optPtr->litLengthSum = sum_u32(baseLLfreqs, MaxLL+1);
228             }
229
230             {   unsigned ml;
231                 for (ml=0; ml<=MaxML; ml++)
232                     optPtr->matchLengthFreq[ml] = 1;
233             }
234             optPtr->matchLengthSum = MaxML+1;
235
236             {   unsigned const baseOFCfreqs[MaxOff+1] = {
237                     6, 2, 1, 1, 2, 3, 4, 4,
238                     4, 3, 2, 1, 1, 1, 1, 1,
239                     1, 1, 1, 1, 1, 1, 1, 1,
240                     1, 1, 1, 1, 1, 1, 1, 1
241                 };
242                 ZSTD_memcpy(optPtr->offCodeFreq, baseOFCfreqs, sizeof(baseOFCfreqs));
243                 optPtr->offCodeSum = sum_u32(baseOFCfreqs, MaxOff+1);
244             }
245
246         }
247
248     } else {   /* new block : scale down accumulated statistics */
249
250         if (compressedLiterals)
251             optPtr->litSum = ZSTD_scaleStats(optPtr->litFreq, MaxLit, 12);
252         optPtr->litLengthSum = ZSTD_scaleStats(optPtr->litLengthFreq, MaxLL, 11);
253         optPtr->matchLengthSum = ZSTD_scaleStats(optPtr->matchLengthFreq, MaxML, 11);
254         optPtr->offCodeSum = ZSTD_scaleStats(optPtr->offCodeFreq, MaxOff, 11);
255     }
256
257     ZSTD_setBasePrices(optPtr, optLevel);
258 }
259
260 /* ZSTD_rawLiteralsCost() :
261  * price of literals (only) in specified segment (which length can be 0).
262  * does not include price of literalLength symbol */
263 static U32 ZSTD_rawLiteralsCost(const BYTE* const literals, U32 const litLength,
264                                 const optState_t* const optPtr,
265                                 int optLevel)
266 {
267     if (litLength == 0) return 0;
268
269     if (!ZSTD_compressedLiterals(optPtr))
270         return (litLength << 3) * BITCOST_MULTIPLIER;  /* Uncompressed - 8 bytes per literal. */
271
272     if (optPtr->priceType == zop_predef)
273         return (litLength*6) * BITCOST_MULTIPLIER;  /* 6 bit per literal - no statistic used */
274
275     /* dynamic statistics */
276     {   U32 price = optPtr->litSumBasePrice * litLength;
277         U32 const litPriceMax = optPtr->litSumBasePrice - BITCOST_MULTIPLIER;
278         U32 u;
279         assert(optPtr->litSumBasePrice >= BITCOST_MULTIPLIER);
280         for (u=0; u < litLength; u++) {
281             U32 litPrice = WEIGHT(optPtr->litFreq[literals[u]], optLevel);
282             if (UNLIKELY(litPrice > litPriceMax)) litPrice = litPriceMax;
283             price -= litPrice;
284         }
285         return price;
286     }
287 }
288
289 /* ZSTD_litLengthPrice() :
290  * cost of literalLength symbol */
291 static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optPtr, int optLevel)
292 {
293     assert(litLength <= ZSTD_BLOCKSIZE_MAX);
294     if (optPtr->priceType == zop_predef)
295         return WEIGHT(litLength, optLevel);
296
297     /* ZSTD_LLcode() can't compute litLength price for sizes >= ZSTD_BLOCKSIZE_MAX
298      * because it isn't representable in the zstd format.
299      * So instead just pretend it would cost 1 bit more than ZSTD_BLOCKSIZE_MAX - 1.
300      * In such a case, the block would be all literals.
301      */
302     if (litLength == ZSTD_BLOCKSIZE_MAX)
303         return BITCOST_MULTIPLIER + ZSTD_litLengthPrice(ZSTD_BLOCKSIZE_MAX - 1, optPtr, optLevel);
304
305     /* dynamic statistics */
306     {   U32 const llCode = ZSTD_LLcode(litLength);
307         return (LL_bits[llCode] * BITCOST_MULTIPLIER)
308              + optPtr->litLengthSumBasePrice
309              - WEIGHT(optPtr->litLengthFreq[llCode], optLevel);
310     }
311 }
312
313 /* ZSTD_getMatchPrice() :
314  * Provides the cost of the match part (offset + matchLength) of a sequence.
315  * Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence.
316  * @offBase : sumtype, representing an offset or a repcode, and using numeric representation of ZSTD_storeSeq()
317  * @optLevel: when <2, favors small offset for decompression speed (improved cache efficiency)
318  */
319 FORCE_INLINE_TEMPLATE U32
320 ZSTD_getMatchPrice(U32 const offBase,
321                    U32 const matchLength,
322              const optState_t* const optPtr,
323                    int const optLevel)
324 {
325     U32 price;
326     U32 const offCode = ZSTD_highbit32(offBase);
327     U32 const mlBase = matchLength - MINMATCH;
328     assert(matchLength >= MINMATCH);
329
330     if (optPtr->priceType == zop_predef)  /* fixed scheme, does not use statistics */
331         return WEIGHT(mlBase, optLevel)
332              + ((16 + offCode) * BITCOST_MULTIPLIER); /* emulated offset cost */
333
334     /* dynamic statistics */
335     price = (offCode * BITCOST_MULTIPLIER) + (optPtr->offCodeSumBasePrice - WEIGHT(optPtr->offCodeFreq[offCode], optLevel));
336     if ((optLevel<2) /*static*/ && offCode >= 20)
337         price += (offCode-19)*2 * BITCOST_MULTIPLIER; /* handicap for long distance offsets, favor decompression speed */
338
339     /* match Length */
340     {   U32 const mlCode = ZSTD_MLcode(mlBase);
341         price += (ML_bits[mlCode] * BITCOST_MULTIPLIER) + (optPtr->matchLengthSumBasePrice - WEIGHT(optPtr->matchLengthFreq[mlCode], optLevel));
342     }
343
344     price += BITCOST_MULTIPLIER / 5;   /* heuristic : make matches a bit more costly to favor less sequences -> faster decompression speed */
345
346     DEBUGLOG(8, "ZSTD_getMatchPrice(ml:%u) = %u", matchLength, price);
347     return price;
348 }
349
350 /* ZSTD_updateStats() :
351  * assumption : literals + litLength <= iend */
352 static void ZSTD_updateStats(optState_t* const optPtr,
353                              U32 litLength, const BYTE* literals,
354                              U32 offBase, U32 matchLength)
355 {
356     /* literals */
357     if (ZSTD_compressedLiterals(optPtr)) {
358         U32 u;
359         for (u=0; u < litLength; u++)
360             optPtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD;
361         optPtr->litSum += litLength*ZSTD_LITFREQ_ADD;
362     }
363
364     /* literal Length */
365     {   U32 const llCode = ZSTD_LLcode(litLength);
366         optPtr->litLengthFreq[llCode]++;
367         optPtr->litLengthSum++;
368     }
369
370     /* offset code : follows storeSeq() numeric representation */
371     {   U32 const offCode = ZSTD_highbit32(offBase);
372         assert(offCode <= MaxOff);
373         optPtr->offCodeFreq[offCode]++;
374         optPtr->offCodeSum++;
375     }
376
377     /* match Length */
378     {   U32 const mlBase = matchLength - MINMATCH;
379         U32 const mlCode = ZSTD_MLcode(mlBase);
380         optPtr->matchLengthFreq[mlCode]++;
381         optPtr->matchLengthSum++;
382     }
383 }
384
385
386 /* ZSTD_readMINMATCH() :
387  * function safe only for comparisons
388  * assumption : memPtr must be at least 4 bytes before end of buffer */
389 MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
390 {
391     switch (length)
392     {
393     default :
394     case 4 : return MEM_read32(memPtr);
395     case 3 : if (MEM_isLittleEndian())
396                 return MEM_read32(memPtr)<<8;
397              else
398                 return MEM_read32(memPtr)>>8;
399     }
400 }
401
402
403 /* Update hashTable3 up to ip (excluded)
404    Assumption : always within prefix (i.e. not within extDict) */
405 static U32 ZSTD_insertAndFindFirstIndexHash3 (const ZSTD_matchState_t* ms,
406                                               U32* nextToUpdate3,
407                                               const BYTE* const ip)
408 {
409     U32* const hashTable3 = ms->hashTable3;
410     U32 const hashLog3 = ms->hashLog3;
411     const BYTE* const base = ms->window.base;
412     U32 idx = *nextToUpdate3;
413     U32 const target = (U32)(ip - base);
414     size_t const hash3 = ZSTD_hash3Ptr(ip, hashLog3);
415     assert(hashLog3 > 0);
416
417     while(idx < target) {
418         hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx;
419         idx++;
420     }
421
422     *nextToUpdate3 = target;
423     return hashTable3[hash3];
424 }
425
426
427 /*-*************************************
428 *  Binary Tree search
429 ***************************************/
430 /** ZSTD_insertBt1() : add one or multiple positions to tree.
431  * @param ip assumed <= iend-8 .
432  * @param target The target of ZSTD_updateTree_internal() - we are filling to this position
433  * @return : nb of positions added */
434 static U32 ZSTD_insertBt1(
435                 const ZSTD_matchState_t* ms,
436                 const BYTE* const ip, const BYTE* const iend,
437                 U32 const target,
438                 U32 const mls, const int extDict)
439 {
440     const ZSTD_compressionParameters* const cParams = &ms->cParams;
441     U32*   const hashTable = ms->hashTable;
442     U32    const hashLog = cParams->hashLog;
443     size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
444     U32*   const bt = ms->chainTable;
445     U32    const btLog  = cParams->chainLog - 1;
446     U32    const btMask = (1 << btLog) - 1;
447     U32 matchIndex = hashTable[h];
448     size_t commonLengthSmaller=0, commonLengthLarger=0;
449     const BYTE* const base = ms->window.base;
450     const BYTE* const dictBase = ms->window.dictBase;
451     const U32 dictLimit = ms->window.dictLimit;
452     const BYTE* const dictEnd = dictBase + dictLimit;
453     const BYTE* const prefixStart = base + dictLimit;
454     const BYTE* match;
455     const U32 curr = (U32)(ip-base);
456     const U32 btLow = btMask >= curr ? 0 : curr - btMask;
457     U32* smallerPtr = bt + 2*(curr&btMask);
458     U32* largerPtr  = smallerPtr + 1;
459     U32 dummy32;   /* to be nullified at the end */
460     /* windowLow is based on target because
461      * we only need positions that will be in the window at the end of the tree update.
462      */
463     U32 const windowLow = ZSTD_getLowestMatchIndex(ms, target, cParams->windowLog);
464     U32 matchEndIdx = curr+8+1;
465     size_t bestLength = 8;
466     U32 nbCompares = 1U << cParams->searchLog;
467 #ifdef ZSTD_C_PREDICT
468     U32 predictedSmall = *(bt + 2*((curr-1)&btMask) + 0);
469     U32 predictedLarge = *(bt + 2*((curr-1)&btMask) + 1);
470     predictedSmall += (predictedSmall>0);
471     predictedLarge += (predictedLarge>0);
472 #endif /* ZSTD_C_PREDICT */
473
474     DEBUGLOG(8, "ZSTD_insertBt1 (%u)", curr);
475
476     assert(curr <= target);
477     assert(ip <= iend-8);   /* required for h calculation */
478     hashTable[h] = curr;   /* Update Hash Table */
479
480     assert(windowLow > 0);
481     for (; nbCompares && (matchIndex >= windowLow); --nbCompares) {
482         U32* const nextPtr = bt + 2*(matchIndex & btMask);
483         size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
484         assert(matchIndex < curr);
485
486 #ifdef ZSTD_C_PREDICT   /* note : can create issues when hlog small <= 11 */
487         const U32* predictPtr = bt + 2*((matchIndex-1) & btMask);   /* written this way, as bt is a roll buffer */
488         if (matchIndex == predictedSmall) {
489             /* no need to check length, result known */
490             *smallerPtr = matchIndex;
491             if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
492             smallerPtr = nextPtr+1;               /* new "smaller" => larger of match */
493             matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
494             predictedSmall = predictPtr[1] + (predictPtr[1]>0);
495             continue;
496         }
497         if (matchIndex == predictedLarge) {
498             *largerPtr = matchIndex;
499             if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
500             largerPtr = nextPtr;
501             matchIndex = nextPtr[0];
502             predictedLarge = predictPtr[0] + (predictPtr[0]>0);
503             continue;
504         }
505 #endif
506
507         if (!extDict || (matchIndex+matchLength >= dictLimit)) {
508             assert(matchIndex+matchLength >= dictLimit);   /* might be wrong if actually extDict */
509             match = base + matchIndex;
510             matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
511         } else {
512             match = dictBase + matchIndex;
513             matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
514             if (matchIndex+matchLength >= dictLimit)
515                 match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */
516         }
517
518         if (matchLength > bestLength) {
519             bestLength = matchLength;
520             if (matchLength > matchEndIdx - matchIndex)
521                 matchEndIdx = matchIndex + (U32)matchLength;
522         }
523
524         if (ip+matchLength == iend) {   /* equal : no way to know if inf or sup */
525             break;   /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */
526         }
527
528         if (match[matchLength] < ip[matchLength]) {  /* necessarily within buffer */
529             /* match is smaller than current */
530             *smallerPtr = matchIndex;             /* update smaller idx */
531             commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
532             if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop searching */
533             smallerPtr = nextPtr+1;               /* new "candidate" => larger than match, which was smaller than target */
534             matchIndex = nextPtr[1];              /* new matchIndex, larger than previous and closer to current */
535         } else {
536             /* match is larger than current */
537             *largerPtr = matchIndex;
538             commonLengthLarger = matchLength;
539             if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop searching */
540             largerPtr = nextPtr;
541             matchIndex = nextPtr[0];
542     }   }
543
544     *smallerPtr = *largerPtr = 0;
545     {   U32 positions = 0;
546         if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384));   /* speed optimization */
547         assert(matchEndIdx > curr + 8);
548         return MAX(positions, matchEndIdx - (curr + 8));
549     }
550 }
551
552 FORCE_INLINE_TEMPLATE
553 void ZSTD_updateTree_internal(
554                 ZSTD_matchState_t* ms,
555                 const BYTE* const ip, const BYTE* const iend,
556                 const U32 mls, const ZSTD_dictMode_e dictMode)
557 {
558     const BYTE* const base = ms->window.base;
559     U32 const target = (U32)(ip - base);
560     U32 idx = ms->nextToUpdate;
561     DEBUGLOG(6, "ZSTD_updateTree_internal, from %u to %u  (dictMode:%u)",
562                 idx, target, dictMode);
563
564     while(idx < target) {
565         U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, target, mls, dictMode == ZSTD_extDict);
566         assert(idx < (U32)(idx + forward));
567         idx += forward;
568     }
569     assert((size_t)(ip - base) <= (size_t)(U32)(-1));
570     assert((size_t)(iend - base) <= (size_t)(U32)(-1));
571     ms->nextToUpdate = target;
572 }
573
574 void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend) {
575     ZSTD_updateTree_internal(ms, ip, iend, ms->cParams.minMatch, ZSTD_noDict);
576 }
577
578 FORCE_INLINE_TEMPLATE U32
579 ZSTD_insertBtAndGetAllMatches (
580                 ZSTD_match_t* matches,  /* store result (found matches) in this table (presumed large enough) */
581                 ZSTD_matchState_t* ms,
582                 U32* nextToUpdate3,
583                 const BYTE* const ip, const BYTE* const iLimit,
584                 const ZSTD_dictMode_e dictMode,
585                 const U32 rep[ZSTD_REP_NUM],
586                 const U32 ll0,  /* tells if associated literal length is 0 or not. This value must be 0 or 1 */
587                 const U32 lengthToBeat,
588                 const U32 mls /* template */)
589 {
590     const ZSTD_compressionParameters* const cParams = &ms->cParams;
591     U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
592     const BYTE* const base = ms->window.base;
593     U32 const curr = (U32)(ip-base);
594     U32 const hashLog = cParams->hashLog;
595     U32 const minMatch = (mls==3) ? 3 : 4;
596     U32* const hashTable = ms->hashTable;
597     size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);
598     U32 matchIndex  = hashTable[h];
599     U32* const bt   = ms->chainTable;
600     U32 const btLog = cParams->chainLog - 1;
601     U32 const btMask= (1U << btLog) - 1;
602     size_t commonLengthSmaller=0, commonLengthLarger=0;
603     const BYTE* const dictBase = ms->window.dictBase;
604     U32 const dictLimit = ms->window.dictLimit;
605     const BYTE* const dictEnd = dictBase + dictLimit;
606     const BYTE* const prefixStart = base + dictLimit;
607     U32 const btLow = (btMask >= curr) ? 0 : curr - btMask;
608     U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog);
609     U32 const matchLow = windowLow ? windowLow : 1;
610     U32* smallerPtr = bt + 2*(curr&btMask);
611     U32* largerPtr  = bt + 2*(curr&btMask) + 1;
612     U32 matchEndIdx = curr+8+1;   /* farthest referenced position of any match => detects repetitive patterns */
613     U32 dummy32;   /* to be nullified at the end */
614     U32 mnum = 0;
615     U32 nbCompares = 1U << cParams->searchLog;
616
617     const ZSTD_matchState_t* dms    = dictMode == ZSTD_dictMatchState ? ms->dictMatchState : NULL;
618     const ZSTD_compressionParameters* const dmsCParams =
619                                       dictMode == ZSTD_dictMatchState ? &dms->cParams : NULL;
620     const BYTE* const dmsBase       = dictMode == ZSTD_dictMatchState ? dms->window.base : NULL;
621     const BYTE* const dmsEnd        = dictMode == ZSTD_dictMatchState ? dms->window.nextSrc : NULL;
622     U32         const dmsHighLimit  = dictMode == ZSTD_dictMatchState ? (U32)(dmsEnd - dmsBase) : 0;
623     U32         const dmsLowLimit   = dictMode == ZSTD_dictMatchState ? dms->window.lowLimit : 0;
624     U32         const dmsIndexDelta = dictMode == ZSTD_dictMatchState ? windowLow - dmsHighLimit : 0;
625     U32         const dmsHashLog    = dictMode == ZSTD_dictMatchState ? dmsCParams->hashLog : hashLog;
626     U32         const dmsBtLog      = dictMode == ZSTD_dictMatchState ? dmsCParams->chainLog - 1 : btLog;
627     U32         const dmsBtMask     = dictMode == ZSTD_dictMatchState ? (1U << dmsBtLog) - 1 : 0;
628     U32         const dmsBtLow      = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit;
629
630     size_t bestLength = lengthToBeat-1;
631     DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", curr);
632
633     /* check repCode */
634     assert(ll0 <= 1);   /* necessarily 1 or 0 */
635     {   U32 const lastR = ZSTD_REP_NUM + ll0;
636         U32 repCode;
637         for (repCode = ll0; repCode < lastR; repCode++) {
638             U32 const repOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
639             U32 const repIndex = curr - repOffset;
640             U32 repLen = 0;
641             assert(curr >= dictLimit);
642             if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < curr-dictLimit) {  /* equivalent to `curr > repIndex >= dictLimit` */
643                 /* We must validate the repcode offset because when we're using a dictionary the
644                  * valid offset range shrinks when the dictionary goes out of bounds.
645                  */
646                 if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) {
647                     repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch;
648                 }
649             } else {  /* repIndex < dictLimit || repIndex >= curr */
650                 const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ?
651                                              dmsBase + repIndex - dmsIndexDelta :
652                                              dictBase + repIndex;
653                 assert(curr >= windowLow);
654                 if ( dictMode == ZSTD_extDict
655                   && ( ((repOffset-1) /*intentional overflow*/ < curr - windowLow)  /* equivalent to `curr > repIndex >= windowLow` */
656                      & (((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */)
657                   && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
658                     repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch;
659                 }
660                 if (dictMode == ZSTD_dictMatchState
661                   && ( ((repOffset-1) /*intentional overflow*/ < curr - (dmsLowLimit + dmsIndexDelta))  /* equivalent to `curr > repIndex >= dmsLowLimit` */
662                      & ((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */
663                   && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {
664                     repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch;
665             }   }
666             /* save longer solution */
667             if (repLen > bestLength) {
668                 DEBUGLOG(8, "found repCode %u (ll0:%u, offset:%u) of length %u",
669                             repCode, ll0, repOffset, repLen);
670                 bestLength = repLen;
671                 matches[mnum].off = REPCODE_TO_OFFBASE(repCode - ll0 + 1);  /* expect value between 1 and 3 */
672                 matches[mnum].len = (U32)repLen;
673                 mnum++;
674                 if ( (repLen > sufficient_len)
675                    | (ip+repLen == iLimit) ) {  /* best possible */
676                     return mnum;
677     }   }   }   }
678
679     /* HC3 match finder */
680     if ((mls == 3) /*static*/ && (bestLength < mls)) {
681         U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip);
682         if ((matchIndex3 >= matchLow)
683           & (curr - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {
684             size_t mlen;
685             if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) {
686                 const BYTE* const match = base + matchIndex3;
687                 mlen = ZSTD_count(ip, match, iLimit);
688             } else {
689                 const BYTE* const match = dictBase + matchIndex3;
690                 mlen = ZSTD_count_2segments(ip, match, iLimit, dictEnd, prefixStart);
691             }
692
693             /* save best solution */
694             if (mlen >= mls /* == 3 > bestLength */) {
695                 DEBUGLOG(8, "found small match with hlog3, of length %u",
696                             (U32)mlen);
697                 bestLength = mlen;
698                 assert(curr > matchIndex3);
699                 assert(mnum==0);  /* no prior solution */
700                 matches[0].off = OFFSET_TO_OFFBASE(curr - matchIndex3);
701                 matches[0].len = (U32)mlen;
702                 mnum = 1;
703                 if ( (mlen > sufficient_len) |
704                      (ip+mlen == iLimit) ) {  /* best possible length */
705                     ms->nextToUpdate = curr+1;  /* skip insertion */
706                     return 1;
707         }   }   }
708         /* no dictMatchState lookup: dicts don't have a populated HC3 table */
709     }  /* if (mls == 3) */
710
711     hashTable[h] = curr;   /* Update Hash Table */
712
713     for (; nbCompares && (matchIndex >= matchLow); --nbCompares) {
714         U32* const nextPtr = bt + 2*(matchIndex & btMask);
715         const BYTE* match;
716         size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
717         assert(curr > matchIndex);
718
719         if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) {
720             assert(matchIndex+matchLength >= dictLimit);  /* ensure the condition is correct when !extDict */
721             match = base + matchIndex;
722             if (matchIndex >= dictLimit) assert(memcmp(match, ip, matchLength) == 0);  /* ensure early section of match is equal as expected */
723             matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit);
724         } else {
725             match = dictBase + matchIndex;
726             assert(memcmp(match, ip, matchLength) == 0);  /* ensure early section of match is equal as expected */
727             matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
728             if (matchIndex+matchLength >= dictLimit)
729                 match = base + matchIndex;   /* prepare for match[matchLength] read */
730         }
731
732         if (matchLength > bestLength) {
733             DEBUGLOG(8, "found match of length %u at distance %u (offBase=%u)",
734                     (U32)matchLength, curr - matchIndex, OFFSET_TO_OFFBASE(curr - matchIndex));
735             assert(matchEndIdx > matchIndex);
736             if (matchLength > matchEndIdx - matchIndex)
737                 matchEndIdx = matchIndex + (U32)matchLength;
738             bestLength = matchLength;
739             matches[mnum].off = OFFSET_TO_OFFBASE(curr - matchIndex);
740             matches[mnum].len = (U32)matchLength;
741             mnum++;
742             if ( (matchLength > ZSTD_OPT_NUM)
743                | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) {
744                 if (dictMode == ZSTD_dictMatchState) nbCompares = 0; /* break should also skip searching dms */
745                 break; /* drop, to preserve bt consistency (miss a little bit of compression) */
746         }   }
747
748         if (match[matchLength] < ip[matchLength]) {
749             /* match smaller than current */
750             *smallerPtr = matchIndex;             /* update smaller idx */
751             commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
752             if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
753             smallerPtr = nextPtr+1;               /* new candidate => larger than match, which was smaller than current */
754             matchIndex = nextPtr[1];              /* new matchIndex, larger than previous, closer to current */
755         } else {
756             *largerPtr = matchIndex;
757             commonLengthLarger = matchLength;
758             if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */
759             largerPtr = nextPtr;
760             matchIndex = nextPtr[0];
761     }   }
762
763     *smallerPtr = *largerPtr = 0;
764
765     assert(nbCompares <= (1U << ZSTD_SEARCHLOG_MAX)); /* Check we haven't underflowed. */
766     if (dictMode == ZSTD_dictMatchState && nbCompares) {
767         size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls);
768         U32 dictMatchIndex = dms->hashTable[dmsH];
769         const U32* const dmsBt = dms->chainTable;
770         commonLengthSmaller = commonLengthLarger = 0;
771         for (; nbCompares && (dictMatchIndex > dmsLowLimit); --nbCompares) {
772             const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask);
773             size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */
774             const BYTE* match = dmsBase + dictMatchIndex;
775             matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dmsEnd, prefixStart);
776             if (dictMatchIndex+matchLength >= dmsHighLimit)
777                 match = base + dictMatchIndex + dmsIndexDelta;   /* to prepare for next usage of match[matchLength] */
778
779             if (matchLength > bestLength) {
780                 matchIndex = dictMatchIndex + dmsIndexDelta;
781                 DEBUGLOG(8, "found dms match of length %u at distance %u (offBase=%u)",
782                         (U32)matchLength, curr - matchIndex, OFFSET_TO_OFFBASE(curr - matchIndex));
783                 if (matchLength > matchEndIdx - matchIndex)
784                     matchEndIdx = matchIndex + (U32)matchLength;
785                 bestLength = matchLength;
786                 matches[mnum].off = OFFSET_TO_OFFBASE(curr - matchIndex);
787                 matches[mnum].len = (U32)matchLength;
788                 mnum++;
789                 if ( (matchLength > ZSTD_OPT_NUM)
790                    | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) {
791                     break;   /* drop, to guarantee consistency (miss a little bit of compression) */
792             }   }
793
794             if (dictMatchIndex <= dmsBtLow) { break; }   /* beyond tree size, stop the search */
795             if (match[matchLength] < ip[matchLength]) {
796                 commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */
797                 dictMatchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */
798             } else {
799                 /* match is larger than current */
800                 commonLengthLarger = matchLength;
801                 dictMatchIndex = nextPtr[0];
802     }   }   }  /* if (dictMode == ZSTD_dictMatchState) */
803
804     assert(matchEndIdx > curr+8);
805     ms->nextToUpdate = matchEndIdx - 8;  /* skip repetitive patterns */
806     return mnum;
807 }
808
809 typedef U32 (*ZSTD_getAllMatchesFn)(
810     ZSTD_match_t*,
811     ZSTD_matchState_t*,
812     U32*,
813     const BYTE*,
814     const BYTE*,
815     const U32 rep[ZSTD_REP_NUM],
816     U32 const ll0,
817     U32 const lengthToBeat);
818
819 FORCE_INLINE_TEMPLATE U32 ZSTD_btGetAllMatches_internal(
820         ZSTD_match_t* matches,
821         ZSTD_matchState_t* ms,
822         U32* nextToUpdate3,
823         const BYTE* ip,
824         const BYTE* const iHighLimit,
825         const U32 rep[ZSTD_REP_NUM],
826         U32 const ll0,
827         U32 const lengthToBeat,
828         const ZSTD_dictMode_e dictMode,
829         const U32 mls)
830 {
831     assert(BOUNDED(3, ms->cParams.minMatch, 6) == mls);
832     DEBUGLOG(8, "ZSTD_BtGetAllMatches(dictMode=%d, mls=%u)", (int)dictMode, mls);
833     if (ip < ms->window.base + ms->nextToUpdate)
834         return 0;   /* skipped area */
835     ZSTD_updateTree_internal(ms, ip, iHighLimit, mls, dictMode);
836     return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, mls);
837 }
838
839 #define ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls) ZSTD_btGetAllMatches_##dictMode##_##mls
840
841 #define GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, mls)            \
842     static U32 ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, mls)(      \
843             ZSTD_match_t* matches,                             \
844             ZSTD_matchState_t* ms,                             \
845             U32* nextToUpdate3,                                \
846             const BYTE* ip,                                    \
847             const BYTE* const iHighLimit,                      \
848             const U32 rep[ZSTD_REP_NUM],                       \
849             U32 const ll0,                                     \
850             U32 const lengthToBeat)                            \
851     {                                                          \
852         return ZSTD_btGetAllMatches_internal(                  \
853                 matches, ms, nextToUpdate3, ip, iHighLimit,    \
854                 rep, ll0, lengthToBeat, ZSTD_##dictMode, mls); \
855     }
856
857 #define GEN_ZSTD_BT_GET_ALL_MATCHES(dictMode)  \
858     GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 3)  \
859     GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 4)  \
860     GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 5)  \
861     GEN_ZSTD_BT_GET_ALL_MATCHES_(dictMode, 6)
862
863 GEN_ZSTD_BT_GET_ALL_MATCHES(noDict)
864 GEN_ZSTD_BT_GET_ALL_MATCHES(extDict)
865 GEN_ZSTD_BT_GET_ALL_MATCHES(dictMatchState)
866
867 #define ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMode)  \
868     {                                            \
869         ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 3), \
870         ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 4), \
871         ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 5), \
872         ZSTD_BT_GET_ALL_MATCHES_FN(dictMode, 6)  \
873     }
874
875 static ZSTD_getAllMatchesFn
876 ZSTD_selectBtGetAllMatches(ZSTD_matchState_t const* ms, ZSTD_dictMode_e const dictMode)
877 {
878     ZSTD_getAllMatchesFn const getAllMatchesFns[3][4] = {
879         ZSTD_BT_GET_ALL_MATCHES_ARRAY(noDict),
880         ZSTD_BT_GET_ALL_MATCHES_ARRAY(extDict),
881         ZSTD_BT_GET_ALL_MATCHES_ARRAY(dictMatchState)
882     };
883     U32 const mls = BOUNDED(3, ms->cParams.minMatch, 6);
884     assert((U32)dictMode < 3);
885     assert(mls - 3 < 4);
886     return getAllMatchesFns[(int)dictMode][mls - 3];
887 }
888
889 /*************************
890 *  LDM helper functions  *
891 *************************/
892
893 /* Struct containing info needed to make decision about ldm inclusion */
894 typedef struct {
895     rawSeqStore_t seqStore;   /* External match candidates store for this block */
896     U32 startPosInBlock;      /* Start position of the current match candidate */
897     U32 endPosInBlock;        /* End position of the current match candidate */
898     U32 offset;               /* Offset of the match candidate */
899 } ZSTD_optLdm_t;
900
901 /* ZSTD_optLdm_skipRawSeqStoreBytes():
902  * Moves forward in @rawSeqStore by @nbBytes,
903  * which will update the fields 'pos' and 'posInSequence'.
904  */
905 static void ZSTD_optLdm_skipRawSeqStoreBytes(rawSeqStore_t* rawSeqStore, size_t nbBytes)
906 {
907     U32 currPos = (U32)(rawSeqStore->posInSequence + nbBytes);
908     while (currPos && rawSeqStore->pos < rawSeqStore->size) {
909         rawSeq currSeq = rawSeqStore->seq[rawSeqStore->pos];
910         if (currPos >= currSeq.litLength + currSeq.matchLength) {
911             currPos -= currSeq.litLength + currSeq.matchLength;
912             rawSeqStore->pos++;
913         } else {
914             rawSeqStore->posInSequence = currPos;
915             break;
916         }
917     }
918     if (currPos == 0 || rawSeqStore->pos == rawSeqStore->size) {
919         rawSeqStore->posInSequence = 0;
920     }
921 }
922
923 /* ZSTD_opt_getNextMatchAndUpdateSeqStore():
924  * Calculates the beginning and end of the next match in the current block.
925  * Updates 'pos' and 'posInSequence' of the ldmSeqStore.
926  */
927 static void
928 ZSTD_opt_getNextMatchAndUpdateSeqStore(ZSTD_optLdm_t* optLdm, U32 currPosInBlock,
929                                        U32 blockBytesRemaining)
930 {
931     rawSeq currSeq;
932     U32 currBlockEndPos;
933     U32 literalsBytesRemaining;
934     U32 matchBytesRemaining;
935
936     /* Setting match end position to MAX to ensure we never use an LDM during this block */
937     if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
938         optLdm->startPosInBlock = UINT_MAX;
939         optLdm->endPosInBlock = UINT_MAX;
940         return;
941     }
942     /* Calculate appropriate bytes left in matchLength and litLength
943      * after adjusting based on ldmSeqStore->posInSequence */
944     currSeq = optLdm->seqStore.seq[optLdm->seqStore.pos];
945     assert(optLdm->seqStore.posInSequence <= currSeq.litLength + currSeq.matchLength);
946     currBlockEndPos = currPosInBlock + blockBytesRemaining;
947     literalsBytesRemaining = (optLdm->seqStore.posInSequence < currSeq.litLength) ?
948             currSeq.litLength - (U32)optLdm->seqStore.posInSequence :
949             0;
950     matchBytesRemaining = (literalsBytesRemaining == 0) ?
951             currSeq.matchLength - ((U32)optLdm->seqStore.posInSequence - currSeq.litLength) :
952             currSeq.matchLength;
953
954     /* If there are more literal bytes than bytes remaining in block, no ldm is possible */
955     if (literalsBytesRemaining >= blockBytesRemaining) {
956         optLdm->startPosInBlock = UINT_MAX;
957         optLdm->endPosInBlock = UINT_MAX;
958         ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, blockBytesRemaining);
959         return;
960     }
961
962     /* Matches may be < MINMATCH by this process. In that case, we will reject them
963        when we are deciding whether or not to add the ldm */
964     optLdm->startPosInBlock = currPosInBlock + literalsBytesRemaining;
965     optLdm->endPosInBlock = optLdm->startPosInBlock + matchBytesRemaining;
966     optLdm->offset = currSeq.offset;
967
968     if (optLdm->endPosInBlock > currBlockEndPos) {
969         /* Match ends after the block ends, we can't use the whole match */
970         optLdm->endPosInBlock = currBlockEndPos;
971         ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, currBlockEndPos - currPosInBlock);
972     } else {
973         /* Consume nb of bytes equal to size of sequence left */
974         ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, literalsBytesRemaining + matchBytesRemaining);
975     }
976 }
977
978 /* ZSTD_optLdm_maybeAddMatch():
979  * Adds a match if it's long enough,
980  * based on it's 'matchStartPosInBlock' and 'matchEndPosInBlock',
981  * into 'matches'. Maintains the correct ordering of 'matches'.
982  */
983 static void ZSTD_optLdm_maybeAddMatch(ZSTD_match_t* matches, U32* nbMatches,
984                                       const ZSTD_optLdm_t* optLdm, U32 currPosInBlock)
985 {
986     U32 const posDiff = currPosInBlock - optLdm->startPosInBlock;
987     /* Note: ZSTD_match_t actually contains offBase and matchLength (before subtracting MINMATCH) */
988     U32 const candidateMatchLength = optLdm->endPosInBlock - optLdm->startPosInBlock - posDiff;
989
990     /* Ensure that current block position is not outside of the match */
991     if (currPosInBlock < optLdm->startPosInBlock
992       || currPosInBlock >= optLdm->endPosInBlock
993       || candidateMatchLength < MINMATCH) {
994         return;
995     }
996
997     if (*nbMatches == 0 || ((candidateMatchLength > matches[*nbMatches-1].len) && *nbMatches < ZSTD_OPT_NUM)) {
998         U32 const candidateOffBase = OFFSET_TO_OFFBASE(optLdm->offset);
999         DEBUGLOG(6, "ZSTD_optLdm_maybeAddMatch(): Adding ldm candidate match (offBase: %u matchLength %u) at block position=%u",
1000                  candidateOffBase, candidateMatchLength, currPosInBlock);
1001         matches[*nbMatches].len = candidateMatchLength;
1002         matches[*nbMatches].off = candidateOffBase;
1003         (*nbMatches)++;
1004     }
1005 }
1006
1007 /* ZSTD_optLdm_processMatchCandidate():
1008  * Wrapper function to update ldm seq store and call ldm functions as necessary.
1009  */
1010 static void
1011 ZSTD_optLdm_processMatchCandidate(ZSTD_optLdm_t* optLdm,
1012                                   ZSTD_match_t* matches, U32* nbMatches,
1013                                   U32 currPosInBlock, U32 remainingBytes)
1014 {
1015     if (optLdm->seqStore.size == 0 || optLdm->seqStore.pos >= optLdm->seqStore.size) {
1016         return;
1017     }
1018
1019     if (currPosInBlock >= optLdm->endPosInBlock) {
1020         if (currPosInBlock > optLdm->endPosInBlock) {
1021             /* The position at which ZSTD_optLdm_processMatchCandidate() is called is not necessarily
1022              * at the end of a match from the ldm seq store, and will often be some bytes
1023              * over beyond matchEndPosInBlock. As such, we need to correct for these "overshoots"
1024              */
1025             U32 const posOvershoot = currPosInBlock - optLdm->endPosInBlock;
1026             ZSTD_optLdm_skipRawSeqStoreBytes(&optLdm->seqStore, posOvershoot);
1027         }
1028         ZSTD_opt_getNextMatchAndUpdateSeqStore(optLdm, currPosInBlock, remainingBytes);
1029     }
1030     ZSTD_optLdm_maybeAddMatch(matches, nbMatches, optLdm, currPosInBlock);
1031 }
1032
1033
1034 /*-*******************************
1035 *  Optimal parser
1036 *********************************/
1037
1038 static U32 ZSTD_totalLen(ZSTD_optimal_t sol)
1039 {
1040     return sol.litlen + sol.mlen;
1041 }
1042
1043 #if 0 /* debug */
1044
1045 static void
1046 listStats(const U32* table, int lastEltID)
1047 {
1048     int const nbElts = lastEltID + 1;
1049     int enb;
1050     for (enb=0; enb < nbElts; enb++) {
1051         (void)table;
1052         /* RAWLOG(2, "%3i:%3i,  ", enb, table[enb]); */
1053         RAWLOG(2, "%4i,", table[enb]);
1054     }
1055     RAWLOG(2, " \n");
1056 }
1057
1058 #endif
1059
1060 FORCE_INLINE_TEMPLATE size_t
1061 ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
1062                                seqStore_t* seqStore,
1063                                U32 rep[ZSTD_REP_NUM],
1064                          const void* src, size_t srcSize,
1065                          const int optLevel,
1066                          const ZSTD_dictMode_e dictMode)
1067 {
1068     optState_t* const optStatePtr = &ms->opt;
1069     const BYTE* const istart = (const BYTE*)src;
1070     const BYTE* ip = istart;
1071     const BYTE* anchor = istart;
1072     const BYTE* const iend = istart + srcSize;
1073     const BYTE* const ilimit = iend - 8;
1074     const BYTE* const base = ms->window.base;
1075     const BYTE* const prefixStart = base + ms->window.dictLimit;
1076     const ZSTD_compressionParameters* const cParams = &ms->cParams;
1077
1078     ZSTD_getAllMatchesFn getAllMatches = ZSTD_selectBtGetAllMatches(ms, dictMode);
1079
1080     U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
1081     U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4;
1082     U32 nextToUpdate3 = ms->nextToUpdate;
1083
1084     ZSTD_optimal_t* const opt = optStatePtr->priceTable;
1085     ZSTD_match_t* const matches = optStatePtr->matchTable;
1086     ZSTD_optimal_t lastSequence;
1087     ZSTD_optLdm_t optLdm;
1088
1089     ZSTD_memset(&lastSequence, 0, sizeof(ZSTD_optimal_t));
1090
1091     optLdm.seqStore = ms->ldmSeqStore ? *ms->ldmSeqStore : kNullRawSeqStore;
1092     optLdm.endPosInBlock = optLdm.startPosInBlock = optLdm.offset = 0;
1093     ZSTD_opt_getNextMatchAndUpdateSeqStore(&optLdm, (U32)(ip-istart), (U32)(iend-ip));
1094
1095     /* init */
1096     DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u",
1097                 (U32)(ip - base), ms->window.dictLimit, ms->nextToUpdate);
1098     assert(optLevel <= 2);
1099     ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize, optLevel);
1100     ip += (ip==prefixStart);
1101
1102     /* Match Loop */
1103     while (ip < ilimit) {
1104         U32 cur, last_pos = 0;
1105
1106         /* find first match */
1107         {   U32 const litlen = (U32)(ip - anchor);
1108             U32 const ll0 = !litlen;
1109             U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, ip, iend, rep, ll0, minMatch);
1110             ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
1111                                               (U32)(ip-istart), (U32)(iend - ip));
1112             if (!nbMatches) { ip++; continue; }
1113
1114             /* initialize opt[0] */
1115             { U32 i ; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
1116             opt[0].mlen = 0;  /* means is_a_literal */
1117             opt[0].litlen = litlen;
1118             /* We don't need to include the actual price of the literals because
1119              * it is static for the duration of the forward pass, and is included
1120              * in every price. We include the literal length to avoid negative
1121              * prices when we subtract the previous literal length.
1122              */
1123             opt[0].price = (int)ZSTD_litLengthPrice(litlen, optStatePtr, optLevel);
1124
1125             /* large match -> immediate encoding */
1126             {   U32 const maxML = matches[nbMatches-1].len;
1127                 U32 const maxOffBase = matches[nbMatches-1].off;
1128                 DEBUGLOG(6, "found %u matches of maxLength=%u and maxOffBase=%u at cPos=%u => start new series",
1129                             nbMatches, maxML, maxOffBase, (U32)(ip-prefixStart));
1130
1131                 if (maxML > sufficient_len) {
1132                     lastSequence.litlen = litlen;
1133                     lastSequence.mlen = maxML;
1134                     lastSequence.off = maxOffBase;
1135                     DEBUGLOG(6, "large match (%u>%u), immediate encoding",
1136                                 maxML, sufficient_len);
1137                     cur = 0;
1138                     last_pos = ZSTD_totalLen(lastSequence);
1139                     goto _shortestPath;
1140             }   }
1141
1142             /* set prices for first matches starting position == 0 */
1143             assert(opt[0].price >= 0);
1144             {   U32 const literalsPrice = (U32)opt[0].price + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
1145                 U32 pos;
1146                 U32 matchNb;
1147                 for (pos = 1; pos < minMatch; pos++) {
1148                     opt[pos].price = ZSTD_MAX_PRICE;   /* mlen, litlen and price will be fixed during forward scanning */
1149                 }
1150                 for (matchNb = 0; matchNb < nbMatches; matchNb++) {
1151                     U32 const offBase = matches[matchNb].off;
1152                     U32 const end = matches[matchNb].len;
1153                     for ( ; pos <= end ; pos++ ) {
1154                         U32 const matchPrice = ZSTD_getMatchPrice(offBase, pos, optStatePtr, optLevel);
1155                         U32 const sequencePrice = literalsPrice + matchPrice;
1156                         DEBUGLOG(7, "rPos:%u => set initial price : %.2f",
1157                                     pos, ZSTD_fCost((int)sequencePrice));
1158                         opt[pos].mlen = pos;
1159                         opt[pos].off = offBase;
1160                         opt[pos].litlen = litlen;
1161                         opt[pos].price = (int)sequencePrice;
1162                 }   }
1163                 last_pos = pos-1;
1164             }
1165         }
1166
1167         /* check further positions */
1168         for (cur = 1; cur <= last_pos; cur++) {
1169             const BYTE* const inr = ip + cur;
1170             assert(cur < ZSTD_OPT_NUM);
1171             DEBUGLOG(7, "cPos:%zi==rPos:%u", inr-istart, cur)
1172
1173             /* Fix current position with one literal if cheaper */
1174             {   U32 const litlen = (opt[cur-1].mlen == 0) ? opt[cur-1].litlen + 1 : 1;
1175                 int const price = opt[cur-1].price
1176                                 + (int)ZSTD_rawLiteralsCost(ip+cur-1, 1, optStatePtr, optLevel)
1177                                 + (int)ZSTD_litLengthPrice(litlen, optStatePtr, optLevel)
1178                                 - (int)ZSTD_litLengthPrice(litlen-1, optStatePtr, optLevel);
1179                 assert(price < 1000000000); /* overflow check */
1180                 if (price <= opt[cur].price) {
1181                     DEBUGLOG(7, "cPos:%zi==rPos:%u : better price (%.2f<=%.2f) using literal (ll==%u) (hist:%u,%u,%u)",
1182                                 inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price), litlen,
1183                                 opt[cur-1].rep[0], opt[cur-1].rep[1], opt[cur-1].rep[2]);
1184                     opt[cur].mlen = 0;
1185                     opt[cur].off = 0;
1186                     opt[cur].litlen = litlen;
1187                     opt[cur].price = price;
1188                 } else {
1189                     DEBUGLOG(7, "cPos:%zi==rPos:%u : literal would cost more (%.2f>%.2f) (hist:%u,%u,%u)",
1190                                 inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price),
1191                                 opt[cur].rep[0], opt[cur].rep[1], opt[cur].rep[2]);
1192                 }
1193             }
1194
1195             /* Set the repcodes of the current position. We must do it here
1196              * because we rely on the repcodes of the 2nd to last sequence being
1197              * correct to set the next chunks repcodes during the backward
1198              * traversal.
1199              */
1200             ZSTD_STATIC_ASSERT(sizeof(opt[cur].rep) == sizeof(repcodes_t));
1201             assert(cur >= opt[cur].mlen);
1202             if (opt[cur].mlen != 0) {
1203                 U32 const prev = cur - opt[cur].mlen;
1204                 repcodes_t const newReps = ZSTD_newRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0);
1205                 ZSTD_memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t));
1206             } else {
1207                 ZSTD_memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t));
1208             }
1209
1210             /* last match must start at a minimum distance of 8 from oend */
1211             if (inr > ilimit) continue;
1212
1213             if (cur == last_pos) break;
1214
1215             if ( (optLevel==0) /*static_test*/
1216               && (opt[cur+1].price <= opt[cur].price + (BITCOST_MULTIPLIER/2)) ) {
1217                 DEBUGLOG(7, "move to next rPos:%u : price is <=", cur+1);
1218                 continue;  /* skip unpromising positions; about ~+6% speed, -0.01 ratio */
1219             }
1220
1221             assert(opt[cur].price >= 0);
1222             {   U32 const ll0 = (opt[cur].mlen != 0);
1223                 U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
1224                 U32 const previousPrice = (U32)opt[cur].price;
1225                 U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
1226                 U32 nbMatches = getAllMatches(matches, ms, &nextToUpdate3, inr, iend, opt[cur].rep, ll0, minMatch);
1227                 U32 matchNb;
1228
1229                 ZSTD_optLdm_processMatchCandidate(&optLdm, matches, &nbMatches,
1230                                                   (U32)(inr-istart), (U32)(iend-inr));
1231
1232                 if (!nbMatches) {
1233                     DEBUGLOG(7, "rPos:%u : no match found", cur);
1234                     continue;
1235                 }
1236
1237                 {   U32 const maxML = matches[nbMatches-1].len;
1238                     DEBUGLOG(7, "cPos:%zi==rPos:%u, found %u matches, of maxLength=%u",
1239                                 inr-istart, cur, nbMatches, maxML);
1240
1241                     if ( (maxML > sufficient_len)
1242                       || (cur + maxML >= ZSTD_OPT_NUM) ) {
1243                         lastSequence.mlen = maxML;
1244                         lastSequence.off = matches[nbMatches-1].off;
1245                         lastSequence.litlen = litlen;
1246                         cur -= (opt[cur].mlen==0) ? opt[cur].litlen : 0;  /* last sequence is actually only literals, fix cur to last match - note : may underflow, in which case, it's first sequence, and it's okay */
1247                         last_pos = cur + ZSTD_totalLen(lastSequence);
1248                         if (cur > ZSTD_OPT_NUM) cur = 0;   /* underflow => first match */
1249                         goto _shortestPath;
1250                 }   }
1251
1252                 /* set prices using matches found at position == cur */
1253                 for (matchNb = 0; matchNb < nbMatches; matchNb++) {
1254                     U32 const offset = matches[matchNb].off;
1255                     U32 const lastML = matches[matchNb].len;
1256                     U32 const startML = (matchNb>0) ? matches[matchNb-1].len+1 : minMatch;
1257                     U32 mlen;
1258
1259                     DEBUGLOG(7, "testing match %u => offBase=%4u, mlen=%2u, llen=%2u",
1260                                 matchNb, matches[matchNb].off, lastML, litlen);
1261
1262                     for (mlen = lastML; mlen >= startML; mlen--) {  /* scan downward */
1263                         U32 const pos = cur + mlen;
1264                         int const price = (int)basePrice + (int)ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel);
1265
1266                         if ((pos > last_pos) || (price < opt[pos].price)) {
1267                             DEBUGLOG(7, "rPos:%u (ml=%2u) => new better price (%.2f<%.2f)",
1268                                         pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price));
1269                             while (last_pos < pos) { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; }   /* fill empty positions */
1270                             opt[pos].mlen = mlen;
1271                             opt[pos].off = offset;
1272                             opt[pos].litlen = litlen;
1273                             opt[pos].price = price;
1274                         } else {
1275                             DEBUGLOG(7, "rPos:%u (ml=%2u) => new price is worse (%.2f>=%.2f)",
1276                                         pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price));
1277                             if (optLevel==0) break;  /* early update abort; gets ~+10% speed for about -0.01 ratio loss */
1278                         }
1279             }   }   }
1280         }  /* for (cur = 1; cur <= last_pos; cur++) */
1281
1282         lastSequence = opt[last_pos];
1283         cur = last_pos > ZSTD_totalLen(lastSequence) ? last_pos - ZSTD_totalLen(lastSequence) : 0;  /* single sequence, and it starts before `ip` */
1284         assert(cur < ZSTD_OPT_NUM);  /* control overflow*/
1285
1286 _shortestPath:   /* cur, last_pos, best_mlen, best_off have to be set */
1287         assert(opt[0].mlen == 0);
1288
1289         /* Set the next chunk's repcodes based on the repcodes of the beginning
1290          * of the last match, and the last sequence. This avoids us having to
1291          * update them while traversing the sequences.
1292          */
1293         if (lastSequence.mlen != 0) {
1294             repcodes_t const reps = ZSTD_newRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0);
1295             ZSTD_memcpy(rep, &reps, sizeof(reps));
1296         } else {
1297             ZSTD_memcpy(rep, opt[cur].rep, sizeof(repcodes_t));
1298         }
1299
1300         {   U32 const storeEnd = cur + 1;
1301             U32 storeStart = storeEnd;
1302             U32 seqPos = cur;
1303
1304             DEBUGLOG(6, "start reverse traversal (last_pos:%u, cur:%u)",
1305                         last_pos, cur); (void)last_pos;
1306             assert(storeEnd < ZSTD_OPT_NUM);
1307             DEBUGLOG(6, "last sequence copied into pos=%u (llen=%u,mlen=%u,ofc=%u)",
1308                         storeEnd, lastSequence.litlen, lastSequence.mlen, lastSequence.off);
1309             opt[storeEnd] = lastSequence;
1310             while (seqPos > 0) {
1311                 U32 const backDist = ZSTD_totalLen(opt[seqPos]);
1312                 storeStart--;
1313                 DEBUGLOG(6, "sequence from rPos=%u copied into pos=%u (llen=%u,mlen=%u,ofc=%u)",
1314                             seqPos, storeStart, opt[seqPos].litlen, opt[seqPos].mlen, opt[seqPos].off);
1315                 opt[storeStart] = opt[seqPos];
1316                 seqPos = (seqPos > backDist) ? seqPos - backDist : 0;
1317             }
1318
1319             /* save sequences */
1320             DEBUGLOG(6, "sending selected sequences into seqStore")
1321             {   U32 storePos;
1322                 for (storePos=storeStart; storePos <= storeEnd; storePos++) {
1323                     U32 const llen = opt[storePos].litlen;
1324                     U32 const mlen = opt[storePos].mlen;
1325                     U32 const offBase = opt[storePos].off;
1326                     U32 const advance = llen + mlen;
1327                     DEBUGLOG(6, "considering seq starting at %zi, llen=%u, mlen=%u",
1328                                 anchor - istart, (unsigned)llen, (unsigned)mlen);
1329
1330                     if (mlen==0) {  /* only literals => must be last "sequence", actually starting a new stream of sequences */
1331                         assert(storePos == storeEnd);   /* must be last sequence */
1332                         ip = anchor + llen;     /* last "sequence" is a bunch of literals => don't progress anchor */
1333                         continue;   /* will finish */
1334                     }
1335
1336                     assert(anchor + llen <= iend);
1337                     ZSTD_updateStats(optStatePtr, llen, anchor, offBase, mlen);
1338                     ZSTD_storeSeq(seqStore, llen, anchor, iend, offBase, mlen);
1339                     anchor += advance;
1340                     ip = anchor;
1341             }   }
1342             ZSTD_setBasePrices(optStatePtr, optLevel);
1343         }
1344     }   /* while (ip < ilimit) */
1345
1346     /* Return the last literals size */
1347     return (size_t)(iend - anchor);
1348 }
1349
1350 static size_t ZSTD_compressBlock_opt0(
1351         ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1352         const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode)
1353 {
1354     return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /* optLevel */, dictMode);
1355 }
1356
1357 static size_t ZSTD_compressBlock_opt2(
1358         ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1359         const void* src, size_t srcSize, const ZSTD_dictMode_e dictMode)
1360 {
1361     return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /* optLevel */, dictMode);
1362 }
1363
1364 size_t ZSTD_compressBlock_btopt(
1365         ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1366         const void* src, size_t srcSize)
1367 {
1368     DEBUGLOG(5, "ZSTD_compressBlock_btopt");
1369     return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_noDict);
1370 }
1371
1372
1373
1374
1375 /* ZSTD_initStats_ultra():
1376  * make a first compression pass, just to seed stats with more accurate starting values.
1377  * only works on first block, with no dictionary and no ldm.
1378  * this function cannot error out, its narrow contract must be respected.
1379  */
1380 static void
1381 ZSTD_initStats_ultra(ZSTD_matchState_t* ms,
1382                      seqStore_t* seqStore,
1383                      U32 rep[ZSTD_REP_NUM],
1384                const void* src, size_t srcSize)
1385 {
1386     U32 tmpRep[ZSTD_REP_NUM];  /* updated rep codes will sink here */
1387     ZSTD_memcpy(tmpRep, rep, sizeof(tmpRep));
1388
1389     DEBUGLOG(4, "ZSTD_initStats_ultra (srcSize=%zu)", srcSize);
1390     assert(ms->opt.litLengthSum == 0);    /* first block */
1391     assert(seqStore->sequences == seqStore->sequencesStart);   /* no ldm */
1392     assert(ms->window.dictLimit == ms->window.lowLimit);   /* no dictionary */
1393     assert(ms->window.dictLimit - ms->nextToUpdate <= 1);  /* no prefix (note: intentional overflow, defined as 2-complement) */
1394
1395     ZSTD_compressBlock_opt2(ms, seqStore, tmpRep, src, srcSize, ZSTD_noDict);   /* generate stats into ms->opt*/
1396
1397     /* invalidate first scan from history, only keep entropy stats */
1398     ZSTD_resetSeqStore(seqStore);
1399     ms->window.base -= srcSize;
1400     ms->window.dictLimit += (U32)srcSize;
1401     ms->window.lowLimit = ms->window.dictLimit;
1402     ms->nextToUpdate = ms->window.dictLimit;
1403
1404 }
1405
1406 size_t ZSTD_compressBlock_btultra(
1407         ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1408         const void* src, size_t srcSize)
1409 {
1410     DEBUGLOG(5, "ZSTD_compressBlock_btultra (srcSize=%zu)", srcSize);
1411     return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict);
1412 }
1413
1414 size_t ZSTD_compressBlock_btultra2(
1415         ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1416         const void* src, size_t srcSize)
1417 {
1418     U32 const curr = (U32)((const BYTE*)src - ms->window.base);
1419     DEBUGLOG(5, "ZSTD_compressBlock_btultra2 (srcSize=%zu)", srcSize);
1420
1421     /* 2-passes strategy:
1422      * this strategy makes a first pass over first block to collect statistics
1423      * in order to seed next round's statistics with it.
1424      * After 1st pass, function forgets history, and starts a new block.
1425      * Consequently, this can only work if no data has been previously loaded in tables,
1426      * aka, no dictionary, no prefix, no ldm preprocessing.
1427      * The compression ratio gain is generally small (~0.5% on first block),
1428     ** the cost is 2x cpu time on first block. */
1429     assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
1430     if ( (ms->opt.litLengthSum==0)   /* first block */
1431       && (seqStore->sequences == seqStore->sequencesStart)  /* no ldm */
1432       && (ms->window.dictLimit == ms->window.lowLimit)   /* no dictionary */
1433       && (curr == ms->window.dictLimit)    /* start of frame, nothing already loaded nor skipped */
1434       && (srcSize > ZSTD_PREDEF_THRESHOLD) /* input large enough to not employ default stats */
1435       ) {
1436         ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize);
1437     }
1438
1439     return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_noDict);
1440 }
1441
1442 size_t ZSTD_compressBlock_btopt_dictMatchState(
1443         ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1444         const void* src, size_t srcSize)
1445 {
1446     return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState);
1447 }
1448
1449 size_t ZSTD_compressBlock_btultra_dictMatchState(
1450         ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1451         const void* src, size_t srcSize)
1452 {
1453     return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_dictMatchState);
1454 }
1455
1456 size_t ZSTD_compressBlock_btopt_extDict(
1457         ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1458         const void* src, size_t srcSize)
1459 {
1460     return ZSTD_compressBlock_opt0(ms, seqStore, rep, src, srcSize, ZSTD_extDict);
1461 }
1462
1463 size_t ZSTD_compressBlock_btultra_extDict(
1464         ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1465         const void* src, size_t srcSize)
1466 {
1467     return ZSTD_compressBlock_opt2(ms, seqStore, rep, src, srcSize, ZSTD_extDict);
1468 }
1469
1470 /* note : no btultra2 variant for extDict nor dictMatchState,
1471  * because btultra2 is not meant to work with dictionaries
1472  * and is only specific for the first block (no prefix) */