extzstd 0.3.2 → 0.4
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.
- checksums.yaml +4 -4
- data/README.md +4 -3
- data/contrib/zstd/CHANGELOG +225 -1
- data/contrib/zstd/CONTRIBUTING.md +158 -75
- data/contrib/zstd/LICENSE +4 -4
- data/contrib/zstd/Makefile +106 -69
- data/contrib/zstd/Package.swift +36 -0
- data/contrib/zstd/README.md +64 -36
- data/contrib/zstd/SECURITY.md +15 -0
- data/contrib/zstd/TESTING.md +2 -3
- data/contrib/zstd/lib/BUCK +5 -7
- data/contrib/zstd/lib/Makefile +117 -199
- data/contrib/zstd/lib/README.md +37 -7
- data/contrib/zstd/lib/common/allocations.h +55 -0
- data/contrib/zstd/lib/common/bits.h +200 -0
- data/contrib/zstd/lib/common/bitstream.h +80 -86
- data/contrib/zstd/lib/common/compiler.h +225 -63
- data/contrib/zstd/lib/common/cpu.h +37 -1
- data/contrib/zstd/lib/common/debug.c +7 -1
- data/contrib/zstd/lib/common/debug.h +21 -12
- data/contrib/zstd/lib/common/entropy_common.c +15 -37
- data/contrib/zstd/lib/common/error_private.c +9 -2
- data/contrib/zstd/lib/common/error_private.h +93 -5
- data/contrib/zstd/lib/common/fse.h +12 -87
- data/contrib/zstd/lib/common/fse_decompress.c +37 -117
- data/contrib/zstd/lib/common/huf.h +97 -172
- data/contrib/zstd/lib/common/mem.h +58 -58
- data/contrib/zstd/lib/common/pool.c +38 -17
- data/contrib/zstd/lib/common/pool.h +10 -4
- data/contrib/zstd/lib/common/portability_macros.h +158 -0
- data/contrib/zstd/lib/common/threading.c +74 -14
- data/contrib/zstd/lib/common/threading.h +5 -10
- data/contrib/zstd/lib/common/xxhash.c +6 -814
- data/contrib/zstd/lib/common/xxhash.h +6930 -195
- data/contrib/zstd/lib/common/zstd_common.c +1 -36
- data/contrib/zstd/lib/common/zstd_deps.h +1 -1
- data/contrib/zstd/lib/common/zstd_internal.h +68 -154
- data/contrib/zstd/lib/common/zstd_trace.h +163 -0
- data/contrib/zstd/lib/compress/clevels.h +134 -0
- data/contrib/zstd/lib/compress/fse_compress.c +75 -155
- data/contrib/zstd/lib/compress/hist.c +1 -1
- data/contrib/zstd/lib/compress/hist.h +1 -1
- data/contrib/zstd/lib/compress/huf_compress.c +810 -259
- data/contrib/zstd/lib/compress/zstd_compress.c +2864 -919
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +523 -192
- data/contrib/zstd/lib/compress/zstd_compress_literals.c +117 -40
- data/contrib/zstd/lib/compress/zstd_compress_literals.h +16 -6
- data/contrib/zstd/lib/compress/zstd_compress_sequences.c +28 -19
- data/contrib/zstd/lib/compress/zstd_compress_sequences.h +1 -1
- data/contrib/zstd/lib/compress/zstd_compress_superblock.c +251 -412
- data/contrib/zstd/lib/compress/zstd_compress_superblock.h +1 -1
- data/contrib/zstd/lib/compress/zstd_cwksp.h +284 -97
- data/contrib/zstd/lib/compress/zstd_double_fast.c +382 -133
- data/contrib/zstd/lib/compress/zstd_double_fast.h +14 -2
- data/contrib/zstd/lib/compress/zstd_fast.c +732 -260
- data/contrib/zstd/lib/compress/zstd_fast.h +3 -2
- data/contrib/zstd/lib/compress/zstd_lazy.c +1177 -390
- data/contrib/zstd/lib/compress/zstd_lazy.h +129 -14
- data/contrib/zstd/lib/compress/zstd_ldm.c +280 -210
- data/contrib/zstd/lib/compress/zstd_ldm.h +3 -2
- data/contrib/zstd/lib/compress/zstd_ldm_geartab.h +106 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +516 -285
- data/contrib/zstd/lib/compress/zstd_opt.h +32 -8
- data/contrib/zstd/lib/compress/zstdmt_compress.c +202 -131
- data/contrib/zstd/lib/compress/zstdmt_compress.h +9 -6
- data/contrib/zstd/lib/decompress/huf_decompress.c +1149 -555
- data/contrib/zstd/lib/decompress/huf_decompress_amd64.S +595 -0
- data/contrib/zstd/lib/decompress/zstd_ddict.c +4 -4
- data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
- data/contrib/zstd/lib/decompress/zstd_decompress.c +583 -106
- data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1054 -379
- data/contrib/zstd/lib/decompress/zstd_decompress_block.h +14 -3
- data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +56 -6
- data/contrib/zstd/lib/deprecated/zbuff.h +1 -1
- data/contrib/zstd/lib/deprecated/zbuff_common.c +1 -1
- data/contrib/zstd/lib/deprecated/zbuff_compress.c +24 -4
- data/contrib/zstd/lib/deprecated/zbuff_decompress.c +3 -1
- data/contrib/zstd/lib/dictBuilder/cover.c +60 -44
- data/contrib/zstd/lib/dictBuilder/cover.h +6 -11
- data/contrib/zstd/lib/dictBuilder/divsufsort.c +1 -1
- data/contrib/zstd/lib/dictBuilder/fastcover.c +26 -18
- data/contrib/zstd/lib/dictBuilder/zdict.c +100 -101
- data/contrib/zstd/lib/legacy/zstd_legacy.h +38 -1
- data/contrib/zstd/lib/legacy/zstd_v01.c +18 -53
- data/contrib/zstd/lib/legacy/zstd_v01.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v02.c +28 -85
- data/contrib/zstd/lib/legacy/zstd_v02.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v03.c +29 -88
- data/contrib/zstd/lib/legacy/zstd_v03.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v04.c +27 -80
- data/contrib/zstd/lib/legacy/zstd_v04.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v05.c +36 -85
- data/contrib/zstd/lib/legacy/zstd_v05.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v06.c +44 -96
- data/contrib/zstd/lib/legacy/zstd_v06.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v07.c +37 -92
- data/contrib/zstd/lib/legacy/zstd_v07.h +1 -1
- data/contrib/zstd/lib/libzstd.mk +237 -0
- data/contrib/zstd/lib/libzstd.pc.in +4 -3
- data/contrib/zstd/lib/module.modulemap +35 -0
- data/contrib/zstd/lib/{dictBuilder/zdict.h → zdict.h} +202 -33
- data/contrib/zstd/lib/zstd.h +1030 -332
- data/contrib/zstd/lib/{common/zstd_errors.h → zstd_errors.h} +27 -8
- data/ext/extconf.rb +26 -7
- data/ext/extzstd.c +51 -24
- data/ext/extzstd.h +33 -6
- data/ext/extzstd_stream.c +74 -31
- data/ext/libzstd_conf.h +0 -1
- data/ext/zstd_decompress_asm.S +1 -0
- metadata +17 -7
- data/contrib/zstd/appveyor.yml +0 -292
- data/ext/depend +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -11,8 +11,49 @@
|
|
|
11
11
|
#include "zstd_compress_internal.h"
|
|
12
12
|
#include "zstd_double_fast.h"
|
|
13
13
|
|
|
14
|
+
#ifndef ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
static
|
|
17
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
18
|
+
void ZSTD_fillDoubleHashTableForCDict(ZSTD_matchState_t* ms,
|
|
19
|
+
void const* end, ZSTD_dictTableLoadMethod_e dtlm)
|
|
20
|
+
{
|
|
21
|
+
const ZSTD_compressionParameters* const cParams = &ms->cParams;
|
|
22
|
+
U32* const hashLarge = ms->hashTable;
|
|
23
|
+
U32 const hBitsL = cParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS;
|
|
24
|
+
U32 const mls = cParams->minMatch;
|
|
25
|
+
U32* const hashSmall = ms->chainTable;
|
|
26
|
+
U32 const hBitsS = cParams->chainLog + ZSTD_SHORT_CACHE_TAG_BITS;
|
|
27
|
+
const BYTE* const base = ms->window.base;
|
|
28
|
+
const BYTE* ip = base + ms->nextToUpdate;
|
|
29
|
+
const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
|
|
30
|
+
const U32 fastHashFillStep = 3;
|
|
31
|
+
|
|
32
|
+
/* Always insert every fastHashFillStep position into the hash tables.
|
|
33
|
+
* Insert the other positions into the large hash table if their entry
|
|
34
|
+
* is empty.
|
|
35
|
+
*/
|
|
36
|
+
for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) {
|
|
37
|
+
U32 const curr = (U32)(ip - base);
|
|
38
|
+
U32 i;
|
|
39
|
+
for (i = 0; i < fastHashFillStep; ++i) {
|
|
40
|
+
size_t const smHashAndTag = ZSTD_hashPtr(ip + i, hBitsS, mls);
|
|
41
|
+
size_t const lgHashAndTag = ZSTD_hashPtr(ip + i, hBitsL, 8);
|
|
42
|
+
if (i == 0) {
|
|
43
|
+
ZSTD_writeTaggedIndex(hashSmall, smHashAndTag, curr + i);
|
|
44
|
+
}
|
|
45
|
+
if (i == 0 || hashLarge[lgHashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS] == 0) {
|
|
46
|
+
ZSTD_writeTaggedIndex(hashLarge, lgHashAndTag, curr + i);
|
|
47
|
+
}
|
|
48
|
+
/* Only load extra positions for ZSTD_dtlm_full */
|
|
49
|
+
if (dtlm == ZSTD_dtlm_fast)
|
|
50
|
+
break;
|
|
51
|
+
} }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static
|
|
55
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
56
|
+
void ZSTD_fillDoubleHashTableForCCtx(ZSTD_matchState_t* ms,
|
|
16
57
|
void const* end, ZSTD_dictTableLoadMethod_e dtlm)
|
|
17
58
|
{
|
|
18
59
|
const ZSTD_compressionParameters* const cParams = &ms->cParams;
|
|
@@ -43,15 +84,239 @@ void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms,
|
|
|
43
84
|
/* Only load extra positions for ZSTD_dtlm_full */
|
|
44
85
|
if (dtlm == ZSTD_dtlm_fast)
|
|
45
86
|
break;
|
|
46
|
-
|
|
87
|
+
} }
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
void ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms,
|
|
91
|
+
const void* const end,
|
|
92
|
+
ZSTD_dictTableLoadMethod_e dtlm,
|
|
93
|
+
ZSTD_tableFillPurpose_e tfp)
|
|
94
|
+
{
|
|
95
|
+
if (tfp == ZSTD_tfp_forCDict) {
|
|
96
|
+
ZSTD_fillDoubleHashTableForCDict(ms, end, dtlm);
|
|
97
|
+
} else {
|
|
98
|
+
ZSTD_fillDoubleHashTableForCCtx(ms, end, dtlm);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
FORCE_INLINE_TEMPLATE
|
|
104
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
105
|
+
size_t ZSTD_compressBlock_doubleFast_noDict_generic(
|
|
106
|
+
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
|
107
|
+
void const* src, size_t srcSize, U32 const mls /* template */)
|
|
108
|
+
{
|
|
109
|
+
ZSTD_compressionParameters const* cParams = &ms->cParams;
|
|
110
|
+
U32* const hashLong = ms->hashTable;
|
|
111
|
+
const U32 hBitsL = cParams->hashLog;
|
|
112
|
+
U32* const hashSmall = ms->chainTable;
|
|
113
|
+
const U32 hBitsS = cParams->chainLog;
|
|
114
|
+
const BYTE* const base = ms->window.base;
|
|
115
|
+
const BYTE* const istart = (const BYTE*)src;
|
|
116
|
+
const BYTE* anchor = istart;
|
|
117
|
+
const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);
|
|
118
|
+
/* presumes that, if there is a dictionary, it must be using Attach mode */
|
|
119
|
+
const U32 prefixLowestIndex = ZSTD_getLowestPrefixIndex(ms, endIndex, cParams->windowLog);
|
|
120
|
+
const BYTE* const prefixLowest = base + prefixLowestIndex;
|
|
121
|
+
const BYTE* const iend = istart + srcSize;
|
|
122
|
+
const BYTE* const ilimit = iend - HASH_READ_SIZE;
|
|
123
|
+
U32 offset_1=rep[0], offset_2=rep[1];
|
|
124
|
+
U32 offsetSaved1 = 0, offsetSaved2 = 0;
|
|
125
|
+
|
|
126
|
+
size_t mLength;
|
|
127
|
+
U32 offset;
|
|
128
|
+
U32 curr;
|
|
129
|
+
|
|
130
|
+
/* how many positions to search before increasing step size */
|
|
131
|
+
const size_t kStepIncr = 1 << kSearchStrength;
|
|
132
|
+
/* the position at which to increment the step size if no match is found */
|
|
133
|
+
const BYTE* nextStep;
|
|
134
|
+
size_t step; /* the current step size */
|
|
135
|
+
|
|
136
|
+
size_t hl0; /* the long hash at ip */
|
|
137
|
+
size_t hl1; /* the long hash at ip1 */
|
|
138
|
+
|
|
139
|
+
U32 idxl0; /* the long match index for ip */
|
|
140
|
+
U32 idxl1; /* the long match index for ip1 */
|
|
141
|
+
|
|
142
|
+
const BYTE* matchl0; /* the long match for ip */
|
|
143
|
+
const BYTE* matchs0; /* the short match for ip */
|
|
144
|
+
const BYTE* matchl1; /* the long match for ip1 */
|
|
145
|
+
|
|
146
|
+
const BYTE* ip = istart; /* the current position */
|
|
147
|
+
const BYTE* ip1; /* the next position */
|
|
148
|
+
|
|
149
|
+
DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_noDict_generic");
|
|
150
|
+
|
|
151
|
+
/* init */
|
|
152
|
+
ip += ((ip - prefixLowest) == 0);
|
|
153
|
+
{
|
|
154
|
+
U32 const current = (U32)(ip - base);
|
|
155
|
+
U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, current, cParams->windowLog);
|
|
156
|
+
U32 const maxRep = current - windowLow;
|
|
157
|
+
if (offset_2 > maxRep) offsetSaved2 = offset_2, offset_2 = 0;
|
|
158
|
+
if (offset_1 > maxRep) offsetSaved1 = offset_1, offset_1 = 0;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Outer Loop: one iteration per match found and stored */
|
|
162
|
+
while (1) {
|
|
163
|
+
step = 1;
|
|
164
|
+
nextStep = ip + kStepIncr;
|
|
165
|
+
ip1 = ip + step;
|
|
166
|
+
|
|
167
|
+
if (ip1 > ilimit) {
|
|
168
|
+
goto _cleanup;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
hl0 = ZSTD_hashPtr(ip, hBitsL, 8);
|
|
172
|
+
idxl0 = hashLong[hl0];
|
|
173
|
+
matchl0 = base + idxl0;
|
|
174
|
+
|
|
175
|
+
/* Inner Loop: one iteration per search / position */
|
|
176
|
+
do {
|
|
177
|
+
const size_t hs0 = ZSTD_hashPtr(ip, hBitsS, mls);
|
|
178
|
+
const U32 idxs0 = hashSmall[hs0];
|
|
179
|
+
curr = (U32)(ip-base);
|
|
180
|
+
matchs0 = base + idxs0;
|
|
181
|
+
|
|
182
|
+
hashLong[hl0] = hashSmall[hs0] = curr; /* update hash tables */
|
|
183
|
+
|
|
184
|
+
/* check noDict repcode */
|
|
185
|
+
if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
|
|
186
|
+
mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
|
|
187
|
+
ip++;
|
|
188
|
+
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength);
|
|
189
|
+
goto _match_stored;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
hl1 = ZSTD_hashPtr(ip1, hBitsL, 8);
|
|
193
|
+
|
|
194
|
+
if (idxl0 > prefixLowestIndex) {
|
|
195
|
+
/* check prefix long match */
|
|
196
|
+
if (MEM_read64(matchl0) == MEM_read64(ip)) {
|
|
197
|
+
mLength = ZSTD_count(ip+8, matchl0+8, iend) + 8;
|
|
198
|
+
offset = (U32)(ip-matchl0);
|
|
199
|
+
while (((ip>anchor) & (matchl0>prefixLowest)) && (ip[-1] == matchl0[-1])) { ip--; matchl0--; mLength++; } /* catch up */
|
|
200
|
+
goto _match_found;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
idxl1 = hashLong[hl1];
|
|
205
|
+
matchl1 = base + idxl1;
|
|
206
|
+
|
|
207
|
+
if (idxs0 > prefixLowestIndex) {
|
|
208
|
+
/* check prefix short match */
|
|
209
|
+
if (MEM_read32(matchs0) == MEM_read32(ip)) {
|
|
210
|
+
goto _search_next_long;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (ip1 >= nextStep) {
|
|
215
|
+
PREFETCH_L1(ip1 + 64);
|
|
216
|
+
PREFETCH_L1(ip1 + 128);
|
|
217
|
+
step++;
|
|
218
|
+
nextStep += kStepIncr;
|
|
219
|
+
}
|
|
220
|
+
ip = ip1;
|
|
221
|
+
ip1 += step;
|
|
222
|
+
|
|
223
|
+
hl0 = hl1;
|
|
224
|
+
idxl0 = idxl1;
|
|
225
|
+
matchl0 = matchl1;
|
|
226
|
+
#if defined(__aarch64__)
|
|
227
|
+
PREFETCH_L1(ip+256);
|
|
228
|
+
#endif
|
|
229
|
+
} while (ip1 <= ilimit);
|
|
230
|
+
|
|
231
|
+
_cleanup:
|
|
232
|
+
/* If offset_1 started invalid (offsetSaved1 != 0) and became valid (offset_1 != 0),
|
|
233
|
+
* rotate saved offsets. See comment in ZSTD_compressBlock_fast_noDict for more context. */
|
|
234
|
+
offsetSaved2 = ((offsetSaved1 != 0) && (offset_1 != 0)) ? offsetSaved1 : offsetSaved2;
|
|
235
|
+
|
|
236
|
+
/* save reps for next block */
|
|
237
|
+
rep[0] = offset_1 ? offset_1 : offsetSaved1;
|
|
238
|
+
rep[1] = offset_2 ? offset_2 : offsetSaved2;
|
|
239
|
+
|
|
240
|
+
/* Return the last literals size */
|
|
241
|
+
return (size_t)(iend - anchor);
|
|
242
|
+
|
|
243
|
+
_search_next_long:
|
|
244
|
+
|
|
245
|
+
/* check prefix long +1 match */
|
|
246
|
+
if (idxl1 > prefixLowestIndex) {
|
|
247
|
+
if (MEM_read64(matchl1) == MEM_read64(ip1)) {
|
|
248
|
+
ip = ip1;
|
|
249
|
+
mLength = ZSTD_count(ip+8, matchl1+8, iend) + 8;
|
|
250
|
+
offset = (U32)(ip-matchl1);
|
|
251
|
+
while (((ip>anchor) & (matchl1>prefixLowest)) && (ip[-1] == matchl1[-1])) { ip--; matchl1--; mLength++; } /* catch up */
|
|
252
|
+
goto _match_found;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* if no long +1 match, explore the short match we found */
|
|
257
|
+
mLength = ZSTD_count(ip+4, matchs0+4, iend) + 4;
|
|
258
|
+
offset = (U32)(ip - matchs0);
|
|
259
|
+
while (((ip>anchor) & (matchs0>prefixLowest)) && (ip[-1] == matchs0[-1])) { ip--; matchs0--; mLength++; } /* catch up */
|
|
260
|
+
|
|
261
|
+
/* fall-through */
|
|
262
|
+
|
|
263
|
+
_match_found: /* requires ip, offset, mLength */
|
|
264
|
+
offset_2 = offset_1;
|
|
265
|
+
offset_1 = offset;
|
|
266
|
+
|
|
267
|
+
if (step < 4) {
|
|
268
|
+
/* It is unsafe to write this value back to the hashtable when ip1 is
|
|
269
|
+
* greater than or equal to the new ip we will have after we're done
|
|
270
|
+
* processing this match. Rather than perform that test directly
|
|
271
|
+
* (ip1 >= ip + mLength), which costs speed in practice, we do a simpler
|
|
272
|
+
* more predictable test. The minmatch even if we take a short match is
|
|
273
|
+
* 4 bytes, so as long as step, the distance between ip and ip1
|
|
274
|
+
* (initially) is less than 4, we know ip1 < new ip. */
|
|
275
|
+
hashLong[hl1] = (U32)(ip1 - base);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength);
|
|
279
|
+
|
|
280
|
+
_match_stored:
|
|
281
|
+
/* match found */
|
|
282
|
+
ip += mLength;
|
|
283
|
+
anchor = ip;
|
|
284
|
+
|
|
285
|
+
if (ip <= ilimit) {
|
|
286
|
+
/* Complementary insertion */
|
|
287
|
+
/* done after iLimit test, as candidates could be > iend-8 */
|
|
288
|
+
{ U32 const indexToInsert = curr+2;
|
|
289
|
+
hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;
|
|
290
|
+
hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
|
|
291
|
+
hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;
|
|
292
|
+
hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* check immediate repcode */
|
|
296
|
+
while ( (ip <= ilimit)
|
|
297
|
+
&& ( (offset_2>0)
|
|
298
|
+
& (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
|
|
299
|
+
/* store sequence */
|
|
300
|
+
size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
|
|
301
|
+
U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */
|
|
302
|
+
hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
|
|
303
|
+
hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
|
|
304
|
+
ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, rLength);
|
|
305
|
+
ip += rLength;
|
|
306
|
+
anchor = ip;
|
|
307
|
+
continue; /* faster when present ... (?) */
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
47
311
|
}
|
|
48
312
|
|
|
49
313
|
|
|
50
314
|
FORCE_INLINE_TEMPLATE
|
|
51
|
-
|
|
315
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
316
|
+
size_t ZSTD_compressBlock_doubleFast_dictMatchState_generic(
|
|
52
317
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
|
53
318
|
void const* src, size_t srcSize,
|
|
54
|
-
U32 const mls /* template
|
|
319
|
+
U32 const mls /* template */)
|
|
55
320
|
{
|
|
56
321
|
ZSTD_compressionParameters const* cParams = &ms->cParams;
|
|
57
322
|
U32* const hashLong = ms->hashTable;
|
|
@@ -69,57 +334,39 @@ size_t ZSTD_compressBlock_doubleFast_generic(
|
|
|
69
334
|
const BYTE* const iend = istart + srcSize;
|
|
70
335
|
const BYTE* const ilimit = iend - HASH_READ_SIZE;
|
|
71
336
|
U32 offset_1=rep[0], offset_2=rep[1];
|
|
72
|
-
U32 offsetSaved = 0;
|
|
73
337
|
|
|
74
338
|
const ZSTD_matchState_t* const dms = ms->dictMatchState;
|
|
75
|
-
const ZSTD_compressionParameters* const dictCParams =
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const U32
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
const U32
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
dms->window.base : NULL;
|
|
86
|
-
const BYTE* const dictStart = dictMode == ZSTD_dictMatchState ?
|
|
87
|
-
dictBase + dictStartIndex : NULL;
|
|
88
|
-
const BYTE* const dictEnd = dictMode == ZSTD_dictMatchState ?
|
|
89
|
-
dms->window.nextSrc : NULL;
|
|
90
|
-
const U32 dictIndexDelta = dictMode == ZSTD_dictMatchState ?
|
|
91
|
-
prefixLowestIndex - (U32)(dictEnd - dictBase) :
|
|
92
|
-
0;
|
|
93
|
-
const U32 dictHBitsL = dictMode == ZSTD_dictMatchState ?
|
|
94
|
-
dictCParams->hashLog : hBitsL;
|
|
95
|
-
const U32 dictHBitsS = dictMode == ZSTD_dictMatchState ?
|
|
96
|
-
dictCParams->chainLog : hBitsS;
|
|
339
|
+
const ZSTD_compressionParameters* const dictCParams = &dms->cParams;
|
|
340
|
+
const U32* const dictHashLong = dms->hashTable;
|
|
341
|
+
const U32* const dictHashSmall = dms->chainTable;
|
|
342
|
+
const U32 dictStartIndex = dms->window.dictLimit;
|
|
343
|
+
const BYTE* const dictBase = dms->window.base;
|
|
344
|
+
const BYTE* const dictStart = dictBase + dictStartIndex;
|
|
345
|
+
const BYTE* const dictEnd = dms->window.nextSrc;
|
|
346
|
+
const U32 dictIndexDelta = prefixLowestIndex - (U32)(dictEnd - dictBase);
|
|
347
|
+
const U32 dictHBitsL = dictCParams->hashLog + ZSTD_SHORT_CACHE_TAG_BITS;
|
|
348
|
+
const U32 dictHBitsS = dictCParams->chainLog + ZSTD_SHORT_CACHE_TAG_BITS;
|
|
97
349
|
const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictStart));
|
|
98
350
|
|
|
99
|
-
DEBUGLOG(5, "
|
|
100
|
-
|
|
101
|
-
assert(dictMode == ZSTD_noDict || dictMode == ZSTD_dictMatchState);
|
|
351
|
+
DEBUGLOG(5, "ZSTD_compressBlock_doubleFast_dictMatchState_generic");
|
|
102
352
|
|
|
103
353
|
/* if a dictionary is attached, it must be within window range */
|
|
104
|
-
|
|
105
|
-
|
|
354
|
+
assert(ms->window.dictLimit + (1U << cParams->windowLog) >= endIndex);
|
|
355
|
+
|
|
356
|
+
if (ms->prefetchCDictTables) {
|
|
357
|
+
size_t const hashTableBytes = (((size_t)1) << dictCParams->hashLog) * sizeof(U32);
|
|
358
|
+
size_t const chainTableBytes = (((size_t)1) << dictCParams->chainLog) * sizeof(U32);
|
|
359
|
+
PREFETCH_AREA(dictHashLong, hashTableBytes);
|
|
360
|
+
PREFETCH_AREA(dictHashSmall, chainTableBytes);
|
|
106
361
|
}
|
|
107
362
|
|
|
108
363
|
/* init */
|
|
109
364
|
ip += (dictAndPrefixLength == 0);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
|
|
116
|
-
}
|
|
117
|
-
if (dictMode == ZSTD_dictMatchState) {
|
|
118
|
-
/* dictMatchState repCode checks don't currently handle repCode == 0
|
|
119
|
-
* disabling. */
|
|
120
|
-
assert(offset_1 <= dictAndPrefixLength);
|
|
121
|
-
assert(offset_2 <= dictAndPrefixLength);
|
|
122
|
-
}
|
|
365
|
+
|
|
366
|
+
/* dictMatchState repCode checks don't currently handle repCode == 0
|
|
367
|
+
* disabling. */
|
|
368
|
+
assert(offset_1 <= dictAndPrefixLength);
|
|
369
|
+
assert(offset_2 <= dictAndPrefixLength);
|
|
123
370
|
|
|
124
371
|
/* Main Search Loop */
|
|
125
372
|
while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
|
|
@@ -127,37 +374,30 @@ size_t ZSTD_compressBlock_doubleFast_generic(
|
|
|
127
374
|
U32 offset;
|
|
128
375
|
size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
|
|
129
376
|
size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
|
|
130
|
-
size_t const
|
|
131
|
-
size_t const
|
|
377
|
+
size_t const dictHashAndTagL = ZSTD_hashPtr(ip, dictHBitsL, 8);
|
|
378
|
+
size_t const dictHashAndTagS = ZSTD_hashPtr(ip, dictHBitsS, mls);
|
|
379
|
+
U32 const dictMatchIndexAndTagL = dictHashLong[dictHashAndTagL >> ZSTD_SHORT_CACHE_TAG_BITS];
|
|
380
|
+
U32 const dictMatchIndexAndTagS = dictHashSmall[dictHashAndTagS >> ZSTD_SHORT_CACHE_TAG_BITS];
|
|
381
|
+
int const dictTagsMatchL = ZSTD_comparePackedTags(dictMatchIndexAndTagL, dictHashAndTagL);
|
|
382
|
+
int const dictTagsMatchS = ZSTD_comparePackedTags(dictMatchIndexAndTagS, dictHashAndTagS);
|
|
132
383
|
U32 const curr = (U32)(ip-base);
|
|
133
384
|
U32 const matchIndexL = hashLong[h2];
|
|
134
385
|
U32 matchIndexS = hashSmall[h];
|
|
135
386
|
const BYTE* matchLong = base + matchIndexL;
|
|
136
387
|
const BYTE* match = base + matchIndexS;
|
|
137
388
|
const U32 repIndex = curr + 1 - offset_1;
|
|
138
|
-
const BYTE* repMatch = (
|
|
139
|
-
&& repIndex < prefixLowestIndex) ?
|
|
389
|
+
const BYTE* repMatch = (repIndex < prefixLowestIndex) ?
|
|
140
390
|
dictBase + (repIndex - dictIndexDelta) :
|
|
141
391
|
base + repIndex;
|
|
142
392
|
hashLong[h2] = hashSmall[h] = curr; /* update hash tables */
|
|
143
393
|
|
|
144
|
-
/* check
|
|
145
|
-
if (
|
|
146
|
-
&& ((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
|
|
394
|
+
/* check repcode */
|
|
395
|
+
if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)
|
|
147
396
|
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
|
|
148
397
|
const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;
|
|
149
398
|
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;
|
|
150
399
|
ip++;
|
|
151
|
-
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend,
|
|
152
|
-
goto _match_stored;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/* check noDict repcode */
|
|
156
|
-
if ( dictMode == ZSTD_noDict
|
|
157
|
-
&& ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {
|
|
158
|
-
mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
|
|
159
|
-
ip++;
|
|
160
|
-
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);
|
|
400
|
+
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength);
|
|
161
401
|
goto _match_stored;
|
|
162
402
|
}
|
|
163
403
|
|
|
@@ -169,9 +409,9 @@ size_t ZSTD_compressBlock_doubleFast_generic(
|
|
|
169
409
|
while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
|
|
170
410
|
goto _match_found;
|
|
171
411
|
}
|
|
172
|
-
} else if (
|
|
412
|
+
} else if (dictTagsMatchL) {
|
|
173
413
|
/* check dictMatchState long match */
|
|
174
|
-
U32 const dictMatchIndexL =
|
|
414
|
+
U32 const dictMatchIndexL = dictMatchIndexAndTagL >> ZSTD_SHORT_CACHE_TAG_BITS;
|
|
175
415
|
const BYTE* dictMatchL = dictBase + dictMatchIndexL;
|
|
176
416
|
assert(dictMatchL < dictEnd);
|
|
177
417
|
|
|
@@ -187,9 +427,9 @@ size_t ZSTD_compressBlock_doubleFast_generic(
|
|
|
187
427
|
if (MEM_read32(match) == MEM_read32(ip)) {
|
|
188
428
|
goto _search_next_long;
|
|
189
429
|
}
|
|
190
|
-
} else if (
|
|
430
|
+
} else if (dictTagsMatchS) {
|
|
191
431
|
/* check dictMatchState short match */
|
|
192
|
-
U32 const dictMatchIndexS =
|
|
432
|
+
U32 const dictMatchIndexS = dictMatchIndexAndTagS >> ZSTD_SHORT_CACHE_TAG_BITS;
|
|
193
433
|
match = dictBase + dictMatchIndexS;
|
|
194
434
|
matchIndexS = dictMatchIndexS + dictIndexDelta;
|
|
195
435
|
|
|
@@ -204,10 +444,11 @@ size_t ZSTD_compressBlock_doubleFast_generic(
|
|
|
204
444
|
continue;
|
|
205
445
|
|
|
206
446
|
_search_next_long:
|
|
207
|
-
|
|
208
447
|
{ size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
|
|
209
|
-
size_t const
|
|
448
|
+
size_t const dictHashAndTagL3 = ZSTD_hashPtr(ip+1, dictHBitsL, 8);
|
|
210
449
|
U32 const matchIndexL3 = hashLong[hl3];
|
|
450
|
+
U32 const dictMatchIndexAndTagL3 = dictHashLong[dictHashAndTagL3 >> ZSTD_SHORT_CACHE_TAG_BITS];
|
|
451
|
+
int const dictTagsMatchL3 = ZSTD_comparePackedTags(dictMatchIndexAndTagL3, dictHashAndTagL3);
|
|
211
452
|
const BYTE* matchL3 = base + matchIndexL3;
|
|
212
453
|
hashLong[hl3] = curr + 1;
|
|
213
454
|
|
|
@@ -220,9 +461,9 @@ _search_next_long:
|
|
|
220
461
|
while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */
|
|
221
462
|
goto _match_found;
|
|
222
463
|
}
|
|
223
|
-
} else if (
|
|
464
|
+
} else if (dictTagsMatchL3) {
|
|
224
465
|
/* check dict long +1 match */
|
|
225
|
-
U32 const dictMatchIndexL3 =
|
|
466
|
+
U32 const dictMatchIndexL3 = dictMatchIndexAndTagL3 >> ZSTD_SHORT_CACHE_TAG_BITS;
|
|
226
467
|
const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3;
|
|
227
468
|
assert(dictMatchL3 < dictEnd);
|
|
228
469
|
if (dictMatchL3 > dictStart && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) {
|
|
@@ -234,7 +475,7 @@ _search_next_long:
|
|
|
234
475
|
} } }
|
|
235
476
|
|
|
236
477
|
/* if no long +1 match, explore the short match we found */
|
|
237
|
-
if (
|
|
478
|
+
if (matchIndexS < prefixLowestIndex) {
|
|
238
479
|
mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4;
|
|
239
480
|
offset = (U32)(curr - matchIndexS);
|
|
240
481
|
while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
|
@@ -244,13 +485,11 @@ _search_next_long:
|
|
|
244
485
|
while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
|
|
245
486
|
}
|
|
246
487
|
|
|
247
|
-
/* fall-through */
|
|
248
|
-
|
|
249
488
|
_match_found:
|
|
250
489
|
offset_2 = offset_1;
|
|
251
490
|
offset_1 = offset;
|
|
252
491
|
|
|
253
|
-
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset
|
|
492
|
+
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength);
|
|
254
493
|
|
|
255
494
|
_match_stored:
|
|
256
495
|
/* match found */
|
|
@@ -268,53 +507,55 @@ _match_stored:
|
|
|
268
507
|
}
|
|
269
508
|
|
|
270
509
|
/* check immediate repcode */
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
|
|
287
|
-
ip += repLength2;
|
|
288
|
-
anchor = ip;
|
|
289
|
-
continue;
|
|
290
|
-
}
|
|
291
|
-
break;
|
|
292
|
-
} }
|
|
293
|
-
|
|
294
|
-
if (dictMode == ZSTD_noDict) {
|
|
295
|
-
while ( (ip <= ilimit)
|
|
296
|
-
&& ( (offset_2>0)
|
|
297
|
-
& (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
|
|
298
|
-
/* store sequence */
|
|
299
|
-
size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
|
|
300
|
-
U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; /* swap offset_2 <=> offset_1 */
|
|
301
|
-
hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
|
|
302
|
-
hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
|
|
303
|
-
ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH);
|
|
304
|
-
ip += rLength;
|
|
510
|
+
while (ip <= ilimit) {
|
|
511
|
+
U32 const current2 = (U32)(ip-base);
|
|
512
|
+
U32 const repIndex2 = current2 - offset_2;
|
|
513
|
+
const BYTE* repMatch2 = repIndex2 < prefixLowestIndex ?
|
|
514
|
+
dictBase + repIndex2 - dictIndexDelta :
|
|
515
|
+
base + repIndex2;
|
|
516
|
+
if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */)
|
|
517
|
+
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
|
|
518
|
+
const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend;
|
|
519
|
+
size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4;
|
|
520
|
+
U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
|
|
521
|
+
ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2);
|
|
522
|
+
hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
|
|
523
|
+
hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
|
|
524
|
+
ip += repLength2;
|
|
305
525
|
anchor = ip;
|
|
306
|
-
continue;
|
|
307
|
-
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
308
531
|
} /* while (ip < ilimit) */
|
|
309
532
|
|
|
310
533
|
/* save reps for next block */
|
|
311
|
-
rep[0] = offset_1
|
|
312
|
-
rep[1] = offset_2
|
|
534
|
+
rep[0] = offset_1;
|
|
535
|
+
rep[1] = offset_2;
|
|
313
536
|
|
|
314
537
|
/* Return the last literals size */
|
|
315
538
|
return (size_t)(iend - anchor);
|
|
316
539
|
}
|
|
317
540
|
|
|
541
|
+
#define ZSTD_GEN_DFAST_FN(dictMode, mls) \
|
|
542
|
+
static size_t ZSTD_compressBlock_doubleFast_##dictMode##_##mls( \
|
|
543
|
+
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM], \
|
|
544
|
+
void const* src, size_t srcSize) \
|
|
545
|
+
{ \
|
|
546
|
+
return ZSTD_compressBlock_doubleFast_##dictMode##_generic(ms, seqStore, rep, src, srcSize, mls); \
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
ZSTD_GEN_DFAST_FN(noDict, 4)
|
|
550
|
+
ZSTD_GEN_DFAST_FN(noDict, 5)
|
|
551
|
+
ZSTD_GEN_DFAST_FN(noDict, 6)
|
|
552
|
+
ZSTD_GEN_DFAST_FN(noDict, 7)
|
|
553
|
+
|
|
554
|
+
ZSTD_GEN_DFAST_FN(dictMatchState, 4)
|
|
555
|
+
ZSTD_GEN_DFAST_FN(dictMatchState, 5)
|
|
556
|
+
ZSTD_GEN_DFAST_FN(dictMatchState, 6)
|
|
557
|
+
ZSTD_GEN_DFAST_FN(dictMatchState, 7)
|
|
558
|
+
|
|
318
559
|
|
|
319
560
|
size_t ZSTD_compressBlock_doubleFast(
|
|
320
561
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
|
@@ -325,13 +566,13 @@ size_t ZSTD_compressBlock_doubleFast(
|
|
|
325
566
|
{
|
|
326
567
|
default: /* includes case 3 */
|
|
327
568
|
case 4 :
|
|
328
|
-
return
|
|
569
|
+
return ZSTD_compressBlock_doubleFast_noDict_4(ms, seqStore, rep, src, srcSize);
|
|
329
570
|
case 5 :
|
|
330
|
-
return
|
|
571
|
+
return ZSTD_compressBlock_doubleFast_noDict_5(ms, seqStore, rep, src, srcSize);
|
|
331
572
|
case 6 :
|
|
332
|
-
return
|
|
573
|
+
return ZSTD_compressBlock_doubleFast_noDict_6(ms, seqStore, rep, src, srcSize);
|
|
333
574
|
case 7 :
|
|
334
|
-
return
|
|
575
|
+
return ZSTD_compressBlock_doubleFast_noDict_7(ms, seqStore, rep, src, srcSize);
|
|
335
576
|
}
|
|
336
577
|
}
|
|
337
578
|
|
|
@@ -345,18 +586,20 @@ size_t ZSTD_compressBlock_doubleFast_dictMatchState(
|
|
|
345
586
|
{
|
|
346
587
|
default: /* includes case 3 */
|
|
347
588
|
case 4 :
|
|
348
|
-
return
|
|
589
|
+
return ZSTD_compressBlock_doubleFast_dictMatchState_4(ms, seqStore, rep, src, srcSize);
|
|
349
590
|
case 5 :
|
|
350
|
-
return
|
|
591
|
+
return ZSTD_compressBlock_doubleFast_dictMatchState_5(ms, seqStore, rep, src, srcSize);
|
|
351
592
|
case 6 :
|
|
352
|
-
return
|
|
593
|
+
return ZSTD_compressBlock_doubleFast_dictMatchState_6(ms, seqStore, rep, src, srcSize);
|
|
353
594
|
case 7 :
|
|
354
|
-
return
|
|
595
|
+
return ZSTD_compressBlock_doubleFast_dictMatchState_7(ms, seqStore, rep, src, srcSize);
|
|
355
596
|
}
|
|
356
597
|
}
|
|
357
598
|
|
|
358
599
|
|
|
359
|
-
static
|
|
600
|
+
static
|
|
601
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
602
|
+
size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
360
603
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
|
361
604
|
void const* src, size_t srcSize,
|
|
362
605
|
U32 const mls /* template */)
|
|
@@ -387,7 +630,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
|
387
630
|
|
|
388
631
|
/* if extDict is invalidated due to maxDistance, switch to "regular" variant */
|
|
389
632
|
if (prefixStartIndex == dictStartIndex)
|
|
390
|
-
return
|
|
633
|
+
return ZSTD_compressBlock_doubleFast(ms, seqStore, rep, src, srcSize);
|
|
391
634
|
|
|
392
635
|
/* Search Loop */
|
|
393
636
|
while (ip < ilimit) { /* < instead of <=, because (ip+1) */
|
|
@@ -409,12 +652,12 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
|
409
652
|
hashSmall[hSmall] = hashLong[hLong] = curr; /* update hash table */
|
|
410
653
|
|
|
411
654
|
if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */
|
|
412
|
-
& (
|
|
655
|
+
& (offset_1 <= curr+1 - dictStartIndex)) /* note: we are searching at curr+1 */
|
|
413
656
|
&& (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
|
|
414
657
|
const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;
|
|
415
658
|
mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;
|
|
416
659
|
ip++;
|
|
417
|
-
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend,
|
|
660
|
+
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, REPCODE1_TO_OFFBASE, mLength);
|
|
418
661
|
} else {
|
|
419
662
|
if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
|
|
420
663
|
const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend;
|
|
@@ -425,7 +668,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
|
425
668
|
while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
|
|
426
669
|
offset_2 = offset_1;
|
|
427
670
|
offset_1 = offset;
|
|
428
|
-
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset
|
|
671
|
+
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength);
|
|
429
672
|
|
|
430
673
|
} else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) {
|
|
431
674
|
size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
|
|
@@ -450,7 +693,7 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
|
450
693
|
}
|
|
451
694
|
offset_2 = offset_1;
|
|
452
695
|
offset_1 = offset;
|
|
453
|
-
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset
|
|
696
|
+
ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, OFFSET_TO_OFFBASE(offset), mLength);
|
|
454
697
|
|
|
455
698
|
} else {
|
|
456
699
|
ip += ((ip-anchor) >> kSearchStrength) + 1;
|
|
@@ -477,12 +720,12 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
|
477
720
|
U32 const repIndex2 = current2 - offset_2;
|
|
478
721
|
const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;
|
|
479
722
|
if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) /* intentional overflow : ensure repIndex2 doesn't overlap dict + prefix */
|
|
480
|
-
& (
|
|
723
|
+
& (offset_2 <= current2 - dictStartIndex))
|
|
481
724
|
&& (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
|
|
482
725
|
const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;
|
|
483
726
|
size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;
|
|
484
727
|
U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
|
|
485
|
-
ZSTD_storeSeq(seqStore, 0, anchor, iend,
|
|
728
|
+
ZSTD_storeSeq(seqStore, 0, anchor, iend, REPCODE1_TO_OFFBASE, repLength2);
|
|
486
729
|
hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
|
|
487
730
|
hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
|
|
488
731
|
ip += repLength2;
|
|
@@ -500,6 +743,10 @@ static size_t ZSTD_compressBlock_doubleFast_extDict_generic(
|
|
|
500
743
|
return (size_t)(iend - anchor);
|
|
501
744
|
}
|
|
502
745
|
|
|
746
|
+
ZSTD_GEN_DFAST_FN(extDict, 4)
|
|
747
|
+
ZSTD_GEN_DFAST_FN(extDict, 5)
|
|
748
|
+
ZSTD_GEN_DFAST_FN(extDict, 6)
|
|
749
|
+
ZSTD_GEN_DFAST_FN(extDict, 7)
|
|
503
750
|
|
|
504
751
|
size_t ZSTD_compressBlock_doubleFast_extDict(
|
|
505
752
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
|
@@ -510,12 +757,14 @@ size_t ZSTD_compressBlock_doubleFast_extDict(
|
|
|
510
757
|
{
|
|
511
758
|
default: /* includes case 3 */
|
|
512
759
|
case 4 :
|
|
513
|
-
return
|
|
760
|
+
return ZSTD_compressBlock_doubleFast_extDict_4(ms, seqStore, rep, src, srcSize);
|
|
514
761
|
case 5 :
|
|
515
|
-
return
|
|
762
|
+
return ZSTD_compressBlock_doubleFast_extDict_5(ms, seqStore, rep, src, srcSize);
|
|
516
763
|
case 6 :
|
|
517
|
-
return
|
|
764
|
+
return ZSTD_compressBlock_doubleFast_extDict_6(ms, seqStore, rep, src, srcSize);
|
|
518
765
|
case 7 :
|
|
519
|
-
return
|
|
766
|
+
return ZSTD_compressBlock_doubleFast_extDict_7(ms, seqStore, rep, src, srcSize);
|
|
520
767
|
}
|
|
521
768
|
}
|
|
769
|
+
|
|
770
|
+
#endif /* ZSTD_EXCLUDE_DFAST_BLOCK_COMPRESSOR */
|