extzstd 0.3.1 → 0.3.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.
- checksums.yaml +4 -4
- data/README.md +28 -14
- data/contrib/zstd/CHANGELOG +114 -56
- data/contrib/zstd/CONTRIBUTING.md +14 -0
- data/contrib/zstd/Makefile +37 -31
- data/contrib/zstd/README.md +6 -0
- data/contrib/zstd/appveyor.yml +4 -1
- data/contrib/zstd/lib/Makefile +231 -134
- data/contrib/zstd/lib/README.md +28 -0
- data/contrib/zstd/lib/common/bitstream.h +24 -15
- data/contrib/zstd/lib/common/compiler.h +116 -3
- data/contrib/zstd/lib/common/cpu.h +0 -2
- data/contrib/zstd/lib/common/debug.h +11 -18
- data/contrib/zstd/lib/common/entropy_common.c +188 -42
- data/contrib/zstd/lib/common/error_private.c +1 -0
- data/contrib/zstd/lib/common/error_private.h +1 -1
- data/contrib/zstd/lib/common/fse.h +38 -11
- data/contrib/zstd/lib/common/fse_decompress.c +123 -16
- data/contrib/zstd/lib/common/huf.h +26 -5
- data/contrib/zstd/lib/common/mem.h +66 -93
- data/contrib/zstd/lib/common/pool.c +22 -16
- data/contrib/zstd/lib/common/pool.h +1 -1
- data/contrib/zstd/lib/common/threading.c +6 -5
- data/contrib/zstd/lib/common/xxhash.c +18 -56
- data/contrib/zstd/lib/common/xxhash.h +1 -1
- data/contrib/zstd/lib/common/zstd_common.c +9 -9
- data/contrib/zstd/lib/common/zstd_deps.h +111 -0
- data/contrib/zstd/lib/common/zstd_errors.h +1 -0
- data/contrib/zstd/lib/common/zstd_internal.h +89 -58
- data/contrib/zstd/lib/compress/fse_compress.c +30 -23
- data/contrib/zstd/lib/compress/hist.c +26 -28
- data/contrib/zstd/lib/compress/hist.h +1 -1
- data/contrib/zstd/lib/compress/huf_compress.c +210 -95
- data/contrib/zstd/lib/compress/zstd_compress.c +1339 -409
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +119 -41
- data/contrib/zstd/lib/compress/zstd_compress_literals.c +4 -4
- data/contrib/zstd/lib/compress/zstd_compress_sequences.c +17 -3
- data/contrib/zstd/lib/compress/zstd_compress_superblock.c +23 -19
- data/contrib/zstd/lib/compress/zstd_cwksp.h +60 -24
- data/contrib/zstd/lib/compress/zstd_double_fast.c +22 -22
- data/contrib/zstd/lib/compress/zstd_fast.c +19 -19
- data/contrib/zstd/lib/compress/zstd_lazy.c +351 -77
- data/contrib/zstd/lib/compress/zstd_lazy.h +20 -0
- data/contrib/zstd/lib/compress/zstd_ldm.c +59 -18
- data/contrib/zstd/lib/compress/zstd_ldm.h +6 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +190 -45
- data/contrib/zstd/lib/compress/zstdmt_compress.c +74 -406
- data/contrib/zstd/lib/compress/zstdmt_compress.h +26 -108
- data/contrib/zstd/lib/decompress/huf_decompress.c +302 -200
- data/contrib/zstd/lib/decompress/zstd_ddict.c +8 -8
- data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
- data/contrib/zstd/lib/decompress/zstd_decompress.c +125 -80
- data/contrib/zstd/lib/decompress/zstd_decompress_block.c +145 -37
- data/contrib/zstd/lib/decompress/zstd_decompress_block.h +5 -2
- data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +11 -10
- data/contrib/zstd/lib/dictBuilder/cover.c +29 -20
- data/contrib/zstd/lib/dictBuilder/cover.h +1 -1
- data/contrib/zstd/lib/dictBuilder/fastcover.c +20 -19
- data/contrib/zstd/lib/dictBuilder/zdict.c +15 -16
- data/contrib/zstd/lib/dictBuilder/zdict.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v01.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v02.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v03.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v04.c +6 -2
- data/contrib/zstd/lib/legacy/zstd_v05.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v06.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v07.c +5 -1
- data/contrib/zstd/lib/libzstd.pc.in +3 -3
- data/contrib/zstd/lib/zstd.h +348 -47
- data/ext/extzstd.c +6 -0
- data/ext/extzstd.h +6 -0
- data/gemstub.rb +3 -21
- data/lib/extzstd.rb +0 -2
- data/lib/extzstd/version.rb +6 -1
- data/test/test_basic.rb +0 -5
- metadata +5 -4
@@ -58,11 +58,11 @@ ZSTD_updateDUBT(ZSTD_matchState_t* ms,
|
|
58
58
|
|
59
59
|
/** ZSTD_insertDUBT1() :
|
60
60
|
* sort one already inserted but unsorted position
|
61
|
-
* assumption :
|
61
|
+
* assumption : curr >= btlow == (curr - btmask)
|
62
62
|
* doesn't fail */
|
63
63
|
static void
|
64
64
|
ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
|
65
|
-
U32
|
65
|
+
U32 curr, const BYTE* inputEnd,
|
66
66
|
U32 nbCompares, U32 btLow,
|
67
67
|
const ZSTD_dictMode_e dictMode)
|
68
68
|
{
|
@@ -74,41 +74,41 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
|
|
74
74
|
const BYTE* const base = ms->window.base;
|
75
75
|
const BYTE* const dictBase = ms->window.dictBase;
|
76
76
|
const U32 dictLimit = ms->window.dictLimit;
|
77
|
-
const BYTE* const ip = (
|
78
|
-
const BYTE* const iend = (
|
77
|
+
const BYTE* const ip = (curr>=dictLimit) ? base + curr : dictBase + curr;
|
78
|
+
const BYTE* const iend = (curr>=dictLimit) ? inputEnd : dictBase + dictLimit;
|
79
79
|
const BYTE* const dictEnd = dictBase + dictLimit;
|
80
80
|
const BYTE* const prefixStart = base + dictLimit;
|
81
81
|
const BYTE* match;
|
82
|
-
U32* smallerPtr = bt + 2*(
|
82
|
+
U32* smallerPtr = bt + 2*(curr&btMask);
|
83
83
|
U32* largerPtr = smallerPtr + 1;
|
84
84
|
U32 matchIndex = *smallerPtr; /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */
|
85
85
|
U32 dummy32; /* to be nullified at the end */
|
86
86
|
U32 const windowValid = ms->window.lowLimit;
|
87
87
|
U32 const maxDistance = 1U << cParams->windowLog;
|
88
|
-
U32 const windowLow = (
|
88
|
+
U32 const windowLow = (curr - windowValid > maxDistance) ? curr - maxDistance : windowValid;
|
89
89
|
|
90
90
|
|
91
91
|
DEBUGLOG(8, "ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)",
|
92
|
-
|
93
|
-
assert(
|
92
|
+
curr, dictLimit, windowLow);
|
93
|
+
assert(curr >= btLow);
|
94
94
|
assert(ip < iend); /* condition for ZSTD_count */
|
95
95
|
|
96
96
|
while (nbCompares-- && (matchIndex > windowLow)) {
|
97
97
|
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
98
98
|
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
99
|
-
assert(matchIndex <
|
99
|
+
assert(matchIndex < curr);
|
100
100
|
/* note : all candidates are now supposed sorted,
|
101
101
|
* but it's still possible to have nextPtr[1] == ZSTD_DUBT_UNSORTED_MARK
|
102
102
|
* when a real index has the same value as ZSTD_DUBT_UNSORTED_MARK */
|
103
103
|
|
104
104
|
if ( (dictMode != ZSTD_extDict)
|
105
105
|
|| (matchIndex+matchLength >= dictLimit) /* both in current segment*/
|
106
|
-
|| (
|
106
|
+
|| (curr < dictLimit) /* both in extDict */) {
|
107
107
|
const BYTE* const mBase = ( (dictMode != ZSTD_extDict)
|
108
108
|
|| (matchIndex+matchLength >= dictLimit)) ?
|
109
109
|
base : dictBase;
|
110
110
|
assert( (matchIndex+matchLength >= dictLimit) /* might be wrong if extDict is incorrectly set to 0 */
|
111
|
-
|| (
|
111
|
+
|| (curr < dictLimit) );
|
112
112
|
match = mBase + matchIndex;
|
113
113
|
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);
|
114
114
|
} else {
|
@@ -119,7 +119,7 @@ ZSTD_insertDUBT1(ZSTD_matchState_t* ms,
|
|
119
119
|
}
|
120
120
|
|
121
121
|
DEBUGLOG(8, "ZSTD_insertDUBT1: comparing %u with %u : found %u common bytes ",
|
122
|
-
|
122
|
+
curr, matchIndex, (U32)matchLength);
|
123
123
|
|
124
124
|
if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
|
125
125
|
break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */
|
@@ -168,7 +168,7 @@ ZSTD_DUBT_findBetterDictMatch (
|
|
168
168
|
|
169
169
|
const BYTE* const base = ms->window.base;
|
170
170
|
const BYTE* const prefixStart = base + ms->window.dictLimit;
|
171
|
-
U32 const
|
171
|
+
U32 const curr = (U32)(ip-base);
|
172
172
|
const BYTE* const dictBase = dms->window.base;
|
173
173
|
const BYTE* const dictEnd = dms->window.nextSrc;
|
174
174
|
U32 const dictHighLimit = (U32)(dms->window.nextSrc - dms->window.base);
|
@@ -195,10 +195,10 @@ ZSTD_DUBT_findBetterDictMatch (
|
|
195
195
|
|
196
196
|
if (matchLength > bestLength) {
|
197
197
|
U32 matchIndex = dictMatchIndex + dictIndexDelta;
|
198
|
-
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(
|
198
|
+
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) {
|
199
199
|
DEBUGLOG(9, "ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)",
|
200
|
-
|
201
|
-
bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE +
|
200
|
+
curr, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, ZSTD_REP_MOVE + curr - matchIndex, dictMatchIndex, matchIndex);
|
201
|
+
bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
|
202
202
|
}
|
203
203
|
if (ip+matchLength == iend) { /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */
|
204
204
|
break; /* drop, to guarantee consistency (miss a little bit of compression) */
|
@@ -218,9 +218,9 @@ ZSTD_DUBT_findBetterDictMatch (
|
|
218
218
|
}
|
219
219
|
|
220
220
|
if (bestLength >= MINMATCH) {
|
221
|
-
U32 const mIndex =
|
221
|
+
U32 const mIndex = curr - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
|
222
222
|
DEBUGLOG(8, "ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
|
223
|
-
|
223
|
+
curr, (U32)bestLength, (U32)*offsetPtr, mIndex);
|
224
224
|
}
|
225
225
|
return bestLength;
|
226
226
|
|
@@ -241,13 +241,13 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
|
|
241
241
|
U32 matchIndex = hashTable[h];
|
242
242
|
|
243
243
|
const BYTE* const base = ms->window.base;
|
244
|
-
U32 const
|
245
|
-
U32 const windowLow = ZSTD_getLowestMatchIndex(ms,
|
244
|
+
U32 const curr = (U32)(ip-base);
|
245
|
+
U32 const windowLow = ZSTD_getLowestMatchIndex(ms, curr, cParams->windowLog);
|
246
246
|
|
247
247
|
U32* const bt = ms->chainTable;
|
248
248
|
U32 const btLog = cParams->chainLog - 1;
|
249
249
|
U32 const btMask = (1 << btLog) - 1;
|
250
|
-
U32 const btLow = (btMask >=
|
250
|
+
U32 const btLow = (btMask >= curr) ? 0 : curr - btMask;
|
251
251
|
U32 const unsortLimit = MAX(btLow, windowLow);
|
252
252
|
|
253
253
|
U32* nextCandidate = bt + 2*(matchIndex&btMask);
|
@@ -256,8 +256,9 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
|
|
256
256
|
U32 nbCandidates = nbCompares;
|
257
257
|
U32 previousCandidate = 0;
|
258
258
|
|
259
|
-
DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ",
|
259
|
+
DEBUGLOG(7, "ZSTD_DUBT_findBestMatch (%u) ", curr);
|
260
260
|
assert(ip <= iend-8); /* required for h calculation */
|
261
|
+
assert(dictMode != ZSTD_dedicatedDictSearch);
|
261
262
|
|
262
263
|
/* reach end of unsorted candidates list */
|
263
264
|
while ( (matchIndex > unsortLimit)
|
@@ -299,14 +300,14 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
|
|
299
300
|
const U32 dictLimit = ms->window.dictLimit;
|
300
301
|
const BYTE* const dictEnd = dictBase + dictLimit;
|
301
302
|
const BYTE* const prefixStart = base + dictLimit;
|
302
|
-
U32* smallerPtr = bt + 2*(
|
303
|
-
U32* largerPtr = bt + 2*(
|
304
|
-
U32 matchEndIdx =
|
303
|
+
U32* smallerPtr = bt + 2*(curr&btMask);
|
304
|
+
U32* largerPtr = bt + 2*(curr&btMask) + 1;
|
305
|
+
U32 matchEndIdx = curr + 8 + 1;
|
305
306
|
U32 dummy32; /* to be nullified at the end */
|
306
307
|
size_t bestLength = 0;
|
307
308
|
|
308
309
|
matchIndex = hashTable[h];
|
309
|
-
hashTable[h] =
|
310
|
+
hashTable[h] = curr; /* Update Hash Table */
|
310
311
|
|
311
312
|
while (nbCompares-- && (matchIndex > windowLow)) {
|
312
313
|
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
@@ -326,8 +327,8 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
|
|
326
327
|
if (matchLength > bestLength) {
|
327
328
|
if (matchLength > matchEndIdx - matchIndex)
|
328
329
|
matchEndIdx = matchIndex + (U32)matchLength;
|
329
|
-
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(
|
330
|
-
bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE +
|
330
|
+
if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(curr-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
|
331
|
+
bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + curr - matchIndex;
|
331
332
|
if (ip+matchLength == iend) { /* equal : no way to know if inf or sup */
|
332
333
|
if (dictMode == ZSTD_dictMatchState) {
|
333
334
|
nbCompares = 0; /* in addition to avoiding checking any
|
@@ -363,12 +364,12 @@ ZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,
|
|
363
364
|
mls, dictMode);
|
364
365
|
}
|
365
366
|
|
366
|
-
assert(matchEndIdx >
|
367
|
+
assert(matchEndIdx > curr+8); /* ensure nextToUpdate is increased */
|
367
368
|
ms->nextToUpdate = matchEndIdx - 8; /* skip repetitive patterns */
|
368
369
|
if (bestLength >= MINMATCH) {
|
369
|
-
U32 const mIndex =
|
370
|
+
U32 const mIndex = curr - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;
|
370
371
|
DEBUGLOG(8, "ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)",
|
371
|
-
|
372
|
+
curr, (U32)bestLength, (U32)*offsetPtr, mIndex);
|
372
373
|
}
|
373
374
|
return bestLength;
|
374
375
|
}
|
@@ -446,7 +447,7 @@ static size_t ZSTD_BtFindBestMatch_extDict_selectMLS (
|
|
446
447
|
|
447
448
|
/* Update chains up to ip (excluded)
|
448
449
|
Assumption : always within prefix (i.e. not within extDict) */
|
449
|
-
|
450
|
+
FORCE_INLINE_TEMPLATE U32 ZSTD_insertAndFindFirstIndex_internal(
|
450
451
|
ZSTD_matchState_t* ms,
|
451
452
|
const ZSTD_compressionParameters* const cParams,
|
452
453
|
const BYTE* ip, U32 const mls)
|
@@ -475,6 +476,121 @@ U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) {
|
|
475
476
|
return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch);
|
476
477
|
}
|
477
478
|
|
479
|
+
void ZSTD_dedicatedDictSearch_lazy_loadDictionary(ZSTD_matchState_t* ms, const BYTE* const ip)
|
480
|
+
{
|
481
|
+
const BYTE* const base = ms->window.base;
|
482
|
+
U32 const target = (U32)(ip - base);
|
483
|
+
U32* const hashTable = ms->hashTable;
|
484
|
+
U32* const chainTable = ms->chainTable;
|
485
|
+
U32 const chainSize = 1 << ms->cParams.chainLog;
|
486
|
+
U32 idx = ms->nextToUpdate;
|
487
|
+
U32 const minChain = chainSize < target ? target - chainSize : idx;
|
488
|
+
U32 const bucketSize = 1 << ZSTD_LAZY_DDSS_BUCKET_LOG;
|
489
|
+
U32 const cacheSize = bucketSize - 1;
|
490
|
+
U32 const chainAttempts = (1 << ms->cParams.searchLog) - cacheSize;
|
491
|
+
U32 const chainLimit = chainAttempts > 255 ? 255 : chainAttempts;
|
492
|
+
|
493
|
+
/* We know the hashtable is oversized by a factor of `bucketSize`.
|
494
|
+
* We are going to temporarily pretend `bucketSize == 1`, keeping only a
|
495
|
+
* single entry. We will use the rest of the space to construct a temporary
|
496
|
+
* chaintable.
|
497
|
+
*/
|
498
|
+
U32 const hashLog = ms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG;
|
499
|
+
U32* const tmpHashTable = hashTable;
|
500
|
+
U32* const tmpChainTable = hashTable + ((size_t)1 << hashLog);
|
501
|
+
U32 const tmpChainSize = ((1 << ZSTD_LAZY_DDSS_BUCKET_LOG) - 1) << hashLog;
|
502
|
+
U32 const tmpMinChain = tmpChainSize < target ? target - tmpChainSize : idx;
|
503
|
+
|
504
|
+
U32 hashIdx;
|
505
|
+
|
506
|
+
assert(ms->cParams.chainLog <= 24);
|
507
|
+
assert(ms->cParams.hashLog >= ms->cParams.chainLog);
|
508
|
+
assert(idx != 0);
|
509
|
+
assert(tmpMinChain <= minChain);
|
510
|
+
|
511
|
+
/* fill conventional hash table and conventional chain table */
|
512
|
+
for ( ; idx < target; idx++) {
|
513
|
+
U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch);
|
514
|
+
if (idx >= tmpMinChain) {
|
515
|
+
tmpChainTable[idx - tmpMinChain] = hashTable[h];
|
516
|
+
}
|
517
|
+
tmpHashTable[h] = idx;
|
518
|
+
}
|
519
|
+
|
520
|
+
/* sort chains into ddss chain table */
|
521
|
+
{
|
522
|
+
U32 chainPos = 0;
|
523
|
+
for (hashIdx = 0; hashIdx < (1U << hashLog); hashIdx++) {
|
524
|
+
U32 count;
|
525
|
+
U32 countBeyondMinChain = 0;
|
526
|
+
U32 i = tmpHashTable[hashIdx];
|
527
|
+
for (count = 0; i >= tmpMinChain && count < cacheSize; count++) {
|
528
|
+
/* skip through the chain to the first position that won't be
|
529
|
+
* in the hash cache bucket */
|
530
|
+
if (i < minChain) {
|
531
|
+
countBeyondMinChain++;
|
532
|
+
}
|
533
|
+
i = tmpChainTable[i - tmpMinChain];
|
534
|
+
}
|
535
|
+
if (count == cacheSize) {
|
536
|
+
for (count = 0; count < chainLimit;) {
|
537
|
+
if (i < minChain) {
|
538
|
+
if (!i || countBeyondMinChain++ > cacheSize) {
|
539
|
+
/* only allow pulling `cacheSize` number of entries
|
540
|
+
* into the cache or chainTable beyond `minChain`,
|
541
|
+
* to replace the entries pulled out of the
|
542
|
+
* chainTable into the cache. This lets us reach
|
543
|
+
* back further without increasing the total number
|
544
|
+
* of entries in the chainTable, guaranteeing the
|
545
|
+
* DDSS chain table will fit into the space
|
546
|
+
* allocated for the regular one. */
|
547
|
+
break;
|
548
|
+
}
|
549
|
+
}
|
550
|
+
chainTable[chainPos++] = i;
|
551
|
+
count++;
|
552
|
+
if (i < tmpMinChain) {
|
553
|
+
break;
|
554
|
+
}
|
555
|
+
i = tmpChainTable[i - tmpMinChain];
|
556
|
+
}
|
557
|
+
} else {
|
558
|
+
count = 0;
|
559
|
+
}
|
560
|
+
if (count) {
|
561
|
+
tmpHashTable[hashIdx] = ((chainPos - count) << 8) + count;
|
562
|
+
} else {
|
563
|
+
tmpHashTable[hashIdx] = 0;
|
564
|
+
}
|
565
|
+
}
|
566
|
+
assert(chainPos <= chainSize); /* I believe this is guaranteed... */
|
567
|
+
}
|
568
|
+
|
569
|
+
/* move chain pointers into the last entry of each hash bucket */
|
570
|
+
for (hashIdx = (1 << hashLog); hashIdx; ) {
|
571
|
+
U32 const bucketIdx = --hashIdx << ZSTD_LAZY_DDSS_BUCKET_LOG;
|
572
|
+
U32 const chainPackedPointer = tmpHashTable[hashIdx];
|
573
|
+
U32 i;
|
574
|
+
for (i = 0; i < cacheSize; i++) {
|
575
|
+
hashTable[bucketIdx + i] = 0;
|
576
|
+
}
|
577
|
+
hashTable[bucketIdx + bucketSize - 1] = chainPackedPointer;
|
578
|
+
}
|
579
|
+
|
580
|
+
/* fill the buckets of the hash table */
|
581
|
+
for (idx = ms->nextToUpdate; idx < target; idx++) {
|
582
|
+
U32 const h = (U32)ZSTD_hashPtr(base + idx, hashLog, ms->cParams.minMatch)
|
583
|
+
<< ZSTD_LAZY_DDSS_BUCKET_LOG;
|
584
|
+
U32 i;
|
585
|
+
/* Shift hash cache down 1. */
|
586
|
+
for (i = cacheSize - 1; i; i--)
|
587
|
+
hashTable[h + i] = hashTable[h + i - 1];
|
588
|
+
hashTable[h] = idx;
|
589
|
+
}
|
590
|
+
|
591
|
+
ms->nextToUpdate = target;
|
592
|
+
}
|
593
|
+
|
478
594
|
|
479
595
|
/* inlining is important to hardwire a hot branch (template emulation) */
|
480
596
|
FORCE_INLINE_TEMPLATE
|
@@ -493,20 +609,33 @@ size_t ZSTD_HcFindBestMatch_generic (
|
|
493
609
|
const U32 dictLimit = ms->window.dictLimit;
|
494
610
|
const BYTE* const prefixStart = base + dictLimit;
|
495
611
|
const BYTE* const dictEnd = dictBase + dictLimit;
|
496
|
-
const U32
|
612
|
+
const U32 curr = (U32)(ip-base);
|
497
613
|
const U32 maxDistance = 1U << cParams->windowLog;
|
498
614
|
const U32 lowestValid = ms->window.lowLimit;
|
499
|
-
const U32 withinMaxDistance = (
|
615
|
+
const U32 withinMaxDistance = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
|
500
616
|
const U32 isDictionary = (ms->loadedDictEnd != 0);
|
501
617
|
const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance;
|
502
|
-
const U32 minChain =
|
618
|
+
const U32 minChain = curr > chainSize ? curr - chainSize : 0;
|
503
619
|
U32 nbAttempts = 1U << cParams->searchLog;
|
504
620
|
size_t ml=4-1;
|
505
621
|
|
622
|
+
const ZSTD_matchState_t* const dms = ms->dictMatchState;
|
623
|
+
const U32 ddsHashLog = dictMode == ZSTD_dedicatedDictSearch
|
624
|
+
? dms->cParams.hashLog - ZSTD_LAZY_DDSS_BUCKET_LOG : 0;
|
625
|
+
const size_t ddsIdx = dictMode == ZSTD_dedicatedDictSearch
|
626
|
+
? ZSTD_hashPtr(ip, ddsHashLog, mls) << ZSTD_LAZY_DDSS_BUCKET_LOG : 0;
|
627
|
+
|
628
|
+
U32 matchIndex;
|
629
|
+
|
630
|
+
if (dictMode == ZSTD_dedicatedDictSearch) {
|
631
|
+
const U32* entry = &dms->hashTable[ddsIdx];
|
632
|
+
PREFETCH_L1(entry);
|
633
|
+
}
|
634
|
+
|
506
635
|
/* HC4 match finder */
|
507
|
-
|
636
|
+
matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls);
|
508
637
|
|
509
|
-
for ( ; (matchIndex
|
638
|
+
for ( ; (matchIndex>=lowLimit) & (nbAttempts>0) ; nbAttempts--) {
|
510
639
|
size_t currentMl=0;
|
511
640
|
if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {
|
512
641
|
const BYTE* const match = base + matchIndex;
|
@@ -523,7 +652,7 @@ size_t ZSTD_HcFindBestMatch_generic (
|
|
523
652
|
/* save best solution */
|
524
653
|
if (currentMl > ml) {
|
525
654
|
ml = currentMl;
|
526
|
-
*offsetPtr =
|
655
|
+
*offsetPtr = curr - matchIndex + ZSTD_REP_MOVE;
|
527
656
|
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
|
528
657
|
}
|
529
658
|
|
@@ -531,8 +660,92 @@ size_t ZSTD_HcFindBestMatch_generic (
|
|
531
660
|
matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
|
532
661
|
}
|
533
662
|
|
534
|
-
if (dictMode ==
|
535
|
-
const
|
663
|
+
if (dictMode == ZSTD_dedicatedDictSearch) {
|
664
|
+
const U32 ddsLowestIndex = dms->window.dictLimit;
|
665
|
+
const BYTE* const ddsBase = dms->window.base;
|
666
|
+
const BYTE* const ddsEnd = dms->window.nextSrc;
|
667
|
+
const U32 ddsSize = (U32)(ddsEnd - ddsBase);
|
668
|
+
const U32 ddsIndexDelta = dictLimit - ddsSize;
|
669
|
+
const U32 bucketSize = (1 << ZSTD_LAZY_DDSS_BUCKET_LOG);
|
670
|
+
const U32 bucketLimit = nbAttempts < bucketSize - 1 ? nbAttempts : bucketSize - 1;
|
671
|
+
U32 ddsAttempt;
|
672
|
+
|
673
|
+
for (ddsAttempt = 0; ddsAttempt < bucketSize - 1; ddsAttempt++) {
|
674
|
+
PREFETCH_L1(ddsBase + dms->hashTable[ddsIdx + ddsAttempt]);
|
675
|
+
}
|
676
|
+
|
677
|
+
{
|
678
|
+
U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
|
679
|
+
U32 const chainIndex = chainPackedPointer >> 8;
|
680
|
+
|
681
|
+
PREFETCH_L1(&dms->chainTable[chainIndex]);
|
682
|
+
}
|
683
|
+
|
684
|
+
for (ddsAttempt = 0; ddsAttempt < bucketLimit; ddsAttempt++) {
|
685
|
+
size_t currentMl=0;
|
686
|
+
const BYTE* match;
|
687
|
+
matchIndex = dms->hashTable[ddsIdx + ddsAttempt];
|
688
|
+
match = ddsBase + matchIndex;
|
689
|
+
|
690
|
+
if (!matchIndex) {
|
691
|
+
return ml;
|
692
|
+
}
|
693
|
+
|
694
|
+
/* guaranteed by table construction */
|
695
|
+
(void)ddsLowestIndex;
|
696
|
+
assert(matchIndex >= ddsLowestIndex);
|
697
|
+
assert(match+4 <= ddsEnd);
|
698
|
+
if (MEM_read32(match) == MEM_read32(ip)) {
|
699
|
+
/* assumption : matchIndex <= dictLimit-4 (by table construction) */
|
700
|
+
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
|
701
|
+
}
|
702
|
+
|
703
|
+
/* save best solution */
|
704
|
+
if (currentMl > ml) {
|
705
|
+
ml = currentMl;
|
706
|
+
*offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
|
707
|
+
if (ip+currentMl == iLimit) {
|
708
|
+
/* best possible, avoids read overflow on next attempt */
|
709
|
+
return ml;
|
710
|
+
}
|
711
|
+
}
|
712
|
+
}
|
713
|
+
|
714
|
+
{
|
715
|
+
U32 const chainPackedPointer = dms->hashTable[ddsIdx + bucketSize - 1];
|
716
|
+
U32 chainIndex = chainPackedPointer >> 8;
|
717
|
+
U32 const chainLength = chainPackedPointer & 0xFF;
|
718
|
+
U32 const chainAttempts = nbAttempts - ddsAttempt;
|
719
|
+
U32 const chainLimit = chainAttempts > chainLength ? chainLength : chainAttempts;
|
720
|
+
U32 chainAttempt;
|
721
|
+
|
722
|
+
for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++) {
|
723
|
+
PREFETCH_L1(ddsBase + dms->chainTable[chainIndex + chainAttempt]);
|
724
|
+
}
|
725
|
+
|
726
|
+
for (chainAttempt = 0 ; chainAttempt < chainLimit; chainAttempt++, chainIndex++) {
|
727
|
+
size_t currentMl=0;
|
728
|
+
const BYTE* match;
|
729
|
+
matchIndex = dms->chainTable[chainIndex];
|
730
|
+
match = ddsBase + matchIndex;
|
731
|
+
|
732
|
+
/* guaranteed by table construction */
|
733
|
+
assert(matchIndex >= ddsLowestIndex);
|
734
|
+
assert(match+4 <= ddsEnd);
|
735
|
+
if (MEM_read32(match) == MEM_read32(ip)) {
|
736
|
+
/* assumption : matchIndex <= dictLimit-4 (by table construction) */
|
737
|
+
currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, ddsEnd, prefixStart) + 4;
|
738
|
+
}
|
739
|
+
|
740
|
+
/* save best solution */
|
741
|
+
if (currentMl > ml) {
|
742
|
+
ml = currentMl;
|
743
|
+
*offsetPtr = curr - (matchIndex + ddsIndexDelta) + ZSTD_REP_MOVE;
|
744
|
+
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
|
745
|
+
}
|
746
|
+
}
|
747
|
+
}
|
748
|
+
} else if (dictMode == ZSTD_dictMatchState) {
|
536
749
|
const U32* const dmsChainTable = dms->chainTable;
|
537
750
|
const U32 dmsChainSize = (1 << dms->cParams.chainLog);
|
538
751
|
const U32 dmsChainMask = dmsChainSize - 1;
|
@@ -545,7 +758,7 @@ size_t ZSTD_HcFindBestMatch_generic (
|
|
545
758
|
|
546
759
|
matchIndex = dms->hashTable[ZSTD_hashPtr(ip, dms->cParams.hashLog, mls)];
|
547
760
|
|
548
|
-
for ( ; (matchIndex
|
761
|
+
for ( ; (matchIndex>=dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) {
|
549
762
|
size_t currentMl=0;
|
550
763
|
const BYTE* const match = dmsBase + matchIndex;
|
551
764
|
assert(match+4 <= dmsEnd);
|
@@ -555,11 +768,12 @@ size_t ZSTD_HcFindBestMatch_generic (
|
|
555
768
|
/* save best solution */
|
556
769
|
if (currentMl > ml) {
|
557
770
|
ml = currentMl;
|
558
|
-
*offsetPtr =
|
771
|
+
*offsetPtr = curr - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE;
|
559
772
|
if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
|
560
773
|
}
|
561
774
|
|
562
775
|
if (matchIndex <= dmsMinChain) break;
|
776
|
+
|
563
777
|
matchIndex = dmsChainTable[matchIndex & dmsChainMask];
|
564
778
|
}
|
565
779
|
}
|
@@ -600,6 +814,22 @@ static size_t ZSTD_HcFindBestMatch_dictMatchState_selectMLS (
|
|
600
814
|
}
|
601
815
|
|
602
816
|
|
817
|
+
static size_t ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS (
|
818
|
+
ZSTD_matchState_t* ms,
|
819
|
+
const BYTE* ip, const BYTE* const iLimit,
|
820
|
+
size_t* offsetPtr)
|
821
|
+
{
|
822
|
+
switch(ms->cParams.minMatch)
|
823
|
+
{
|
824
|
+
default : /* includes case 3 */
|
825
|
+
case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_dedicatedDictSearch);
|
826
|
+
case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_dedicatedDictSearch);
|
827
|
+
case 7 :
|
828
|
+
case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_dedicatedDictSearch);
|
829
|
+
}
|
830
|
+
}
|
831
|
+
|
832
|
+
|
603
833
|
FORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
|
604
834
|
ZSTD_matchState_t* ms,
|
605
835
|
const BYTE* ip, const BYTE* const iLimit,
|
@@ -641,39 +871,62 @@ ZSTD_compressBlock_lazy_generic(
|
|
641
871
|
typedef size_t (*searchMax_f)(
|
642
872
|
ZSTD_matchState_t* ms,
|
643
873
|
const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
874
|
+
|
875
|
+
/**
|
876
|
+
* This table is indexed first by the four ZSTD_dictMode_e values, and then
|
877
|
+
* by the two searchMethod_e values. NULLs are placed for configurations
|
878
|
+
* that should never occur (extDict modes go to the other implementation
|
879
|
+
* below and there is no DDSS for binary tree search yet).
|
880
|
+
*/
|
881
|
+
const searchMax_f searchFuncs[4][2] = {
|
882
|
+
{
|
883
|
+
ZSTD_HcFindBestMatch_selectMLS,
|
884
|
+
ZSTD_BtFindBestMatch_selectMLS
|
885
|
+
},
|
886
|
+
{
|
887
|
+
NULL,
|
888
|
+
NULL
|
889
|
+
},
|
890
|
+
{
|
891
|
+
ZSTD_HcFindBestMatch_dictMatchState_selectMLS,
|
892
|
+
ZSTD_BtFindBestMatch_dictMatchState_selectMLS
|
893
|
+
},
|
894
|
+
{
|
895
|
+
ZSTD_HcFindBestMatch_dedicatedDictSearch_selectMLS,
|
896
|
+
NULL
|
897
|
+
}
|
898
|
+
};
|
899
|
+
|
900
|
+
searchMax_f const searchMax = searchFuncs[dictMode][searchMethod == search_binaryTree];
|
649
901
|
U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;
|
650
902
|
|
903
|
+
const int isDMS = dictMode == ZSTD_dictMatchState;
|
904
|
+
const int isDDS = dictMode == ZSTD_dedicatedDictSearch;
|
905
|
+
const int isDxS = isDMS || isDDS;
|
651
906
|
const ZSTD_matchState_t* const dms = ms->dictMatchState;
|
652
|
-
const U32 dictLowestIndex =
|
653
|
-
|
654
|
-
const BYTE* const
|
655
|
-
|
656
|
-
const
|
657
|
-
dictBase + dictLowestIndex : NULL;
|
658
|
-
const BYTE* const dictEnd = dictMode == ZSTD_dictMatchState ?
|
659
|
-
dms->window.nextSrc : NULL;
|
660
|
-
const U32 dictIndexDelta = dictMode == ZSTD_dictMatchState ?
|
907
|
+
const U32 dictLowestIndex = isDxS ? dms->window.dictLimit : 0;
|
908
|
+
const BYTE* const dictBase = isDxS ? dms->window.base : NULL;
|
909
|
+
const BYTE* const dictLowest = isDxS ? dictBase + dictLowestIndex : NULL;
|
910
|
+
const BYTE* const dictEnd = isDxS ? dms->window.nextSrc : NULL;
|
911
|
+
const U32 dictIndexDelta = isDxS ?
|
661
912
|
prefixLowestIndex - (U32)(dictEnd - dictBase) :
|
662
913
|
0;
|
663
914
|
const U32 dictAndPrefixLength = (U32)((ip - prefixLowest) + (dictEnd - dictLowest));
|
664
915
|
|
916
|
+
assert(searchMax != NULL);
|
917
|
+
|
665
918
|
DEBUGLOG(5, "ZSTD_compressBlock_lazy_generic (dictMode=%u)", (U32)dictMode);
|
666
919
|
|
667
920
|
/* init */
|
668
921
|
ip += (dictAndPrefixLength == 0);
|
669
922
|
if (dictMode == ZSTD_noDict) {
|
670
|
-
U32 const
|
671
|
-
U32 const windowLow = ZSTD_getLowestPrefixIndex(ms,
|
672
|
-
U32 const maxRep =
|
923
|
+
U32 const curr = (U32)(ip - base);
|
924
|
+
U32 const windowLow = ZSTD_getLowestPrefixIndex(ms, curr, ms->cParams.windowLog);
|
925
|
+
U32 const maxRep = curr - windowLow;
|
673
926
|
if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
|
674
927
|
if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
|
675
928
|
}
|
676
|
-
if (
|
929
|
+
if (isDxS) {
|
677
930
|
/* dictMatchState repCode checks don't currently handle repCode == 0
|
678
931
|
* disabling. */
|
679
932
|
assert(offset_1 <= dictAndPrefixLength);
|
@@ -693,9 +946,9 @@ ZSTD_compressBlock_lazy_generic(
|
|
693
946
|
const BYTE* start=ip+1;
|
694
947
|
|
695
948
|
/* check repCode */
|
696
|
-
if (
|
949
|
+
if (isDxS) {
|
697
950
|
const U32 repIndex = (U32)(ip - base) + 1 - offset_1;
|
698
|
-
const BYTE* repMatch = (dictMode == ZSTD_dictMatchState
|
951
|
+
const BYTE* repMatch = ((dictMode == ZSTD_dictMatchState || dictMode == ZSTD_dedicatedDictSearch)
|
699
952
|
&& repIndex < prefixLowestIndex) ?
|
700
953
|
dictBase + (repIndex - dictIndexDelta) :
|
701
954
|
base + repIndex;
|
@@ -736,7 +989,7 @@ ZSTD_compressBlock_lazy_generic(
|
|
736
989
|
if ((mlRep >= 4) && (gain2 > gain1))
|
737
990
|
matchLength = mlRep, offset = 0, start = ip;
|
738
991
|
}
|
739
|
-
if (
|
992
|
+
if (isDxS) {
|
740
993
|
const U32 repIndex = (U32)(ip - base) - offset_1;
|
741
994
|
const BYTE* repMatch = repIndex < prefixLowestIndex ?
|
742
995
|
dictBase + (repIndex - dictIndexDelta) :
|
@@ -771,7 +1024,7 @@ ZSTD_compressBlock_lazy_generic(
|
|
771
1024
|
if ((mlRep >= 4) && (gain2 > gain1))
|
772
1025
|
matchLength = mlRep, offset = 0, start = ip;
|
773
1026
|
}
|
774
|
-
if (
|
1027
|
+
if (isDxS) {
|
775
1028
|
const U32 repIndex = (U32)(ip - base) - offset_1;
|
776
1029
|
const BYTE* repMatch = repIndex < prefixLowestIndex ?
|
777
1030
|
dictBase + (repIndex - dictIndexDelta) :
|
@@ -809,7 +1062,7 @@ ZSTD_compressBlock_lazy_generic(
|
|
809
1062
|
&& (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) ) /* only search for offset within prefix */
|
810
1063
|
{ start--; matchLength++; }
|
811
1064
|
}
|
812
|
-
if (
|
1065
|
+
if (isDxS) {
|
813
1066
|
U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
|
814
1067
|
const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex;
|
815
1068
|
const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest;
|
@@ -825,12 +1078,11 @@ _storeSequence:
|
|
825
1078
|
}
|
826
1079
|
|
827
1080
|
/* check immediate repcode */
|
828
|
-
if (
|
1081
|
+
if (isDxS) {
|
829
1082
|
while (ip <= ilimit) {
|
830
1083
|
U32 const current2 = (U32)(ip-base);
|
831
1084
|
U32 const repIndex = current2 - offset_2;
|
832
|
-
const BYTE* repMatch =
|
833
|
-
&& repIndex < prefixLowestIndex ?
|
1085
|
+
const BYTE* repMatch = repIndex < prefixLowestIndex ?
|
834
1086
|
dictBase - dictIndexDelta + repIndex :
|
835
1087
|
base + repIndex;
|
836
1088
|
if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex) >= 3 /* intentional overflow */)
|
@@ -925,6 +1177,28 @@ size_t ZSTD_compressBlock_greedy_dictMatchState(
|
|
925
1177
|
}
|
926
1178
|
|
927
1179
|
|
1180
|
+
size_t ZSTD_compressBlock_lazy2_dedicatedDictSearch(
|
1181
|
+
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
1182
|
+
void const* src, size_t srcSize)
|
1183
|
+
{
|
1184
|
+
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dedicatedDictSearch);
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
size_t ZSTD_compressBlock_lazy_dedicatedDictSearch(
|
1188
|
+
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
1189
|
+
void const* src, size_t srcSize)
|
1190
|
+
{
|
1191
|
+
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dedicatedDictSearch);
|
1192
|
+
}
|
1193
|
+
|
1194
|
+
size_t ZSTD_compressBlock_greedy_dedicatedDictSearch(
|
1195
|
+
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
1196
|
+
void const* src, size_t srcSize)
|
1197
|
+
{
|
1198
|
+
return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dedicatedDictSearch);
|
1199
|
+
}
|
1200
|
+
|
1201
|
+
|
928
1202
|
FORCE_INLINE_TEMPLATE
|
929
1203
|
size_t ZSTD_compressBlock_lazy_extDict_generic(
|
930
1204
|
ZSTD_matchState_t* ms, seqStore_t* seqStore,
|
@@ -968,11 +1242,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
|
|
968
1242
|
size_t matchLength=0;
|
969
1243
|
size_t offset=0;
|
970
1244
|
const BYTE* start=ip+1;
|
971
|
-
U32
|
1245
|
+
U32 curr = (U32)(ip-base);
|
972
1246
|
|
973
1247
|
/* check repCode */
|
974
|
-
{ const U32 windowLow = ZSTD_getLowestMatchIndex(ms,
|
975
|
-
const U32 repIndex = (U32)(
|
1248
|
+
{ const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr+1, windowLog);
|
1249
|
+
const U32 repIndex = (U32)(curr+1 - offset_1);
|
976
1250
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
977
1251
|
const BYTE* const repMatch = repBase + repIndex;
|
978
1252
|
if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
|
@@ -999,11 +1273,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
|
|
999
1273
|
if (depth>=1)
|
1000
1274
|
while (ip<ilimit) {
|
1001
1275
|
ip ++;
|
1002
|
-
|
1276
|
+
curr++;
|
1003
1277
|
/* check repCode */
|
1004
1278
|
if (offset) {
|
1005
|
-
const U32 windowLow = ZSTD_getLowestMatchIndex(ms,
|
1006
|
-
const U32 repIndex = (U32)(
|
1279
|
+
const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog);
|
1280
|
+
const U32 repIndex = (U32)(curr - offset_1);
|
1007
1281
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
1008
1282
|
const BYTE* const repMatch = repBase + repIndex;
|
1009
1283
|
if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
|
@@ -1030,11 +1304,11 @@ size_t ZSTD_compressBlock_lazy_extDict_generic(
|
|
1030
1304
|
/* let's find an even better one */
|
1031
1305
|
if ((depth==2) && (ip<ilimit)) {
|
1032
1306
|
ip ++;
|
1033
|
-
|
1307
|
+
curr++;
|
1034
1308
|
/* check repCode */
|
1035
1309
|
if (offset) {
|
1036
|
-
const U32 windowLow = ZSTD_getLowestMatchIndex(ms,
|
1037
|
-
const U32 repIndex = (U32)(
|
1310
|
+
const U32 windowLow = ZSTD_getLowestMatchIndex(ms, curr, windowLog);
|
1311
|
+
const U32 repIndex = (U32)(curr - offset_1);
|
1038
1312
|
const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
|
1039
1313
|
const BYTE* const repMatch = repBase + repIndex;
|
1040
1314
|
if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > windowLow)) /* intentional overflow */
|