extzstd 0.2 → 0.3

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.ja.md +13 -0
  3. data/README.md +17 -14
  4. data/contrib/zstd/{NEWS → CHANGELOG} +115 -2
  5. data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
  6. data/contrib/zstd/Makefile +99 -53
  7. data/contrib/zstd/README.md +59 -39
  8. data/contrib/zstd/TESTING.md +1 -1
  9. data/contrib/zstd/appveyor.yml +17 -6
  10. data/contrib/zstd/lib/BUCK +29 -2
  11. data/contrib/zstd/lib/Makefile +118 -21
  12. data/contrib/zstd/lib/README.md +84 -44
  13. data/contrib/zstd/lib/common/bitstream.h +17 -33
  14. data/contrib/zstd/lib/common/compiler.h +62 -8
  15. data/contrib/zstd/lib/common/cpu.h +215 -0
  16. data/contrib/zstd/lib/common/debug.c +44 -0
  17. data/contrib/zstd/lib/common/debug.h +134 -0
  18. data/contrib/zstd/lib/common/entropy_common.c +16 -1
  19. data/contrib/zstd/lib/common/error_private.c +7 -0
  20. data/contrib/zstd/lib/common/fse.h +48 -44
  21. data/contrib/zstd/lib/common/fse_decompress.c +3 -3
  22. data/contrib/zstd/lib/common/huf.h +169 -113
  23. data/contrib/zstd/lib/common/mem.h +20 -2
  24. data/contrib/zstd/lib/common/pool.c +135 -49
  25. data/contrib/zstd/lib/common/pool.h +40 -21
  26. data/contrib/zstd/lib/common/threading.c +2 -2
  27. data/contrib/zstd/lib/common/threading.h +12 -12
  28. data/contrib/zstd/lib/common/xxhash.c +3 -2
  29. data/contrib/zstd/lib/common/zstd_common.c +3 -6
  30. data/contrib/zstd/lib/common/zstd_errors.h +17 -7
  31. data/contrib/zstd/lib/common/zstd_internal.h +76 -48
  32. data/contrib/zstd/lib/compress/fse_compress.c +89 -209
  33. data/contrib/zstd/lib/compress/hist.c +203 -0
  34. data/contrib/zstd/lib/compress/hist.h +95 -0
  35. data/contrib/zstd/lib/compress/huf_compress.c +188 -80
  36. data/contrib/zstd/lib/compress/zstd_compress.c +2500 -1203
  37. data/contrib/zstd/lib/compress/zstd_compress_internal.h +463 -62
  38. data/contrib/zstd/lib/compress/zstd_double_fast.c +321 -131
  39. data/contrib/zstd/lib/compress/zstd_double_fast.h +13 -4
  40. data/contrib/zstd/lib/compress/zstd_fast.c +335 -108
  41. data/contrib/zstd/lib/compress/zstd_fast.h +12 -6
  42. data/contrib/zstd/lib/compress/zstd_lazy.c +654 -313
  43. data/contrib/zstd/lib/compress/zstd_lazy.h +44 -16
  44. data/contrib/zstd/lib/compress/zstd_ldm.c +310 -420
  45. data/contrib/zstd/lib/compress/zstd_ldm.h +63 -26
  46. data/contrib/zstd/lib/compress/zstd_opt.c +773 -325
  47. data/contrib/zstd/lib/compress/zstd_opt.h +31 -5
  48. data/contrib/zstd/lib/compress/zstdmt_compress.c +1468 -518
  49. data/contrib/zstd/lib/compress/zstdmt_compress.h +96 -45
  50. data/contrib/zstd/lib/decompress/huf_decompress.c +518 -282
  51. data/contrib/zstd/lib/decompress/zstd_ddict.c +240 -0
  52. data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
  53. data/contrib/zstd/lib/decompress/zstd_decompress.c +613 -1513
  54. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1311 -0
  55. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +59 -0
  56. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +175 -0
  57. data/contrib/zstd/lib/dictBuilder/cover.c +194 -113
  58. data/contrib/zstd/lib/dictBuilder/cover.h +112 -0
  59. data/contrib/zstd/lib/dictBuilder/divsufsort.c +3 -3
  60. data/contrib/zstd/lib/dictBuilder/fastcover.c +740 -0
  61. data/contrib/zstd/lib/dictBuilder/zdict.c +142 -106
  62. data/contrib/zstd/lib/dictBuilder/zdict.h +115 -49
  63. data/contrib/zstd/lib/legacy/zstd_legacy.h +44 -12
  64. data/contrib/zstd/lib/legacy/zstd_v01.c +41 -10
  65. data/contrib/zstd/lib/legacy/zstd_v01.h +12 -7
  66. data/contrib/zstd/lib/legacy/zstd_v02.c +37 -12
  67. data/contrib/zstd/lib/legacy/zstd_v02.h +12 -7
  68. data/contrib/zstd/lib/legacy/zstd_v03.c +38 -12
  69. data/contrib/zstd/lib/legacy/zstd_v03.h +12 -7
  70. data/contrib/zstd/lib/legacy/zstd_v04.c +55 -174
  71. data/contrib/zstd/lib/legacy/zstd_v04.h +12 -7
  72. data/contrib/zstd/lib/legacy/zstd_v05.c +59 -31
  73. data/contrib/zstd/lib/legacy/zstd_v05.h +12 -7
  74. data/contrib/zstd/lib/legacy/zstd_v06.c +48 -20
  75. data/contrib/zstd/lib/legacy/zstd_v06.h +10 -5
  76. data/contrib/zstd/lib/legacy/zstd_v07.c +62 -29
  77. data/contrib/zstd/lib/legacy/zstd_v07.h +10 -5
  78. data/contrib/zstd/lib/zstd.h +1346 -832
  79. data/ext/extzstd.c +27 -19
  80. data/ext/extzstd_stream.c +20 -4
  81. data/ext/zstd_compress.c +1 -0
  82. data/ext/zstd_decompress.c +4 -0
  83. data/ext/zstd_dictbuilder.c +4 -0
  84. data/ext/zstd_dictbuilder_fastcover.c +5 -0
  85. data/lib/extzstd.rb +52 -220
  86. data/lib/extzstd/version.rb +1 -1
  87. metadata +21 -7
  88. data/contrib/zstd/circle.yml +0 -63
@@ -16,13 +16,19 @@ extern "C" {
16
16
  #endif
17
17
 
18
18
  #include "mem.h" /* U32 */
19
- #include "zstd.h" /* ZSTD_CCtx, size_t */
19
+ #include "zstd_compress_internal.h"
20
20
 
21
- void ZSTD_fillHashTable(ZSTD_CCtx* zc, const void* end, const U32 mls);
22
- size_t ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
23
- const void* src, size_t srcSize);
24
- size_t ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
25
- const void* src, size_t srcSize);
21
+ void ZSTD_fillHashTable(ZSTD_matchState_t* ms,
22
+ void const* end, ZSTD_dictTableLoadMethod_e dtlm);
23
+ size_t ZSTD_compressBlock_fast(
24
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
25
+ void const* src, size_t srcSize);
26
+ size_t ZSTD_compressBlock_fast_dictMatchState(
27
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
28
+ void const* src, size_t srcSize);
29
+ size_t ZSTD_compressBlock_fast_extDict(
30
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
31
+ void const* src, size_t srcSize);
26
32
 
27
33
  #if defined (__cplusplus)
28
34
  }
@@ -15,89 +15,108 @@
15
15
  /*-*************************************
16
16
  * Binary Tree search
17
17
  ***************************************/
18
- /** ZSTD_insertBt1() : add one or multiple positions to tree.
19
- * ip : assumed <= iend-8 .
20
- * @return : nb of positions added */
21
- static U32 ZSTD_insertBt1(ZSTD_CCtx* zc,
22
- const BYTE* const ip, const BYTE* const iend,
23
- U32 nbCompares, U32 const mls, U32 const extDict)
18
+
19
+ static void
20
+ ZSTD_updateDUBT(ZSTD_matchState_t* ms,
21
+ const BYTE* ip, const BYTE* iend,
22
+ U32 mls)
24
23
  {
25
- U32* const hashTable = zc->hashTable;
26
- U32 const hashLog = zc->appliedParams.cParams.hashLog;
27
- size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
28
- U32* const bt = zc->chainTable;
29
- U32 const btLog = zc->appliedParams.cParams.chainLog - 1;
30
- U32 const btMask = (1 << btLog) - 1;
31
- U32 matchIndex = hashTable[h];
24
+ const ZSTD_compressionParameters* const cParams = &ms->cParams;
25
+ U32* const hashTable = ms->hashTable;
26
+ U32 const hashLog = cParams->hashLog;
27
+
28
+ U32* const bt = ms->chainTable;
29
+ U32 const btLog = cParams->chainLog - 1;
30
+ U32 const btMask = (1 << btLog) - 1;
31
+
32
+ const BYTE* const base = ms->window.base;
33
+ U32 const target = (U32)(ip - base);
34
+ U32 idx = ms->nextToUpdate;
35
+
36
+ if (idx != target)
37
+ DEBUGLOG(7, "ZSTD_updateDUBT, from %u to %u (dictLimit:%u)",
38
+ idx, target, ms->window.dictLimit);
39
+ assert(ip + 8 <= iend); /* condition for ZSTD_hashPtr */
40
+ (void)iend;
41
+
42
+ assert(idx >= ms->window.dictLimit); /* condition for valid base+idx */
43
+ for ( ; idx < target ; idx++) {
44
+ size_t const h = ZSTD_hashPtr(base + idx, hashLog, mls); /* assumption : ip + 8 <= iend */
45
+ U32 const matchIndex = hashTable[h];
46
+
47
+ U32* const nextCandidatePtr = bt + 2*(idx&btMask);
48
+ U32* const sortMarkPtr = nextCandidatePtr + 1;
49
+
50
+ DEBUGLOG(8, "ZSTD_updateDUBT: insert %u", idx);
51
+ hashTable[h] = idx; /* Update Hash Table */
52
+ *nextCandidatePtr = matchIndex; /* update BT like a chain */
53
+ *sortMarkPtr = ZSTD_DUBT_UNSORTED_MARK;
54
+ }
55
+ ms->nextToUpdate = target;
56
+ }
57
+
58
+
59
+ /** ZSTD_insertDUBT1() :
60
+ * sort one already inserted but unsorted position
61
+ * assumption : current >= btlow == (current - btmask)
62
+ * doesn't fail */
63
+ static void
64
+ ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
65
+ U32 current, const BYTE* inputEnd,
66
+ U32 nbCompares, U32 btLow,
67
+ const ZSTD_dictMode_e dictMode)
68
+ {
69
+ const ZSTD_compressionParameters* const cParams = &ms->cParams;
70
+ U32* const bt = ms->chainTable;
71
+ U32 const btLog = cParams->chainLog - 1;
72
+ U32 const btMask = (1 << btLog) - 1;
32
73
  size_t commonLengthSmaller=0, commonLengthLarger=0;
33
- const BYTE* const base = zc->base;
34
- const BYTE* const dictBase = zc->dictBase;
35
- const U32 dictLimit = zc->dictLimit;
74
+ const BYTE* const base = ms->window.base;
75
+ const BYTE* const dictBase = ms->window.dictBase;
76
+ const U32 dictLimit = ms->window.dictLimit;
77
+ const BYTE* const ip = (current>=dictLimit) ? base + current : dictBase + current;
78
+ const BYTE* const iend = (current>=dictLimit) ? inputEnd : dictBase + dictLimit;
36
79
  const BYTE* const dictEnd = dictBase + dictLimit;
37
80
  const BYTE* const prefixStart = base + dictLimit;
38
81
  const BYTE* match;
39
- const U32 current = (U32)(ip-base);
40
- const U32 btLow = btMask >= current ? 0 : current - btMask;
41
82
  U32* smallerPtr = bt + 2*(current&btMask);
42
83
  U32* largerPtr = smallerPtr + 1;
84
+ U32 matchIndex = *smallerPtr; /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */
43
85
  U32 dummy32; /* to be nullified at the end */
44
- U32 const windowLow = zc->lowLimit;
45
- U32 matchEndIdx = current+8+1;
46
- size_t bestLength = 8;
47
- #ifdef ZSTD_C_PREDICT
48
- U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
49
- U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);
50
- predictedSmall += (predictedSmall>0);
51
- predictedLarge += (predictedLarge>0);
52
- #endif /* ZSTD_C_PREDICT */
53
-
54
- DEBUGLOG(8, "ZSTD_insertBt1 (%u)", current);
86
+ U32 const windowLow = ms->window.lowLimit;
55
87
 
56
- assert(ip <= iend-8); /* required for h calculation */
57
- hashTable[h] = current; /* Update Hash Table */
88
+ DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)",
89
+ current, dictLimit, windowLow);
90
+ assert(current >= btLow);
91
+ assert(ip < iend); /* condition for ZSTD_count */
58
92
 
59
93
  while (nbCompares-- && (matchIndex > windowLow)) {
60
94
  U32* const nextPtr = bt + 2*(matchIndex & btMask);
61
95
  size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
62
96
  assert(matchIndex < current);
63
-
64
- #ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */
65
- const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
66
- if (matchIndex == predictedSmall) {
67
- /* no need to check length, result known */
68
- *smallerPtr = matchIndex;
69
- if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
70
- smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
71
- matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
72
- predictedSmall = predictPtr[1] + (predictPtr[1]>0);
73
- continue;
74
- }
75
- if (matchIndex == predictedLarge) {
76
- *largerPtr = matchIndex;
77
- if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
78
- largerPtr = nextPtr;
79
- matchIndex = nextPtr[0];
80
- predictedLarge = predictPtr[0] + (predictPtr[0]>0);
81
- continue;
82
- }
83
- #endif
84
-
85
- if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
86
- assert(matchIndex+matchLength >= dictLimit); /* might be wrong if extDict is incorrectly set to 0 */
87
- match = base + matchIndex;
97
+ /* note : all candidates are now supposed sorted,
98
+ * but it's still possible to have nextPtr[1] == ZSTD_DUBT_UNSORTED_MARK
99
+ * when a real index has the same value as ZSTD_DUBT_UNSORTED_MARK */
100
+
101
+ if ( (dictMode != ZSTD_extDict)
102
+ || (matchIndex+matchLength >= dictLimit) /* both in current segment*/
103
+ || (current < dictLimit) /* both in extDict */) {
104
+ const BYTE* const mBase = ( (dictMode != ZSTD_extDict)
105
+ || (matchIndex+matchLength >= dictLimit)) ?
106
+ base : dictBase;
107
+ assert( (matchIndex+matchLength >= dictLimit) /* might be wrong if extDict is incorrectly set to 0 */
108
+ || (current < dictLimit) );
109
+ match = mBase + matchIndex;
88
110
  matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
89
111
  } else {
90
112
  match = dictBase + matchIndex;
91
113
  matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
92
114
  if (matchIndex+matchLength >= dictLimit)
93
- match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
115
+ match = base + matchIndex; /* preparation for next read of match[matchLength] */
94
116
  }
95
117
 
96
- if (matchLength > bestLength) {
97
- bestLength = matchLength;
98
- if (matchLength > matchEndIdx - matchIndex)
99
- matchEndIdx = matchIndex + (U32)matchLength;
100
- }
118
+ DEBUGLOG(8, "ZSTD_insertDUBT1: comparing %u with %u : found %u common bytes ",
119
+ current, matchIndex, (U32)matchLength);
101
120
 
102
121
  if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
103
122
  break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */
@@ -108,6 +127,8 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc,
108
127
  *smallerPtr = matchIndex; /* update smaller idx */
109
128
  commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
110
129
  if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop searching */
130
+ DEBUGLOG(8, "ZSTD_insertDUBT1: %u (>btLow=%u) is smaller : next => %u",
131
+ matchIndex, btLow, nextPtr[1]);
111
132
  smallerPtr = nextPtr+1; /* new "candidate" => larger than match, which was smaller than target */
112
133
  matchIndex = nextPtr[1]; /* new matchIndex, larger than previous and closer to current */
113
134
  } else {
@@ -115,184 +136,301 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc,
115
136
  *largerPtr = matchIndex;
116
137
  commonLengthLarger = matchLength;
117
138
  if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop searching */
139
+ DEBUGLOG(8, "ZSTD_insertDUBT1: %u (>btLow=%u) is larger => %u",
140
+ matchIndex, btLow, nextPtr[0]);
118
141
  largerPtr = nextPtr;
119
142
  matchIndex = nextPtr[0];
120
143
  } }
121
144
 
122
145
  *smallerPtr = *largerPtr = 0;
123
- if (bestLength > 384) return MIN(192, (U32)(bestLength - 384)); /* speed optimization */
124
- assert(matchEndIdx > current + 8);
125
- return matchEndIdx - (current + 8);
126
146
  }
127
147
 
128
- FORCE_INLINE_TEMPLATE
129
- void ZSTD_updateTree_internal(ZSTD_CCtx* zc,
130
- const BYTE* const ip, const BYTE* const iend,
131
- const U32 nbCompares, const U32 mls, const U32 extDict)
132
- {
133
- const BYTE* const base = zc->base;
134
- U32 const target = (U32)(ip - base);
135
- U32 idx = zc->nextToUpdate;
136
- DEBUGLOG(7, "ZSTD_updateTree_internal, from %u to %u (extDict:%u)",
137
- idx, target, extDict);
138
148
 
139
- while(idx < target)
140
- idx += ZSTD_insertBt1(zc, base+idx, iend, nbCompares, mls, extDict);
141
- zc->nextToUpdate = target;
142
- }
143
-
144
- void ZSTD_updateTree(ZSTD_CCtx* zc,
145
- const BYTE* const ip, const BYTE* const iend,
146
- const U32 nbCompares, const U32 mls)
149
+ static size_t
150
+ ZSTD_DUBT_findBetterDictMatch (
151
+ ZSTD_matchState_t* ms,
152
+ const BYTE* const ip, const BYTE* const iend,
153
+ size_t* offsetPtr,
154
+ size_t bestLength,
155
+ U32 nbCompares,
156
+ U32 const mls,
157
+ const ZSTD_dictMode_e dictMode)
147
158
  {
148
- ZSTD_updateTree_internal(zc, ip, iend, nbCompares, mls, 0 /*extDict*/);
149
- }
150
-
151
- void ZSTD_updateTree_extDict(ZSTD_CCtx* zc,
152
- const BYTE* const ip, const BYTE* const iend,
153
- const U32 nbCompares, const U32 mls)
154
- {
155
- ZSTD_updateTree_internal(zc, ip, iend, nbCompares, mls, 1 /*extDict*/);
156
- }
159
+ const ZSTD_matchState_t * const dms = ms->dictMatchState;
160
+ const ZSTD_compressionParameters* const dmsCParams = &dms->cParams;
161
+ const U32 * const dictHashTable = dms->hashTable;
162
+ U32 const hashLog = dmsCParams->hashLog;
163
+ size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
164
+ U32 dictMatchIndex = dictHashTable[h];
165
+
166
+ const BYTE* const base = ms->window.base;
167
+ const BYTE* const prefixStart = base + ms->window.dictLimit;
168
+ U32 const current = (U32)(ip-base);
169
+ const BYTE* const dictBase = dms->window.base;
170
+ const BYTE* const dictEnd = dms->window.nextSrc;
171
+ U32 const dictHighLimit = (U32)(dms->window.nextSrc - dms->window.base);
172
+ U32 const dictLowLimit = dms->window.lowLimit;
173
+ U32 const dictIndexDelta = ms->window.lowLimit - dictHighLimit;
174
+
175
+ U32* const dictBt = dms->chainTable;
176
+ U32 const btLog = dmsCParams->chainLog - 1;
177
+ U32 const btMask = (1 << btLog) - 1;
178
+ U32 const btLow = (btMask >= dictHighLimit - dictLowLimit) ? dictLowLimit : dictHighLimit - btMask;
157
179
 
158
-
159
- static size_t ZSTD_insertBtAndFindBestMatch (
160
- ZSTD_CCtx* zc,
161
- const BYTE* const ip, const BYTE* const iend,
162
- size_t* offsetPtr,
163
- U32 nbCompares, const U32 mls,
164
- U32 extDict)
165
- {
166
- U32* const hashTable = zc->hashTable;
167
- U32 const hashLog = zc->appliedParams.cParams.hashLog;
168
- size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
169
- U32* const bt = zc->chainTable;
170
- U32 const btLog = zc->appliedParams.cParams.chainLog - 1;
171
- U32 const btMask = (1 << btLog) - 1;
172
- U32 matchIndex = hashTable[h];
173
180
  size_t commonLengthSmaller=0, commonLengthLarger=0;
174
- const BYTE* const base = zc->base;
175
- const BYTE* const dictBase = zc->dictBase;
176
- const U32 dictLimit = zc->dictLimit;
177
- const BYTE* const dictEnd = dictBase + dictLimit;
178
- const BYTE* const prefixStart = base + dictLimit;
179
- const U32 current = (U32)(ip-base);
180
- const U32 btLow = btMask >= current ? 0 : current - btMask;
181
- const U32 windowLow = zc->lowLimit;
182
- U32* smallerPtr = bt + 2*(current&btMask);
183
- U32* largerPtr = bt + 2*(current&btMask) + 1;
184
- U32 matchEndIdx = current+8+1;
185
- U32 dummy32; /* to be nullified at the end */
186
- size_t bestLength = 0;
187
181
 
188
- assert(ip <= iend-8); /* required for h calculation */
189
- hashTable[h] = current; /* Update Hash Table */
182
+ (void)dictMode;
183
+ assert(dictMode == ZSTD_dictMatchState);
190
184
 
191
- while (nbCompares-- && (matchIndex > windowLow)) {
192
- U32* const nextPtr = bt + 2*(matchIndex & btMask);
185
+ while (nbCompares-- && (dictMatchIndex > dictLowLimit)) {
186
+ U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask);
193
187
  size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
194
- const BYTE* match;
195
-
196
- if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
197
- match = base + matchIndex;
198
- matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
199
- } else {
200
- match = dictBase + matchIndex;
201
- matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
202
- if (matchIndex+matchLength >= dictLimit)
203
- match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
204
- }
188
+ const BYTE* match = dictBase + dictMatchIndex;
189
+ matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
190
+ if (dictMatchIndex+matchLength >= dictHighLimit)
191
+ match = base + dictMatchIndex + dictIndexDelta; /* to prepare for next usage of match[matchLength] */
205
192
 
206
193
  if (matchLength > bestLength) {
207
- if (matchLength > matchEndIdx - matchIndex)
208
- matchEndIdx = matchIndex + (U32)matchLength;
209
- if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
194
+ U32 matchIndex = dictMatchIndex + dictIndexDelta;
195
+ if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) {
196
+ DEBUGLOG(9, "ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)",
197
+ current, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, ZSTD_REP_MOVE + current - matchIndex, dictMatchIndex, matchIndex);
210
198
  bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
211
- if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
199
+ }
200
+ if (ip+matchLength == iend) { /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */
212
201
  break; /* drop, to guarantee consistency (miss a little bit of compression) */
213
202
  }
214
203
  }
215
204
 
216
205
  if (match[matchLength] < ip[matchLength]) {
217
- /* match is smaller than current */
218
- *smallerPtr = matchIndex; /* update smaller idx */
206
+ if (dictMatchIndex <= btLow) { break; } /* beyond tree size, stop the search */
219
207
  commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
220
- if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
221
- smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
222
- matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
208
+ dictMatchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
223
209
  } else {
224
210
  /* match is larger than current */
225
- *largerPtr = matchIndex;
211
+ if (dictMatchIndex <= btLow) { break; } /* beyond tree size, stop the search */
226
212
  commonLengthLarger = matchLength;
227
- if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
228
- largerPtr = nextPtr;
229
- matchIndex = nextPtr[0];
230
- } }
231
-
232
- *smallerPtr = *largerPtr = 0;
213
+ dictMatchIndex = nextPtr[0];
214
+ }
215
+ }
233
216
 
234
- assert(matchEndIdx > current+8);
235
- zc->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
217
+ if (bestLength >= MINMATCH) {
218
+ U32 const mIndex = current - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
219
+ DEBUGLOG(8, "ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
220
+ current, (U32)bestLength, (U32)*offsetPtr, mIndex);
221
+ }
236
222
  return bestLength;
223
+
237
224
  }
238
225
 
239
226
 
240
- /** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
241
- static size_t ZSTD_BtFindBestMatch (
242
- ZSTD_CCtx* zc,
243
- const BYTE* const ip, const BYTE* const iLimit,
227
+ static size_t
228
+ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
229
+ const BYTE* const ip, const BYTE* const iend,
244
230
  size_t* offsetPtr,
245
- const U32 maxNbAttempts, const U32 mls)
231
+ U32 const mls,
232
+ const ZSTD_dictMode_e dictMode)
246
233
  {
247
- if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
248
- ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
249
- return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 0);
234
+ const ZSTD_compressionParameters* const cParams = &ms->cParams;
235
+ U32* const hashTable = ms->hashTable;
236
+ U32 const hashLog = cParams->hashLog;
237
+ size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
238
+ U32 matchIndex = hashTable[h];
239
+
240
+ const BYTE* const base = ms->window.base;
241
+ U32 const current = (U32)(ip-base);
242
+ U32 const windowLow = ms->window.lowLimit;
243
+
244
+ U32* const bt = ms->chainTable;
245
+ U32 const btLog = cParams->chainLog - 1;
246
+ U32 const btMask = (1 << btLog) - 1;
247
+ U32 const btLow = (btMask >= current) ? 0 : current - btMask;
248
+ U32 const unsortLimit = MAX(btLow, windowLow);
249
+
250
+ U32* nextCandidate = bt + 2*(matchIndex&btMask);
251
+ U32* unsortedMark = bt + 2*(matchIndex&btMask) + 1;
252
+ U32 nbCompares = 1U << cParams->searchLog;
253
+ U32 nbCandidates = nbCompares;
254
+ U32 previousCandidate = 0;
255
+
256
+ DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", current);
257
+ assert(ip <= iend-8); /* required for h calculation */
258
+
259
+ /* reach end of unsorted candidates list */
260
+ while ( (matchIndex > unsortLimit)
261
+ && (*unsortedMark == ZSTD_DUBT_UNSORTED_MARK)
262
+ && (nbCandidates > 1) ) {
263
+ DEBUGLOG(8, "ZSTD_DUBT_findBestMatch: candidate %u is unsorted",
264
+ matchIndex);
265
+ *unsortedMark = previousCandidate; /* the unsortedMark becomes a reversed chain, to move up back to original position */
266
+ previousCandidate = matchIndex;
267
+ matchIndex = *nextCandidate;
268
+ nextCandidate = bt + 2*(matchIndex&btMask);
269
+ unsortedMark = bt + 2*(matchIndex&btMask) + 1;
270
+ nbCandidates --;
271
+ }
272
+
273
+ /* nullify last candidate if it's still unsorted
274
+ * simplification, detrimental to compression ratio, beneficial for speed */
275
+ if ( (matchIndex > unsortLimit)
276
+ && (*unsortedMark==ZSTD_DUBT_UNSORTED_MARK) ) {
277
+ DEBUGLOG(7, "ZSTD_DUBT_findBestMatch: nullify last unsorted candidate %u",
278
+ matchIndex);
279
+ *nextCandidate = *unsortedMark = 0;
280
+ }
281
+
282
+ /* batch sort stacked candidates */
283
+ matchIndex = previousCandidate;
284
+ while (matchIndex) { /* will end on matchIndex == 0 */
285
+ U32* const nextCandidateIdxPtr = bt + 2*(matchIndex&btMask) + 1;
286
+ U32 const nextCandidateIdx = *nextCandidateIdxPtr;
287
+ ZSTD_insertDUBT1(ms, matchIndex, iend,
288
+ nbCandidates, unsortLimit, dictMode);
289
+ matchIndex = nextCandidateIdx;
290
+ nbCandidates++;
291
+ }
292
+
293
+ /* find longest match */
294
+ { size_t commonLengthSmaller = 0, commonLengthLarger = 0;
295
+ const BYTE* const dictBase = ms->window.dictBase;
296
+ const U32 dictLimit = ms->window.dictLimit;
297
+ const BYTE* const dictEnd = dictBase + dictLimit;
298
+ const BYTE* const prefixStart = base + dictLimit;
299
+ U32* smallerPtr = bt + 2*(current&btMask);
300
+ U32* largerPtr = bt + 2*(current&btMask) + 1;
301
+ U32 matchEndIdx = current + 8 + 1;
302
+ U32 dummy32; /* to be nullified at the end */
303
+ size_t bestLength = 0;
304
+
305
+ matchIndex = hashTable[h];
306
+ hashTable[h] = current; /* Update Hash Table */
307
+
308
+ while (nbCompares-- && (matchIndex > windowLow)) {
309
+ U32* const nextPtr = bt + 2*(matchIndex & btMask);
310
+ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
311
+ const BYTE* match;
312
+
313
+ if ((dictMode != ZSTD_extDict) || (matchIndex+matchLength >= dictLimit)) {
314
+ match = base + matchIndex;
315
+ matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
316
+ } else {
317
+ match = dictBase + matchIndex;
318
+ matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
319
+ if (matchIndex+matchLength >= dictLimit)
320
+ match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
321
+ }
322
+
323
+ if (matchLength > bestLength) {
324
+ if (matchLength > matchEndIdx - matchIndex)
325
+ matchEndIdx = matchIndex + (U32)matchLength;
326
+ if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
327
+ bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
328
+ if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
329
+ if (dictMode == ZSTD_dictMatchState) {
330
+ nbCompares = 0; /* in addition to avoiding checking any
331
+ * further in this loop, make sure we
332
+ * skip checking in the dictionary. */
333
+ }
334
+ break; /* drop, to guarantee consistency (miss a little bit of compression) */
335
+ }
336
+ }
337
+
338
+ if (match[matchLength] < ip[matchLength]) {
339
+ /* match is smaller than current */
340
+ *smallerPtr = matchIndex; /* update smaller idx */
341
+ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
342
+ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
343
+ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
344
+ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
345
+ } else {
346
+ /* match is larger than current */
347
+ *largerPtr = matchIndex;
348
+ commonLengthLarger = matchLength;
349
+ if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
350
+ largerPtr = nextPtr;
351
+ matchIndex = nextPtr[0];
352
+ } }
353
+
354
+ *smallerPtr = *largerPtr = 0;
355
+
356
+ if (dictMode == ZSTD_dictMatchState && nbCompares) {
357
+ bestLength = ZSTD_DUBT_findBetterDictMatch(
358
+ ms, ip, iend,
359
+ offsetPtr, bestLength, nbCompares,
360
+ mls, dictMode);
361
+ }
362
+
363
+ assert(matchEndIdx > current+8); /* ensure nextToUpdate is increased */
364
+ ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
365
+ if (bestLength >= MINMATCH) {
366
+ U32 const mIndex = current - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
367
+ DEBUGLOG(8, "ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
368
+ current, (U32)bestLength, (U32)*offsetPtr, mIndex);
369
+ }
370
+ return bestLength;
371
+ }
250
372
  }
251
373
 
252
374
 
253
- static size_t ZSTD_BtFindBestMatch_selectMLS (
254
- ZSTD_CCtx* zc, /* Index table will be updated */
255
- const BYTE* ip, const BYTE* const iLimit,
256
- size_t* offsetPtr,
257
- const U32 maxNbAttempts, const U32 matchLengthSearch)
375
+ /** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
376
+ FORCE_INLINE_TEMPLATE size_t
377
+ ZSTD_BtFindBestMatch( ZSTD_matchState_t* ms,
378
+ const BYTE* const ip, const BYTE* const iLimit,
379
+ size_t* offsetPtr,
380
+ const U32 mls /* template */,
381
+ const ZSTD_dictMode_e dictMode)
382
+ {
383
+ DEBUGLOG(7, "ZSTD_BtFindBestMatch");
384
+ if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */
385
+ ZSTD_updateDUBT(ms, ip, iLimit, mls);
386
+ return ZSTD_DUBT_findBestMatch(ms, ip, iLimit, offsetPtr, mls, dictMode);
387
+ }
388
+
389
+
390
+ static size_t
391
+ ZSTD_BtFindBestMatch_selectMLS ( ZSTD_matchState_t* ms,
392
+ const BYTE* ip, const BYTE* const iLimit,
393
+ size_t* offsetPtr)
258
394
  {
259
- switch(matchLengthSearch)
395
+ switch(ms->cParams.minMatch)
260
396
  {
261
397
  default : /* includes case 3 */
262
- case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
263
- case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
398
+ case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_noDict);
399
+ case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_noDict);
264
400
  case 7 :
265
- case 6 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
401
+ case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_noDict);
266
402
  }
267
403
  }
268
404
 
269
405
 
270
- /** Tree updater, providing best match */
271
- static size_t ZSTD_BtFindBestMatch_extDict (
272
- ZSTD_CCtx* zc,
273
- const BYTE* const ip, const BYTE* const iLimit,
274
- size_t* offsetPtr,
275
- const U32 maxNbAttempts, const U32 mls)
406
+ static size_t ZSTD_BtFindBestMatch_dictMatchState_selectMLS (
407
+ ZSTD_matchState_t* ms,
408
+ const BYTE* ip, const BYTE* const iLimit,
409
+ size_t* offsetPtr)
276
410
  {
277
- if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
278
- ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
279
- return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 1);
411
+ switch(ms->cParams.minMatch)
412
+ {
413
+ default : /* includes case 3 */
414
+ case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_dictMatchState);
415
+ case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_dictMatchState);
416
+ case 7 :
417
+ case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_dictMatchState);
418
+ }
280
419
  }
281
420
 
282
421
 
283
- static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
284
- ZSTD_CCtx* zc, /* Index table will be updated */
422
+ static size_t ZSTD_BtFindBestMatch_extDict_selectMLS (
423
+ ZSTD_matchState_t* ms,
285
424
  const BYTE* ip, const BYTE* const iLimit,
286
- size_t* offsetPtr,
287
- const U32 maxNbAttempts, const U32 matchLengthSearch)
425
+ size_t* offsetPtr)
288
426
  {
289
- switch(matchLengthSearch)
427
+ switch(ms->cParams.minMatch)
290
428
  {
291
429
  default : /* includes case 3 */
292
- case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
293
- case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
430
+ case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_extDict);
431
+ case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_extDict);
294
432
  case 7 :
295
- case 6 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
433
+ case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_extDict);
296
434
  }
297
435
  }
298
436
 
@@ -301,19 +439,22 @@ static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
301
439
  /* *********************************
302
440
  * Hash Chain
303
441
  ***********************************/
304
- #define NEXT_IN_CHAIN(d, mask) chainTable[(d) & mask]
442
+ #define NEXT_IN_CHAIN(d, mask) chainTable[(d) & (mask)]
305
443
 
306
444
  /* Update chains up to ip (excluded)
307
445
  Assumption : always within prefix (i.e. not within extDict) */
308
- U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
446
+ static U32 ZSTD_insertAndFindFirstIndex_internal(
447
+ ZSTD_matchState_t* ms,
448
+ const ZSTD_compressionParameters* const cParams,
449
+ const BYTE* ip, U32 const mls)
309
450
  {
310
- U32* const hashTable = zc->hashTable;
311
- const U32 hashLog = zc->appliedParams.cParams.hashLog;
312
- U32* const chainTable = zc->chainTable;
313
- const U32 chainMask = (1 << zc->appliedParams.cParams.chainLog) - 1;
314
- const BYTE* const base = zc->base;
451
+ U32* const hashTable = ms->hashTable;
452
+ const U32 hashLog = cParams->hashLog;
453
+ U32* const chainTable = ms->chainTable;
454
+ const U32 chainMask = (1 << cParams->chainLog) - 1;
455
+ const BYTE* const base = ms->window.base;
315
456
  const U32 target = (U32)(ip - base);
316
- U32 idx = zc->nextToUpdate;
457
+ U32 idx = ms->nextToUpdate;
317
458
 
318
459
  while(idx < target) { /* catch up */
319
460
  size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
@@ -322,40 +463,47 @@ U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
322
463
  idx++;
323
464
  }
324
465
 
325
- zc->nextToUpdate = target;
466
+ ms->nextToUpdate = target;
326
467
  return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
327
468
  }
328
469
 
470
+ U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) {
471
+ const ZSTD_compressionParameters* const cParams = &ms->cParams;
472
+ return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch);
473
+ }
474
+
329
475
 
330
476
  /* inlining is important to hardwire a hot branch (template emulation) */
331
477
  FORCE_INLINE_TEMPLATE
332
478
  size_t ZSTD_HcFindBestMatch_generic (
333
- ZSTD_CCtx* zc, /* Index table will be updated */
479
+ ZSTD_matchState_t* ms,
334
480
  const BYTE* const ip, const BYTE* const iLimit,
335
481
  size_t* offsetPtr,
336
- const U32 maxNbAttempts, const U32 mls, const U32 extDict)
482
+ const U32 mls, const ZSTD_dictMode_e dictMode)
337
483
  {
338
- U32* const chainTable = zc->chainTable;
339
- const U32 chainSize = (1 << zc->appliedParams.cParams.chainLog);
484
+ const ZSTD_compressionParameters* const cParams = &ms->cParams;
485
+ U32* const chainTable = ms->chainTable;
486
+ const U32 chainSize = (1 << cParams->chainLog);
340
487
  const U32 chainMask = chainSize-1;
341
- const BYTE* const base = zc->base;
342
- const BYTE* const dictBase = zc->dictBase;
343
- const U32 dictLimit = zc->dictLimit;
488
+ const BYTE* const base = ms->window.base;
489
+ const BYTE* const dictBase = ms->window.dictBase;
490
+ const U32 dictLimit = ms->window.dictLimit;
344
491
  const BYTE* const prefixStart = base + dictLimit;
345
492
  const BYTE* const dictEnd = dictBase + dictLimit;
346
- const U32 lowLimit = zc->lowLimit;
493
+ const U32 lowLimit = ms->window.lowLimit;
347
494
  const U32 current = (U32)(ip-base);
348
495
  const U32 minChain = current > chainSize ? current - chainSize : 0;
349
- int nbAttempts=maxNbAttempts;
496
+ U32 nbAttempts = 1U << cParams->searchLog;
350
497
  size_t ml=4-1;
351
498
 
352
499
  /* HC4 match finder */
353
- U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
500
+ U32 matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls);
354
501
 
355
502
  for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
356
503
  size_t currentMl=0;
357
- if ((!extDict) || matchIndex >= dictLimit) {
504
+ if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {
358
505
  const BYTE* const match = base + matchIndex;
506
+ assert(matchIndex >= dictLimit); /* ensures this is true if dictMode != ZSTD_extDict */
359
507
  if (match[ml] == ip[ml]) /* potentially better */
360
508
  currentMl = ZSTD_count(ip, match, iLimit);
361
509
  } else {
@@ -376,40 +524,87 @@ size_t ZSTD_HcFindBestMatch_generic (
376
524
  matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
377
525
  }
378
526
 
527
+ if (dictMode == ZSTD_dictMatchState) {
528
+ const ZSTD_matchState_t* const dms = ms->dictMatchState;
529
+ const U32* const dmsChainTable = dms->chainTable;
530
+ const U32 dmsChainSize = (1 << dms->cParams.chainLog);
531
+ const U32 dmsChainMask = dmsChainSize - 1;
532
+ const U32 dmsLowestIndex = dms->window.dictLimit;
533
+ const BYTE* const dmsBase = dms->window.base;
534
+ const BYTE* const dmsEnd = dms->window.nextSrc;
535
+ const U32 dmsSize = (U32)(dmsEnd - dmsBase);
536
+ const U32 dmsIndexDelta = dictLimit - dmsSize;
537
+ const U32 dmsMinChain = dmsSize > dmsChainSize ? dmsSize - dmsChainSize : 0;
538
+
539
+ matchIndex = dms->hashTable[ZSTD_hashPtr(ip, dms->cParams.hashLog, mls)];
540
+
541
+ for ( ; (matchIndex>dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) {
542
+ size_t currentMl=0;
543
+ const BYTE* const match = dmsBase + matchIndex;
544
+ assert(match+4 <= dmsEnd);
545
+ if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
546
+ currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4;
547
+
548
+ /* save best solution */
549
+ if (currentMl > ml) {
550
+ ml = currentMl;
551
+ *offsetPtr = current - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE;
552
+ if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
553
+ }
554
+
555
+ if (matchIndex <= dmsMinChain) break;
556
+ matchIndex = dmsChainTable[matchIndex & dmsChainMask];
557
+ }
558
+ }
559
+
379
560
  return ml;
380
561
  }
381
562
 
382
563
 
383
564
  FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_selectMLS (
384
- ZSTD_CCtx* zc,
565
+ ZSTD_matchState_t* ms,
385
566
  const BYTE* ip, const BYTE* const iLimit,
386
- size_t* offsetPtr,
387
- const U32 maxNbAttempts, const U32 matchLengthSearch)
567
+ size_t* offsetPtr)
568
+ {
569
+ switch(ms->cParams.minMatch)
570
+ {
571
+ default : /* includes case 3 */
572
+ case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_noDict);
573
+ case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_noDict);
574
+ case 7 :
575
+ case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_noDict);
576
+ }
577
+ }
578
+
579
+
580
+ static size_t ZSTD_HcFindBestMatch_dictMatchState_selectMLS (
581
+ ZSTD_matchState_t* ms,
582
+ const BYTE* ip, const BYTE* const iLimit,
583
+ size_t* offsetPtr)
388
584
  {
389
- switch(matchLengthSearch)
585
+ switch(ms->cParams.minMatch)
390
586
  {
391
587
  default : /* includes case 3 */
392
- case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0);
393
- case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0);
588
+ case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_dictMatchState);
589
+ case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_dictMatchState);
394
590
  case 7 :
395
- case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0);
591
+ case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_dictMatchState);
396
592
  }
397
593
  }
398
594
 
399
595
 
400
596
  FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
401
- ZSTD_CCtx* const zc,
597
+ ZSTD_matchState_t* ms,
402
598
  const BYTE* ip, const BYTE* const iLimit,
403
- size_t* const offsetPtr,
404
- U32 const maxNbAttempts, U32 const matchLengthSearch)
599
+ size_t* offsetPtr)
405
600
  {
406
- switch(matchLengthSearch)
601
+ switch(ms->cParams.minMatch)
407
602
  {
408
603
  default : /* includes case 3 */
409
- case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1);
410
- case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1);
604
+ case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_extDict);
605
+ case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_extDict);
411
606
  case 7 :
412
- case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1);
607
+ case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_extDict);
413
608
  }
414
609
  }
415
610
 
@@ -418,34 +613,58 @@ FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
418
613
  * Common parser - lazy strategy
419
614
  *********************************/
420
615
  FORCE_INLINE_TEMPLATE
421
- size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
422
- const void* src, size_t srcSize,
423
- const U32 searchMethod, const U32 depth)
616
+ size_t ZSTD_compressBlock_lazy_generic(
617
+ ZSTD_matchState_t* ms, seqStore_t* seqStore,
618
+ U32 rep[ZSTD_REP_NUM],
619
+ const void* src, size_t srcSize,
620
+ const U32 searchMethod, const U32 depth,
621
+ ZSTD_dictMode_e const dictMode)
424
622
  {
425
- seqStore_t* seqStorePtr = &(ctx->seqStore);
426
623
  const BYTE* const istart = (const BYTE*)src;
427
624
  const BYTE* ip = istart;
428
625
  const BYTE* anchor = istart;
429
626
  const BYTE* const iend = istart + srcSize;
430
627
  const BYTE* const ilimit = iend - 8;
431
- const BYTE* const base = ctx->base + ctx->dictLimit;
432
-
433
- U32 const maxSearches = 1 << ctx->appliedParams.cParams.searchLog;
434
- U32 const mls = ctx->appliedParams.cParams.searchLength;
435
-
436
- typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
437
- size_t* offsetPtr,
438
- U32 maxNbAttempts, U32 matchLengthSearch);
439
- searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS;
440
- U32 offset_1 = seqStorePtr->rep[0], offset_2 = seqStorePtr->rep[1], savedOffset=0;
628
+ const BYTE* const base = ms->window.base;
629
+ const U32 prefixLowestIndex = ms->window.dictLimit;
630
+ const BYTE* const prefixLowest = base + prefixLowestIndex;
631
+
632
+ typedef size_t (*searchMax_f)(
633
+ ZSTD_matchState_t* ms,
634
+ const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
635
+ searchMax_f const searchMax = dictMode == ZSTD_dictMatchState ?
636
+ (searchMethod ? ZSTD_BtFindBestMatch_dictMatchState_selectMLS : ZSTD_HcFindBestMatch_dictMatchState_selectMLS) :
637
+ (searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS);
638
+ U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
639
+
640
+ const ZSTD_matchState_t* const dms = ms->dictMatchState;
641
+ const U32 dictLowestIndex = dictMode == ZSTD_dictMatchState ?
642
+ dms->window.dictLimit : 0;
643
+ const BYTE* const dictBase = dictMode == ZSTD_dictMatchState ?
644
+ dms->window.base : NULL;
645
+ const BYTE* const dictLowest = dictMode == ZSTD_dictMatchState ?
646
+ dictBase + dictLowestIndex : NULL;
647
+ const BYTE* const dictEnd = dictMode == ZSTD_dictMatchState ?
648
+ dms->window.nextSrc : NULL;
649
+ const U32 dictIndexDelta = dictMode == ZSTD_dictMatchState ?
650
+ prefixLowestIndex - (U32)(dictEnd - dictBase) :
651
+ 0;
652
+ const U32 dictAndPrefixLength = (U32)(ip - prefixLowest + dictEnd - dictLowest);
441
653
 
442
654
  /* init */
443
- ip += (ip==base);
444
- ctx->nextToUpdate3 = ctx->nextToUpdate;
445
- { U32 const maxRep = (U32)(ip-base);
655
+ ip += (dictAndPrefixLength == 0);
656
+ ms->nextToUpdate3 = ms->nextToUpdate;
657
+ if (dictMode == ZSTD_noDict) {
658
+ U32 const maxRep = (U32)(ip - prefixLowest);
446
659
  if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
447
660
  if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
448
661
  }
662
+ if (dictMode == ZSTD_dictMatchState) {
663
+ /* dictMatchState repCode checks don't currently handle repCode == 0
664
+ * disabling. */
665
+ assert(offset_1 <= dictAndPrefixLength);
666
+ assert(offset_2 <= dictAndPrefixLength);
667
+ }
449
668
 
450
669
  /* Match Loop */
451
670
  while (ip < ilimit) {
@@ -454,21 +673,34 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
454
673
  const BYTE* start=ip+1;
455
674
 
456
675
  /* check repCode */
457
- if ((offset_1>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))) {
458
- /* repcode : we take it */
676
+ if (dictMode == ZSTD_dictMatchState) {
677
+ const U32 repIndex = (U32)(ip - base) + 1 - offset_1;
678
+ const BYTE* repMatch = (dictMode == ZSTD_dictMatchState
679
+ && repIndex < prefixLowestIndex) ?
680
+ dictBase + (repIndex - dictIndexDelta) :
681
+ base + repIndex;
682
+ if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
683
+ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
684
+ const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
685
+ matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
686
+ if (depth==0) goto _storeSequence;
687
+ }
688
+ }
689
+ if ( dictMode == ZSTD_noDict
690
+ && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {
459
691
  matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
460
692
  if (depth==0) goto _storeSequence;
461
693
  }
462
694
 
463
695
  /* first search (depth 0) */
464
- { size_t offsetFound = 99999999;
465
- size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
696
+ { size_t offsetFound = 999999999;
697
+ size_t const ml2 = searchMax(ms, ip, iend, &offsetFound);
466
698
  if (ml2 > matchLength)
467
699
  matchLength = ml2, start = ip, offset=offsetFound;
468
700
  }
469
701
 
470
702
  if (matchLength < 4) {
471
- ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
703
+ ip += ((ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */
472
704
  continue;
473
705
  }
474
706
 
@@ -476,15 +708,31 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
476
708
  if (depth>=1)
477
709
  while (ip<ilimit) {
478
710
  ip ++;
479
- if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
711
+ if ( (dictMode == ZSTD_noDict)
712
+ && (offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
480
713
  size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
481
714
  int const gain2 = (int)(mlRep * 3);
482
715
  int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
483
716
  if ((mlRep >= 4) && (gain2 > gain1))
484
717
  matchLength = mlRep, offset = 0, start = ip;
485
718
  }
486
- { size_t offset2=99999999;
487
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
719
+ if (dictMode == ZSTD_dictMatchState) {
720
+ const U32 repIndex = (U32)(ip - base) - offset_1;
721
+ const BYTE* repMatch = repIndex < prefixLowestIndex ?
722
+ dictBase + (repIndex - dictIndexDelta) :
723
+ base + repIndex;
724
+ if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
725
+ && (MEM_read32(repMatch) == MEM_read32(ip)) ) {
726
+ const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
727
+ size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
728
+ int const gain2 = (int)(mlRep * 3);
729
+ int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
730
+ if ((mlRep >= 4) && (gain2 > gain1))
731
+ matchLength = mlRep, offset = 0, start = ip;
732
+ }
733
+ }
734
+ { size_t offset2=999999999;
735
+ size_t const ml2 = searchMax(ms, ip, iend, &offset2);
488
736
  int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
489
737
  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
490
738
  if ((ml2 >= 4) && (gain2 > gain1)) {
@@ -495,15 +743,31 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
495
743
  /* let's find an even better one */
496
744
  if ((depth==2) && (ip<ilimit)) {
497
745
  ip ++;
498
- if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
499
- size_t const ml2 = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
500
- int const gain2 = (int)(ml2 * 4);
746
+ if ( (dictMode == ZSTD_noDict)
747
+ && (offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
748
+ size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
749
+ int const gain2 = (int)(mlRep * 4);
501
750
  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
502
- if ((ml2 >= 4) && (gain2 > gain1))
503
- matchLength = ml2, offset = 0, start = ip;
751
+ if ((mlRep >= 4) && (gain2 > gain1))
752
+ matchLength = mlRep, offset = 0, start = ip;
504
753
  }
505
- { size_t offset2=99999999;
506
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
754
+ if (dictMode == ZSTD_dictMatchState) {
755
+ const U32 repIndex = (U32)(ip - base) - offset_1;
756
+ const BYTE* repMatch = repIndex < prefixLowestIndex ?
757
+ dictBase + (repIndex - dictIndexDelta) :
758
+ base + repIndex;
759
+ if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
760
+ && (MEM_read32(repMatch) == MEM_read32(ip)) ) {
761
+ const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
762
+ size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
763
+ int const gain2 = (int)(mlRep * 4);
764
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
765
+ if ((mlRep >= 4) && (gain2 > gain1))
766
+ matchLength = mlRep, offset = 0, start = ip;
767
+ }
768
+ }
769
+ { size_t offset2=999999999;
770
+ size_t const ml2 = searchMax(ms, ip, iend, &offset2);
507
771
  int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
508
772
  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
509
773
  if ((ml2 >= 4) && (gain2 > gain1)) {
@@ -520,91 +784,156 @@ size_t ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
520
784
  */
521
785
  /* catch up */
522
786
  if (offset) {
523
- while ( ((start > anchor) & (start - (offset-ZSTD_REP_MOVE) > base))
524
- && (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) ) /* only search for offset within prefix */
525
- { start--; matchLength++; }
787
+ if (dictMode == ZSTD_noDict) {
788
+ while ( ((start > anchor) & (start - (offset-ZSTD_REP_MOVE) > prefixLowest))
789
+ && (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) ) /* only search for offset within prefix */
790
+ { start--; matchLength++; }
791
+ }
792
+ if (dictMode == ZSTD_dictMatchState) {
793
+ U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
794
+ const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex;
795
+ const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest;
796
+ while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
797
+ }
526
798
  offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
527
799
  }
528
800
  /* store sequence */
529
801
  _storeSequence:
530
802
  { size_t const litLength = start - anchor;
531
- ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
803
+ ZSTD_storeSeq(seqStore, litLength, anchor, (U32)offset, matchLength-MINMATCH);
532
804
  anchor = ip = start + matchLength;
533
805
  }
534
806
 
535
807
  /* check immediate repcode */
536
- while ( ((ip <= ilimit) & (offset_2>0))
537
- && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
538
- /* store sequence */
539
- matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
540
- offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
541
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
542
- ip += matchLength;
543
- anchor = ip;
544
- continue; /* faster when present ... (?) */
545
- } }
808
+ if (dictMode == ZSTD_dictMatchState) {
809
+ while (ip <= ilimit) {
810
+ U32 const current2 = (U32)(ip-base);
811
+ U32 const repIndex = current2 - offset_2;
812
+ const BYTE* repMatch = dictMode == ZSTD_dictMatchState
813
+ && repIndex < prefixLowestIndex ?
814
+ dictBase - dictIndexDelta + repIndex :
815
+ base + repIndex;
816
+ if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex) >= 3 /* intentional overflow */)
817
+ && (MEM_read32(repMatch) == MEM_read32(ip)) ) {
818
+ const BYTE* const repEnd2 = repIndex < prefixLowestIndex ? dictEnd : iend;
819
+ matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd2, prefixLowest) + 4;
820
+ offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset_2 <=> offset_1 */
821
+ ZSTD_storeSeq(seqStore, 0, anchor, 0, matchLength-MINMATCH);
822
+ ip += matchLength;
823
+ anchor = ip;
824
+ continue;
825
+ }
826
+ break;
827
+ }
828
+ }
829
+
830
+ if (dictMode == ZSTD_noDict) {
831
+ while ( ((ip <= ilimit) & (offset_2>0))
832
+ && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {
833
+ /* store sequence */
834
+ matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
835
+ offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
836
+ ZSTD_storeSeq(seqStore, 0, anchor, 0, matchLength-MINMATCH);
837
+ ip += matchLength;
838
+ anchor = ip;
839
+ continue; /* faster when present ... (?) */
840
+ } } }
546
841
 
547
842
  /* Save reps for next block */
548
- seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : savedOffset;
549
- seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : savedOffset;
843
+ rep[0] = offset_1 ? offset_1 : savedOffset;
844
+ rep[1] = offset_2 ? offset_2 : savedOffset;
550
845
 
551
846
  /* Return the last literals size */
552
847
  return iend - anchor;
553
848
  }
554
849
 
555
850
 
556
- size_t ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
851
+ size_t ZSTD_compressBlock_btlazy2(
852
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
853
+ void const* src, size_t srcSize)
557
854
  {
558
- return ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2);
855
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 1, 2, ZSTD_noDict);
559
856
  }
560
857
 
561
- size_t ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
858
+ size_t ZSTD_compressBlock_lazy2(
859
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
860
+ void const* src, size_t srcSize)
562
861
  {
563
- return ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2);
862
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 2, ZSTD_noDict);
564
863
  }
565
864
 
566
- size_t ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
865
+ size_t ZSTD_compressBlock_lazy(
866
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
867
+ void const* src, size_t srcSize)
567
868
  {
568
- return ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1);
869
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 1, ZSTD_noDict);
569
870
  }
570
871
 
571
- size_t ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
872
+ size_t ZSTD_compressBlock_greedy(
873
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
874
+ void const* src, size_t srcSize)
572
875
  {
573
- return ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0);
876
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 0, ZSTD_noDict);
877
+ }
878
+
879
+ size_t ZSTD_compressBlock_btlazy2_dictMatchState(
880
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
881
+ void const* src, size_t srcSize)
882
+ {
883
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 1, 2, ZSTD_dictMatchState);
884
+ }
885
+
886
+ size_t ZSTD_compressBlock_lazy2_dictMatchState(
887
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
888
+ void const* src, size_t srcSize)
889
+ {
890
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 2, ZSTD_dictMatchState);
891
+ }
892
+
893
+ size_t ZSTD_compressBlock_lazy_dictMatchState(
894
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
895
+ void const* src, size_t srcSize)
896
+ {
897
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 1, ZSTD_dictMatchState);
898
+ }
899
+
900
+ size_t ZSTD_compressBlock_greedy_dictMatchState(
901
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
902
+ void const* src, size_t srcSize)
903
+ {
904
+ return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, 0, 0, ZSTD_dictMatchState);
574
905
  }
575
906
 
576
907
 
577
908
  FORCE_INLINE_TEMPLATE
578
- size_t ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
579
- const void* src, size_t srcSize,
580
- const U32 searchMethod, const U32 depth)
909
+ size_t ZSTD_compressBlock_lazy_extDict_generic(
910
+ ZSTD_matchState_t* ms, seqStore_t* seqStore,
911
+ U32 rep[ZSTD_REP_NUM],
912
+ const void* src, size_t srcSize,
913
+ const U32 searchMethod, const U32 depth)
581
914
  {
582
- seqStore_t* seqStorePtr = &(ctx->seqStore);
583
915
  const BYTE* const istart = (const BYTE*)src;
584
916
  const BYTE* ip = istart;
585
917
  const BYTE* anchor = istart;
586
918
  const BYTE* const iend = istart + srcSize;
587
919
  const BYTE* const ilimit = iend - 8;
588
- const BYTE* const base = ctx->base;
589
- const U32 dictLimit = ctx->dictLimit;
590
- const U32 lowestIndex = ctx->lowLimit;
920
+ const BYTE* const base = ms->window.base;
921
+ const U32 dictLimit = ms->window.dictLimit;
922
+ const U32 lowestIndex = ms->window.lowLimit;
591
923
  const BYTE* const prefixStart = base + dictLimit;
592
- const BYTE* const dictBase = ctx->dictBase;
924
+ const BYTE* const dictBase = ms->window.dictBase;
593
925
  const BYTE* const dictEnd = dictBase + dictLimit;
594
- const BYTE* const dictStart = dictBase + ctx->lowLimit;
926
+ const BYTE* const dictStart = dictBase + lowestIndex;
595
927
 
596
- const U32 maxSearches = 1 << ctx->appliedParams.cParams.searchLog;
597
- const U32 mls = ctx->appliedParams.cParams.searchLength;
928
+ typedef size_t (*searchMax_f)(
929
+ ZSTD_matchState_t* ms,
930
+ const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
931
+ searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_extDict_selectMLS : ZSTD_HcFindBestMatch_extDict_selectMLS;
598
932
 
599
- typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
600
- size_t* offsetPtr,
601
- U32 maxNbAttempts, U32 matchLengthSearch);
602
- searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS;
603
-
604
- U32 offset_1 = seqStorePtr->rep[0], offset_2 = seqStorePtr->rep[1];
933
+ U32 offset_1 = rep[0], offset_2 = rep[1];
605
934
 
606
935
  /* init */
607
- ctx->nextToUpdate3 = ctx->nextToUpdate;
936
+ ms->nextToUpdate3 = ms->nextToUpdate;
608
937
  ip += (ip == prefixStart);
609
938
 
610
939
  /* Match Loop */
@@ -627,14 +956,14 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
627
956
  } }
628
957
 
629
958
  /* first search (depth 0) */
630
- { size_t offsetFound = 99999999;
631
- size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
959
+ { size_t offsetFound = 999999999;
960
+ size_t const ml2 = searchMax(ms, ip, iend, &offsetFound);
632
961
  if (ml2 > matchLength)
633
962
  matchLength = ml2, start = ip, offset=offsetFound;
634
963
  }
635
964
 
636
965
  if (matchLength < 4) {
637
- ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
966
+ ip += ((ip-anchor) >> kSearchStrength) + 1; /* jump faster over incompressible sections */
638
967
  continue;
639
968
  }
640
969
 
@@ -660,8 +989,8 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
660
989
  } }
661
990
 
662
991
  /* search match, depth 1 */
663
- { size_t offset2=99999999;
664
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
992
+ { size_t offset2=999999999;
993
+ size_t const ml2 = searchMax(ms, ip, iend, &offset2);
665
994
  int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
666
995
  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
667
996
  if ((ml2 >= 4) && (gain2 > gain1)) {
@@ -690,8 +1019,8 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
690
1019
  } }
691
1020
 
692
1021
  /* search match, depth 2 */
693
- { size_t offset2=99999999;
694
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
1022
+ { size_t offset2=999999999;
1023
+ size_t const ml2 = searchMax(ms, ip, iend, &offset2);
695
1024
  int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
696
1025
  int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
697
1026
  if ((ml2 >= 4) && (gain2 > gain1)) {
@@ -713,7 +1042,7 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
713
1042
  /* store sequence */
714
1043
  _storeSequence:
715
1044
  { size_t const litLength = start - anchor;
716
- ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
1045
+ ZSTD_storeSeq(seqStore, litLength, anchor, (U32)offset, matchLength-MINMATCH);
717
1046
  anchor = ip = start + matchLength;
718
1047
  }
719
1048
 
@@ -728,7 +1057,7 @@ _storeSequence:
728
1057
  const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
729
1058
  matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
730
1059
  offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset history */
731
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
1060
+ ZSTD_storeSeq(seqStore, 0, anchor, 0, matchLength-MINMATCH);
732
1061
  ip += matchLength;
733
1062
  anchor = ip;
734
1063
  continue; /* faster when present ... (?) */
@@ -737,29 +1066,41 @@ _storeSequence:
737
1066
  } }
738
1067
 
739
1068
  /* Save reps for next block */
740
- seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
1069
+ rep[0] = offset_1;
1070
+ rep[1] = offset_2;
741
1071
 
742
1072
  /* Return the last literals size */
743
1073
  return iend - anchor;
744
1074
  }
745
1075
 
746
1076
 
747
- size_t ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
1077
+ size_t ZSTD_compressBlock_greedy_extDict(
1078
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1079
+ void const* src, size_t srcSize)
748
1080
  {
749
- return ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0);
1081
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 0, 0);
750
1082
  }
751
1083
 
752
- size_t ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
1084
+ size_t ZSTD_compressBlock_lazy_extDict(
1085
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1086
+ void const* src, size_t srcSize)
1087
+
753
1088
  {
754
- return ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1);
1089
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 0, 1);
755
1090
  }
756
1091
 
757
- size_t ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
1092
+ size_t ZSTD_compressBlock_lazy2_extDict(
1093
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1094
+ void const* src, size_t srcSize)
1095
+
758
1096
  {
759
- return ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2);
1097
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 0, 2);
760
1098
  }
761
1099
 
762
- size_t ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
1100
+ size_t ZSTD_compressBlock_btlazy2_extDict(
1101
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
1102
+ void const* src, size_t srcSize)
1103
+
763
1104
  {
764
- return ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2);
1105
+ return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, 1, 2);
765
1106
  }