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
@@ -12,103 +12,239 @@
12
12
  #include "zstd_double_fast.h"
13
13
 
14
14
 
15
- void ZSTD_fillDoubleHashTable(ZSTD_CCtx* cctx, const void* end, const U32 mls)
15
+ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms,
16
+ void const* end, ZSTD_dictTableLoadMethod_e dtlm)
16
17
  {
17
- U32* const hashLarge = cctx->hashTable;
18
- U32 const hBitsL = cctx->appliedParams.cParams.hashLog;
19
- U32* const hashSmall = cctx->chainTable;
20
- U32 const hBitsS = cctx->appliedParams.cParams.chainLog;
21
- const BYTE* const base = cctx->base;
22
- const BYTE* ip = base + cctx->nextToUpdate;
18
+ const ZSTD_compressionParameters* const cParams = &ms->cParams;
19
+ U32* const hashLarge = ms->hashTable;
20
+ U32 const hBitsL = cParams->hashLog;
21
+ U32 const mls = cParams->minMatch;
22
+ U32* const hashSmall = ms->chainTable;
23
+ U32 const hBitsS = cParams->chainLog;
24
+ const BYTE* const base = ms->window.base;
25
+ const BYTE* ip = base + ms->nextToUpdate;
23
26
  const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
24
- const size_t fastHashFillStep = 3;
25
-
26
- while(ip <= iend) {
27
- hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base);
28
- hashLarge[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base);
29
- ip += fastHashFillStep;
27
+ const U32 fastHashFillStep = 3;
28
+
29
+ /* Always insert every fastHashFillStep position into the hash tables.
30
+ * Insert the other positions into the large hash table if their entry
31
+ * is empty.
32
+ */
33
+ for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) {
34
+ U32 const current = (U32)(ip - base);
35
+ U32 i;
36
+ for (i = 0; i < fastHashFillStep; ++i) {
37
+ size_t const smHash = ZSTD_hashPtr(ip + i, hBitsS, mls);
38
+ size_t const lgHash = ZSTD_hashPtr(ip + i, hBitsL, 8);
39
+ if (i == 0)
40
+ hashSmall[smHash] = current + i;
41
+ if (i == 0 || hashLarge[lgHash] == 0)
42
+ hashLarge[lgHash] = current + i;
43
+ /* Only load extra positions for ZSTD_dtlm_full */
44
+ if (dtlm == ZSTD_dtlm_fast)
45
+ break;
46
+ }
30
47
  }
31
48
  }
32
49
 
33
50
 
34
51
  FORCE_INLINE_TEMPLATE
35
- size_t ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
36
- const void* src, size_t srcSize,
37
- const U32 mls)
52
+ size_t ZSTD_compressBlock_doubleFast_generic(
53
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
54
+ void const* src, size_t srcSize,
55
+ U32 const mls /* template */, ZSTD_dictMode_e const dictMode)
38
56
  {
39
- U32* const hashLong = cctx->hashTable;
40
- const U32 hBitsL = cctx->appliedParams.cParams.hashLog;
41
- U32* const hashSmall = cctx->chainTable;
42
- const U32 hBitsS = cctx->appliedParams.cParams.chainLog;
43
- seqStore_t* seqStorePtr = &(cctx->seqStore);
44
- const BYTE* const base = cctx->base;
57
+ ZSTD_compressionParameters const* cParams = &ms->cParams;
58
+ U32* const hashLong = ms->hashTable;
59
+ const U32 hBitsL = cParams->hashLog;
60
+ U32* const hashSmall = ms->chainTable;
61
+ const U32 hBitsS = cParams->chainLog;
62
+ const BYTE* const base = ms->window.base;
45
63
  const BYTE* const istart = (const BYTE*)src;
46
64
  const BYTE* ip = istart;
47
65
  const BYTE* anchor = istart;
48
- const U32 lowestIndex = cctx->dictLimit;
49
- const BYTE* const lowest = base + lowestIndex;
66
+ const U32 prefixLowestIndex = ms->window.dictLimit;
67
+ const BYTE* const prefixLowest = base + prefixLowestIndex;
50
68
  const BYTE* const iend = istart + srcSize;
51
69
  const BYTE* const ilimit = iend - HASH_READ_SIZE;
52
- U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
70
+ U32 offset_1=rep[0], offset_2=rep[1];
53
71
  U32 offsetSaved = 0;
54
72
 
73
+ const ZSTD_matchState_t* const dms = ms->dictMatchState;
74
+ const ZSTD_compressionParameters* const dictCParams =
75
+ dictMode == ZSTD_dictMatchState ?
76
+ &dms->cParams : NULL;
77
+ const U32* const dictHashLong = dictMode == ZSTD_dictMatchState ?
78
+ dms->hashTable : NULL;
79
+ const U32* const dictHashSmall = dictMode == ZSTD_dictMatchState ?
80
+ dms->chainTable : NULL;
81
+ const U32 dictStartIndex = dictMode == ZSTD_dictMatchState ?
82
+ dms->window.dictLimit : 0;
83
+ const BYTE* const dictBase = dictMode == ZSTD_dictMatchState ?
84
+ dms->window.base : NULL;
85
+ const BYTE* const dictStart = dictMode == ZSTD_dictMatchState ?
86
+ dictBase + dictStartIndex : NULL;
87
+ const BYTE* const dictEnd = dictMode == ZSTD_dictMatchState ?
88
+ dms->window.nextSrc : NULL;
89
+ const U32 dictIndexDelta = dictMode == ZSTD_dictMatchState ?
90
+ prefixLowestIndex - (U32)(dictEnd - dictBase) :
91
+ 0;
92
+ const U32 dictHBitsL = dictMode == ZSTD_dictMatchState ?
93
+ dictCParams->hashLog : hBitsL;
94
+ const U32 dictHBitsS = dictMode == ZSTD_dictMatchState ?
95
+ dictCParams->chainLog : hBitsS;
96
+ const U32 dictAndPrefixLength = (U32)(ip - prefixLowest + dictEnd - dictStart);
97
+
98
+ assert(dictMode == ZSTD_noDict || dictMode == ZSTD_dictMatchState);
99
+
55
100
  /* init */
56
- ip += (ip==lowest);
57
- { U32 const maxRep = (U32)(ip-lowest);
101
+ ip += (dictAndPrefixLength == 0);
102
+ if (dictMode == ZSTD_noDict) {
103
+ U32 const maxRep = (U32)(ip - prefixLowest);
58
104
  if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
59
105
  if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
60
106
  }
107
+ if (dictMode == ZSTD_dictMatchState) {
108
+ /* dictMatchState repCode checks don't currently handle repCode == 0
109
+ * disabling. */
110
+ assert(offset_1 <= dictAndPrefixLength);
111
+ assert(offset_2 <= dictAndPrefixLength);
112
+ }
61
113
 
62
114
  /* Main Search Loop */
63
115
  while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
64
116
  size_t mLength;
117
+ U32 offset;
65
118
  size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
66
119
  size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
120
+ size_t const dictHL = ZSTD_hashPtr(ip, dictHBitsL, 8);
121
+ size_t const dictHS = ZSTD_hashPtr(ip, dictHBitsS, mls);
67
122
  U32 const current = (U32)(ip-base);
68
123
  U32 const matchIndexL = hashLong[h2];
69
- U32 const matchIndexS = hashSmall[h];
124
+ U32 matchIndexS = hashSmall[h];
70
125
  const BYTE* matchLong = base + matchIndexL;
71
126
  const BYTE* match = base + matchIndexS;
127
+ const U32 repIndex = current + 1 - offset_1;
128
+ const BYTE* repMatch = (dictMode == ZSTD_dictMatchState
129
+ && repIndex < prefixLowestIndex) ?
130
+ dictBase + (repIndex - dictIndexDelta) :
131
+ base + repIndex;
72
132
  hashLong[h2] = hashSmall[h] = current; /* update hash tables */
73
133
 
74
- assert(offset_1 <= current); /* supposed guaranteed by construction */
75
- if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
76
- /* favor repcode */
134
+ /* check dictMatchState repcode */
135
+ if (dictMode == ZSTD_dictMatchState
136
+ && ((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
137
+ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
138
+ const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
139
+ mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
140
+ ip++;
141
+ ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
142
+ goto _match_stored;
143
+ }
144
+
145
+ /* check noDict repcode */
146
+ if ( dictMode == ZSTD_noDict
147
+ && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {
77
148
  mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
78
149
  ip++;
79
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
80
- } else {
81
- U32 offset;
82
- if ( (matchIndexL > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) {
150
+ ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
151
+ goto _match_stored;
152
+ }
153
+
154
+ if (matchIndexL > prefixLowestIndex) {
155
+ /* check prefix long match */
156
+ if (MEM_read64(matchLong) == MEM_read64(ip)) {
83
157
  mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
84
158
  offset = (U32)(ip-matchLong);
85
- while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
86
- } else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
87
- size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
88
- U32 const matchIndexL3 = hashLong[hl3];
89
- const BYTE* matchL3 = base + matchIndexL3;
90
- hashLong[hl3] = current + 1;
91
- if ( (matchIndexL3 > lowestIndex) && (MEM_read64(matchL3) == MEM_read64(ip+1)) ) {
159
+ while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
160
+ goto _match_found;
161
+ }
162
+ } else if (dictMode == ZSTD_dictMatchState) {
163
+ /* check dictMatchState long match */
164
+ U32 const dictMatchIndexL = dictHashLong[dictHL];
165
+ const BYTE* dictMatchL = dictBase + dictMatchIndexL;
166
+ assert(dictMatchL < dictEnd);
167
+
168
+ if (dictMatchL > dictStart && MEM_read64(dictMatchL) == MEM_read64(ip)) {
169
+ mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8;
170
+ offset = (U32)(current - dictMatchIndexL - dictIndexDelta);
171
+ while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */
172
+ goto _match_found;
173
+ }
174
+ }
175
+
176
+ if (matchIndexS > prefixLowestIndex) {
177
+ /* check prefix short match */
178
+ if (MEM_read32(match) == MEM_read32(ip)) {
179
+ goto _search_next_long;
180
+ }
181
+ } else if (dictMode == ZSTD_dictMatchState) {
182
+ /* check dictMatchState short match */
183
+ U32 const dictMatchIndexS = dictHashSmall[dictHS];
184
+ match = dictBase + dictMatchIndexS;
185
+ matchIndexS = dictMatchIndexS + dictIndexDelta;
186
+
187
+ if (match > dictStart && MEM_read32(match) == MEM_read32(ip)) {
188
+ goto _search_next_long;
189
+ }
190
+ }
191
+
192
+ ip += ((ip-anchor) >> kSearchStrength) + 1;
193
+ continue;
194
+
195
+ _search_next_long:
196
+
197
+ {
198
+ size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
199
+ size_t const dictHLNext = ZSTD_hashPtr(ip+1, dictHBitsL, 8);
200
+ U32 const matchIndexL3 = hashLong[hl3];
201
+ const BYTE* matchL3 = base + matchIndexL3;
202
+ hashLong[hl3] = current + 1;
203
+
204
+ /* check prefix long +1 match */
205
+ if (matchIndexL3 > prefixLowestIndex) {
206
+ if (MEM_read64(matchL3) == MEM_read64(ip+1)) {
92
207
  mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8;
93
208
  ip++;
94
209
  offset = (U32)(ip-matchL3);
95
- while (((ip>anchor) & (matchL3>lowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */
96
- } else {
97
- mLength = ZSTD_count(ip+4, match+4, iend) + 4;
98
- offset = (U32)(ip-match);
99
- while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
210
+ while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */
211
+ goto _match_found;
212
+ }
213
+ } else if (dictMode == ZSTD_dictMatchState) {
214
+ /* check dict long +1 match */
215
+ U32 const dictMatchIndexL3 = dictHashLong[dictHLNext];
216
+ const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3;
217
+ assert(dictMatchL3 < dictEnd);
218
+ if (dictMatchL3 > dictStart && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) {
219
+ mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8;
220
+ ip++;
221
+ offset = (U32)(current + 1 - dictMatchIndexL3 - dictIndexDelta);
222
+ while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */
223
+ goto _match_found;
100
224
  }
101
- } else {
102
- ip += ((ip-anchor) >> g_searchStrength) + 1;
103
- continue;
104
225
  }
226
+ }
105
227
 
106
- offset_2 = offset_1;
107
- offset_1 = offset;
108
-
109
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
228
+ /* if no long +1 match, explore the short match we found */
229
+ if (dictMode == ZSTD_dictMatchState && matchIndexS < prefixLowestIndex) {
230
+ mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4;
231
+ offset = (U32)(current - matchIndexS);
232
+ while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
233
+ } else {
234
+ mLength = ZSTD_count(ip+4, match+4, iend) + 4;
235
+ offset = (U32)(ip - match);
236
+ while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
110
237
  }
111
238
 
239
+ /* fall-through */
240
+
241
+ _match_found:
242
+ offset_2 = offset_1;
243
+ offset_1 = offset;
244
+
245
+ ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
246
+
247
+ _match_stored:
112
248
  /* match found */
113
249
  ip += mLength;
114
250
  anchor = ip;
@@ -121,134 +257,185 @@ size_t ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
121
257
  hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
122
258
 
123
259
  /* check immediate repcode */
124
- while ( (ip <= ilimit)
125
- && ( (offset_2>0)
126
- & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
127
- /* store sequence */
128
- size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
129
- { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
130
- hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
131
- hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
132
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
133
- ip += rLength;
134
- anchor = ip;
135
- continue; /* faster when present ... (?) */
136
- } } }
260
+ if (dictMode == ZSTD_dictMatchState) {
261
+ while (ip <= ilimit) {
262
+ U32 const current2 = (U32)(ip-base);
263
+ U32 const repIndex2 = current2 - offset_2;
264
+ const BYTE* repMatch2 = dictMode == ZSTD_dictMatchState
265
+ && repIndex2 < prefixLowestIndex ?
266
+ dictBase - dictIndexDelta + repIndex2 :
267
+ base + repIndex2;
268
+ if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */)
269
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
270
+ const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend;
271
+ size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4;
272
+ U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
273
+ ZSTD_storeSeq(seqStore, 0, anchor, 0, repLength2-MINMATCH);
274
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
275
+ hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
276
+ ip += repLength2;
277
+ anchor = ip;
278
+ continue;
279
+ }
280
+ break;
281
+ }
282
+ }
283
+
284
+ if (dictMode == ZSTD_noDict) {
285
+ while ( (ip <= ilimit)
286
+ && ( (offset_2>0)
287
+ & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
288
+ /* store sequence */
289
+ size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
290
+ U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */
291
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
292
+ hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
293
+ ZSTD_storeSeq(seqStore, 0, anchor, 0, rLength-MINMATCH);
294
+ ip += rLength;
295
+ anchor = ip;
296
+ continue; /* faster when present ... (?) */
297
+ } } } }
137
298
 
138
299
  /* save reps for next block */
139
- seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
140
- seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
300
+ rep[0] = offset_1 ? offset_1 : offsetSaved;
301
+ rep[1] = offset_2 ? offset_2 : offsetSaved;
141
302
 
142
303
  /* Return the last literals size */
143
304
  return iend - anchor;
144
305
  }
145
306
 
146
307
 
147
- size_t ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
308
+ size_t ZSTD_compressBlock_doubleFast(
309
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
310
+ void const* src, size_t srcSize)
148
311
  {
149
- const U32 mls = ctx->appliedParams.cParams.searchLength;
312
+ const U32 mls = ms->cParams.minMatch;
150
313
  switch(mls)
151
314
  {
152
315
  default: /* includes case 3 */
153
316
  case 4 :
154
- return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4);
317
+ return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 4, ZSTD_noDict);
155
318
  case 5 :
156
- return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5);
319
+ return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 5, ZSTD_noDict);
157
320
  case 6 :
158
- return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6);
321
+ return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 6, ZSTD_noDict);
159
322
  case 7 :
160
- return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7);
323
+ return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 7, ZSTD_noDict);
161
324
  }
162
325
  }
163
326
 
164
327
 
165
- static size_t ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
166
- const void* src, size_t srcSize,
167
- const U32 mls)
328
+ size_t ZSTD_compressBlock_doubleFast_dictMatchState(
329
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
330
+ void const* src, size_t srcSize)
168
331
  {
169
- U32* const hashLong = ctx->hashTable;
170
- U32 const hBitsL = ctx->appliedParams.cParams.hashLog;
171
- U32* const hashSmall = ctx->chainTable;
172
- U32 const hBitsS = ctx->appliedParams.cParams.chainLog;
173
- seqStore_t* seqStorePtr = &(ctx->seqStore);
174
- const BYTE* const base = ctx->base;
175
- const BYTE* const dictBase = ctx->dictBase;
332
+ const U32 mls = ms->cParams.minMatch;
333
+ switch(mls)
334
+ {
335
+ default: /* includes case 3 */
336
+ case 4 :
337
+ return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 4, ZSTD_dictMatchState);
338
+ case 5 :
339
+ return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 5, ZSTD_dictMatchState);
340
+ case 6 :
341
+ return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 6, ZSTD_dictMatchState);
342
+ case 7 :
343
+ return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 7, ZSTD_dictMatchState);
344
+ }
345
+ }
346
+
347
+
348
+ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
349
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
350
+ void const* src, size_t srcSize,
351
+ U32 const mls /* template */)
352
+ {
353
+ ZSTD_compressionParameters const* cParams = &ms->cParams;
354
+ U32* const hashLong = ms->hashTable;
355
+ U32 const hBitsL = cParams->hashLog;
356
+ U32* const hashSmall = ms->chainTable;
357
+ U32 const hBitsS = cParams->chainLog;
176
358
  const BYTE* const istart = (const BYTE*)src;
177
359
  const BYTE* ip = istart;
178
360
  const BYTE* anchor = istart;
179
- const U32 lowestIndex = ctx->lowLimit;
180
- const BYTE* const dictStart = dictBase + lowestIndex;
181
- const U32 dictLimit = ctx->dictLimit;
182
- const BYTE* const lowPrefixPtr = base + dictLimit;
183
- const BYTE* const dictEnd = dictBase + dictLimit;
184
361
  const BYTE* const iend = istart + srcSize;
185
362
  const BYTE* const ilimit = iend - 8;
186
- U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
363
+ const U32 prefixStartIndex = ms->window.dictLimit;
364
+ const BYTE* const base = ms->window.base;
365
+ const BYTE* const prefixStart = base + prefixStartIndex;
366
+ const U32 dictStartIndex = ms->window.lowLimit;
367
+ const BYTE* const dictBase = ms->window.dictBase;
368
+ const BYTE* const dictStart = dictBase + dictStartIndex;
369
+ const BYTE* const dictEnd = dictBase + prefixStartIndex;
370
+ U32 offset_1=rep[0], offset_2=rep[1];
371
+
372
+ DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_extDict_generic (srcSize=%zu)", srcSize);
187
373
 
188
374
  /* Search Loop */
189
375
  while (ip < ilimit) { /* < instead of <=, because (ip+1) */
190
376
  const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
191
377
  const U32 matchIndex = hashSmall[hSmall];
192
- const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
378
+ const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base;
193
379
  const BYTE* match = matchBase + matchIndex;
194
380
 
195
381
  const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);
196
382
  const U32 matchLongIndex = hashLong[hLong];
197
- const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
383
+ const BYTE* const matchLongBase = matchLongIndex < prefixStartIndex ? dictBase : base;
198
384
  const BYTE* matchLong = matchLongBase + matchLongIndex;
199
385
 
200
386
  const U32 current = (U32)(ip-base);
201
387
  const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
202
- const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
203
- const BYTE* repMatch = repBase + repIndex;
388
+ const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;
389
+ const BYTE* const repMatch = repBase + repIndex;
204
390
  size_t mLength;
205
391
  hashSmall[hSmall] = hashLong[hLong] = current; /* update hash table */
206
392
 
207
- if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
208
- && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
209
- const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
210
- mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
393
+ if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */
394
+ & (repIndex > dictStartIndex))
395
+ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
396
+ const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
397
+ mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
211
398
  ip++;
212
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
399
+ ZSTD_storeSeq(seqStore, ip-anchor, anchor, 0, mLength-MINMATCH);
213
400
  } else {
214
- if ((matchLongIndex > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
215
- const BYTE* matchEnd = matchLongIndex < dictLimit ? dictEnd : iend;
216
- const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
401
+ if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
402
+ const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend;
403
+ const BYTE* const lowMatchPtr = matchLongIndex < prefixStartIndex ? dictStart : prefixStart;
217
404
  U32 offset;
218
- mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
405
+ mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, prefixStart) + 8;
219
406
  offset = current - matchLongIndex;
220
407
  while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
221
408
  offset_2 = offset_1;
222
409
  offset_1 = offset;
223
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
410
+ ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
224
411
 
225
- } else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
412
+ } else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) {
226
413
  size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
227
414
  U32 const matchIndex3 = hashLong[h3];
228
- const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
415
+ const BYTE* const match3Base = matchIndex3 < prefixStartIndex ? dictBase : base;
229
416
  const BYTE* match3 = match3Base + matchIndex3;
230
417
  U32 offset;
231
418
  hashLong[h3] = current + 1;
232
- if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
233
- const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
234
- const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
235
- mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
419
+ if ( (matchIndex3 > dictStartIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
420
+ const BYTE* const matchEnd = matchIndex3 < prefixStartIndex ? dictEnd : iend;
421
+ const BYTE* const lowMatchPtr = matchIndex3 < prefixStartIndex ? dictStart : prefixStart;
422
+ mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, prefixStart) + 8;
236
423
  ip++;
237
424
  offset = current+1 - matchIndex3;
238
425
  while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
239
426
  } else {
240
- const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
241
- const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
242
- mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
427
+ const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
428
+ const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
429
+ mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
243
430
  offset = current - matchIndex;
244
431
  while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
245
432
  }
246
433
  offset_2 = offset_1;
247
434
  offset_1 = offset;
248
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
435
+ ZSTD_storeSeq(seqStore, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
249
436
 
250
437
  } else {
251
- ip += ((ip-anchor) >> g_searchStrength) + 1;
438
+ ip += ((ip-anchor) >> kSearchStrength) + 1;
252
439
  continue;
253
440
  } }
254
441
 
@@ -266,13 +453,14 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
266
453
  while (ip <= ilimit) {
267
454
  U32 const current2 = (U32)(ip-base);
268
455
  U32 const repIndex2 = current2 - offset_2;
269
- const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
270
- if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
271
- && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
272
- const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
273
- size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, lowPrefixPtr) + 4;
274
- U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
275
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
456
+ const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
457
+ if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) /* intentional overflow : ensure repIndex2 doesn't overlap dict + prefix */
458
+ & (repIndex2 > dictStartIndex))
459
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
460
+ const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
461
+ size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
462
+ U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
463
+ ZSTD_storeSeq(seqStore, 0, anchor, 0, repLength2-MINMATCH);
276
464
  hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
277
465
  hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
278
466
  ip += repLength2;
@@ -283,27 +471,29 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
283
471
  } } }
284
472
 
285
473
  /* save reps for next block */
286
- seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
474
+ rep[0] = offset_1;
475
+ rep[1] = offset_2;
287
476
 
288
477
  /* Return the last literals size */
289
478
  return iend - anchor;
290
479
  }
291
480
 
292
481
 
293
- size_t ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
294
- const void* src, size_t srcSize)
482
+ size_t ZSTD_compressBlock_doubleFast_extDict(
483
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
484
+ void const* src, size_t srcSize)
295
485
  {
296
- U32 const mls = ctx->appliedParams.cParams.searchLength;
486
+ U32 const mls = ms->cParams.minMatch;
297
487
  switch(mls)
298
488
  {
299
489
  default: /* includes case 3 */
300
490
  case 4 :
301
- return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4);
491
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 4);
302
492
  case 5 :
303
- return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5);
493
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 5);
304
494
  case 6 :
305
- return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6);
495
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 6);
306
496
  case 7 :
307
- return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7);
497
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 7);
308
498
  }
309
499
  }