extzstd 0.0.3.CONCEPT → 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.ja +5 -0
  3. data/LICENSE +6 -6
  4. data/README.md +35 -22
  5. data/contrib/zstd/LICENSE +13 -9
  6. data/contrib/zstd/README.md +37 -44
  7. data/contrib/zstd/common/entropy_common.c +33 -39
  8. data/contrib/zstd/common/error_private.c +43 -0
  9. data/contrib/zstd/common/error_private.h +11 -60
  10. data/contrib/zstd/common/fse.h +11 -5
  11. data/contrib/zstd/common/fse_decompress.c +14 -16
  12. data/contrib/zstd/common/huf.h +1 -1
  13. data/contrib/zstd/common/mem.h +36 -43
  14. data/contrib/zstd/common/xxhash.c +31 -18
  15. data/contrib/zstd/common/xxhash.h +71 -35
  16. data/contrib/zstd/common/zbuff.h +29 -35
  17. data/contrib/zstd/common/zstd_common.c +24 -32
  18. data/contrib/zstd/common/zstd_errors.h +60 -0
  19. data/contrib/zstd/common/zstd_internal.h +109 -80
  20. data/contrib/zstd/compress/fse_compress.c +9 -6
  21. data/contrib/zstd/compress/huf_compress.c +30 -74
  22. data/contrib/zstd/compress/zbuff_compress.c +43 -51
  23. data/contrib/zstd/compress/zstd_compress.c +953 -763
  24. data/contrib/zstd/compress/zstd_opt.h +115 -261
  25. data/contrib/zstd/decompress/huf_decompress.c +29 -40
  26. data/contrib/zstd/decompress/zbuff_decompress.c +36 -78
  27. data/contrib/zstd/decompress/zstd_decompress.c +976 -496
  28. data/contrib/zstd/dictBuilder/divsufsort.h +5 -5
  29. data/contrib/zstd/dictBuilder/zdict.c +194 -229
  30. data/contrib/zstd/dictBuilder/zdict.h +66 -68
  31. data/contrib/zstd/legacy/zstd_legacy.h +168 -49
  32. data/contrib/zstd/legacy/zstd_v01.c +95 -178
  33. data/contrib/zstd/legacy/zstd_v01.h +12 -32
  34. data/contrib/zstd/legacy/zstd_v02.c +48 -274
  35. data/contrib/zstd/legacy/zstd_v02.h +12 -32
  36. data/contrib/zstd/legacy/zstd_v03.c +48 -274
  37. data/contrib/zstd/legacy/zstd_v03.h +12 -32
  38. data/contrib/zstd/legacy/zstd_v04.c +63 -320
  39. data/contrib/zstd/legacy/zstd_v04.h +13 -33
  40. data/contrib/zstd/legacy/zstd_v05.c +80 -345
  41. data/contrib/zstd/legacy/zstd_v05.h +9 -31
  42. data/contrib/zstd/legacy/zstd_v06.c +48 -458
  43. data/contrib/zstd/legacy/zstd_v06.h +41 -67
  44. data/contrib/zstd/legacy/zstd_v07.c +4544 -0
  45. data/contrib/zstd/legacy/zstd_v07.h +173 -0
  46. data/contrib/zstd/zstd.h +640 -0
  47. data/ext/extconf.rb +7 -3
  48. data/ext/extzstd.c +263 -106
  49. data/ext/extzstd.h +8 -6
  50. data/ext/extzstd_nogvls.h +0 -117
  51. data/ext/extzstd_stream.c +347 -0
  52. data/ext/zstd_common.c +8 -0
  53. data/ext/zstd_compress.c +6 -0
  54. data/ext/zstd_decompress.c +5 -0
  55. data/ext/zstd_dictbuilder.c +5 -0
  56. data/ext/zstd_legacy_v07.c +1 -0
  57. data/gemstub.rb +18 -16
  58. data/lib/extzstd/version.rb +1 -1
  59. data/lib/extzstd.rb +77 -43
  60. data/test/test_basic.rb +11 -6
  61. metadata +23 -10
  62. data/contrib/zstd/common/error_public.h +0 -77
  63. data/contrib/zstd/common/zstd.h +0 -475
  64. data/ext/extzstd_buffered.c +0 -265
  65. data/ext/zstd_amalgam.c +0 -18
@@ -1,35 +1,12 @@
1
- /*
2
- ZSTD Optimal mode
3
- Copyright (C) 2016, Przemyslaw Skibinski, Yann Collet.
4
-
5
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
-
7
- Redistribution and use in source and binary forms, with or without
8
- modification, are permitted provided that the following conditions are
9
- met:
10
-
11
- * Redistributions of source code must retain the above copyright
12
- notice, this list of conditions and the following disclaimer.
13
- * Redistributions in binary form must reproduce the above
14
- copyright notice, this list of conditions and the following disclaimer
15
- in the documentation and/or other materials provided with the
16
- distribution.
17
-
18
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
-
30
- You can contact the author at :
31
- - Zstd source repository : https://www.zstd.net
32
- */
1
+ /**
2
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ */
9
+
33
10
 
34
11
  /* Note : this file is intended to be included within zstd_compress.c */
35
12
 
@@ -39,6 +16,7 @@
39
16
 
40
17
 
41
18
  #define ZSTD_FREQ_DIV 5
19
+ #define ZSTD_MAX_PRICE (1<<30)
42
20
 
43
21
  /*-*************************************
44
22
  * Price functions for optimal parser
@@ -134,15 +112,7 @@ FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BY
134
112
  }
135
113
 
136
114
  /* literal Length */
137
- { static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
138
- 8, 9, 10, 11, 12, 13, 14, 15,
139
- 16, 16, 17, 17, 18, 18, 19, 19,
140
- 20, 20, 20, 20, 21, 21, 21, 21,
141
- 22, 22, 22, 22, 22, 22, 22, 22,
142
- 23, 23, 23, 23, 23, 23, 23, 23,
143
- 24, 24, 24, 24, 24, 24, 24, 24,
144
- 24, 24, 24, 24, 24, 24, 24, 24 };
145
- const BYTE LL_deltaCode = 19;
115
+ { const BYTE LL_deltaCode = 19;
146
116
  const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
147
117
  price += LL_bits[llCode] + ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[llCode]+1);
148
118
  }
@@ -151,22 +121,16 @@ FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BY
151
121
  }
152
122
 
153
123
 
154
- FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength)
124
+ FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength, const int ultra)
155
125
  {
156
126
  /* offset */
157
127
  BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
158
128
  U32 price = offCode + seqStorePtr->log2offCodeSum - ZSTD_highbit32(seqStorePtr->offCodeFreq[offCode]+1);
159
129
 
130
+ if (!ultra && offCode >= 20) price += (offCode-19)*2;
131
+
160
132
  /* match Length */
161
- { static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
162
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
163
- 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
164
- 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
165
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
166
- 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
167
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
168
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
169
- const BYTE ML_deltaCode = 36;
133
+ { const BYTE ML_deltaCode = 36;
170
134
  const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
171
135
  price += ML_bits[mlCode] + seqStorePtr->log2matchLengthSum - ZSTD_highbit32(seqStorePtr->matchLengthFreq[mlCode]+1);
172
136
  }
@@ -185,15 +149,7 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
185
149
  seqStorePtr->litFreq[literals[u]]++;
186
150
 
187
151
  /* literal Length */
188
- { static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
189
- 8, 9, 10, 11, 12, 13, 14, 15,
190
- 16, 16, 17, 17, 18, 18, 19, 19,
191
- 20, 20, 20, 20, 21, 21, 21, 21,
192
- 22, 22, 22, 22, 22, 22, 22, 22,
193
- 23, 23, 23, 23, 23, 23, 23, 23,
194
- 24, 24, 24, 24, 24, 24, 24, 24,
195
- 24, 24, 24, 24, 24, 24, 24, 24 };
196
- const BYTE LL_deltaCode = 19;
152
+ { const BYTE LL_deltaCode = 19;
197
153
  const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
198
154
  seqStorePtr->litLengthFreq[llCode]++;
199
155
  seqStorePtr->litLengthSum++;
@@ -206,15 +162,7 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
206
162
  }
207
163
 
208
164
  /* match Length */
209
- { static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
210
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
211
- 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
212
- 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
213
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
214
- 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
215
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
216
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
217
- const BYTE ML_deltaCode = 36;
165
+ { const BYTE ML_deltaCode = 36;
218
166
  const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
219
167
  seqStorePtr->matchLengthFreq[mlCode]++;
220
168
  seqStorePtr->matchLengthSum++;
@@ -226,12 +174,11 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
226
174
 
227
175
  #define SET_PRICE(pos, mlen_, offset_, litlen_, price_) \
228
176
  { \
229
- while (last_pos < pos) { opt[last_pos+1].price = 1<<30; last_pos++; } \
177
+ while (last_pos < pos) { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; } \
230
178
  opt[pos].mlen = mlen_; \
231
179
  opt[pos].off = offset_; \
232
180
  opt[pos].litlen = litlen_; \
233
181
  opt[pos].price = price_; \
234
- ZSTD_LOG_PARSER("%d: SET price[%d/%d]=%d litlen=%d len=%d off=%d\n", (int)(inr-base), (int)pos, (int)last_pos, opt[pos].price, opt[pos].litlen, opt[pos].mlen, opt[pos].off); \
235
182
  }
236
183
 
237
184
 
@@ -308,7 +255,7 @@ static U32 ZSTD_insertBtAndGetAllMatches (
308
255
  /* save best solution */
309
256
  if (currentMl > bestLength) {
310
257
  bestLength = currentMl;
311
- matches[mnum].off = ZSTD_REP_MOVE + current - matchIndex3;
258
+ matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex3;
312
259
  matches[mnum].len = (U32)currentMl;
313
260
  mnum++;
314
261
  if (currentMl > ZSTD_OPT_NUM) goto update;
@@ -327,25 +274,11 @@ static U32 ZSTD_insertBtAndGetAllMatches (
327
274
  if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
328
275
  match = base + matchIndex;
329
276
  if (match[matchLength] == ip[matchLength]) {
330
- #if ZSTD_OPT_DEBUG >= 5
331
- size_t ml;
332
- if (matchIndex < dictLimit)
333
- ml = ZSTD_count_2segments(ip, dictBase + matchIndex, iLimit, dictEnd, prefixStart);
334
- else
335
- ml = ZSTD_count(ip, match, ip+matchLength);
336
- if (ml < matchLength)
337
- printf("%d: ERROR_NOEXT: offset=%d matchLength=%d matchIndex=%d dictLimit=%d ml=%d\n", current, (int)(current - matchIndex), (int)matchLength, (int)matchIndex, (int)dictLimit, (int)ml), exit(0);
338
- #endif
339
277
  matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iLimit) +1;
340
278
  }
341
279
  } else {
342
280
  match = dictBase + matchIndex;
343
- #if ZSTD_OPT_DEBUG >= 5
344
- if (memcmp(match, ip, matchLength) != 0)
345
- printf("%d: ERROR_EXT: matchLength=%d ZSTD_count=%d\n", current, (int)matchLength, (int)ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart)), exit(0);
346
- #endif
347
281
  matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
348
- ZSTD_LOG_PARSER("%d: ZSTD_INSERTBTANDGETALLMATCHES=%d offset=%d dictBase=%p dictEnd=%p prefixStart=%p ip=%p match=%p\n", (int)current, (int)matchLength, (int)(current - matchIndex), dictBase, dictEnd, prefixStart, ip, match);
349
282
  if (matchIndex+matchLength >= dictLimit)
350
283
  match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
351
284
  }
@@ -353,7 +286,7 @@ static U32 ZSTD_insertBtAndGetAllMatches (
353
286
  if (matchLength > bestLength) {
354
287
  if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength;
355
288
  bestLength = matchLength;
356
- matches[mnum].off = ZSTD_REP_MOVE + current - matchIndex;
289
+ matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex;
357
290
  matches[mnum].len = (U32)matchLength;
358
291
  mnum++;
359
292
  if (matchLength > ZSTD_OPT_NUM) break;
@@ -445,7 +378,7 @@ static U32 ZSTD_BtGetAllMatches_selectMLS_extDict (
445
378
  *********************************/
446
379
  FORCE_INLINE
447
380
  void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
448
- const void* src, size_t srcSize)
381
+ const void* src, size_t srcSize, const int ultra)
449
382
  {
450
383
  seqStore_t* seqStorePtr = &(ctx->seqStore);
451
384
  const BYTE* const istart = (const BYTE*)src;
@@ -464,15 +397,13 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
464
397
  ZSTD_optimal_t* opt = seqStorePtr->priceTable;
465
398
  ZSTD_match_t* matches = seqStorePtr->matchTable;
466
399
  const BYTE* inr;
467
- U32 offset, rep[ZSTD_REP_INIT];
400
+ U32 offset, rep[ZSTD_REP_NUM];
468
401
 
469
402
  /* init */
470
403
  ctx->nextToUpdate3 = ctx->nextToUpdate;
471
404
  ZSTD_rescaleFreqs(seqStorePtr);
472
405
  ip += (ip==prefixStart);
473
- { U32 i; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=ctx->rep[i]; }
474
-
475
- ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_GENERIC srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len);
406
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) rep[i]=ctx->rep[i]; }
476
407
 
477
408
  /* Match Loop */
478
409
  while (ip < ilimit) {
@@ -483,19 +414,19 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
483
414
  litlen = (U32)(ip - anchor);
484
415
 
485
416
  /* check repCode */
486
- { U32 i;
487
- for (i=0; i<ZSTD_REP_NUM; i++) {
488
- if ((rep[i]<(U32)(ip-prefixStart))
489
- && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - rep[i], minMatch))) {
490
- mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-rep[i], iend) + minMatch;
491
- ZSTD_LOG_PARSER("%d: start try REP rep[%d]=%d mlen=%d\n", (int)(ip-base), i, (int)rep[i], (int)mlen);
417
+ { U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
418
+ for (i=(ip == anchor); i<last_i; i++) {
419
+ const S32 repCur = ((i==ZSTD_REP_MOVE_OPT) && (ip==anchor)) ? (rep[0] - 1) : rep[i];
420
+ if ( (repCur > 0) && (repCur < (S32)(ip-prefixStart))
421
+ && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - repCur, minMatch))) {
422
+ mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch;
492
423
  if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
493
424
  best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
494
425
  goto _storeSequence;
495
426
  }
496
- best_off = (i<=1 && ip == anchor) ? 1-i : i;
427
+ best_off = i - (ip == anchor);
497
428
  do {
498
- price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
429
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
499
430
  if (mlen > last_pos || price < opt[mlen].price)
500
431
  SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
501
432
  mlen--;
@@ -504,7 +435,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
504
435
 
505
436
  match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);
506
437
 
507
- ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos);
508
438
  if (!last_pos && !match_num) { ip++; continue; }
509
439
 
510
440
  if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
@@ -520,9 +450,8 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
520
450
  for (u = 0; u < match_num; u++) {
521
451
  mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
522
452
  best_mlen = matches[u].len;
523
- ZSTD_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-base), matches[u].len, matches[u].off, (int)best_mlen, (int)last_pos);
524
453
  while (mlen <= best_mlen) {
525
- price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off, mlen - MINMATCH);
454
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
526
455
  if (mlen > last_pos || price < opt[mlen].price)
527
456
  SET_PRICE(mlen, mlen, matches[u].off, litlen, price); /* note : macro modifies last_pos */
528
457
  mlen++;
@@ -531,7 +460,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
531
460
  if (last_pos < minMatch) { ip++; continue; }
532
461
 
533
462
  /* initialize opt[0] */
534
- { U32 i ; for (i=0; i<ZSTD_REP_INIT; i++) opt[0].rep[i] = rep[i]; }
463
+ { U32 i ; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
535
464
  opt[0].mlen = 1;
536
465
  opt[0].litlen = litlen;
537
466
 
@@ -550,7 +479,7 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
550
479
  price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1);
551
480
  }
552
481
 
553
- if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen)))
482
+ if (cur > last_pos || price <= opt[cur].price)
554
483
  SET_PRICE(cur, 1, 0, litlen, price);
555
484
 
556
485
  if (cur == last_pos) break;
@@ -559,50 +488,44 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
559
488
  continue;
560
489
 
561
490
  mlen = opt[cur].mlen;
562
- if (opt[cur].off >= ZSTD_REP_NUM) {
491
+ if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
563
492
  opt[cur].rep[2] = opt[cur-mlen].rep[1];
564
493
  opt[cur].rep[1] = opt[cur-mlen].rep[0];
565
- opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE;
566
- ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]);
494
+ opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
567
495
  } else {
568
496
  opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
569
497
  opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
570
- opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off];
571
- ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]);
498
+ opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
572
499
  }
573
500
 
574
- ZSTD_LOG_PARSER("%d: CURRENT_NoExt price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]);
575
-
576
- best_mlen = minMatch;
577
- { U32 i;
578
- for (i=0; i<ZSTD_REP_NUM; i++) {
579
- if ((opt[cur].rep[i]<(U32)(inr-prefixStart))
580
- && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - opt[cur].rep[i], minMatch))) { /* check rep */
581
- mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - opt[cur].rep[i], iend) + minMatch;
582
- ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off);
501
+ best_mlen = minMatch;
502
+ { U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
503
+ for (i=(opt[cur].mlen != 1); i<last_i; i++) { /* check rep */
504
+ const S32 repCur = ((i==ZSTD_REP_MOVE_OPT) && (opt[cur].mlen != 1)) ? (opt[cur].rep[0] - 1) : opt[cur].rep[i];
505
+ if ( (repCur > 0) && (repCur < (S32)(inr-prefixStart))
506
+ && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - repCur, minMatch))) {
507
+ mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch;
583
508
 
584
509
  if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
585
- ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos);
586
510
  best_mlen = mlen; best_off = i; last_pos = cur + 1;
587
511
  goto _storeSequence;
588
512
  }
589
513
 
590
- best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i;
591
- if (opt[cur].mlen == 1) {
592
- litlen = opt[cur].litlen;
593
- if (cur > litlen) {
594
- price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH);
595
- } else
596
- price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
597
- } else {
598
- litlen = 0;
599
- price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH);
600
- }
601
-
602
- if (mlen > best_mlen) best_mlen = mlen;
603
- ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_off, price, litlen);
514
+ best_off = i - (opt[cur].mlen != 1);
515
+ if (mlen > best_mlen) best_mlen = mlen;
516
+
517
+ do {
518
+ if (opt[cur].mlen == 1) {
519
+ litlen = opt[cur].litlen;
520
+ if (cur > litlen) {
521
+ price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);
522
+ } else
523
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
524
+ } else {
525
+ litlen = 0;
526
+ price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);
527
+ }
604
528
 
605
- do {
606
529
  if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
607
530
  SET_PRICE(cur + mlen, mlen, i, litlen, price);
608
531
  mlen--;
@@ -610,7 +533,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
610
533
  } } }
611
534
 
612
535
  match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches, best_mlen);
613
- ZSTD_LOG_PARSER("%d: ZSTD_GetAllMatches match_num=%d\n", (int)(inr-base), match_num);
614
536
 
615
537
  if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
616
538
  best_mlen = matches[match_num-1].len;
@@ -624,25 +546,23 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
624
546
  mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
625
547
  best_mlen = matches[u].len;
626
548
 
627
- // ZSTD_LOG_PARSER("%d: Found1 cur=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, matches[u].len, matches[u].off, best_mlen, last_pos);
628
549
  while (mlen <= best_mlen) {
629
550
  if (opt[cur].mlen == 1) {
630
551
  litlen = opt[cur].litlen;
631
552
  if (cur > litlen)
632
- price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off, mlen - MINMATCH);
553
+ price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off-1, mlen - MINMATCH, ultra);
633
554
  else
634
- price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off, mlen - MINMATCH);
555
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
635
556
  } else {
636
557
  litlen = 0;
637
- price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off, mlen - MINMATCH);
558
+ price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH, ultra);
638
559
  }
639
560
 
640
- // ZSTD_LOG_PARSER("%d: Found2 mlen=%d best_mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_mlen, matches[u].off, price, litlen);
641
561
  if (cur + mlen > last_pos || (price < opt[cur + mlen].price))
642
562
  SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
643
563
 
644
564
  mlen++;
645
- } } } // for (cur = 1; cur <= last_pos; cur++)
565
+ } } }
646
566
 
647
567
  best_mlen = opt[last_pos].mlen;
648
568
  best_off = opt[last_pos].off;
@@ -650,10 +570,6 @@ void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
650
570
 
651
571
  /* store sequence */
652
572
  _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
653
- for (u = 1; u <= last_pos; u++)
654
- ZSTD_LOG_PARSER("%d: price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]);
655
- ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep[0]=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep[0]);
656
-
657
573
  opt[0].mlen = 1;
658
574
 
659
575
  while (1) {
@@ -668,49 +584,31 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
668
584
  }
669
585
 
670
586
  for (u = 0; u <= last_pos;) {
671
- ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]);
672
587
  u += opt[u].mlen;
673
588
  }
674
589
 
675
590
  for (cur=0; cur < last_pos; ) {
676
- ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]);
677
591
  mlen = opt[cur].mlen;
678
592
  if (mlen == 1) { ip++; cur++; continue; }
679
593
  offset = opt[cur].off;
680
594
  cur += mlen;
681
595
  litLength = (U32)(ip - anchor);
682
- // ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
683
596
 
684
- if (offset >= ZSTD_REP_NUM) {
597
+ if (offset > ZSTD_REP_MOVE_OPT) {
685
598
  rep[2] = rep[1];
686
599
  rep[1] = rep[0];
687
- rep[0] = offset - ZSTD_REP_MOVE;
600
+ rep[0] = offset - ZSTD_REP_MOVE_OPT;
601
+ offset--;
688
602
  } else {
689
603
  if (offset != 0) {
690
- best_off = rep[offset];
604
+ best_off = ((offset==ZSTD_REP_MOVE_OPT) && (litLength==0)) ? (rep[0] - 1) : (rep[offset]);
691
605
  if (offset != 1) rep[2] = rep[1];
692
606
  rep[1] = rep[0];
693
607
  rep[0] = best_off;
694
608
  }
695
- if (litLength == 0 && offset<=1) offset = 1-offset;
609
+ if (litLength==0) offset--;
696
610
  }
697
611
 
698
- ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
699
-
700
- #if ZSTD_OPT_DEBUG >= 5
701
- U32 ml2;
702
- if (offset >= ZSTD_REP_NUM)
703
- ml2 = (U32)ZSTD_count(ip, ip-(offset-ZSTD_REP_MOVE), iend);
704
- else
705
- ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend);
706
- if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) {
707
- printf("%d: ERROR_NoExt iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); }
708
- if (ip < anchor) {
709
- printf("%d: ERROR_NoExt ip < anchor iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); }
710
- if (ip + mlen > iend) {
711
- printf("%d: ERROR_NoExt ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); }
712
- #endif
713
-
714
612
  ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
715
613
  ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
716
614
  anchor = ip = ip + mlen;
@@ -721,7 +619,6 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
721
619
 
722
620
  /* Last Literals */
723
621
  { size_t const lastLLSize = iend - anchor;
724
- ZSTD_LOG_ENCODE("%d: lastLLSize literals=%u\n", (int)(ip-base), (U32)lastLLSize);
725
622
  memcpy(seqStorePtr->lit, anchor, lastLLSize);
726
623
  seqStorePtr->lit += lastLLSize;
727
624
  }
@@ -730,7 +627,7 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
730
627
 
731
628
  FORCE_INLINE
732
629
  void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
733
- const void* src, size_t srcSize)
630
+ const void* src, size_t srcSize, const int ultra)
734
631
  {
735
632
  seqStore_t* seqStorePtr = &(ctx->seqStore);
736
633
  const BYTE* const istart = (const BYTE*)src;
@@ -755,15 +652,13 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
755
652
  const BYTE* inr;
756
653
 
757
654
  /* init */
758
- U32 offset, rep[ZSTD_REP_INIT];
759
- { U32 i; for (i=0; i<ZSTD_REP_INIT; i++) rep[i]=ctx->rep[i]; }
655
+ U32 offset, rep[ZSTD_REP_NUM];
656
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) rep[i]=ctx->rep[i]; }
760
657
 
761
658
  ctx->nextToUpdate3 = ctx->nextToUpdate;
762
659
  ZSTD_rescaleFreqs(seqStorePtr);
763
660
  ip += (ip==prefixStart);
764
661
 
765
- ZSTD_LOG_BLOCK("%d: COMPBLOCK_OPT_EXTDICT srcSz=%d maxSrch=%d mls=%d sufLen=%d\n", (int)(ip-base), (int)srcSize, maxSearches, mls, sufficient_len);
766
-
767
662
  /* Match Loop */
768
663
  while (ip < ilimit) {
769
664
  U32 cur, match_num, last_pos, litlen, price;
@@ -771,31 +666,31 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
771
666
  U32 current = (U32)(ip-base);
772
667
  memset(opt, 0, sizeof(ZSTD_optimal_t));
773
668
  last_pos = 0;
774
- inr = ip;
775
669
  opt[0].litlen = (U32)(ip - anchor);
776
670
 
777
671
  /* check repCode */
778
- { U32 i;
779
- for (i=0; i<ZSTD_REP_NUM; i++) {
780
- const U32 repIndex = (U32)(current - rep[i]);
672
+ { U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
673
+ for (i = (ip==anchor); i<last_i; i++) {
674
+ const S32 repCur = ((i==ZSTD_REP_MOVE_OPT) && (ip==anchor)) ? (rep[0] - 1) : rep[i];
675
+ const U32 repIndex = (U32)(current - repCur);
781
676
  const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
782
677
  const BYTE* const repMatch = repBase + repIndex;
783
- if ( (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
678
+ if ( (repCur > 0 && repCur <= (S32)current)
679
+ && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
784
680
  && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
785
681
  /* repcode detected we should take it */
786
682
  const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
787
683
  mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
788
684
 
789
- ZSTD_LOG_PARSER("%d: start try REP rep[%d]=%d mlen=%d\n", (int)(ip-base), i, (int)rep[i], (int)mlen);
790
685
  if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
791
686
  best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
792
687
  goto _storeSequence;
793
688
  }
794
689
 
795
- best_off = (i<=1 && ip == anchor) ? 1-i : i;
690
+ best_off = i - (ip==anchor);
796
691
  litlen = opt[0].litlen;
797
692
  do {
798
- price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
693
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
799
694
  if (mlen > last_pos || price < opt[mlen].price)
800
695
  SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
801
696
  mlen--;
@@ -804,10 +699,9 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
804
699
 
805
700
  match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches, minMatch); /* first search (depth 0) */
806
701
 
807
- ZSTD_LOG_PARSER("%d: match_num=%d last_pos=%d\n", (int)(ip-base), match_num, last_pos);
808
702
  if (!last_pos && !match_num) { ip++; continue; }
809
703
 
810
- { U32 i; for (i=0; i<ZSTD_REP_INIT; i++) opt[0].rep[i] = rep[i]; }
704
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
811
705
  opt[0].mlen = 1;
812
706
 
813
707
  if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
@@ -820,21 +714,19 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
820
714
 
821
715
  best_mlen = (last_pos) ? last_pos : minMatch;
822
716
 
823
- // set prices using matches at position = 0
717
+ /* set prices using matches at position = 0 */
824
718
  for (u = 0; u < match_num; u++) {
825
719
  mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
826
720
  best_mlen = matches[u].len;
827
- ZSTD_LOG_PARSER("%d: start Found mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(ip-base), matches[u].len, matches[u].off, (int)best_mlen, (int)last_pos);
828
721
  litlen = opt[0].litlen;
829
722
  while (mlen <= best_mlen) {
830
- price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off, mlen - MINMATCH);
723
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
831
724
  if (mlen > last_pos || price < opt[mlen].price)
832
725
  SET_PRICE(mlen, mlen, matches[u].off, litlen, price);
833
726
  mlen++;
834
727
  } }
835
728
 
836
729
  if (last_pos < minMatch) {
837
- // ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
838
730
  ip++; continue;
839
731
  }
840
732
 
@@ -853,7 +745,7 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
853
745
  price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1);
854
746
  }
855
747
 
856
- if (cur > last_pos || price <= opt[cur].price) // || ((price == opt[cur].price) && (opt[cur-1].mlen == 1) && (cur != litlen)))
748
+ if (cur > last_pos || price <= opt[cur].price)
857
749
  SET_PRICE(cur, 1, 0, litlen, price);
858
750
 
859
751
  if (cur == last_pos) break;
@@ -862,55 +754,50 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
862
754
  continue;
863
755
 
864
756
  mlen = opt[cur].mlen;
865
- if (opt[cur].off >= ZSTD_REP_NUM) {
757
+ if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
866
758
  opt[cur].rep[2] = opt[cur-mlen].rep[1];
867
759
  opt[cur].rep[1] = opt[cur-mlen].rep[0];
868
- opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE;
869
- ZSTD_LOG_ENCODE("%d: COPYREP_OFF cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]);
760
+ opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
870
761
  } else {
871
762
  opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
872
763
  opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
873
- opt[cur].rep[0] = opt[cur-mlen].rep[opt[cur].off];
874
- ZSTD_LOG_ENCODE("%d: COPYREP_NOR cur=%d mlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, mlen, opt[cur].rep[0], opt[cur].rep[1]);
764
+ opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
875
765
  }
876
766
 
877
- ZSTD_LOG_PARSER("%d: CURRENT_Ext price[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(inr-base), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]);
878
- best_mlen = 0;
879
-
880
- { U32 i;
881
- for (i=0; i<ZSTD_REP_NUM; i++) {
882
- const U32 repIndex = (U32)(current+cur - opt[cur].rep[i]);
767
+ best_mlen = minMatch;
768
+ { U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
769
+ for (i = (mlen != 1); i<last_i; i++) {
770
+ const S32 repCur = ((i==ZSTD_REP_MOVE_OPT) && (opt[cur].mlen != 1)) ? (opt[cur].rep[0] - 1) : opt[cur].rep[i];
771
+ const U32 repIndex = (U32)(current+cur - repCur);
883
772
  const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
884
773
  const BYTE* const repMatch = repBase + repIndex;
885
- if ( (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
774
+ if ( (repCur > 0 && repCur <= (S32)(current+cur))
775
+ && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
886
776
  && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
887
777
  /* repcode detected */
888
778
  const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
889
779
  mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
890
- ZSTD_LOG_PARSER("%d: Found REP %d/%d mlen=%d off=%d rep=%d opt[%d].off=%d\n", (int)(inr-base), i, ZSTD_REP_NUM, mlen, i, opt[cur].rep[i], cur, opt[cur].off);
891
780
 
892
781
  if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
893
- ZSTD_LOG_PARSER("%d: REP sufficient_len=%d best_mlen=%d best_off=%d last_pos=%d\n", (int)(inr-base), sufficient_len, best_mlen, best_off, last_pos);
894
782
  best_mlen = mlen; best_off = i; last_pos = cur + 1;
895
783
  goto _storeSequence;
896
784
  }
897
785
 
898
- best_off = (i<=1 && opt[cur].mlen != 1) ? 1-i : i;
899
- if (opt[cur].mlen == 1) {
900
- litlen = opt[cur].litlen;
901
- if (cur > litlen) {
902
- price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH);
903
- } else
904
- price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH);
905
- } else {
906
- litlen = 0;
907
- price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH);
908
- }
909
-
910
- best_mlen = mlen;
911
- ZSTD_LOG_PARSER("%d: Found REP mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_off, price, litlen);
786
+ best_off = i - (opt[cur].mlen != 1);
787
+ if (mlen > best_mlen) best_mlen = mlen;
912
788
 
913
789
  do {
790
+ if (opt[cur].mlen == 1) {
791
+ litlen = opt[cur].litlen;
792
+ if (cur > litlen) {
793
+ price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);
794
+ } else
795
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
796
+ } else {
797
+ litlen = 0;
798
+ price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);
799
+ }
800
+
914
801
  if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
915
802
  SET_PRICE(cur + mlen, mlen, i, litlen, price);
916
803
  mlen--;
@@ -918,7 +805,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
918
805
  } } }
919
806
 
920
807
  match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches, minMatch);
921
- ZSTD_LOG_PARSER("%d: ZSTD_GetAllMatches match_num=%d\n", (int)(inr-base), match_num);
922
808
 
923
809
  if (match_num > 0 && matches[match_num-1].len > sufficient_len) {
924
810
  best_mlen = matches[match_num-1].len;
@@ -927,27 +813,23 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
927
813
  goto _storeSequence;
928
814
  }
929
815
 
930
- best_mlen = (best_mlen > minMatch) ? best_mlen : minMatch;
931
-
932
816
  /* set prices using matches at position = cur */
933
817
  for (u = 0; u < match_num; u++) {
934
818
  mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
935
819
  best_mlen = (cur + matches[u].len < ZSTD_OPT_NUM) ? matches[u].len : ZSTD_OPT_NUM - cur;
936
820
 
937
- // ZSTD_LOG_PARSER("%d: Found1 cur=%d mlen=%d off=%d best_mlen=%d last_pos=%d\n", (int)(inr-base), cur, matches[u].len, matches[u].off, best_mlen, last_pos);
938
821
  while (mlen <= best_mlen) {
939
822
  if (opt[cur].mlen == 1) {
940
823
  litlen = opt[cur].litlen;
941
824
  if (cur > litlen)
942
- price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off, mlen - MINMATCH);
825
+ price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off-1, mlen - MINMATCH, ultra);
943
826
  else
944
- price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off, mlen - MINMATCH);
827
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
945
828
  } else {
946
829
  litlen = 0;
947
- price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off, mlen - MINMATCH);
830
+ price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH, ultra);
948
831
  }
949
832
 
950
- // ZSTD_LOG_PARSER("%d: Found2 mlen=%d best_mlen=%d off=%d price=%d litlen=%d\n", (int)(inr-base), mlen, best_mlen, matches[u].off, price, litlen);
951
833
  if (cur + mlen > last_pos || (price < opt[cur + mlen].price))
952
834
  SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
953
835
 
@@ -960,10 +842,6 @@ void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
960
842
 
961
843
  /* store sequence */
962
844
  _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
963
- for (u = 1; u <= last_pos; u++)
964
- ZSTD_LOG_PARSER("%d: price[%u/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]);
965
- ZSTD_LOG_PARSER("%d: cur=%d/%d best_mlen=%d best_off=%d rep[0]=%d\n", (int)(ip-base+cur), (int)cur, (int)last_pos, (int)best_mlen, (int)best_off, opt[cur].rep[0]);
966
-
967
845
  opt[0].mlen = 1;
968
846
 
969
847
  while (1) {
@@ -978,54 +856,31 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
978
856
  }
979
857
 
980
858
  for (u = 0; u <= last_pos; ) {
981
- ZSTD_LOG_PARSER("%d: price2[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+u), u, last_pos, opt[u].price, opt[u].off, opt[u].mlen, opt[u].litlen, opt[u].rep[0], opt[u].rep[1]);
982
859
  u += opt[u].mlen;
983
860
  }
984
861
 
985
862
  for (cur=0; cur < last_pos; ) {
986
- ZSTD_LOG_PARSER("%d: price3[%d/%d]=%d off=%d mlen=%d litlen=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base+cur), cur, last_pos, opt[cur].price, opt[cur].off, opt[cur].mlen, opt[cur].litlen, opt[cur].rep[0], opt[cur].rep[1]);
987
863
  mlen = opt[cur].mlen;
988
864
  if (mlen == 1) { ip++; cur++; continue; }
989
865
  offset = opt[cur].off;
990
866
  cur += mlen;
991
867
  litLength = (U32)(ip - anchor);
992
- // ZSTD_LOG_ENCODE("%d/%d: ENCODE1 literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
993
868
 
994
- if (offset >= ZSTD_REP_NUM) {
869
+ if (offset > ZSTD_REP_MOVE_OPT) {
995
870
  rep[2] = rep[1];
996
871
  rep[1] = rep[0];
997
- rep[0] = offset - ZSTD_REP_MOVE;
872
+ rep[0] = offset - ZSTD_REP_MOVE_OPT;
873
+ offset--;
998
874
  } else {
999
875
  if (offset != 0) {
1000
- best_off = rep[offset];
876
+ best_off = ((offset==ZSTD_REP_MOVE_OPT) && (litLength==0)) ? (rep[0] - 1) : (rep[offset]);
1001
877
  if (offset != 1) rep[2] = rep[1];
1002
878
  rep[1] = rep[0];
1003
879
  rep[0] = best_off;
1004
- }
1005
- if (litLength == 0 && offset<=1) offset = 1-offset;
1006
- }
1007
-
1008
- ZSTD_LOG_ENCODE("%d/%d: ENCODE literals=%d mlen=%d off=%d rep[0]=%d rep[1]=%d\n", (int)(ip-base), (int)(iend-base), (int)(litLength), (int)mlen, (int)(offset), (int)rep[0], (int)rep[1]);
1009
-
1010
- #if ZSTD_OPT_DEBUG >= 5
1011
- U32 ml2;
1012
- if (offset >= ZSTD_REP_NUM) {
1013
- best_off = offset - ZSTD_REP_MOVE;
1014
- if (best_off > (size_t)(ip - prefixStart)) {
1015
- const BYTE* match = dictEnd - (best_off - (ip - prefixStart));
1016
- ml2 = ZSTD_count_2segments(ip, match, iend, dictEnd, prefixStart);
1017
- ZSTD_LOG_PARSER("%d: ZSTD_count_2segments=%d offset=%d dictBase=%p dictEnd=%p prefixStart=%p ip=%p match=%p\n", (int)current, (int)ml2, (int)best_off, dictBase, dictEnd, prefixStart, ip, match);
1018
880
  }
1019
- else ml2 = (U32)ZSTD_count(ip, ip-offset, iend);
881
+
882
+ if (litLength==0) offset--;
1020
883
  }
1021
- else ml2 = (U32)ZSTD_count(ip, ip-rep[0], iend);
1022
- if ((offset >= 8) && (ml2 < mlen || ml2 < minMatch)) {
1023
- printf("%d: ERROR_Ext iend=%d mlen=%d offset=%d ml2=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset, (int)ml2); exit(0); }
1024
- if (ip < anchor) {
1025
- printf("%d: ERROR_Ext ip < anchor iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); }
1026
- if (ip + mlen > iend) {
1027
- printf("%d: ERROR_Ext ip + mlen >= iend iend=%d mlen=%d offset=%d\n", (int)(ip - base), (int)(iend - ip), (int)mlen, (int)offset); exit(0); }
1028
- #endif
1029
884
 
1030
885
  ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
1031
886
  ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
@@ -1033,11 +888,10 @@ _storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
1033
888
  } } /* for (cur=0; cur < last_pos; ) */
1034
889
 
1035
890
  /* Save reps for next block */
1036
- ctx->savedRep[0] = rep[0]; ctx->savedRep[1] = rep[1]; ctx->savedRep[2] = rep[2];
891
+ { int i; for (i=0; i<ZSTD_REP_NUM; i++) ctx->savedRep[i] = rep[i]; }
1037
892
 
1038
893
  /* Last Literals */
1039
894
  { size_t lastLLSize = iend - anchor;
1040
- ZSTD_LOG_ENCODE("%d: lastLLSize literals=%u\n", (int)(ip-base), (U32)(lastLLSize));
1041
895
  memcpy(seqStorePtr->lit, anchor, lastLLSize);
1042
896
  seqStorePtr->lit += lastLLSize;
1043
897
  }