zstd-ruby 1.4.2.0 → 1.4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/zstdruby/libzstd/Makefile +0 -2
  4. data/ext/zstdruby/libzstd/README.md +13 -2
  5. data/ext/zstdruby/libzstd/common/bitstream.h +7 -2
  6. data/ext/zstdruby/libzstd/common/compiler.h +17 -5
  7. data/ext/zstdruby/libzstd/common/fse.h +1 -1
  8. data/ext/zstdruby/libzstd/common/fse_decompress.c +2 -0
  9. data/ext/zstdruby/libzstd/common/mem.h +74 -1
  10. data/ext/zstdruby/libzstd/common/pool.c +7 -3
  11. data/ext/zstdruby/libzstd/common/threading.c +46 -1
  12. data/ext/zstdruby/libzstd/common/threading.h +32 -1
  13. data/ext/zstdruby/libzstd/common/xxhash.c +8 -2
  14. data/ext/zstdruby/libzstd/common/zstd_internal.h +37 -58
  15. data/ext/zstdruby/libzstd/compress/zstd_compress.c +644 -445
  16. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +98 -26
  17. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +10 -5
  18. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +1 -1
  19. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +3 -3
  20. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
  21. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +535 -0
  22. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +11 -12
  23. data/ext/zstdruby/libzstd/compress/zstd_fast.c +38 -45
  24. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +35 -31
  25. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +4 -4
  26. data/ext/zstdruby/libzstd/compress/zstd_opt.c +6 -6
  27. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +32 -26
  28. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +2 -0
  29. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +16 -17
  30. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +149 -148
  31. data/ext/zstdruby/libzstd/deprecated/zbuff.h +6 -5
  32. data/ext/zstdruby/libzstd/dictBuilder/cover.c +7 -8
  33. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +1 -1
  34. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -1
  35. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +2 -1
  36. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +2 -1
  37. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +6 -2
  38. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +1 -1
  39. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +1 -1
  40. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +1 -1
  41. data/ext/zstdruby/libzstd/libzstd.pc.in +3 -2
  42. data/ext/zstdruby/libzstd/zstd.h +170 -66
  43. data/lib/zstd-ruby/version.rb +1 -1
  44. data/zstd-ruby.gemspec +1 -1
  45. metadata +5 -4
@@ -65,6 +65,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
65
65
  const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
66
66
  const U32 lowestValid = ms->window.dictLimit;
67
67
  const U32 maxDistance = 1U << cParams->windowLog;
68
+ /* presumes that, if there is a dictionary, it must be using Attach mode */
68
69
  const U32 prefixLowestIndex = (endIndex - lowestValid > maxDistance) ? endIndex - maxDistance : lowestValid;
69
70
  const BYTE* const prefixLowest = base + prefixLowestIndex;
70
71
  const BYTE* const iend = istart + srcSize;
@@ -147,7 +148,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
147
148
  const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
148
149
  mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
149
150
  ip++;
150
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
151
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
151
152
  goto _match_stored;
152
153
  }
153
154
 
@@ -156,7 +157,7 @@ size_t ZSTD_compressBlock_doubleFast_generic(
156
157
  && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {
157
158
  mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
158
159
  ip++;
159
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
160
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
160
161
  goto _match_stored;
161
162
  }
162
163
 
@@ -246,7 +247,7 @@ _match_found:
246
247
  offset_2 = offset_1;
247
248
  offset_1 = offset;
248
249
 
249
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
250
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
250
251
 
251
252
  _match_stored:
252
253
  /* match found */
@@ -277,7 +278,7 @@ _match_stored:
277
278
  const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend;
278
279
  size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4;
279
280
  U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
280
- ZSTD_storeSeq(seqStore, 0, anchor, 0, repLength2-MINMATCH);
281
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH);
281
282
  hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
282
283
  hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
283
284
  ip += repLength2;
@@ -296,7 +297,7 @@ _match_stored:
296
297
  U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */
297
298
  hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
298
299
  hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
299
- ZSTD_storeSeq(seqStore, 0, anchor, 0, rLength-MINMATCH);
300
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH);
300
301
  ip += rLength;
301
302
  anchor = ip;
302
303
  continue; /* faster when present ... (?) */
@@ -369,9 +370,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
369
370
  const BYTE* const ilimit = iend - 8;
370
371
  const BYTE* const base = ms->window.base;
371
372
  const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
372
- const U32 maxDistance = 1U << cParams->windowLog;
373
- const U32 lowestValid = ms->window.lowLimit;
374
- const U32 lowLimit = (endIndex - lowestValid > maxDistance) ? endIndex - maxDistance : lowestValid;
373
+ const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog);
375
374
  const U32 dictStartIndex = lowLimit;
376
375
  const U32 dictLimit = ms->window.dictLimit;
377
376
  const U32 prefixStartIndex = (dictLimit > lowLimit) ? dictLimit : lowLimit;
@@ -412,7 +411,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
412
411
  const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
413
412
  mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
414
413
  ip++;
415
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
414
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
416
415
  } else {
417
416
  if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
418
417
  const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend;
@@ -423,7 +422,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
423
422
  while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
424
423
  offset_2 = offset_1;
425
424
  offset_1 = offset;
426
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
425
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
427
426
 
428
427
  } else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) {
429
428
  size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
@@ -448,7 +447,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
448
447
  }
449
448
  offset_2 = offset_1;
450
449
  offset_1 = offset;
451
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
450
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
452
451
 
453
452
  } else {
454
453
  ip += ((ip-anchor) >> kSearchStrength) + 1;
@@ -480,7 +479,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
480
479
  const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
481
480
  size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
482
481
  U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
483
- ZSTD_storeSeq(seqStore, 0, anchor, 0, repLength2-MINMATCH);
482
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH);
484
483
  hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
485
484
  hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
486
485
  ip += repLength2;
@@ -8,7 +8,7 @@
8
8
  * You may select, at your option, one of the above-listed licenses.
9
9
  */
10
10
 
11
- #include "zstd_compress_internal.h"
11
+ #include "zstd_compress_internal.h" /* ZSTD_hashPtr, ZSTD_count, ZSTD_storeSeq */
12
12
  #include "zstd_fast.h"
13
13
 
14
14
 
@@ -43,8 +43,8 @@ void ZSTD_fillHashTable(ZSTD_matchState_t* ms,
43
43
  }
44
44
 
45
45
 
46
- FORCE_INLINE_TEMPLATE
47
- size_t ZSTD_compressBlock_fast_generic(
46
+ FORCE_INLINE_TEMPLATE size_t
47
+ ZSTD_compressBlock_fast_generic(
48
48
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
49
49
  void const* src, size_t srcSize,
50
50
  U32 const mls)
@@ -71,10 +71,10 @@ size_t ZSTD_compressBlock_fast_generic(
71
71
  U32 offsetSaved = 0;
72
72
 
73
73
  /* init */
74
+ DEBUGLOG(5, "ZSTD_compressBlock_fast_generic");
74
75
  ip0 += (ip0 == prefixStart);
75
76
  ip1 = ip0 + 1;
76
- {
77
- U32 const maxRep = (U32)(ip0 - prefixStart);
77
+ { U32 const maxRep = (U32)(ip0 - prefixStart);
78
78
  if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
79
79
  if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
80
80
  }
@@ -117,8 +117,7 @@ size_t ZSTD_compressBlock_fast_generic(
117
117
  match0 = match1;
118
118
  goto _offset;
119
119
  }
120
- {
121
- size_t const step = ((ip0-anchor) >> (kSearchStrength - 1)) + stepSize;
120
+ { size_t const step = ((size_t)(ip0-anchor) >> (kSearchStrength - 1)) + stepSize;
122
121
  assert(step >= 2);
123
122
  ip0 += step;
124
123
  ip1 += step;
@@ -137,7 +136,7 @@ _offset: /* Requires: ip0, match0 */
137
136
  _match: /* Requires: ip0, match0, offcode */
138
137
  /* Count the forward length */
139
138
  mLength += ZSTD_count(ip0+mLength+4, match0+mLength+4, iend) + 4;
140
- ZSTD_storeSeq(seqStore, ip0-anchor, anchor, offcode, mLength-MINMATCH);
139
+ ZSTD_storeSeq(seqStore, (size_t)(ip0-anchor), anchor, iend, offcode, mLength-MINMATCH);
141
140
  /* match found */
142
141
  ip0 += mLength;
143
142
  anchor = ip0;
@@ -149,16 +148,15 @@ _match: /* Requires: ip0, match0, offcode */
149
148
  hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */
150
149
  hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base);
151
150
 
152
- while ( (ip0 <= ilimit)
153
- && ( (offset_2>0)
154
- & (MEM_read32(ip0) == MEM_read32(ip0 - offset_2)) )) {
151
+ while ( ((ip0 <= ilimit) & (offset_2>0)) /* offset_2==0 means offset_2 is invalidated */
152
+ && (MEM_read32(ip0) == MEM_read32(ip0 - offset_2)) ) {
155
153
  /* store sequence */
156
154
  size_t const rLength = ZSTD_count(ip0+4, ip0+4-offset_2, iend) + 4;
157
- U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */
155
+ { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
158
156
  hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base);
159
157
  ip0 += rLength;
160
158
  ip1 = ip0 + 1;
161
- ZSTD_storeSeq(seqStore, 0, anchor, 0, rLength-MINMATCH);
159
+ ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, 0 /*offCode*/, rLength-MINMATCH);
162
160
  anchor = ip0;
163
161
  continue; /* faster when present (confirmed on gcc-8) ... (?) */
164
162
  }
@@ -178,8 +176,7 @@ size_t ZSTD_compressBlock_fast(
178
176
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
179
177
  void const* src, size_t srcSize)
180
178
  {
181
- ZSTD_compressionParameters const* cParams = &ms->cParams;
182
- U32 const mls = cParams->minMatch;
179
+ U32 const mls = ms->cParams.minMatch;
183
180
  assert(ms->dictMatchState == NULL);
184
181
  switch(mls)
185
182
  {
@@ -239,6 +236,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
239
236
  assert(prefixStartIndex >= (U32)(dictEnd - dictBase));
240
237
 
241
238
  /* init */
239
+ DEBUGLOG(5, "ZSTD_compressBlock_fast_dictMatchState_generic");
242
240
  ip += (dictAndPrefixLength == 0);
243
241
  /* dictMatchState repCode checks don't currently handle repCode == 0
244
242
  * disabling. */
@@ -263,7 +261,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
263
261
  const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
264
262
  mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
265
263
  ip++;
266
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
264
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
267
265
  } else if ( (matchIndex <= prefixStartIndex) ) {
268
266
  size_t const dictHash = ZSTD_hashPtr(ip, dictHLog, mls);
269
267
  U32 const dictMatchIndex = dictHashTable[dictHash];
@@ -283,7 +281,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
283
281
  } /* catch up */
284
282
  offset_2 = offset_1;
285
283
  offset_1 = offset;
286
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
284
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
287
285
  }
288
286
  } else if (MEM_read32(match) != MEM_read32(ip)) {
289
287
  /* it's not a match, and we're not going to check the dictionary */
@@ -298,7 +296,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
298
296
  && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
299
297
  offset_2 = offset_1;
300
298
  offset_1 = offset;
301
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
299
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
302
300
  }
303
301
 
304
302
  /* match found */
@@ -323,7 +321,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
323
321
  const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
324
322
  size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
325
323
  U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
326
- ZSTD_storeSeq(seqStore, 0, anchor, 0, repLength2-MINMATCH);
324
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH);
327
325
  hashTable[ZSTD_hashPtr(ip, hlog, mls)] = current2;
328
326
  ip += repLength2;
329
327
  anchor = ip;
@@ -346,8 +344,7 @@ size_t ZSTD_compressBlock_fast_dictMatchState(
346
344
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
347
345
  void const* src, size_t srcSize)
348
346
  {
349
- ZSTD_compressionParameters const* cParams = &ms->cParams;
350
- U32 const mls = cParams->minMatch;
347
+ U32 const mls = ms->cParams.minMatch;
351
348
  assert(ms->dictMatchState != NULL);
352
349
  switch(mls)
353
350
  {
@@ -379,9 +376,7 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
379
376
  const BYTE* ip = istart;
380
377
  const BYTE* anchor = istart;
381
378
  const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
382
- const U32 maxDistance = 1U << cParams->windowLog;
383
- const U32 validLow = ms->window.lowLimit;
384
- const U32 lowLimit = (endIndex - validLow > maxDistance) ? endIndex - maxDistance : validLow;
379
+ const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog);
385
380
  const U32 dictStartIndex = lowLimit;
386
381
  const BYTE* const dictStart = dictBase + dictStartIndex;
387
382
  const U32 dictLimit = ms->window.dictLimit;
@@ -392,6 +387,8 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
392
387
  const BYTE* const ilimit = iend - 8;
393
388
  U32 offset_1=rep[0], offset_2=rep[1];
394
389
 
390
+ DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic");
391
+
395
392
  /* switch to "regular" variant if extDict is invalidated due to maxDistance */
396
393
  if (prefixStartIndex == dictStartIndex)
397
394
  return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, mls);
@@ -406,16 +403,17 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
406
403
  const U32 repIndex = current + 1 - offset_1;
407
404
  const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;
408
405
  const BYTE* const repMatch = repBase + repIndex;
409
- size_t mLength;
410
406
  hashTable[h] = current; /* update hash table */
411
407
  assert(offset_1 <= current +1); /* check repIndex */
412
408
 
413
409
  if ( (((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > dictStartIndex))
414
410
  && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
415
- const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
416
- mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
411
+ const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
412
+ size_t const rLength = ZSTD_count_2segments(ip+1 +4, repMatch +4, iend, repMatchEnd, prefixStart) + 4;
417
413
  ip++;
418
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, 0, mLength-MINMATCH);
414
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, rLength-MINMATCH);
415
+ ip += rLength;
416
+ anchor = ip;
419
417
  } else {
420
418
  if ( (matchIndex < dictStartIndex) ||
421
419
  (MEM_read32(match) != MEM_read32(ip)) ) {
@@ -423,21 +421,17 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
423
421
  ip += ((ip-anchor) >> kSearchStrength) + stepSize;
424
422
  continue;
425
423
  }
426
- { const BYTE* matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
427
- const BYTE* lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
428
- U32 offset;
429
- mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
424
+ { const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
425
+ const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
426
+ U32 const offset = current - matchIndex;
427
+ size_t mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
430
428
  while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
431
- offset = current - matchIndex;
432
- offset_2 = offset_1;
433
- offset_1 = offset;
434
- ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
429
+ offset_2 = offset_1; offset_1 = offset; /* update offset history */
430
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
431
+ ip += mLength;
432
+ anchor = ip;
435
433
  } }
436
434
 
437
- /* found a match : store it */
438
- ip += mLength;
439
- anchor = ip;
440
-
441
435
  if (ip <= ilimit) {
442
436
  /* Fill Table */
443
437
  hashTable[ZSTD_hashPtr(base+current+2, hlog, mls)] = current+2;
@@ -446,13 +440,13 @@ static size_t ZSTD_compressBlock_fast_extDict_generic(
446
440
  while (ip <= ilimit) {
447
441
  U32 const current2 = (U32)(ip-base);
448
442
  U32 const repIndex2 = current2 - offset_2;
449
- const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
443
+ const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
450
444
  if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) & (repIndex2 > dictStartIndex)) /* intentional overflow */
451
445
  && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
452
446
  const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
453
447
  size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
454
- U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
455
- ZSTD_storeSeq(seqStore, 0, anchor, 0, repLength2-MINMATCH);
448
+ { U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; } /* swap offset_2 <=> offset_1 */
449
+ ZSTD_storeSeq(seqStore, 0 /*litlen*/, anchor, iend, 0 /*offcode*/, repLength2-MINMATCH);
456
450
  hashTable[ZSTD_hashPtr(ip, hlog, mls)] = current2;
457
451
  ip += repLength2;
458
452
  anchor = ip;
@@ -474,8 +468,7 @@ size_t ZSTD_compressBlock_fast_extDict(
474
468
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
475
469
  void const* src, size_t srcSize)
476
470
  {
477
- ZSTD_compressionParameters const* cParams = &ms->cParams;
478
- U32 const mls = cParams->minMatch;
471
+ U32 const mls = ms->cParams.minMatch;
479
472
  switch(mls)
480
473
  {
481
474
  default: /* includes case 3 */
@@ -242,9 +242,7 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
242
242
 
243
243
  const BYTE* const base = ms->window.base;
244
244
  U32 const current = (U32)(ip-base);
245
- U32 const maxDistance = 1U << cParams->windowLog;
246
- U32 const windowValid = ms->window.lowLimit;
247
- U32 const windowLow = (current - windowValid > maxDistance) ? current - maxDistance : windowValid;
245
+ U32 const windowLow = ZSTD_getLowestMatchIndex(ms, current, cParams->windowLog);
248
246
 
249
247
  U32* const bt = ms->chainTable;
250
248
  U32 const btLog = cParams->chainLog - 1;
@@ -497,8 +495,10 @@ size_t ZSTD_HcFindBestMatch_generic (
497
495
  const BYTE* const dictEnd = dictBase + dictLimit;
498
496
  const U32 current = (U32)(ip-base);
499
497
  const U32 maxDistance = 1U << cParams->windowLog;
500
- const U32 lowValid = ms->window.lowLimit;
501
- const U32 lowLimit = (current - lowValid > maxDistance) ? current - maxDistance : lowValid;
498
+ const U32 lowestValid = ms->window.lowLimit;
499
+ const U32 withinMaxDistance = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;
500
+ const U32 isDictionary = (ms->loadedDictEnd != 0);
501
+ const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance;
502
502
  const U32 minChain = current > chainSize ? current - chainSize : 0;
503
503
  U32 nbAttempts = 1U << cParams->searchLog;
504
504
  size_t ml=4-1;
@@ -619,12 +619,14 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
619
619
  /* *******************************
620
620
  * Common parser - lazy strategy
621
621
  *********************************/
622
- FORCE_INLINE_TEMPLATE
623
- size_t ZSTD_compressBlock_lazy_generic(
622
+ typedef enum { search_hashChain, search_binaryTree } searchMethod_e;
623
+
624
+ FORCE_INLINE_TEMPLATE size_t
625
+ ZSTD_compressBlock_lazy_generic(
624
626
  ZSTD_matchState_t* ms, seqStore_t* seqStore,
625
627
  U32 rep[ZSTD_REP_NUM],
626
628
  const void* src, size_t srcSize,
627
- const U32 searchMethod, const U32 depth,
629
+ const searchMethod_e searchMethod, const U32 depth,
628
630
  ZSTD_dictMode_e const dictMode)
629
631
  {
630
632
  const BYTE* const istart = (const BYTE*)src;
@@ -640,8 +642,10 @@ size_t ZSTD_compressBlock_lazy_generic(
640
642
  ZSTD_matchState_t* ms,
641
643
  const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
642
644
  searchMax_f const searchMax = dictMode == ZSTD_dictMatchState ?
643
- (searchMethod ? ZSTD_BtFindBestMatch_dictMatchState_selectMLS : ZSTD_HcFindBestMatch_dictMatchState_selectMLS) :
644
- (searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS);
645
+ (searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_dictMatchState_selectMLS
646
+ : ZSTD_HcFindBestMatch_dictMatchState_selectMLS) :
647
+ (searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_selectMLS
648
+ : ZSTD_HcFindBestMatch_selectMLS);
645
649
  U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
646
650
 
647
651
  const ZSTD_matchState_t* const dms = ms->dictMatchState;
@@ -806,7 +810,7 @@ size_t ZSTD_compressBlock_lazy_generic(
806
810
  /* store sequence */
807
811
  _storeSequence:
808
812
  { size_t const litLength = start - anchor;
809
- ZSTD_storeSeq(seqStore, litLength, anchor, (U32)offset, matchLength-MINMATCH);
813
+ ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offset, matchLength-MINMATCH);
810
814
  anchor = ip = start + matchLength;
811
815
  }
812
816
 
@@ -824,7 +828,7 @@ _storeSequence:
824
828
  const BYTE* const repEnd2 = repIndex < prefixLowestIndex ? dictEnd : iend;
825
829
  matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd2, prefixLowest) + 4;
826
830
  offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset_2 <=> offset_1 */
827
- ZSTD_storeSeq(seqStore, 0, anchor, 0, matchLength-MINMATCH);
831
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, matchLength-MINMATCH);
828
832
  ip += matchLength;
829
833
  anchor = ip;
830
834
  continue;
@@ -839,7 +843,7 @@ _storeSequence:
839
843
  /* store sequence */
840
844
  matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
841
845
  offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
842
- ZSTD_storeSeq(seqStore, 0, anchor, 0, matchLength-MINMATCH);
846
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, matchLength-MINMATCH);
843
847
  ip += matchLength;
844
848
  anchor = ip;
845
849
  continue; /* faster when present ... (?) */
@@ -850,7 +854,7 @@ _storeSequence:
850
854
  rep[1] = offset_2 ? offset_2 : savedOffset;
851
855
 
852
856
  /* Return the last literals size */
853
- return iend - anchor;
857
+ return (size_t)(iend - anchor);
854
858
  }
855
859
 
856
860
 
@@ -858,56 +862,56 @@ size_t ZSTD_compressBlock_btlazy2(
858
862
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
859
863
  void const* src, size_t srcSize)
860
864
  {
861
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 1, 2, ZSTD_noDict);
865
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_noDict);
862
866
  }
863
867
 
864
868
  size_t ZSTD_compressBlock_lazy2(
865
869
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
866
870
  void const* src, size_t srcSize)
867
871
  {
868
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 2, ZSTD_noDict);
872
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_noDict);
869
873
  }
870
874
 
871
875
  size_t ZSTD_compressBlock_lazy(
872
876
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
873
877
  void const* src, size_t srcSize)
874
878
  {
875
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 1, ZSTD_noDict);
879
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_noDict);
876
880
  }
877
881
 
878
882
  size_t ZSTD_compressBlock_greedy(
879
883
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
880
884
  void const* src, size_t srcSize)
881
885
  {
882
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 0, ZSTD_noDict);
886
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_noDict);
883
887
  }
884
888
 
885
889
  size_t ZSTD_compressBlock_btlazy2_dictMatchState(
886
890
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
887
891
  void const* src, size_t srcSize)
888
892
  {
889
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 1, 2, ZSTD_dictMatchState);
893
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_dictMatchState);
890
894
  }
891
895
 
892
896
  size_t ZSTD_compressBlock_lazy2_dictMatchState(
893
897
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
894
898
  void const* src, size_t srcSize)
895
899
  {
896
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 2, ZSTD_dictMatchState);
900
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dictMatchState);
897
901
  }
898
902
 
899
903
  size_t ZSTD_compressBlock_lazy_dictMatchState(
900
904
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
901
905
  void const* src, size_t srcSize)
902
906
  {
903
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 1, ZSTD_dictMatchState);
907
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dictMatchState);
904
908
  }
905
909
 
906
910
  size_t ZSTD_compressBlock_greedy_dictMatchState(
907
911
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
908
912
  void const* src, size_t srcSize)
909
913
  {
910
- return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 0, ZSTD_dictMatchState);
914
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dictMatchState);
911
915
  }
912
916
 
913
917
 
@@ -916,7 +920,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
916
920
  ZSTD_matchState_t* ms, seqStore_t* seqStore,
917
921
  U32 rep[ZSTD_REP_NUM],
918
922
  const void* src, size_t srcSize,
919
- const U32 searchMethod, const U32 depth)
923
+ const searchMethod_e searchMethod, const U32 depth)
920
924
  {
921
925
  const BYTE* const istart = (const BYTE*)src;
922
926
  const BYTE* ip = istart;
@@ -934,7 +938,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
934
938
  typedef size_t (*searchMax_f)(
935
939
  ZSTD_matchState_t* ms,
936
940
  const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
937
- searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_extDict_selectMLS : ZSTD_HcFindBestMatch_extDict_selectMLS;
941
+ searchMax_f searchMax = searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_extDict_selectMLS : ZSTD_HcFindBestMatch_extDict_selectMLS;
938
942
 
939
943
  U32 offset_1 = rep[0], offset_2 = rep[1];
940
944
 
@@ -1047,7 +1051,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
1047
1051
  /* store sequence */
1048
1052
  _storeSequence:
1049
1053
  { size_t const litLength = start - anchor;
1050
- ZSTD_storeSeq(seqStore, litLength, anchor, (U32)offset, matchLength-MINMATCH);
1054
+ ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offset, matchLength-MINMATCH);
1051
1055
  anchor = ip = start + matchLength;
1052
1056
  }
1053
1057
 
@@ -1062,7 +1066,7 @@ _storeSequence:
1062
1066
  const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
1063
1067
  matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
1064
1068
  offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset history */
1065
- ZSTD_storeSeq(seqStore, 0, anchor, 0, matchLength-MINMATCH);
1069
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, matchLength-MINMATCH);
1066
1070
  ip += matchLength;
1067
1071
  anchor = ip;
1068
1072
  continue; /* faster when present ... (?) */
@@ -1075,7 +1079,7 @@ _storeSequence:
1075
1079
  rep[1] = offset_2;
1076
1080
 
1077
1081
  /* Return the last literals size */
1078
- return iend - anchor;
1082
+ return (size_t)(iend - anchor);
1079
1083
  }
1080
1084
 
1081
1085
 
@@ -1083,7 +1087,7 @@ size_t ZSTD_compressBlock_greedy_extDict(
1083
1087
  ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1084
1088
  void const* src, size_t srcSize)
1085
1089
  {
1086
- return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 0, 0);
1090
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0);
1087
1091
  }
1088
1092
 
1089
1093
  size_t ZSTD_compressBlock_lazy_extDict(
@@ -1091,7 +1095,7 @@ size_t ZSTD_compressBlock_lazy_extDict(
1091
1095
  void const* src, size_t srcSize)
1092
1096
 
1093
1097
  {
1094
- return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 0, 1);
1098
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1);
1095
1099
  }
1096
1100
 
1097
1101
  size_t ZSTD_compressBlock_lazy2_extDict(
@@ -1099,7 +1103,7 @@ size_t ZSTD_compressBlock_lazy2_extDict(
1099
1103
  void const* src, size_t srcSize)
1100
1104
 
1101
1105
  {
1102
- return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 0, 2);
1106
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2);
1103
1107
  }
1104
1108
 
1105
1109
  size_t ZSTD_compressBlock_btlazy2_extDict(
@@ -1107,5 +1111,5 @@ size_t ZSTD_compressBlock_btlazy2_extDict(
1107
1111
  void const* src, size_t srcSize)
1108
1112
 
1109
1113
  {
1110
- return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 1, 2);
1114
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2);
1111
1115
  }