zstdlib 0.2.0 → 0.7.0
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/CHANGES.md +30 -1
- data/README.md +2 -2
- data/Rakefile +1 -1
- data/ext/zstdlib/extconf.rb +3 -3
- data/ext/zstdlib/ruby/zlib-2.7/zstdlib.c +4895 -0
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/bitstream.h +38 -39
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/compiler.h +40 -5
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/cpu.h +1 -1
- data/ext/zstdlib/zstd-1.4.5/lib/common/debug.c +24 -0
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/debug.h +11 -31
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/entropy_common.c +13 -33
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/error_private.c +2 -1
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/error_private.h +6 -2
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/fse.h +12 -32
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/fse_decompress.c +12 -35
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/huf.h +15 -33
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/mem.h +75 -2
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/pool.c +8 -4
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/pool.h +2 -2
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/threading.c +50 -4
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/threading.h +36 -4
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/xxhash.c +23 -35
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/xxhash.h +11 -31
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/zstd_common.c +1 -1
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/zstd_errors.h +2 -1
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/common/zstd_internal.h +154 -26
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/fse_compress.c +17 -40
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/hist.c +15 -35
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/hist.h +12 -32
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/huf_compress.c +92 -92
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_compress.c +1191 -1330
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_compress_internal.h +317 -55
- data/ext/zstdlib/zstd-1.4.5/lib/compress/zstd_compress_literals.c +158 -0
- data/ext/zstdlib/zstd-1.4.5/lib/compress/zstd_compress_literals.h +29 -0
- data/ext/zstdlib/zstd-1.4.5/lib/compress/zstd_compress_sequences.c +419 -0
- data/ext/zstdlib/zstd-1.4.5/lib/compress/zstd_compress_sequences.h +54 -0
- data/ext/zstdlib/zstd-1.4.5/lib/compress/zstd_compress_superblock.c +845 -0
- data/ext/zstdlib/zstd-1.4.5/lib/compress/zstd_compress_superblock.h +32 -0
- data/ext/zstdlib/zstd-1.4.5/lib/compress/zstd_cwksp.h +525 -0
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_double_fast.c +65 -43
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_double_fast.h +2 -2
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_fast.c +92 -66
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_fast.h +2 -2
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_lazy.c +74 -42
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_lazy.h +1 -1
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_ldm.c +32 -10
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_ldm.h +7 -2
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_opt.c +81 -114
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstd_opt.h +1 -1
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstdmt_compress.c +95 -51
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/compress/zstdmt_compress.h +3 -2
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/decompress/huf_decompress.c +76 -60
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/decompress/zstd_ddict.c +12 -8
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/decompress/zstd_ddict.h +2 -2
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/decompress/zstd_decompress.c +292 -172
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/decompress/zstd_decompress_block.c +459 -338
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/decompress/zstd_decompress_block.h +3 -3
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/decompress/zstd_decompress_internal.h +18 -4
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/lib/zstd.h +265 -88
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/zlibWrapper/gzclose.c +1 -1
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/zlibWrapper/gzcompatibility.h +1 -1
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/zlibWrapper/gzguts.h +0 -0
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/zlibWrapper/gzlib.c +9 -9
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/zlibWrapper/gzread.c +16 -8
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/zlibWrapper/gzwrite.c +8 -8
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/zlibWrapper/zstd_zlibwrapper.c +16 -12
- data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.5}/zlibWrapper/zstd_zlibwrapper.h +1 -1
- metadata +69 -62
- data/ext/zstdlib/zstd-1.4.0/lib/common/debug.c +0 -44
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2016-
|
|
2
|
+
* Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
7
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.
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
#ifndef ZSTD_LDM_H
|
|
@@ -15,7 +16,7 @@ extern "C" {
|
|
|
15
16
|
#endif
|
|
16
17
|
|
|
17
18
|
#include "zstd_compress_internal.h" /* ldmParams_t, U32 */
|
|
18
|
-
#include "zstd.h" /* ZSTD_CCtx, size_t */
|
|
19
|
+
#include "../zstd.h" /* ZSTD_CCtx, size_t */
|
|
19
20
|
|
|
20
21
|
/*-*************************************
|
|
21
22
|
* Long distance matching
|
|
@@ -23,6 +24,10 @@ extern "C" {
|
|
|
23
24
|
|
|
24
25
|
#define ZSTD_LDM_DEFAULT_WINDOW_LOG ZSTD_WINDOWLOG_LIMIT_DEFAULT
|
|
25
26
|
|
|
27
|
+
void ZSTD_ldm_fillHashTable(
|
|
28
|
+
ldmState_t* state, const BYTE* ip,
|
|
29
|
+
const BYTE* iend, ldmParams_t const* params);
|
|
30
|
+
|
|
26
31
|
/**
|
|
27
32
|
* ZSTD_ldm_generateSequences():
|
|
28
33
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2016-
|
|
2
|
+
* Copyright (c) 2016-2020, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -249,40 +249,6 @@ static U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optP
|
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
/* ZSTD_litLengthContribution() :
|
|
253
|
-
* @return ( cost(litlength) - cost(0) )
|
|
254
|
-
* this value can then be added to rawLiteralsCost()
|
|
255
|
-
* to provide a cost which is directly comparable to a match ending at same position */
|
|
256
|
-
static int ZSTD_litLengthContribution(U32 const litLength, const optState_t* const optPtr, int optLevel)
|
|
257
|
-
{
|
|
258
|
-
if (optPtr->priceType >= zop_predef) return WEIGHT(litLength, optLevel);
|
|
259
|
-
|
|
260
|
-
/* dynamic statistics */
|
|
261
|
-
{ U32 const llCode = ZSTD_LLcode(litLength);
|
|
262
|
-
int const contribution = (LL_bits[llCode] * BITCOST_MULTIPLIER)
|
|
263
|
-
+ WEIGHT(optPtr->litLengthFreq[0], optLevel) /* note: log2litLengthSum cancel out */
|
|
264
|
-
- WEIGHT(optPtr->litLengthFreq[llCode], optLevel);
|
|
265
|
-
#if 1
|
|
266
|
-
return contribution;
|
|
267
|
-
#else
|
|
268
|
-
return MAX(0, contribution); /* sometimes better, sometimes not ... */
|
|
269
|
-
#endif
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/* ZSTD_literalsContribution() :
|
|
274
|
-
* creates a fake cost for the literals part of a sequence
|
|
275
|
-
* which can be compared to the ending cost of a match
|
|
276
|
-
* should a new match start at this position */
|
|
277
|
-
static int ZSTD_literalsContribution(const BYTE* const literals, U32 const litLength,
|
|
278
|
-
const optState_t* const optPtr,
|
|
279
|
-
int optLevel)
|
|
280
|
-
{
|
|
281
|
-
int const contribution = ZSTD_rawLiteralsCost(literals, litLength, optPtr, optLevel)
|
|
282
|
-
+ ZSTD_litLengthContribution(litLength, optPtr, optLevel);
|
|
283
|
-
return contribution;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
252
|
/* ZSTD_getMatchPrice() :
|
|
287
253
|
* Provides the cost of the match part (offset + matchLength) of a sequence
|
|
288
254
|
* Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence.
|
|
@@ -372,13 +338,15 @@ MEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)
|
|
|
372
338
|
|
|
373
339
|
/* Update hashTable3 up to ip (excluded)
|
|
374
340
|
Assumption : always within prefix (i.e. not within extDict) */
|
|
375
|
-
static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms,
|
|
341
|
+
static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms,
|
|
342
|
+
U32* nextToUpdate3,
|
|
343
|
+
const BYTE* const ip)
|
|
376
344
|
{
|
|
377
345
|
U32* const hashTable3 = ms->hashTable3;
|
|
378
346
|
U32 const hashLog3 = ms->hashLog3;
|
|
379
347
|
const BYTE* const base = ms->window.base;
|
|
380
|
-
U32 idx =
|
|
381
|
-
U32 const target =
|
|
348
|
+
U32 idx = *nextToUpdate3;
|
|
349
|
+
U32 const target = (U32)(ip - base);
|
|
382
350
|
size_t const hash3 = ZSTD_hash3Ptr(ip, hashLog3);
|
|
383
351
|
assert(hashLog3 > 0);
|
|
384
352
|
|
|
@@ -387,6 +355,7 @@ static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms, const BYTE*
|
|
|
387
355
|
idx++;
|
|
388
356
|
}
|
|
389
357
|
|
|
358
|
+
*nextToUpdate3 = target;
|
|
390
359
|
return hashTable3[hash3];
|
|
391
360
|
}
|
|
392
361
|
|
|
@@ -503,9 +472,11 @@ static U32 ZSTD_insertBt1(
|
|
|
503
472
|
} }
|
|
504
473
|
|
|
505
474
|
*smallerPtr = *largerPtr = 0;
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
475
|
+
{ U32 positions = 0;
|
|
476
|
+
if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384)); /* speed optimization */
|
|
477
|
+
assert(matchEndIdx > current + 8);
|
|
478
|
+
return MAX(positions, matchEndIdx - (current + 8));
|
|
479
|
+
}
|
|
509
480
|
}
|
|
510
481
|
|
|
511
482
|
FORCE_INLINE_TEMPLATE
|
|
@@ -520,8 +491,13 @@ void ZSTD_updateTree_internal(
|
|
|
520
491
|
DEBUGLOG(6, "ZSTD_updateTree_internal, from %u to %u (dictMode:%u)",
|
|
521
492
|
idx, target, dictMode);
|
|
522
493
|
|
|
523
|
-
while(idx < target)
|
|
524
|
-
|
|
494
|
+
while(idx < target) {
|
|
495
|
+
U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, mls, dictMode == ZSTD_extDict);
|
|
496
|
+
assert(idx < (U32)(idx + forward));
|
|
497
|
+
idx += forward;
|
|
498
|
+
}
|
|
499
|
+
assert((size_t)(ip - base) <= (size_t)(U32)(-1));
|
|
500
|
+
assert((size_t)(iend - base) <= (size_t)(U32)(-1));
|
|
525
501
|
ms->nextToUpdate = target;
|
|
526
502
|
}
|
|
527
503
|
|
|
@@ -531,11 +507,12 @@ void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend) {
|
|
|
531
507
|
|
|
532
508
|
FORCE_INLINE_TEMPLATE
|
|
533
509
|
U32 ZSTD_insertBtAndGetAllMatches (
|
|
510
|
+
ZSTD_match_t* matches, /* store result (found matches) in this table (presumed large enough) */
|
|
534
511
|
ZSTD_matchState_t* ms,
|
|
512
|
+
U32* nextToUpdate3,
|
|
535
513
|
const BYTE* const ip, const BYTE* const iLimit, const ZSTD_dictMode_e dictMode,
|
|
536
|
-
U32 rep[ZSTD_REP_NUM],
|
|
514
|
+
const U32 rep[ZSTD_REP_NUM],
|
|
537
515
|
U32 const ll0, /* tells if associated literal length is 0 or not. This value must be 0 or 1 */
|
|
538
|
-
ZSTD_match_t* matches,
|
|
539
516
|
const U32 lengthToBeat,
|
|
540
517
|
U32 const mls /* template */)
|
|
541
518
|
{
|
|
@@ -556,8 +533,8 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
556
533
|
U32 const dictLimit = ms->window.dictLimit;
|
|
557
534
|
const BYTE* const dictEnd = dictBase + dictLimit;
|
|
558
535
|
const BYTE* const prefixStart = base + dictLimit;
|
|
559
|
-
U32 const btLow = btMask >= current ? 0 : current - btMask;
|
|
560
|
-
U32 const windowLow = ms->
|
|
536
|
+
U32 const btLow = (btMask >= current) ? 0 : current - btMask;
|
|
537
|
+
U32 const windowLow = ZSTD_getLowestMatchIndex(ms, current, cParams->windowLog);
|
|
561
538
|
U32 const matchLow = windowLow ? windowLow : 1;
|
|
562
539
|
U32* smallerPtr = bt + 2*(current&btMask);
|
|
563
540
|
U32* largerPtr = bt + 2*(current&btMask) + 1;
|
|
@@ -592,7 +569,10 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
592
569
|
U32 repLen = 0;
|
|
593
570
|
assert(current >= dictLimit);
|
|
594
571
|
if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < current-dictLimit) { /* equivalent to `current > repIndex >= dictLimit` */
|
|
595
|
-
|
|
572
|
+
/* We must validate the repcode offset because when we're using a dictionary the
|
|
573
|
+
* valid offset range shrinks when the dictionary goes out of bounds.
|
|
574
|
+
*/
|
|
575
|
+
if ((repIndex >= windowLow) & (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch))) {
|
|
596
576
|
repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch;
|
|
597
577
|
}
|
|
598
578
|
} else { /* repIndex < dictLimit || repIndex >= current */
|
|
@@ -627,7 +607,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
627
607
|
|
|
628
608
|
/* HC3 match finder */
|
|
629
609
|
if ((mls == 3) /*static*/ && (bestLength < mls)) {
|
|
630
|
-
U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, ip);
|
|
610
|
+
U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip);
|
|
631
611
|
if ((matchIndex3 >= matchLow)
|
|
632
612
|
& (current - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {
|
|
633
613
|
size_t mlen;
|
|
@@ -653,9 +633,7 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
653
633
|
(ip+mlen == iLimit) ) { /* best possible length */
|
|
654
634
|
ms->nextToUpdate = current+1; /* skip insertion */
|
|
655
635
|
return 1;
|
|
656
|
-
|
|
657
|
-
}
|
|
658
|
-
}
|
|
636
|
+
} } }
|
|
659
637
|
/* no dictMatchState lookup: dicts don't have a populated HC3 table */
|
|
660
638
|
}
|
|
661
639
|
|
|
@@ -663,19 +641,21 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
663
641
|
|
|
664
642
|
while (nbCompares-- && (matchIndex >= matchLow)) {
|
|
665
643
|
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
|
666
|
-
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
|
667
644
|
const BYTE* match;
|
|
645
|
+
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
|
668
646
|
assert(current > matchIndex);
|
|
669
647
|
|
|
670
648
|
if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) {
|
|
671
649
|
assert(matchIndex+matchLength >= dictLimit); /* ensure the condition is correct when !extDict */
|
|
672
650
|
match = base + matchIndex;
|
|
651
|
+
if (matchIndex >= dictLimit) assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */
|
|
673
652
|
matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit);
|
|
674
653
|
} else {
|
|
675
654
|
match = dictBase + matchIndex;
|
|
655
|
+
assert(memcmp(match, ip, matchLength) == 0); /* ensure early section of match is equal as expected */
|
|
676
656
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
|
|
677
657
|
if (matchIndex+matchLength >= dictLimit)
|
|
678
|
-
match = base + matchIndex; /* prepare for match[matchLength] */
|
|
658
|
+
match = base + matchIndex; /* prepare for match[matchLength] read */
|
|
679
659
|
}
|
|
680
660
|
|
|
681
661
|
if (matchLength > bestLength) {
|
|
@@ -760,10 +740,13 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
|
760
740
|
|
|
761
741
|
|
|
762
742
|
FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
|
|
743
|
+
ZSTD_match_t* matches, /* store result (match found, increasing size) in this table */
|
|
763
744
|
ZSTD_matchState_t* ms,
|
|
745
|
+
U32* nextToUpdate3,
|
|
764
746
|
const BYTE* ip, const BYTE* const iHighLimit, const ZSTD_dictMode_e dictMode,
|
|
765
|
-
U32 rep[ZSTD_REP_NUM],
|
|
766
|
-
|
|
747
|
+
const U32 rep[ZSTD_REP_NUM],
|
|
748
|
+
U32 const ll0,
|
|
749
|
+
U32 const lengthToBeat)
|
|
767
750
|
{
|
|
768
751
|
const ZSTD_compressionParameters* const cParams = &ms->cParams;
|
|
769
752
|
U32 const matchLengthSearch = cParams->minMatch;
|
|
@@ -772,12 +755,12 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
|
|
|
772
755
|
ZSTD_updateTree_internal(ms, ip, iHighLimit, matchLengthSearch, dictMode);
|
|
773
756
|
switch(matchLengthSearch)
|
|
774
757
|
{
|
|
775
|
-
case 3 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0,
|
|
758
|
+
case 3 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 3);
|
|
776
759
|
default :
|
|
777
|
-
case 4 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0,
|
|
778
|
-
case 5 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0,
|
|
760
|
+
case 4 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 4);
|
|
761
|
+
case 5 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 5);
|
|
779
762
|
case 7 :
|
|
780
|
-
case 6 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0,
|
|
763
|
+
case 6 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 6);
|
|
781
764
|
}
|
|
782
765
|
}
|
|
783
766
|
|
|
@@ -785,30 +768,6 @@ FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
|
|
|
785
768
|
/*-*******************************
|
|
786
769
|
* Optimal parser
|
|
787
770
|
*********************************/
|
|
788
|
-
typedef struct repcodes_s {
|
|
789
|
-
U32 rep[3];
|
|
790
|
-
} repcodes_t;
|
|
791
|
-
|
|
792
|
-
static repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 const ll0)
|
|
793
|
-
{
|
|
794
|
-
repcodes_t newReps;
|
|
795
|
-
if (offset >= ZSTD_REP_NUM) { /* full offset */
|
|
796
|
-
newReps.rep[2] = rep[1];
|
|
797
|
-
newReps.rep[1] = rep[0];
|
|
798
|
-
newReps.rep[0] = offset - ZSTD_REP_MOVE;
|
|
799
|
-
} else { /* repcode */
|
|
800
|
-
U32 const repCode = offset + ll0;
|
|
801
|
-
if (repCode > 0) { /* note : if repCode==0, no change */
|
|
802
|
-
U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
|
|
803
|
-
newReps.rep[2] = (repCode >= 2) ? rep[1] : rep[2];
|
|
804
|
-
newReps.rep[1] = rep[0];
|
|
805
|
-
newReps.rep[0] = currentOffset;
|
|
806
|
-
} else { /* repCode == 0 */
|
|
807
|
-
memcpy(&newReps, rep, sizeof(newReps));
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
return newReps;
|
|
811
|
-
}
|
|
812
771
|
|
|
813
772
|
|
|
814
773
|
static U32 ZSTD_totalLen(ZSTD_optimal_t sol)
|
|
@@ -825,7 +784,7 @@ listStats(const U32* table, int lastEltID)
|
|
|
825
784
|
int enb;
|
|
826
785
|
for (enb=0; enb < nbElts; enb++) {
|
|
827
786
|
(void)table;
|
|
828
|
-
|
|
787
|
+
/* RAWLOG(2, "%3i:%3i, ", enb, table[enb]); */
|
|
829
788
|
RAWLOG(2, "%4i,", table[enb]);
|
|
830
789
|
}
|
|
831
790
|
RAWLOG(2, " \n");
|
|
@@ -853,6 +812,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
853
812
|
|
|
854
813
|
U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
|
|
855
814
|
U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4;
|
|
815
|
+
U32 nextToUpdate3 = ms->nextToUpdate;
|
|
856
816
|
|
|
857
817
|
ZSTD_optimal_t* const opt = optStatePtr->priceTable;
|
|
858
818
|
ZSTD_match_t* const matches = optStatePtr->matchTable;
|
|
@@ -862,7 +822,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
862
822
|
DEBUGLOG(5, "ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u",
|
|
863
823
|
(U32)(ip - base), ms->window.dictLimit, ms->nextToUpdate);
|
|
864
824
|
assert(optLevel <= 2);
|
|
865
|
-
ms->nextToUpdate3 = ms->nextToUpdate;
|
|
866
825
|
ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize, optLevel);
|
|
867
826
|
ip += (ip==prefixStart);
|
|
868
827
|
|
|
@@ -873,14 +832,19 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
873
832
|
/* find first match */
|
|
874
833
|
{ U32 const litlen = (U32)(ip - anchor);
|
|
875
834
|
U32 const ll0 = !litlen;
|
|
876
|
-
U32 const nbMatches = ZSTD_BtGetAllMatches(ms, ip, iend, dictMode, rep, ll0,
|
|
835
|
+
U32 const nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch);
|
|
877
836
|
if (!nbMatches) { ip++; continue; }
|
|
878
837
|
|
|
879
838
|
/* initialize opt[0] */
|
|
880
839
|
{ U32 i ; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
|
|
881
840
|
opt[0].mlen = 0; /* means is_a_literal */
|
|
882
841
|
opt[0].litlen = litlen;
|
|
883
|
-
|
|
842
|
+
/* We don't need to include the actual price of the literals because
|
|
843
|
+
* it is static for the duration of the forward pass, and is included
|
|
844
|
+
* in every price. We include the literal length to avoid negative
|
|
845
|
+
* prices when we subtract the previous literal length.
|
|
846
|
+
*/
|
|
847
|
+
opt[0].price = ZSTD_litLengthPrice(litlen, optStatePtr, optLevel);
|
|
884
848
|
|
|
885
849
|
/* large match -> immediate encoding */
|
|
886
850
|
{ U32 const maxML = matches[nbMatches-1].len;
|
|
@@ -909,7 +873,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
909
873
|
for (matchNb = 0; matchNb < nbMatches; matchNb++) {
|
|
910
874
|
U32 const offset = matches[matchNb].off;
|
|
911
875
|
U32 const end = matches[matchNb].len;
|
|
912
|
-
repcodes_t const repHistory = ZSTD_updateRep(rep, offset, ll0);
|
|
913
876
|
for ( ; pos <= end ; pos++ ) {
|
|
914
877
|
U32 const matchPrice = ZSTD_getMatchPrice(offset, pos, optStatePtr, optLevel);
|
|
915
878
|
U32 const sequencePrice = literalsPrice + matchPrice;
|
|
@@ -919,8 +882,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
919
882
|
opt[pos].off = offset;
|
|
920
883
|
opt[pos].litlen = litlen;
|
|
921
884
|
opt[pos].price = sequencePrice;
|
|
922
|
-
ZSTD_STATIC_ASSERT(sizeof(opt[pos].rep) == sizeof(repHistory));
|
|
923
|
-
memcpy(opt[pos].rep, &repHistory, sizeof(repHistory));
|
|
924
885
|
} }
|
|
925
886
|
last_pos = pos-1;
|
|
926
887
|
}
|
|
@@ -947,7 +908,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
947
908
|
opt[cur].off = 0;
|
|
948
909
|
opt[cur].litlen = litlen;
|
|
949
910
|
opt[cur].price = price;
|
|
950
|
-
memcpy(opt[cur].rep, opt[cur-1].rep, sizeof(opt[cur].rep));
|
|
951
911
|
} else {
|
|
952
912
|
DEBUGLOG(7, "cPos:%zi==rPos:%u : literal would cost more (%.2f>%.2f) (hist:%u,%u,%u)",
|
|
953
913
|
inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price),
|
|
@@ -955,6 +915,21 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
955
915
|
}
|
|
956
916
|
}
|
|
957
917
|
|
|
918
|
+
/* Set the repcodes of the current position. We must do it here
|
|
919
|
+
* because we rely on the repcodes of the 2nd to last sequence being
|
|
920
|
+
* correct to set the next chunks repcodes during the backward
|
|
921
|
+
* traversal.
|
|
922
|
+
*/
|
|
923
|
+
ZSTD_STATIC_ASSERT(sizeof(opt[cur].rep) == sizeof(repcodes_t));
|
|
924
|
+
assert(cur >= opt[cur].mlen);
|
|
925
|
+
if (opt[cur].mlen != 0) {
|
|
926
|
+
U32 const prev = cur - opt[cur].mlen;
|
|
927
|
+
repcodes_t newReps = ZSTD_updateRep(opt[prev].rep, opt[cur].off, opt[cur].litlen==0);
|
|
928
|
+
memcpy(opt[cur].rep, &newReps, sizeof(repcodes_t));
|
|
929
|
+
} else {
|
|
930
|
+
memcpy(opt[cur].rep, opt[cur - 1].rep, sizeof(repcodes_t));
|
|
931
|
+
}
|
|
932
|
+
|
|
958
933
|
/* last match must start at a minimum distance of 8 from oend */
|
|
959
934
|
if (inr > ilimit) continue;
|
|
960
935
|
|
|
@@ -970,7 +945,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
970
945
|
U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
|
|
971
946
|
U32 const previousPrice = opt[cur].price;
|
|
972
947
|
U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
|
|
973
|
-
U32 const nbMatches = ZSTD_BtGetAllMatches(ms, inr, iend, dictMode, opt[cur].rep, ll0,
|
|
948
|
+
U32 const nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch);
|
|
974
949
|
U32 matchNb;
|
|
975
950
|
if (!nbMatches) {
|
|
976
951
|
DEBUGLOG(7, "rPos:%u : no match found", cur);
|
|
@@ -995,7 +970,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
995
970
|
/* set prices using matches found at position == cur */
|
|
996
971
|
for (matchNb = 0; matchNb < nbMatches; matchNb++) {
|
|
997
972
|
U32 const offset = matches[matchNb].off;
|
|
998
|
-
repcodes_t const repHistory = ZSTD_updateRep(opt[cur].rep, offset, ll0);
|
|
999
973
|
U32 const lastML = matches[matchNb].len;
|
|
1000
974
|
U32 const startML = (matchNb>0) ? matches[matchNb-1].len+1 : minMatch;
|
|
1001
975
|
U32 mlen;
|
|
@@ -1015,8 +989,6 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
1015
989
|
opt[pos].off = offset;
|
|
1016
990
|
opt[pos].litlen = litlen;
|
|
1017
991
|
opt[pos].price = price;
|
|
1018
|
-
ZSTD_STATIC_ASSERT(sizeof(opt[pos].rep) == sizeof(repHistory));
|
|
1019
|
-
memcpy(opt[pos].rep, &repHistory, sizeof(repHistory));
|
|
1020
992
|
} else {
|
|
1021
993
|
DEBUGLOG(7, "rPos:%u (ml=%2u) => new price is worse (%.2f>=%.2f)",
|
|
1022
994
|
pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price));
|
|
@@ -1032,6 +1004,17 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
|
1032
1004
|
_shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
|
|
1033
1005
|
assert(opt[0].mlen == 0);
|
|
1034
1006
|
|
|
1007
|
+
/* Set the next chunk's repcodes based on the repcodes of the beginning
|
|
1008
|
+
* of the last match, and the last sequence. This avoids us having to
|
|
1009
|
+
* update them while traversing the sequences.
|
|
1010
|
+
*/
|
|
1011
|
+
if (lastSequence.mlen != 0) {
|
|
1012
|
+
repcodes_t reps = ZSTD_updateRep(opt[cur].rep, lastSequence.off, lastSequence.litlen==0);
|
|
1013
|
+
memcpy(rep, &reps, sizeof(reps));
|
|
1014
|
+
} else {
|
|
1015
|
+
memcpy(rep, opt[cur].rep, sizeof(repcodes_t));
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1035
1018
|
{ U32 const storeEnd = cur + 1;
|
|
1036
1019
|
U32 storeStart = storeEnd;
|
|
1037
1020
|
U32 seqPos = cur;
|
|
@@ -1068,33 +1051,18 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
|
|
|
1068
1051
|
continue; /* will finish */
|
|
1069
1052
|
}
|
|
1070
1053
|
|
|
1071
|
-
/* repcodes update : like ZSTD_updateRep(), but update in place */
|
|
1072
|
-
if (offCode >= ZSTD_REP_NUM) { /* full offset */
|
|
1073
|
-
rep[2] = rep[1];
|
|
1074
|
-
rep[1] = rep[0];
|
|
1075
|
-
rep[0] = offCode - ZSTD_REP_MOVE;
|
|
1076
|
-
} else { /* repcode */
|
|
1077
|
-
U32 const repCode = offCode + (llen==0);
|
|
1078
|
-
if (repCode) { /* note : if repCode==0, no change */
|
|
1079
|
-
U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
|
|
1080
|
-
if (repCode >= 2) rep[2] = rep[1];
|
|
1081
|
-
rep[1] = rep[0];
|
|
1082
|
-
rep[0] = currentOffset;
|
|
1083
|
-
} }
|
|
1084
|
-
|
|
1085
1054
|
assert(anchor + llen <= iend);
|
|
1086
1055
|
ZSTD_updateStats(optStatePtr, llen, anchor, offCode, mlen);
|
|
1087
|
-
ZSTD_storeSeq(seqStore, llen, anchor, offCode, mlen-MINMATCH);
|
|
1056
|
+
ZSTD_storeSeq(seqStore, llen, anchor, iend, offCode, mlen-MINMATCH);
|
|
1088
1057
|
anchor += advance;
|
|
1089
1058
|
ip = anchor;
|
|
1090
1059
|
} }
|
|
1091
1060
|
ZSTD_setBasePrices(optStatePtr, optLevel);
|
|
1092
1061
|
}
|
|
1093
|
-
|
|
1094
1062
|
} /* while (ip < ilimit) */
|
|
1095
1063
|
|
|
1096
1064
|
/* Return the last literals size */
|
|
1097
|
-
return iend - anchor;
|
|
1065
|
+
return (size_t)(iend - anchor);
|
|
1098
1066
|
}
|
|
1099
1067
|
|
|
1100
1068
|
|
|
@@ -1158,7 +1126,6 @@ ZSTD_initStats_ultra(ZSTD_matchState_t* ms,
|
|
|
1158
1126
|
ms->window.dictLimit += (U32)srcSize;
|
|
1159
1127
|
ms->window.lowLimit = ms->window.dictLimit;
|
|
1160
1128
|
ms->nextToUpdate = ms->window.dictLimit;
|
|
1161
|
-
ms->nextToUpdate3 = ms->window.dictLimit;
|
|
1162
1129
|
|
|
1163
1130
|
/* re-inforce weight of collected statistics */
|
|
1164
1131
|
ZSTD_upscaleStats(&ms->opt);
|