extzstd 0.1.1 → 0.2

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 (85) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.ja.md +18 -0
  3. data/README.md +15 -50
  4. data/contrib/zstd/CONTRIBUTING.md +1 -1
  5. data/contrib/zstd/COPYING +339 -0
  6. data/contrib/zstd/Makefile +82 -51
  7. data/contrib/zstd/NEWS +92 -5
  8. data/contrib/zstd/README.md +50 -41
  9. data/contrib/zstd/appveyor.yml +164 -102
  10. data/contrib/zstd/circle.yml +10 -22
  11. data/contrib/zstd/lib/BUCK +31 -10
  12. data/contrib/zstd/lib/Makefile +57 -31
  13. data/contrib/zstd/lib/README.md +68 -37
  14. data/contrib/zstd/lib/common/bitstream.h +130 -76
  15. data/contrib/zstd/lib/common/compiler.h +86 -0
  16. data/contrib/zstd/lib/common/error_private.c +15 -11
  17. data/contrib/zstd/lib/common/error_private.h +8 -8
  18. data/contrib/zstd/lib/common/fse.h +19 -9
  19. data/contrib/zstd/lib/common/fse_decompress.c +3 -22
  20. data/contrib/zstd/lib/common/huf.h +68 -26
  21. data/contrib/zstd/lib/common/mem.h +23 -35
  22. data/contrib/zstd/lib/common/pool.c +123 -63
  23. data/contrib/zstd/lib/common/pool.h +19 -10
  24. data/contrib/zstd/lib/common/threading.c +11 -16
  25. data/contrib/zstd/lib/common/threading.h +52 -33
  26. data/contrib/zstd/lib/common/xxhash.c +28 -22
  27. data/contrib/zstd/lib/common/zstd_common.c +40 -27
  28. data/contrib/zstd/lib/common/zstd_errors.h +43 -34
  29. data/contrib/zstd/lib/common/zstd_internal.h +131 -123
  30. data/contrib/zstd/lib/compress/fse_compress.c +17 -33
  31. data/contrib/zstd/lib/compress/huf_compress.c +15 -9
  32. data/contrib/zstd/lib/compress/zstd_compress.c +2096 -2363
  33. data/contrib/zstd/lib/compress/zstd_compress_internal.h +462 -0
  34. data/contrib/zstd/lib/compress/zstd_double_fast.c +309 -0
  35. data/contrib/zstd/lib/compress/zstd_double_fast.h +29 -0
  36. data/contrib/zstd/lib/compress/zstd_fast.c +243 -0
  37. data/contrib/zstd/lib/compress/zstd_fast.h +31 -0
  38. data/contrib/zstd/lib/compress/zstd_lazy.c +765 -0
  39. data/contrib/zstd/lib/compress/zstd_lazy.h +39 -0
  40. data/contrib/zstd/lib/compress/zstd_ldm.c +707 -0
  41. data/contrib/zstd/lib/compress/zstd_ldm.h +68 -0
  42. data/contrib/zstd/lib/compress/zstd_opt.c +785 -0
  43. data/contrib/zstd/lib/compress/zstd_opt.h +19 -908
  44. data/contrib/zstd/lib/compress/zstdmt_compress.c +737 -327
  45. data/contrib/zstd/lib/compress/zstdmt_compress.h +88 -26
  46. data/contrib/zstd/lib/decompress/huf_decompress.c +158 -50
  47. data/contrib/zstd/lib/decompress/zstd_decompress.c +884 -699
  48. data/contrib/zstd/lib/deprecated/zbuff.h +5 -4
  49. data/contrib/zstd/lib/deprecated/zbuff_common.c +5 -5
  50. data/contrib/zstd/lib/deprecated/zbuff_compress.c +6 -4
  51. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +5 -4
  52. data/contrib/zstd/lib/dictBuilder/cover.c +93 -77
  53. data/contrib/zstd/lib/dictBuilder/zdict.c +107 -92
  54. data/contrib/zstd/lib/dictBuilder/zdict.h +112 -102
  55. data/contrib/zstd/lib/legacy/zstd_legacy.h +9 -4
  56. data/contrib/zstd/lib/legacy/zstd_v01.c +7 -6
  57. data/contrib/zstd/lib/legacy/zstd_v01.h +5 -4
  58. data/contrib/zstd/lib/legacy/zstd_v02.c +27 -99
  59. data/contrib/zstd/lib/legacy/zstd_v02.h +5 -4
  60. data/contrib/zstd/lib/legacy/zstd_v03.c +26 -98
  61. data/contrib/zstd/lib/legacy/zstd_v03.h +5 -4
  62. data/contrib/zstd/lib/legacy/zstd_v04.c +22 -91
  63. data/contrib/zstd/lib/legacy/zstd_v04.h +5 -4
  64. data/contrib/zstd/lib/legacy/zstd_v05.c +23 -99
  65. data/contrib/zstd/lib/legacy/zstd_v05.h +5 -4
  66. data/contrib/zstd/lib/legacy/zstd_v06.c +22 -96
  67. data/contrib/zstd/lib/legacy/zstd_v06.h +5 -4
  68. data/contrib/zstd/lib/legacy/zstd_v07.c +19 -95
  69. data/contrib/zstd/lib/legacy/zstd_v07.h +5 -4
  70. data/contrib/zstd/lib/zstd.h +895 -271
  71. data/ext/extconf.rb +11 -2
  72. data/ext/extzstd.c +45 -128
  73. data/ext/extzstd.h +74 -31
  74. data/ext/extzstd_stream.c +401 -142
  75. data/ext/zstd_common.c +5 -0
  76. data/ext/zstd_compress.c +8 -0
  77. data/ext/zstd_decompress.c +1 -0
  78. data/ext/zstd_dictbuilder.c +2 -0
  79. data/lib/extzstd/version.rb +1 -1
  80. data/lib/extzstd.rb +48 -1
  81. data/test/test_basic.rb +9 -1
  82. metadata +17 -7
  83. data/HISTORY.ja +0 -10
  84. data/contrib/zstd/LICENSE-examples +0 -11
  85. data/contrib/zstd/PATENTS +0 -33
@@ -0,0 +1,309 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ #include "zstd_compress_internal.h"
12
+ #include "zstd_double_fast.h"
13
+
14
+
15
+ void ZSTD_fillDoubleHashTable(ZSTD_CCtx* cctx, const void* end, const U32 mls)
16
+ {
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;
23
+ 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;
30
+ }
31
+ }
32
+
33
+
34
+ FORCE_INLINE_TEMPLATE
35
+ size_t ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
36
+ const void* src, size_t srcSize,
37
+ const U32 mls)
38
+ {
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;
45
+ const BYTE* const istart = (const BYTE*)src;
46
+ const BYTE* ip = istart;
47
+ const BYTE* anchor = istart;
48
+ const U32 lowestIndex = cctx->dictLimit;
49
+ const BYTE* const lowest = base + lowestIndex;
50
+ const BYTE* const iend = istart + srcSize;
51
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
52
+ U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
53
+ U32 offsetSaved = 0;
54
+
55
+ /* init */
56
+ ip += (ip==lowest);
57
+ { U32 const maxRep = (U32)(ip-lowest);
58
+ if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
59
+ if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
60
+ }
61
+
62
+ /* Main Search Loop */
63
+ while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
64
+ size_t mLength;
65
+ size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
66
+ size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
67
+ U32 const current = (U32)(ip-base);
68
+ U32 const matchIndexL = hashLong[h2];
69
+ U32 const matchIndexS = hashSmall[h];
70
+ const BYTE* matchLong = base + matchIndexL;
71
+ const BYTE* match = base + matchIndexS;
72
+ hashLong[h2] = hashSmall[h] = current; /* update hash tables */
73
+
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 */
77
+ mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
78
+ 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)) ) {
83
+ mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
84
+ 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)) ) {
92
+ mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8;
93
+ ip++;
94
+ 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 */
100
+ }
101
+ } else {
102
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
103
+ continue;
104
+ }
105
+
106
+ offset_2 = offset_1;
107
+ offset_1 = offset;
108
+
109
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
110
+ }
111
+
112
+ /* match found */
113
+ ip += mLength;
114
+ anchor = ip;
115
+
116
+ if (ip <= ilimit) {
117
+ /* Fill Table */
118
+ hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] =
119
+ hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2; /* here because current+2 could be > iend-8 */
120
+ hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
121
+ hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
122
+
123
+ /* 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
+ } } }
137
+
138
+ /* save reps for next block */
139
+ seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
140
+ seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
141
+
142
+ /* Return the last literals size */
143
+ return iend - anchor;
144
+ }
145
+
146
+
147
+ size_t ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
148
+ {
149
+ const U32 mls = ctx->appliedParams.cParams.searchLength;
150
+ switch(mls)
151
+ {
152
+ default: /* includes case 3 */
153
+ case 4 :
154
+ return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4);
155
+ case 5 :
156
+ return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5);
157
+ case 6 :
158
+ return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6);
159
+ case 7 :
160
+ return ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7);
161
+ }
162
+ }
163
+
164
+
165
+ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
166
+ const void* src, size_t srcSize,
167
+ const U32 mls)
168
+ {
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;
176
+ const BYTE* const istart = (const BYTE*)src;
177
+ const BYTE* ip = istart;
178
+ 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
+ const BYTE* const iend = istart + srcSize;
185
+ const BYTE* const ilimit = iend - 8;
186
+ U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
187
+
188
+ /* Search Loop */
189
+ while (ip < ilimit) { /* < instead of <=, because (ip+1) */
190
+ const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
191
+ const U32 matchIndex = hashSmall[hSmall];
192
+ const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
193
+ const BYTE* match = matchBase + matchIndex;
194
+
195
+ const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);
196
+ const U32 matchLongIndex = hashLong[hLong];
197
+ const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
198
+ const BYTE* matchLong = matchLongBase + matchLongIndex;
199
+
200
+ const U32 current = (U32)(ip-base);
201
+ 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;
204
+ size_t mLength;
205
+ hashSmall[hSmall] = hashLong[hLong] = current; /* update hash table */
206
+
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;
211
+ ip++;
212
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
213
+ } 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;
217
+ U32 offset;
218
+ mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
219
+ offset = current - matchLongIndex;
220
+ while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
221
+ offset_2 = offset_1;
222
+ offset_1 = offset;
223
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
224
+
225
+ } else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
226
+ size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
227
+ U32 const matchIndex3 = hashLong[h3];
228
+ const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
229
+ const BYTE* match3 = match3Base + matchIndex3;
230
+ U32 offset;
231
+ 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;
236
+ ip++;
237
+ offset = current+1 - matchIndex3;
238
+ while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
239
+ } 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;
243
+ offset = current - matchIndex;
244
+ while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
245
+ }
246
+ offset_2 = offset_1;
247
+ offset_1 = offset;
248
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
249
+
250
+ } else {
251
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
252
+ continue;
253
+ } }
254
+
255
+ /* found a match : store it */
256
+ ip += mLength;
257
+ anchor = ip;
258
+
259
+ if (ip <= ilimit) {
260
+ /* Fill Table */
261
+ hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
262
+ hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
263
+ hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
264
+ hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
265
+ /* check immediate repcode */
266
+ while (ip <= ilimit) {
267
+ U32 const current2 = (U32)(ip-base);
268
+ 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);
276
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
277
+ hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
278
+ ip += repLength2;
279
+ anchor = ip;
280
+ continue;
281
+ }
282
+ break;
283
+ } } }
284
+
285
+ /* save reps for next block */
286
+ seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
287
+
288
+ /* Return the last literals size */
289
+ return iend - anchor;
290
+ }
291
+
292
+
293
+ size_t ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
294
+ const void* src, size_t srcSize)
295
+ {
296
+ U32 const mls = ctx->appliedParams.cParams.searchLength;
297
+ switch(mls)
298
+ {
299
+ default: /* includes case 3 */
300
+ case 4 :
301
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4);
302
+ case 5 :
303
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5);
304
+ case 6 :
305
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6);
306
+ case 7 :
307
+ return ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7);
308
+ }
309
+ }
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ #ifndef ZSTD_DOUBLE_FAST_H
12
+ #define ZSTD_DOUBLE_FAST_H
13
+
14
+ #if defined (__cplusplus)
15
+ extern "C" {
16
+ #endif
17
+
18
+ #include "mem.h" /* U32 */
19
+ #include "zstd.h" /* ZSTD_CCtx, size_t */
20
+
21
+ void ZSTD_fillDoubleHashTable(ZSTD_CCtx* cctx, const void* end, const U32 mls);
22
+ size_t ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
23
+ size_t ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize);
24
+
25
+ #if defined (__cplusplus)
26
+ }
27
+ #endif
28
+
29
+ #endif /* ZSTD_DOUBLE_FAST_H */
@@ -0,0 +1,243 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ #include "zstd_compress_internal.h"
12
+ #include "zstd_fast.h"
13
+
14
+
15
+ void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
16
+ {
17
+ U32* const hashTable = zc->hashTable;
18
+ U32 const hBits = zc->appliedParams.cParams.hashLog;
19
+ const BYTE* const base = zc->base;
20
+ const BYTE* ip = base + zc->nextToUpdate;
21
+ const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
22
+ const size_t fastHashFillStep = 3;
23
+
24
+ while(ip <= iend) {
25
+ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
26
+ ip += fastHashFillStep;
27
+ }
28
+ }
29
+
30
+
31
+ FORCE_INLINE_TEMPLATE
32
+ size_t ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
33
+ const void* src, size_t srcSize,
34
+ const U32 mls)
35
+ {
36
+ U32* const hashTable = cctx->hashTable;
37
+ U32 const hBits = cctx->appliedParams.cParams.hashLog;
38
+ seqStore_t* seqStorePtr = &(cctx->seqStore);
39
+ const BYTE* const base = cctx->base;
40
+ const BYTE* const istart = (const BYTE*)src;
41
+ const BYTE* ip = istart;
42
+ const BYTE* anchor = istart;
43
+ const U32 lowestIndex = cctx->dictLimit;
44
+ const BYTE* const lowest = base + lowestIndex;
45
+ const BYTE* const iend = istart + srcSize;
46
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
47
+ U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
48
+ U32 offsetSaved = 0;
49
+
50
+ /* init */
51
+ ip += (ip==lowest);
52
+ { U32 const maxRep = (U32)(ip-lowest);
53
+ if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
54
+ if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
55
+ }
56
+
57
+ /* Main Search Loop */
58
+ while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
59
+ size_t mLength;
60
+ size_t const h = ZSTD_hashPtr(ip, hBits, mls);
61
+ U32 const current = (U32)(ip-base);
62
+ U32 const matchIndex = hashTable[h];
63
+ const BYTE* match = base + matchIndex;
64
+ hashTable[h] = current; /* update hash table */
65
+
66
+ if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
67
+ mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
68
+ ip++;
69
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
70
+ } else {
71
+ U32 offset;
72
+ if ( (matchIndex <= lowestIndex) || (MEM_read32(match) != MEM_read32(ip)) ) {
73
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
74
+ continue;
75
+ }
76
+ mLength = ZSTD_count(ip+4, match+4, iend) + 4;
77
+ offset = (U32)(ip-match);
78
+ while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
79
+ offset_2 = offset_1;
80
+ offset_1 = offset;
81
+
82
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
83
+ }
84
+
85
+ /* match found */
86
+ ip += mLength;
87
+ anchor = ip;
88
+
89
+ if (ip <= ilimit) {
90
+ /* Fill Table */
91
+ hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2; /* here because current+2 could be > iend-8 */
92
+ hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
93
+ /* check immediate repcode */
94
+ while ( (ip <= ilimit)
95
+ && ( (offset_2>0)
96
+ & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
97
+ /* store sequence */
98
+ size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
99
+ { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
100
+ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base);
101
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
102
+ ip += rLength;
103
+ anchor = ip;
104
+ continue; /* faster when present ... (?) */
105
+ } } }
106
+
107
+ /* save reps for next block */
108
+ seqStorePtr->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
109
+ seqStorePtr->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
110
+
111
+ /* Return the last literals size */
112
+ return iend - anchor;
113
+ }
114
+
115
+
116
+ size_t ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
117
+ const void* src, size_t srcSize)
118
+ {
119
+ const U32 mls = ctx->appliedParams.cParams.searchLength;
120
+ switch(mls)
121
+ {
122
+ default: /* includes case 3 */
123
+ case 4 :
124
+ return ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4);
125
+ case 5 :
126
+ return ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5);
127
+ case 6 :
128
+ return ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6);
129
+ case 7 :
130
+ return ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7);
131
+ }
132
+ }
133
+
134
+
135
+ static size_t ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
136
+ const void* src, size_t srcSize,
137
+ const U32 mls)
138
+ {
139
+ U32* hashTable = ctx->hashTable;
140
+ const U32 hBits = ctx->appliedParams.cParams.hashLog;
141
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
142
+ const BYTE* const base = ctx->base;
143
+ const BYTE* const dictBase = ctx->dictBase;
144
+ const BYTE* const istart = (const BYTE*)src;
145
+ const BYTE* ip = istart;
146
+ const BYTE* anchor = istart;
147
+ const U32 lowestIndex = ctx->lowLimit;
148
+ const BYTE* const dictStart = dictBase + lowestIndex;
149
+ const U32 dictLimit = ctx->dictLimit;
150
+ const BYTE* const lowPrefixPtr = base + dictLimit;
151
+ const BYTE* const dictEnd = dictBase + dictLimit;
152
+ const BYTE* const iend = istart + srcSize;
153
+ const BYTE* const ilimit = iend - 8;
154
+ U32 offset_1=seqStorePtr->rep[0], offset_2=seqStorePtr->rep[1];
155
+
156
+ /* Search Loop */
157
+ while (ip < ilimit) { /* < instead of <=, because (ip+1) */
158
+ const size_t h = ZSTD_hashPtr(ip, hBits, mls);
159
+ const U32 matchIndex = hashTable[h];
160
+ const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
161
+ const BYTE* match = matchBase + matchIndex;
162
+ const U32 current = (U32)(ip-base);
163
+ const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
164
+ const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
165
+ const BYTE* repMatch = repBase + repIndex;
166
+ size_t mLength;
167
+ hashTable[h] = current; /* update hash table */
168
+
169
+ if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
170
+ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
171
+ const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
172
+ mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
173
+ ip++;
174
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
175
+ } else {
176
+ if ( (matchIndex < lowestIndex) ||
177
+ (MEM_read32(match) != MEM_read32(ip)) ) {
178
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
179
+ continue;
180
+ }
181
+ { const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
182
+ const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
183
+ U32 offset;
184
+ mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
185
+ while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
186
+ offset = current - matchIndex;
187
+ offset_2 = offset_1;
188
+ offset_1 = offset;
189
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
190
+ } }
191
+
192
+ /* found a match : store it */
193
+ ip += mLength;
194
+ anchor = ip;
195
+
196
+ if (ip <= ilimit) {
197
+ /* Fill Table */
198
+ hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
199
+ hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
200
+ /* check immediate repcode */
201
+ while (ip <= ilimit) {
202
+ U32 const current2 = (U32)(ip-base);
203
+ U32 const repIndex2 = current2 - offset_2;
204
+ const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
205
+ if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
206
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
207
+ const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
208
+ size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, lowPrefixPtr) + 4;
209
+ U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
210
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
211
+ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2;
212
+ ip += repLength2;
213
+ anchor = ip;
214
+ continue;
215
+ }
216
+ break;
217
+ } } }
218
+
219
+ /* save reps for next block */
220
+ seqStorePtr->repToConfirm[0] = offset_1; seqStorePtr->repToConfirm[1] = offset_2;
221
+
222
+ /* Return the last literals size */
223
+ return iend - anchor;
224
+ }
225
+
226
+
227
+ size_t ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
228
+ const void* src, size_t srcSize)
229
+ {
230
+ U32 const mls = ctx->appliedParams.cParams.searchLength;
231
+ switch(mls)
232
+ {
233
+ default: /* includes case 3 */
234
+ case 4 :
235
+ return ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4);
236
+ case 5 :
237
+ return ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5);
238
+ case 6 :
239
+ return ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6);
240
+ case 7 :
241
+ return ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7);
242
+ }
243
+ }
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ #ifndef ZSTD_FAST_H
12
+ #define ZSTD_FAST_H
13
+
14
+ #if defined (__cplusplus)
15
+ extern "C" {
16
+ #endif
17
+
18
+ #include "mem.h" /* U32 */
19
+ #include "zstd.h" /* ZSTD_CCtx, size_t */
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);
26
+
27
+ #if defined (__cplusplus)
28
+ }
29
+ #endif
30
+
31
+ #endif /* ZSTD_FAST_H */