zstdlib 0.9.0-x86_64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +6 -0
  3. data/CHANGES.md +78 -0
  4. data/Gemfile +3 -0
  5. data/README.md +107 -0
  6. data/Rakefile +59 -0
  7. data/ext/zstdlib_c/extconf.rb +54 -0
  8. data/ext/zstdlib_c/ruby/zlib-2.2/zstdlib.c +4675 -0
  9. data/ext/zstdlib_c/ruby/zlib-2.3/zstdlib.c +4702 -0
  10. data/ext/zstdlib_c/ruby/zlib-2.4/zstdlib.c +4859 -0
  11. data/ext/zstdlib_c/ruby/zlib-2.5/zstdlib.c +4864 -0
  12. data/ext/zstdlib_c/ruby/zlib-2.6/zstdlib.c +4906 -0
  13. data/ext/zstdlib_c/ruby/zlib-2.7/zstdlib.c +4895 -0
  14. data/ext/zstdlib_c/ruby/zlib-3.0/zstdlib.c +4994 -0
  15. data/ext/zstdlib_c/ruby/zlib-3.1/zstdlib.c +5076 -0
  16. data/ext/zstdlib_c/zlib-1.2.11/adler32.c +186 -0
  17. data/ext/zstdlib_c/zlib-1.2.11/compress.c +86 -0
  18. data/ext/zstdlib_c/zlib-1.2.11/crc32.c +442 -0
  19. data/ext/zstdlib_c/zlib-1.2.11/crc32.h +441 -0
  20. data/ext/zstdlib_c/zlib-1.2.11/deflate.c +2163 -0
  21. data/ext/zstdlib_c/zlib-1.2.11/deflate.h +349 -0
  22. data/ext/zstdlib_c/zlib-1.2.11/gzclose.c +25 -0
  23. data/ext/zstdlib_c/zlib-1.2.11/gzguts.h +218 -0
  24. data/ext/zstdlib_c/zlib-1.2.11/gzlib.c +637 -0
  25. data/ext/zstdlib_c/zlib-1.2.11/gzread.c +654 -0
  26. data/ext/zstdlib_c/zlib-1.2.11/gzwrite.c +665 -0
  27. data/ext/zstdlib_c/zlib-1.2.11/infback.c +640 -0
  28. data/ext/zstdlib_c/zlib-1.2.11/inffast.c +323 -0
  29. data/ext/zstdlib_c/zlib-1.2.11/inffast.h +11 -0
  30. data/ext/zstdlib_c/zlib-1.2.11/inffixed.h +94 -0
  31. data/ext/zstdlib_c/zlib-1.2.11/inflate.c +1561 -0
  32. data/ext/zstdlib_c/zlib-1.2.11/inflate.h +125 -0
  33. data/ext/zstdlib_c/zlib-1.2.11/inftrees.c +304 -0
  34. data/ext/zstdlib_c/zlib-1.2.11/inftrees.h +62 -0
  35. data/ext/zstdlib_c/zlib-1.2.11/trees.c +1203 -0
  36. data/ext/zstdlib_c/zlib-1.2.11/trees.h +128 -0
  37. data/ext/zstdlib_c/zlib-1.2.11/uncompr.c +93 -0
  38. data/ext/zstdlib_c/zlib-1.2.11/zconf.h +534 -0
  39. data/ext/zstdlib_c/zlib-1.2.11/zlib.h +1912 -0
  40. data/ext/zstdlib_c/zlib-1.2.11/zutil.c +325 -0
  41. data/ext/zstdlib_c/zlib-1.2.11/zutil.h +271 -0
  42. data/ext/zstdlib_c/zlib.mk +14 -0
  43. data/ext/zstdlib_c/zlibwrapper/zlibwrapper.c +10 -0
  44. data/ext/zstdlib_c/zlibwrapper.mk +14 -0
  45. data/ext/zstdlib_c/zstd-1.5.2/lib/common/bitstream.h +478 -0
  46. data/ext/zstdlib_c/zstd-1.5.2/lib/common/compiler.h +335 -0
  47. data/ext/zstdlib_c/zstd-1.5.2/lib/common/cpu.h +213 -0
  48. data/ext/zstdlib_c/zstd-1.5.2/lib/common/debug.c +24 -0
  49. data/ext/zstdlib_c/zstd-1.5.2/lib/common/debug.h +107 -0
  50. data/ext/zstdlib_c/zstd-1.5.2/lib/common/entropy_common.c +368 -0
  51. data/ext/zstdlib_c/zstd-1.5.2/lib/common/error_private.c +56 -0
  52. data/ext/zstdlib_c/zstd-1.5.2/lib/common/error_private.h +159 -0
  53. data/ext/zstdlib_c/zstd-1.5.2/lib/common/fse.h +717 -0
  54. data/ext/zstdlib_c/zstd-1.5.2/lib/common/fse_decompress.c +403 -0
  55. data/ext/zstdlib_c/zstd-1.5.2/lib/common/huf.h +364 -0
  56. data/ext/zstdlib_c/zstd-1.5.2/lib/common/mem.h +442 -0
  57. data/ext/zstdlib_c/zstd-1.5.2/lib/common/pool.c +355 -0
  58. data/ext/zstdlib_c/zstd-1.5.2/lib/common/pool.h +84 -0
  59. data/ext/zstdlib_c/zstd-1.5.2/lib/common/portability_macros.h +137 -0
  60. data/ext/zstdlib_c/zstd-1.5.2/lib/common/threading.c +122 -0
  61. data/ext/zstdlib_c/zstd-1.5.2/lib/common/threading.h +155 -0
  62. data/ext/zstdlib_c/zstd-1.5.2/lib/common/xxhash.c +24 -0
  63. data/ext/zstdlib_c/zstd-1.5.2/lib/common/xxhash.h +5686 -0
  64. data/ext/zstdlib_c/zstd-1.5.2/lib/common/zstd_common.c +83 -0
  65. data/ext/zstdlib_c/zstd-1.5.2/lib/common/zstd_deps.h +111 -0
  66. data/ext/zstdlib_c/zstd-1.5.2/lib/common/zstd_internal.h +493 -0
  67. data/ext/zstdlib_c/zstd-1.5.2/lib/common/zstd_trace.h +163 -0
  68. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/clevels.h +134 -0
  69. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/fse_compress.c +741 -0
  70. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/hist.c +181 -0
  71. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/hist.h +75 -0
  72. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/huf_compress.c +1370 -0
  73. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress.c +6327 -0
  74. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress_internal.h +1458 -0
  75. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress_literals.c +159 -0
  76. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress_literals.h +31 -0
  77. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress_sequences.c +442 -0
  78. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress_sequences.h +54 -0
  79. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress_superblock.c +573 -0
  80. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_compress_superblock.h +32 -0
  81. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_cwksp.h +676 -0
  82. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_double_fast.c +696 -0
  83. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_double_fast.h +38 -0
  84. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_fast.c +675 -0
  85. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_fast.h +37 -0
  86. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_lazy.c +2104 -0
  87. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_lazy.h +125 -0
  88. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_ldm.c +724 -0
  89. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_ldm.h +117 -0
  90. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_ldm_geartab.h +106 -0
  91. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_opt.c +1446 -0
  92. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstd_opt.h +56 -0
  93. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstdmt_compress.c +1859 -0
  94. data/ext/zstdlib_c/zstd-1.5.2/lib/compress/zstdmt_compress.h +113 -0
  95. data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/huf_decompress.c +1889 -0
  96. data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/huf_decompress_amd64.S +585 -0
  97. data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/zstd_ddict.c +244 -0
  98. data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/zstd_ddict.h +44 -0
  99. data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/zstd_decompress.c +2230 -0
  100. data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/zstd_decompress_block.c +2072 -0
  101. data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/zstd_decompress_block.h +68 -0
  102. data/ext/zstdlib_c/zstd-1.5.2/lib/decompress/zstd_decompress_internal.h +236 -0
  103. data/ext/zstdlib_c/zstd-1.5.2/lib/zdict.h +452 -0
  104. data/ext/zstdlib_c/zstd-1.5.2/lib/zstd.h +2575 -0
  105. data/ext/zstdlib_c/zstd-1.5.2/lib/zstd_errors.h +95 -0
  106. data/ext/zstdlib_c/zstd-1.5.2/zlibWrapper/gzclose.c +28 -0
  107. data/ext/zstdlib_c/zstd-1.5.2/zlibWrapper/gzcompatibility.h +68 -0
  108. data/ext/zstdlib_c/zstd-1.5.2/zlibWrapper/gzguts.h +229 -0
  109. data/ext/zstdlib_c/zstd-1.5.2/zlibWrapper/gzlib.c +640 -0
  110. data/ext/zstdlib_c/zstd-1.5.2/zlibWrapper/gzread.c +678 -0
  111. data/ext/zstdlib_c/zstd-1.5.2/zlibWrapper/gzwrite.c +671 -0
  112. data/ext/zstdlib_c/zstd-1.5.2/zlibWrapper/zstd_zlibwrapper.c +1198 -0
  113. data/ext/zstdlib_c/zstd-1.5.2/zlibWrapper/zstd_zlibwrapper.h +88 -0
  114. data/ext/zstdlib_c/zstd.mk +15 -0
  115. data/lib/2.4/zstdlib_c.bundle +0 -0
  116. data/lib/2.5/zstdlib_c.bundle +0 -0
  117. data/lib/2.6/zstdlib_c.bundle +0 -0
  118. data/lib/2.7/zstdlib_c.bundle +0 -0
  119. data/lib/3.0/zstdlib_c.bundle +0 -0
  120. data/lib/3.1/zstdlib_c.bundle +0 -0
  121. data/lib/zstdlib.rb +6 -0
  122. data/test/zstdlib_test.rb +21 -0
  123. metadata +237 -0
@@ -0,0 +1,675 @@
1
+ /*
2
+ * Copyright (c) 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" /* ZSTD_hashPtr, ZSTD_count, ZSTD_storeSeq */
12
+ #include "zstd_fast.h"
13
+
14
+
15
+ void ZSTD_fillHashTable(ZSTD_matchState_t* ms,
16
+ const void* const end,
17
+ ZSTD_dictTableLoadMethod_e dtlm)
18
+ {
19
+ const ZSTD_compressionParameters* const cParams = &ms->cParams;
20
+ U32* const hashTable = ms->hashTable;
21
+ U32 const hBits = cParams->hashLog;
22
+ U32 const mls = cParams->minMatch;
23
+ const BYTE* const base = ms->window.base;
24
+ const BYTE* ip = base + ms->nextToUpdate;
25
+ const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
26
+ const U32 fastHashFillStep = 3;
27
+
28
+ /* Always insert every fastHashFillStep position into the hash table.
29
+ * Insert the other positions if their hash entry is empty.
30
+ */
31
+ for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) {
32
+ U32 const curr = (U32)(ip - base);
33
+ size_t const hash0 = ZSTD_hashPtr(ip, hBits, mls);
34
+ hashTable[hash0] = curr;
35
+ if (dtlm == ZSTD_dtlm_fast) continue;
36
+ /* Only load extra positions for ZSTD_dtlm_full */
37
+ { U32 p;
38
+ for (p = 1; p < fastHashFillStep; ++p) {
39
+ size_t const hash = ZSTD_hashPtr(ip + p, hBits, mls);
40
+ if (hashTable[hash] == 0) { /* not yet filled */
41
+ hashTable[hash] = curr + p;
42
+ } } } }
43
+ }
44
+
45
+
46
+ /**
47
+ * If you squint hard enough (and ignore repcodes), the search operation at any
48
+ * given position is broken into 4 stages:
49
+ *
50
+ * 1. Hash (map position to hash value via input read)
51
+ * 2. Lookup (map hash val to index via hashtable read)
52
+ * 3. Load (map index to value at that position via input read)
53
+ * 4. Compare
54
+ *
55
+ * Each of these steps involves a memory read at an address which is computed
56
+ * from the previous step. This means these steps must be sequenced and their
57
+ * latencies are cumulative.
58
+ *
59
+ * Rather than do 1->2->3->4 sequentially for a single position before moving
60
+ * onto the next, this implementation interleaves these operations across the
61
+ * next few positions:
62
+ *
63
+ * R = Repcode Read & Compare
64
+ * H = Hash
65
+ * T = Table Lookup
66
+ * M = Match Read & Compare
67
+ *
68
+ * Pos | Time -->
69
+ * ----+-------------------
70
+ * N | ... M
71
+ * N+1 | ... TM
72
+ * N+2 | R H T M
73
+ * N+3 | H TM
74
+ * N+4 | R H T M
75
+ * N+5 | H ...
76
+ * N+6 | R ...
77
+ *
78
+ * This is very much analogous to the pipelining of execution in a CPU. And just
79
+ * like a CPU, we have to dump the pipeline when we find a match (i.e., take a
80
+ * branch).
81
+ *
82
+ * When this happens, we throw away our current state, and do the following prep
83
+ * to re-enter the loop:
84
+ *
85
+ * Pos | Time -->
86
+ * ----+-------------------
87
+ * N | H T
88
+ * N+1 | H
89
+ *
90
+ * This is also the work we do at the beginning to enter the loop initially.
91
+ */
92
+ FORCE_INLINE_TEMPLATE size_t
93
+ ZSTD_compressBlock_fast_noDict_generic(
94
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
95
+ void const* src, size_t srcSize,
96
+ U32 const mls, U32 const hasStep)
97
+ {
98
+ const ZSTD_compressionParameters* const cParams = &ms->cParams;
99
+ U32* const hashTable = ms->hashTable;
100
+ U32 const hlog = cParams->hashLog;
101
+ /* support stepSize of 0 */
102
+ size_t const stepSize = hasStep ? (cParams->targetLength + !(cParams->targetLength) + 1) : 2;
103
+ const BYTE* const base = ms->window.base;
104
+ const BYTE* const istart = (const BYTE*)src;
105
+ const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
106
+ const U32 prefixStartIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog);
107
+ const BYTE* const prefixStart = base + prefixStartIndex;
108
+ const BYTE* const iend = istart + srcSize;
109
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
110
+
111
+ const BYTE* anchor = istart;
112
+ const BYTE* ip0 = istart;
113
+ const BYTE* ip1;
114
+ const BYTE* ip2;
115
+ const BYTE* ip3;
116
+ U32 current0;
117
+
118
+ U32 rep_offset1 = rep[0];
119
+ U32 rep_offset2 = rep[1];
120
+ U32 offsetSaved = 0;
121
+
122
+ size_t hash0; /* hash for ip0 */
123
+ size_t hash1; /* hash for ip1 */
124
+ U32 idx; /* match idx for ip0 */
125
+ U32 mval; /* src value at match idx */
126
+
127
+ U32 offcode;
128
+ const BYTE* match0;
129
+ size_t mLength;
130
+
131
+ /* ip0 and ip1 are always adjacent. The targetLength skipping and
132
+ * uncompressibility acceleration is applied to every other position,
133
+ * matching the behavior of #1562. step therefore represents the gap
134
+ * between pairs of positions, from ip0 to ip2 or ip1 to ip3. */
135
+ size_t step;
136
+ const BYTE* nextStep;
137
+ const size_t kStepIncr = (1 << (kSearchStrength - 1));
138
+
139
+ DEBUGLOG(5, "ZSTD_compressBlock_fast_generic");
140
+ ip0 += (ip0 == prefixStart);
141
+ { U32 const curr = (U32)(ip0 - base);
142
+ U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, cParams->windowLog);
143
+ U32 const maxRep = curr - windowLow;
144
+ if (rep_offset2 > maxRep) offsetSaved = rep_offset2, rep_offset2 = 0;
145
+ if (rep_offset1 > maxRep) offsetSaved = rep_offset1, rep_offset1 = 0;
146
+ }
147
+
148
+ /* start each op */
149
+ _start: /* Requires: ip0 */
150
+
151
+ step = stepSize;
152
+ nextStep = ip0 + kStepIncr;
153
+
154
+ /* calculate positions, ip0 - anchor == 0, so we skip step calc */
155
+ ip1 = ip0 + 1;
156
+ ip2 = ip0 + step;
157
+ ip3 = ip2 + 1;
158
+
159
+ if (ip3 >= ilimit) {
160
+ goto _cleanup;
161
+ }
162
+
163
+ hash0 = ZSTD_hashPtr(ip0, hlog, mls);
164
+ hash1 = ZSTD_hashPtr(ip1, hlog, mls);
165
+
166
+ idx = hashTable[hash0];
167
+
168
+ do {
169
+ /* load repcode match for ip[2]*/
170
+ const U32 rval = MEM_read32(ip2 - rep_offset1);
171
+
172
+ /* write back hash table entry */
173
+ current0 = (U32)(ip0 - base);
174
+ hashTable[hash0] = current0;
175
+
176
+ /* check repcode at ip[2] */
177
+ if ((MEM_read32(ip2) == rval) & (rep_offset1 > 0)) {
178
+ ip0 = ip2;
179
+ match0 = ip0 - rep_offset1;
180
+ mLength = ip0[-1] == match0[-1];
181
+ ip0 -= mLength;
182
+ match0 -= mLength;
183
+ offcode = STORE_REPCODE_1;
184
+ mLength += 4;
185
+ goto _match;
186
+ }
187
+
188
+ /* load match for ip[0] */
189
+ if (idx >= prefixStartIndex) {
190
+ mval = MEM_read32(base + idx);
191
+ } else {
192
+ mval = MEM_read32(ip0) ^ 1; /* guaranteed to not match. */
193
+ }
194
+
195
+ /* check match at ip[0] */
196
+ if (MEM_read32(ip0) == mval) {
197
+ /* found a match! */
198
+ goto _offset;
199
+ }
200
+
201
+ /* lookup ip[1] */
202
+ idx = hashTable[hash1];
203
+
204
+ /* hash ip[2] */
205
+ hash0 = hash1;
206
+ hash1 = ZSTD_hashPtr(ip2, hlog, mls);
207
+
208
+ /* advance to next positions */
209
+ ip0 = ip1;
210
+ ip1 = ip2;
211
+ ip2 = ip3;
212
+
213
+ /* write back hash table entry */
214
+ current0 = (U32)(ip0 - base);
215
+ hashTable[hash0] = current0;
216
+
217
+ /* load match for ip[0] */
218
+ if (idx >= prefixStartIndex) {
219
+ mval = MEM_read32(base + idx);
220
+ } else {
221
+ mval = MEM_read32(ip0) ^ 1; /* guaranteed to not match. */
222
+ }
223
+
224
+ /* check match at ip[0] */
225
+ if (MEM_read32(ip0) == mval) {
226
+ /* found a match! */
227
+ goto _offset;
228
+ }
229
+
230
+ /* lookup ip[1] */
231
+ idx = hashTable[hash1];
232
+
233
+ /* hash ip[2] */
234
+ hash0 = hash1;
235
+ hash1 = ZSTD_hashPtr(ip2, hlog, mls);
236
+
237
+ /* advance to next positions */
238
+ ip0 = ip1;
239
+ ip1 = ip2;
240
+ ip2 = ip0 + step;
241
+ ip3 = ip1 + step;
242
+
243
+ /* calculate step */
244
+ if (ip2 >= nextStep) {
245
+ step++;
246
+ PREFETCH_L1(ip1 + 64);
247
+ PREFETCH_L1(ip1 + 128);
248
+ nextStep += kStepIncr;
249
+ }
250
+ } while (ip3 < ilimit);
251
+
252
+ _cleanup:
253
+ /* Note that there are probably still a couple positions we could search.
254
+ * However, it seems to be a meaningful performance hit to try to search
255
+ * them. So let's not. */
256
+
257
+ /* save reps for next block */
258
+ rep[0] = rep_offset1 ? rep_offset1 : offsetSaved;
259
+ rep[1] = rep_offset2 ? rep_offset2 : offsetSaved;
260
+
261
+ /* Return the last literals size */
262
+ return (size_t)(iend - anchor);
263
+
264
+ _offset: /* Requires: ip0, idx */
265
+
266
+ /* Compute the offset code. */
267
+ match0 = base + idx;
268
+ rep_offset2 = rep_offset1;
269
+ rep_offset1 = (U32)(ip0-match0);
270
+ offcode = STORE_OFFSET(rep_offset1);
271
+ mLength = 4;
272
+
273
+ /* Count the backwards match length. */
274
+ while (((ip0>anchor) & (match0>prefixStart)) && (ip0[-1] == match0[-1])) {
275
+ ip0--;
276
+ match0--;
277
+ mLength++;
278
+ }
279
+
280
+ _match: /* Requires: ip0, match0, offcode */
281
+
282
+ /* Count the forward length. */
283
+ mLength += ZSTD_count(ip0 + mLength, match0 + mLength, iend);
284
+
285
+ ZSTD_storeSeq(seqStore, (size_t)(ip0 - anchor), anchor, iend, offcode, mLength);
286
+
287
+ ip0 += mLength;
288
+ anchor = ip0;
289
+
290
+ /* write next hash table entry */
291
+ if (ip1 < ip0) {
292
+ hashTable[hash1] = (U32)(ip1 - base);
293
+ }
294
+
295
+ /* Fill table and check for immediate repcode. */
296
+ if (ip0 <= ilimit) {
297
+ /* Fill Table */
298
+ assert(base+current0+2 > istart); /* check base overflow */
299
+ hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2; /* here because current+2 could be > iend-8 */
300
+ hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base);
301
+
302
+ if (rep_offset2 > 0) { /* rep_offset2==0 means rep_offset2 is invalidated */
303
+ while ( (ip0 <= ilimit) && (MEM_read32(ip0) == MEM_read32(ip0 - rep_offset2)) ) {
304
+ /* store sequence */
305
+ size_t const rLength = ZSTD_count(ip0+4, ip0+4-rep_offset2, iend) + 4;
306
+ { U32 const tmpOff = rep_offset2; rep_offset2 = rep_offset1; rep_offset1 = tmpOff; } /* swap rep_offset2 <=> rep_offset1 */
307
+ hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base);
308
+ ip0 += rLength;
309
+ ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, STORE_REPCODE_1, rLength);
310
+ anchor = ip0;
311
+ continue; /* faster when present (confirmed on gcc-8) ... (?) */
312
+ } } }
313
+
314
+ goto _start;
315
+ }
316
+
317
+ #define ZSTD_GEN_FAST_FN(dictMode, mls, step) \
318
+ static size_t ZSTD_compressBlock_fast_##dictMode##_##mls##_##step( \
319
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \
320
+ void const* src, size_t srcSize) \
321
+ { \
322
+ return ZSTD_compressBlock_fast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls, step); \
323
+ }
324
+
325
+ ZSTD_GEN_FAST_FN(noDict, 4, 1)
326
+ ZSTD_GEN_FAST_FN(noDict, 5, 1)
327
+ ZSTD_GEN_FAST_FN(noDict, 6, 1)
328
+ ZSTD_GEN_FAST_FN(noDict, 7, 1)
329
+
330
+ ZSTD_GEN_FAST_FN(noDict, 4, 0)
331
+ ZSTD_GEN_FAST_FN(noDict, 5, 0)
332
+ ZSTD_GEN_FAST_FN(noDict, 6, 0)
333
+ ZSTD_GEN_FAST_FN(noDict, 7, 0)
334
+
335
+ size_t ZSTD_compressBlock_fast(
336
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
337
+ void const* src, size_t srcSize)
338
+ {
339
+ U32 const mls = ms->cParams.minMatch;
340
+ assert(ms->dictMatchState == NULL);
341
+ if (ms->cParams.targetLength > 1) {
342
+ switch(mls)
343
+ {
344
+ default: /* includes case 3 */
345
+ case 4 :
346
+ return ZSTD_compressBlock_fast_noDict_4_1(ms, seqStore, rep, src, srcSize);
347
+ case 5 :
348
+ return ZSTD_compressBlock_fast_noDict_5_1(ms, seqStore, rep, src, srcSize);
349
+ case 6 :
350
+ return ZSTD_compressBlock_fast_noDict_6_1(ms, seqStore, rep, src, srcSize);
351
+ case 7 :
352
+ return ZSTD_compressBlock_fast_noDict_7_1(ms, seqStore, rep, src, srcSize);
353
+ }
354
+ } else {
355
+ switch(mls)
356
+ {
357
+ default: /* includes case 3 */
358
+ case 4 :
359
+ return ZSTD_compressBlock_fast_noDict_4_0(ms, seqStore, rep, src, srcSize);
360
+ case 5 :
361
+ return ZSTD_compressBlock_fast_noDict_5_0(ms, seqStore, rep, src, srcSize);
362
+ case 6 :
363
+ return ZSTD_compressBlock_fast_noDict_6_0(ms, seqStore, rep, src, srcSize);
364
+ case 7 :
365
+ return ZSTD_compressBlock_fast_noDict_7_0(ms, seqStore, rep, src, srcSize);
366
+ }
367
+
368
+ }
369
+ }
370
+
371
+ FORCE_INLINE_TEMPLATE
372
+ size_t ZSTD_compressBlock_fast_dictMatchState_generic(
373
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
374
+ void const* src, size_t srcSize, U32 const mls, U32 const hasStep)
375
+ {
376
+ const ZSTD_compressionParameters* const cParams = &ms->cParams;
377
+ U32* const hashTable = ms->hashTable;
378
+ U32 const hlog = cParams->hashLog;
379
+ /* support stepSize of 0 */
380
+ U32 const stepSize = cParams->targetLength + !(cParams->targetLength);
381
+ const BYTE* const base = ms->window.base;
382
+ const BYTE* const istart = (const BYTE*)src;
383
+ const BYTE* ip = istart;
384
+ const BYTE* anchor = istart;
385
+ const U32 prefixStartIndex = ms->window.dictLimit;
386
+ const BYTE* const prefixStart = base + prefixStartIndex;
387
+ const BYTE* const iend = istart + srcSize;
388
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
389
+ U32 offset_1=rep[0], offset_2=rep[1];
390
+ U32 offsetSaved = 0;
391
+
392
+ const ZSTD_matchState_t* const dms = ms->dictMatchState;
393
+ const ZSTD_compressionParameters* const dictCParams = &dms->cParams ;
394
+ const U32* const dictHashTable = dms->hashTable;
395
+ const U32 dictStartIndex = dms->window.dictLimit;
396
+ const BYTE* const dictBase = dms->window.base;
397
+ const BYTE* const dictStart = dictBase + dictStartIndex;
398
+ const BYTE* const dictEnd = dms->window.nextSrc;
399
+ const U32 dictIndexDelta = prefixStartIndex - (U32)(dictEnd - dictBase);
400
+ const U32 dictAndPrefixLength = (U32)(ip - prefixStart + dictEnd - dictStart);
401
+ const U32 dictHLog = dictCParams->hashLog;
402
+
403
+ /* if a dictionary is still attached, it necessarily means that
404
+ * it is within window size. So we just check it. */
405
+ const U32 maxDistance = 1U << cParams->windowLog;
406
+ const U32 endIndex = (U32)((size_t)(ip - base) + srcSize);
407
+ assert(endIndex - prefixStartIndex <= maxDistance);
408
+ (void)maxDistance; (void)endIndex; /* these variables are not used when assert() is disabled */
409
+
410
+ (void)hasStep; /* not currently specialized on whether it's accelerated */
411
+
412
+ /* ensure there will be no underflow
413
+ * when translating a dict index into a local index */
414
+ assert(prefixStartIndex >= (U32)(dictEnd - dictBase));
415
+
416
+ /* init */
417
+ DEBUGLOG(5, "ZSTD_compressBlock_fast_dictMatchState_generic");
418
+ ip += (dictAndPrefixLength == 0);
419
+ /* dictMatchState repCode checks don't currently handle repCode == 0
420
+ * disabling. */
421
+ assert(offset_1 <= dictAndPrefixLength);
422
+ assert(offset_2 <= dictAndPrefixLength);
423
+
424
+ /* Main Search Loop */
425
+ while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
426
+ size_t mLength;
427
+ size_t const h = ZSTD_hashPtr(ip, hlog, mls);
428
+ U32 const curr = (U32)(ip-base);
429
+ U32 const matchIndex = hashTable[h];
430
+ const BYTE* match = base + matchIndex;
431
+ const U32 repIndex = curr + 1 - offset_1;
432
+ const BYTE* repMatch = (repIndex < prefixStartIndex) ?
433
+ dictBase + (repIndex - dictIndexDelta) :
434
+ base + repIndex;
435
+ hashTable[h] = curr; /* update hash table */
436
+
437
+ if ( ((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex isn't overlapping dict + prefix */
438
+ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
439
+ const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
440
+ mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
441
+ ip++;
442
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_REPCODE_1, mLength);
443
+ } else if ( (matchIndex <= prefixStartIndex) ) {
444
+ size_t const dictHash = ZSTD_hashPtr(ip, dictHLog, mls);
445
+ U32 const dictMatchIndex = dictHashTable[dictHash];
446
+ const BYTE* dictMatch = dictBase + dictMatchIndex;
447
+ if (dictMatchIndex <= dictStartIndex ||
448
+ MEM_read32(dictMatch) != MEM_read32(ip)) {
449
+ assert(stepSize >= 1);
450
+ ip += ((ip-anchor) >> kSearchStrength) + stepSize;
451
+ continue;
452
+ } else {
453
+ /* found a dict match */
454
+ U32 const offset = (U32)(curr-dictMatchIndex-dictIndexDelta);
455
+ mLength = ZSTD_count_2segments(ip+4, dictMatch+4, iend, dictEnd, prefixStart) + 4;
456
+ while (((ip>anchor) & (dictMatch>dictStart))
457
+ && (ip[-1] == dictMatch[-1])) {
458
+ ip--; dictMatch--; mLength++;
459
+ } /* catch up */
460
+ offset_2 = offset_1;
461
+ offset_1 = offset;
462
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_OFFSET(offset), mLength);
463
+ }
464
+ } else if (MEM_read32(match) != MEM_read32(ip)) {
465
+ /* it's not a match, and we're not going to check the dictionary */
466
+ assert(stepSize >= 1);
467
+ ip += ((ip-anchor) >> kSearchStrength) + stepSize;
468
+ continue;
469
+ } else {
470
+ /* found a regular match */
471
+ U32 const offset = (U32)(ip-match);
472
+ mLength = ZSTD_count(ip+4, match+4, iend) + 4;
473
+ while (((ip>anchor) & (match>prefixStart))
474
+ && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
475
+ offset_2 = offset_1;
476
+ offset_1 = offset;
477
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_OFFSET(offset), mLength);
478
+ }
479
+
480
+ /* match found */
481
+ ip += mLength;
482
+ anchor = ip;
483
+
484
+ if (ip <= ilimit) {
485
+ /* Fill Table */
486
+ assert(base+curr+2 > istart); /* check base overflow */
487
+ hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2; /* here because curr+2 could be > iend-8 */
488
+ hashTable[ZSTD_hashPtr(ip-2, hlog, mls)] = (U32)(ip-2-base);
489
+
490
+ /* check immediate repcode */
491
+ while (ip <= ilimit) {
492
+ U32 const current2 = (U32)(ip-base);
493
+ U32 const repIndex2 = current2 - offset_2;
494
+ const BYTE* repMatch2 = repIndex2 < prefixStartIndex ?
495
+ dictBase - dictIndexDelta + repIndex2 :
496
+ base + repIndex2;
497
+ if ( ((U32)((prefixStartIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */)
498
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
499
+ const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
500
+ size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
501
+ U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
502
+ ZSTD_storeSeq(seqStore, 0, anchor, iend, STORE_REPCODE_1, repLength2);
503
+ hashTable[ZSTD_hashPtr(ip, hlog, mls)] = current2;
504
+ ip += repLength2;
505
+ anchor = ip;
506
+ continue;
507
+ }
508
+ break;
509
+ }
510
+ }
511
+ }
512
+
513
+ /* save reps for next block */
514
+ rep[0] = offset_1 ? offset_1 : offsetSaved;
515
+ rep[1] = offset_2 ? offset_2 : offsetSaved;
516
+
517
+ /* Return the last literals size */
518
+ return (size_t)(iend - anchor);
519
+ }
520
+
521
+
522
+ ZSTD_GEN_FAST_FN(dictMatchState, 4, 0)
523
+ ZSTD_GEN_FAST_FN(dictMatchState, 5, 0)
524
+ ZSTD_GEN_FAST_FN(dictMatchState, 6, 0)
525
+ ZSTD_GEN_FAST_FN(dictMatchState, 7, 0)
526
+
527
+ size_t ZSTD_compressBlock_fast_dictMatchState(
528
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
529
+ void const* src, size_t srcSize)
530
+ {
531
+ U32 const mls = ms->cParams.minMatch;
532
+ assert(ms->dictMatchState != NULL);
533
+ switch(mls)
534
+ {
535
+ default: /* includes case 3 */
536
+ case 4 :
537
+ return ZSTD_compressBlock_fast_dictMatchState_4_0(ms, seqStore, rep, src, srcSize);
538
+ case 5 :
539
+ return ZSTD_compressBlock_fast_dictMatchState_5_0(ms, seqStore, rep, src, srcSize);
540
+ case 6 :
541
+ return ZSTD_compressBlock_fast_dictMatchState_6_0(ms, seqStore, rep, src, srcSize);
542
+ case 7 :
543
+ return ZSTD_compressBlock_fast_dictMatchState_7_0(ms, seqStore, rep, src, srcSize);
544
+ }
545
+ }
546
+
547
+
548
+ static size_t ZSTD_compressBlock_fast_extDict_generic(
549
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
550
+ void const* src, size_t srcSize, U32 const mls, U32 const hasStep)
551
+ {
552
+ const ZSTD_compressionParameters* const cParams = &ms->cParams;
553
+ U32* const hashTable = ms->hashTable;
554
+ U32 const hlog = cParams->hashLog;
555
+ /* support stepSize of 0 */
556
+ U32 const stepSize = cParams->targetLength + !(cParams->targetLength);
557
+ const BYTE* const base = ms->window.base;
558
+ const BYTE* const dictBase = ms->window.dictBase;
559
+ const BYTE* const istart = (const BYTE*)src;
560
+ const BYTE* ip = istart;
561
+ const BYTE* anchor = istart;
562
+ const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
563
+ const U32 lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog);
564
+ const U32 dictStartIndex = lowLimit;
565
+ const BYTE* const dictStart = dictBase + dictStartIndex;
566
+ const U32 dictLimit = ms->window.dictLimit;
567
+ const U32 prefixStartIndex = dictLimit < lowLimit ? lowLimit : dictLimit;
568
+ const BYTE* const prefixStart = base + prefixStartIndex;
569
+ const BYTE* const dictEnd = dictBase + prefixStartIndex;
570
+ const BYTE* const iend = istart + srcSize;
571
+ const BYTE* const ilimit = iend - 8;
572
+ U32 offset_1=rep[0], offset_2=rep[1];
573
+
574
+ (void)hasStep; /* not currently specialized on whether it's accelerated */
575
+
576
+ DEBUGLOG(5, "ZSTD_compressBlock_fast_extDict_generic (offset_1=%u)", offset_1);
577
+
578
+ /* switch to "regular" variant if extDict is invalidated due to maxDistance */
579
+ if (prefixStartIndex == dictStartIndex)
580
+ return ZSTD_compressBlock_fast(ms, seqStore, rep, src, srcSize);
581
+
582
+ /* Search Loop */
583
+ while (ip < ilimit) { /* < instead of <=, because (ip+1) */
584
+ const size_t h = ZSTD_hashPtr(ip, hlog, mls);
585
+ const U32 matchIndex = hashTable[h];
586
+ const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base;
587
+ const BYTE* match = matchBase + matchIndex;
588
+ const U32 curr = (U32)(ip-base);
589
+ const U32 repIndex = curr + 1 - offset_1;
590
+ const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;
591
+ const BYTE* const repMatch = repBase + repIndex;
592
+ hashTable[h] = curr; /* update hash table */
593
+ DEBUGLOG(7, "offset_1 = %u , curr = %u", offset_1, curr);
594
+
595
+ if ( ( ((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */
596
+ & (offset_1 <= curr+1 - dictStartIndex) ) /* note: we are searching at curr+1 */
597
+ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
598
+ const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
599
+ size_t const rLength = ZSTD_count_2segments(ip+1 +4, repMatch +4, iend, repMatchEnd, prefixStart) + 4;
600
+ ip++;
601
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_REPCODE_1, rLength);
602
+ ip += rLength;
603
+ anchor = ip;
604
+ } else {
605
+ if ( (matchIndex < dictStartIndex) ||
606
+ (MEM_read32(match) != MEM_read32(ip)) ) {
607
+ assert(stepSize >= 1);
608
+ ip += ((ip-anchor) >> kSearchStrength) + stepSize;
609
+ continue;
610
+ }
611
+ { const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;
612
+ const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;
613
+ U32 const offset = curr - matchIndex;
614
+ size_t mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;
615
+ while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
616
+ offset_2 = offset_1; offset_1 = offset; /* update offset history */
617
+ ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, STORE_OFFSET(offset), mLength);
618
+ ip += mLength;
619
+ anchor = ip;
620
+ } }
621
+
622
+ if (ip <= ilimit) {
623
+ /* Fill Table */
624
+ hashTable[ZSTD_hashPtr(base+curr+2, hlog, mls)] = curr+2;
625
+ hashTable[ZSTD_hashPtr(ip-2, hlog, mls)] = (U32)(ip-2-base);
626
+ /* check immediate repcode */
627
+ while (ip <= ilimit) {
628
+ U32 const current2 = (U32)(ip-base);
629
+ U32 const repIndex2 = current2 - offset_2;
630
+ const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
631
+ if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) & (offset_2 <= curr - dictStartIndex)) /* intentional overflow */
632
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
633
+ const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
634
+ size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
635
+ { U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; } /* swap offset_2 <=> offset_1 */
636
+ ZSTD_storeSeq(seqStore, 0 /*litlen*/, anchor, iend, STORE_REPCODE_1, repLength2);
637
+ hashTable[ZSTD_hashPtr(ip, hlog, mls)] = current2;
638
+ ip += repLength2;
639
+ anchor = ip;
640
+ continue;
641
+ }
642
+ break;
643
+ } } }
644
+
645
+ /* save reps for next block */
646
+ rep[0] = offset_1;
647
+ rep[1] = offset_2;
648
+
649
+ /* Return the last literals size */
650
+ return (size_t)(iend - anchor);
651
+ }
652
+
653
+ ZSTD_GEN_FAST_FN(extDict, 4, 0)
654
+ ZSTD_GEN_FAST_FN(extDict, 5, 0)
655
+ ZSTD_GEN_FAST_FN(extDict, 6, 0)
656
+ ZSTD_GEN_FAST_FN(extDict, 7, 0)
657
+
658
+ size_t ZSTD_compressBlock_fast_extDict(
659
+ ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
660
+ void const* src, size_t srcSize)
661
+ {
662
+ U32 const mls = ms->cParams.minMatch;
663
+ switch(mls)
664
+ {
665
+ default: /* includes case 3 */
666
+ case 4 :
667
+ return ZSTD_compressBlock_fast_extDict_4_0(ms, seqStore, rep, src, srcSize);
668
+ case 5 :
669
+ return ZSTD_compressBlock_fast_extDict_5_0(ms, seqStore, rep, src, srcSize);
670
+ case 6 :
671
+ return ZSTD_compressBlock_fast_extDict_6_0(ms, seqStore, rep, src, srcSize);
672
+ case 7 :
673
+ return ZSTD_compressBlock_fast_extDict_7_0(ms, seqStore, rep, src, srcSize);
674
+ }
675
+ }