zstd-ruby 1.3.5.0 → 1.3.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -2
- data/README.md +2 -1
- data/ext/zstdruby/libzstd/BUCK +1 -0
- data/ext/zstdruby/libzstd/Makefile +25 -13
- data/ext/zstdruby/libzstd/README.md +11 -10
- data/ext/zstdruby/libzstd/common/bitstream.h +8 -11
- data/ext/zstdruby/libzstd/common/compiler.h +30 -8
- data/ext/zstdruby/libzstd/common/cpu.h +1 -1
- data/ext/zstdruby/libzstd/common/mem.h +20 -2
- data/ext/zstdruby/libzstd/common/xxhash.c +1 -0
- data/ext/zstdruby/libzstd/common/zstd_internal.h +3 -2
- data/ext/zstdruby/libzstd/compress/fse_compress.c +55 -48
- data/ext/zstdruby/libzstd/compress/hist.h +1 -1
- data/ext/zstdruby/libzstd/compress/huf_compress.c +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +290 -147
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +5 -2
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +63 -51
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +3 -4
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +44 -33
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +3 -4
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +125 -116
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +13 -15
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +9 -11
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +0 -1
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +42 -36
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +8 -9
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +96 -51
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +16 -6
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +3 -3
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +169 -101
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +111 -87
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +83 -0
- data/ext/zstdruby/libzstd/dictBuilder/divsufsort.c +3 -3
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +728 -0
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +34 -31
- data/ext/zstdruby/libzstd/dictBuilder/zdict.h +60 -5
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +9 -3
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +6 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +6 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +1 -5
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +12 -9
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +10 -10
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +20 -18
- data/ext/zstdruby/libzstd/zstd.h +109 -50
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +4 -2
@@ -17,50 +17,48 @@ extern "C" {
|
|
17
17
|
|
18
18
|
#include "zstd_compress_internal.h"
|
19
19
|
|
20
|
-
U32 ZSTD_insertAndFindFirstIndex(
|
21
|
-
ZSTD_matchState_t* ms, ZSTD_compressionParameters const* cParams,
|
22
|
-
const BYTE* ip);
|
20
|
+
U32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip);
|
23
21
|
|
24
22
|
void ZSTD_preserveUnsortedMark (U32* const table, U32 const size, U32 const reducerValue); /*! used in ZSTD_reduceIndex(). pre-emptively increase value of ZSTD_DUBT_UNSORTED_MARK */
|
25
23
|
|
26
24
|
size_t ZSTD_compressBlock_btlazy2(
|
27
25
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
28
|
-
|
26
|
+
void const* src, size_t srcSize);
|
29
27
|
size_t ZSTD_compressBlock_lazy2(
|
30
28
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
31
|
-
|
29
|
+
void const* src, size_t srcSize);
|
32
30
|
size_t ZSTD_compressBlock_lazy(
|
33
31
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
34
|
-
|
32
|
+
void const* src, size_t srcSize);
|
35
33
|
size_t ZSTD_compressBlock_greedy(
|
36
34
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
37
|
-
|
35
|
+
void const* src, size_t srcSize);
|
38
36
|
|
39
37
|
size_t ZSTD_compressBlock_btlazy2_dictMatchState(
|
40
38
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
41
|
-
|
39
|
+
void const* src, size_t srcSize);
|
42
40
|
size_t ZSTD_compressBlock_lazy2_dictMatchState(
|
43
41
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
44
|
-
|
42
|
+
void const* src, size_t srcSize);
|
45
43
|
size_t ZSTD_compressBlock_lazy_dictMatchState(
|
46
44
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
47
|
-
|
45
|
+
void const* src, size_t srcSize);
|
48
46
|
size_t ZSTD_compressBlock_greedy_dictMatchState(
|
49
47
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
50
|
-
|
48
|
+
void const* src, size_t srcSize);
|
51
49
|
|
52
50
|
size_t ZSTD_compressBlock_greedy_extDict(
|
53
51
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
54
|
-
|
52
|
+
void const* src, size_t srcSize);
|
55
53
|
size_t ZSTD_compressBlock_lazy_extDict(
|
56
54
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
57
|
-
|
55
|
+
void const* src, size_t srcSize);
|
58
56
|
size_t ZSTD_compressBlock_lazy2_extDict(
|
59
57
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
60
|
-
|
58
|
+
void const* src, size_t srcSize);
|
61
59
|
size_t ZSTD_compressBlock_btlazy2_extDict(
|
62
60
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
63
|
-
|
61
|
+
void const* src, size_t srcSize);
|
64
62
|
|
65
63
|
#if defined (__cplusplus)
|
66
64
|
}
|
@@ -218,19 +218,18 @@ static size_t ZSTD_ldm_countBackwardsMatch(
|
|
218
218
|
* The tables for the other strategies are filled within their
|
219
219
|
* block compressors. */
|
220
220
|
static size_t ZSTD_ldm_fillFastTables(ZSTD_matchState_t* ms,
|
221
|
-
ZSTD_compressionParameters const* cParams,
|
222
221
|
void const* end)
|
223
222
|
{
|
224
223
|
const BYTE* const iend = (const BYTE*)end;
|
225
224
|
|
226
|
-
switch(cParams
|
225
|
+
switch(ms->cParams.strategy)
|
227
226
|
{
|
228
227
|
case ZSTD_fast:
|
229
|
-
ZSTD_fillHashTable(ms,
|
228
|
+
ZSTD_fillHashTable(ms, iend, ZSTD_dtlm_fast);
|
230
229
|
break;
|
231
230
|
|
232
231
|
case ZSTD_dfast:
|
233
|
-
ZSTD_fillDoubleHashTable(ms,
|
232
|
+
ZSTD_fillDoubleHashTable(ms, iend, ZSTD_dtlm_fast);
|
234
233
|
break;
|
235
234
|
|
236
235
|
case ZSTD_greedy:
|
@@ -591,8 +590,9 @@ static rawSeq maybeSplitSequence(rawSeqStore_t* rawSeqStore,
|
|
591
590
|
|
592
591
|
size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
|
593
592
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
594
|
-
|
593
|
+
void const* src, size_t srcSize)
|
595
594
|
{
|
595
|
+
const ZSTD_compressionParameters* const cParams = &ms->cParams;
|
596
596
|
unsigned const minMatch = cParams->searchLength;
|
597
597
|
ZSTD_blockCompressor const blockCompressor =
|
598
598
|
ZSTD_selectBlockCompressor(cParams->strategy, ZSTD_matchState_dictMode(ms));
|
@@ -620,13 +620,12 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
|
|
620
620
|
|
621
621
|
/* Fill tables for block compressor */
|
622
622
|
ZSTD_ldm_limitTableUpdate(ms, ip);
|
623
|
-
ZSTD_ldm_fillFastTables(ms,
|
623
|
+
ZSTD_ldm_fillFastTables(ms, ip);
|
624
624
|
/* Run the block compressor */
|
625
625
|
DEBUGLOG(5, "calling block compressor on segment of size %u", sequence.litLength);
|
626
626
|
{
|
627
627
|
size_t const newLitLength =
|
628
|
-
blockCompressor(ms, seqStore, rep,
|
629
|
-
sequence.litLength);
|
628
|
+
blockCompressor(ms, seqStore, rep, ip, sequence.litLength);
|
630
629
|
ip += sequence.litLength;
|
631
630
|
/* Update the repcodes */
|
632
631
|
for (i = ZSTD_REP_NUM - 1; i > 0; i--)
|
@@ -641,8 +640,7 @@ size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
|
|
641
640
|
}
|
642
641
|
/* Fill the tables for the block compressor */
|
643
642
|
ZSTD_ldm_limitTableUpdate(ms, ip);
|
644
|
-
ZSTD_ldm_fillFastTables(ms,
|
643
|
+
ZSTD_ldm_fillFastTables(ms, ip);
|
645
644
|
/* Compress the last literals */
|
646
|
-
return blockCompressor(ms, seqStore, rep,
|
647
|
-
ip, iend - ip);
|
645
|
+
return blockCompressor(ms, seqStore, rep, ip, iend - ip);
|
648
646
|
}
|
@@ -61,7 +61,6 @@ size_t ZSTD_ldm_generateSequences(
|
|
61
61
|
*/
|
62
62
|
size_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,
|
63
63
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
64
|
-
ZSTD_compressionParameters const* cParams,
|
65
64
|
void const* src, size_t srcSize);
|
66
65
|
|
67
66
|
/**
|
@@ -360,10 +360,11 @@ static U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms, const BYTE*
|
|
360
360
|
* ip : assumed <= iend-8 .
|
361
361
|
* @return : nb of positions added */
|
362
362
|
static U32 ZSTD_insertBt1(
|
363
|
-
ZSTD_matchState_t* ms,
|
363
|
+
ZSTD_matchState_t* ms,
|
364
364
|
const BYTE* const ip, const BYTE* const iend,
|
365
365
|
U32 const mls, const int extDict)
|
366
366
|
{
|
367
|
+
const ZSTD_compressionParameters* const cParams = &ms->cParams;
|
367
368
|
U32* const hashTable = ms->hashTable;
|
368
369
|
U32 const hashLog = cParams->hashLog;
|
369
370
|
size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
|
@@ -471,7 +472,7 @@ static U32 ZSTD_insertBt1(
|
|
471
472
|
|
472
473
|
FORCE_INLINE_TEMPLATE
|
473
474
|
void ZSTD_updateTree_internal(
|
474
|
-
ZSTD_matchState_t* ms,
|
475
|
+
ZSTD_matchState_t* ms,
|
475
476
|
const BYTE* const ip, const BYTE* const iend,
|
476
477
|
const U32 mls, const ZSTD_dictMode_e dictMode)
|
477
478
|
{
|
@@ -482,24 +483,22 @@ void ZSTD_updateTree_internal(
|
|
482
483
|
idx, target, dictMode);
|
483
484
|
|
484
485
|
while(idx < target)
|
485
|
-
idx += ZSTD_insertBt1(ms,
|
486
|
+
idx += ZSTD_insertBt1(ms, base+idx, iend, mls, dictMode == ZSTD_extDict);
|
486
487
|
ms->nextToUpdate = target;
|
487
488
|
}
|
488
489
|
|
489
|
-
void ZSTD_updateTree(
|
490
|
-
|
491
|
-
const BYTE* ip, const BYTE* iend)
|
492
|
-
{
|
493
|
-
ZSTD_updateTree_internal(ms, cParams, ip, iend, cParams->searchLength, ZSTD_noDict);
|
490
|
+
void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend) {
|
491
|
+
ZSTD_updateTree_internal(ms, ip, iend, ms->cParams.searchLength, ZSTD_noDict);
|
494
492
|
}
|
495
493
|
|
496
494
|
FORCE_INLINE_TEMPLATE
|
497
495
|
U32 ZSTD_insertBtAndGetAllMatches (
|
498
|
-
ZSTD_matchState_t* ms,
|
496
|
+
ZSTD_matchState_t* ms,
|
499
497
|
const BYTE* const ip, const BYTE* const iLimit, const ZSTD_dictMode_e dictMode,
|
500
498
|
U32 rep[ZSTD_REP_NUM], U32 const ll0,
|
501
499
|
ZSTD_match_t* matches, const U32 lengthToBeat, U32 const mls /* template */)
|
502
500
|
{
|
501
|
+
const ZSTD_compressionParameters* const cParams = &ms->cParams;
|
503
502
|
U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
|
504
503
|
const BYTE* const base = ms->window.base;
|
505
504
|
U32 const current = (U32)(ip-base);
|
@@ -527,12 +526,17 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
527
526
|
U32 nbCompares = 1U << cParams->searchLog;
|
528
527
|
|
529
528
|
const ZSTD_matchState_t* dms = dictMode == ZSTD_dictMatchState ? ms->dictMatchState : NULL;
|
529
|
+
const ZSTD_compressionParameters* const dmsCParams =
|
530
|
+
dictMode == ZSTD_dictMatchState ? &dms->cParams : NULL;
|
530
531
|
const BYTE* const dmsBase = dictMode == ZSTD_dictMatchState ? dms->window.base : NULL;
|
531
532
|
const BYTE* const dmsEnd = dictMode == ZSTD_dictMatchState ? dms->window.nextSrc : NULL;
|
532
533
|
U32 const dmsHighLimit = dictMode == ZSTD_dictMatchState ? (U32)(dmsEnd - dmsBase) : 0;
|
533
534
|
U32 const dmsLowLimit = dictMode == ZSTD_dictMatchState ? dms->window.lowLimit : 0;
|
534
535
|
U32 const dmsIndexDelta = dictMode == ZSTD_dictMatchState ? windowLow - dmsHighLimit : 0;
|
535
|
-
U32 const
|
536
|
+
U32 const dmsHashLog = dictMode == ZSTD_dictMatchState ? dmsCParams->hashLog : hashLog;
|
537
|
+
U32 const dmsBtLog = dictMode == ZSTD_dictMatchState ? dmsCParams->chainLog - 1 : btLog;
|
538
|
+
U32 const dmsBtMask = dictMode == ZSTD_dictMatchState ? (1U << dmsBtLog) - 1 : 0;
|
539
|
+
U32 const dmsBtLow = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit;
|
536
540
|
|
537
541
|
size_t bestLength = lengthToBeat-1;
|
538
542
|
DEBUGLOG(8, "ZSTD_insertBtAndGetAllMatches: current=%u", current);
|
@@ -667,11 +671,12 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
667
671
|
*smallerPtr = *largerPtr = 0;
|
668
672
|
|
669
673
|
if (dictMode == ZSTD_dictMatchState && nbCompares) {
|
670
|
-
|
674
|
+
size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls);
|
675
|
+
U32 dictMatchIndex = dms->hashTable[dmsH];
|
671
676
|
const U32* const dmsBt = dms->chainTable;
|
672
677
|
commonLengthSmaller = commonLengthLarger = 0;
|
673
678
|
while (nbCompares-- && (dictMatchIndex > dmsLowLimit)) {
|
674
|
-
const U32* const nextPtr = dmsBt + 2*(dictMatchIndex &
|
679
|
+
const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask);
|
675
680
|
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
676
681
|
const BYTE* match = dmsBase + dictMatchIndex;
|
677
682
|
matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dmsEnd, prefixStart);
|
@@ -713,23 +718,24 @@ U32 ZSTD_insertBtAndGetAllMatches (
|
|
713
718
|
|
714
719
|
|
715
720
|
FORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (
|
716
|
-
ZSTD_matchState_t* ms,
|
721
|
+
ZSTD_matchState_t* ms,
|
717
722
|
const BYTE* ip, const BYTE* const iHighLimit, const ZSTD_dictMode_e dictMode,
|
718
723
|
U32 rep[ZSTD_REP_NUM], U32 const ll0,
|
719
724
|
ZSTD_match_t* matches, U32 const lengthToBeat)
|
720
725
|
{
|
726
|
+
const ZSTD_compressionParameters* const cParams = &ms->cParams;
|
721
727
|
U32 const matchLengthSearch = cParams->searchLength;
|
722
728
|
DEBUGLOG(8, "ZSTD_BtGetAllMatches");
|
723
729
|
if (ip < ms->window.base + ms->nextToUpdate) return 0; /* skipped area */
|
724
|
-
ZSTD_updateTree_internal(ms,
|
730
|
+
ZSTD_updateTree_internal(ms, ip, iHighLimit, matchLengthSearch, dictMode);
|
725
731
|
switch(matchLengthSearch)
|
726
732
|
{
|
727
|
-
case 3 : return ZSTD_insertBtAndGetAllMatches(ms,
|
733
|
+
case 3 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 3);
|
728
734
|
default :
|
729
|
-
case 4 : return ZSTD_insertBtAndGetAllMatches(ms,
|
730
|
-
case 5 : return ZSTD_insertBtAndGetAllMatches(ms,
|
735
|
+
case 4 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 4);
|
736
|
+
case 5 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 5);
|
731
737
|
case 7 :
|
732
|
-
case 6 : return ZSTD_insertBtAndGetAllMatches(ms,
|
738
|
+
case 6 : return ZSTD_insertBtAndGetAllMatches(ms, ip, iHighLimit, dictMode, rep, ll0, matches, lengthToBeat, 6);
|
733
739
|
}
|
734
740
|
}
|
735
741
|
|
@@ -741,7 +747,7 @@ typedef struct repcodes_s {
|
|
741
747
|
U32 rep[3];
|
742
748
|
} repcodes_t;
|
743
749
|
|
744
|
-
repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 const ll0)
|
750
|
+
static repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 const ll0)
|
745
751
|
{
|
746
752
|
repcodes_t newReps;
|
747
753
|
if (offset >= ZSTD_REP_NUM) { /* full offset */
|
@@ -772,7 +778,6 @@ FORCE_INLINE_TEMPLATE size_t
|
|
772
778
|
ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
773
779
|
seqStore_t* seqStore,
|
774
780
|
U32 rep[ZSTD_REP_NUM],
|
775
|
-
const ZSTD_compressionParameters* cParams,
|
776
781
|
const void* src, size_t srcSize,
|
777
782
|
const int optLevel, const ZSTD_dictMode_e dictMode)
|
778
783
|
{
|
@@ -784,6 +789,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
784
789
|
const BYTE* const ilimit = iend - 8;
|
785
790
|
const BYTE* const base = ms->window.base;
|
786
791
|
const BYTE* const prefixStart = base + ms->window.dictLimit;
|
792
|
+
const ZSTD_compressionParameters* const cParams = &ms->cParams;
|
787
793
|
|
788
794
|
U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);
|
789
795
|
U32 const minMatch = (cParams->searchLength == 3) ? 3 : 4;
|
@@ -806,7 +812,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
806
812
|
/* find first match */
|
807
813
|
{ U32 const litlen = (U32)(ip - anchor);
|
808
814
|
U32 const ll0 = !litlen;
|
809
|
-
U32 const nbMatches = ZSTD_BtGetAllMatches(ms,
|
815
|
+
U32 const nbMatches = ZSTD_BtGetAllMatches(ms, ip, iend, dictMode, rep, ll0, matches, minMatch);
|
810
816
|
if (!nbMatches) { ip++; continue; }
|
811
817
|
|
812
818
|
/* initialize opt[0] */
|
@@ -903,7 +909,7 @@ ZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,
|
|
903
909
|
U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;
|
904
910
|
U32 const previousPrice = opt[cur].price;
|
905
911
|
U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);
|
906
|
-
U32 const nbMatches = ZSTD_BtGetAllMatches(ms,
|
912
|
+
U32 const nbMatches = ZSTD_BtGetAllMatches(ms, inr, iend, dictMode, opt[cur].rep, ll0, matches, minMatch);
|
907
913
|
U32 matchNb;
|
908
914
|
if (!nbMatches) {
|
909
915
|
DEBUGLOG(7, "rPos:%u : no match found", cur);
|
@@ -970,7 +976,7 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
|
|
970
976
|
U32 seqPos = cur;
|
971
977
|
|
972
978
|
DEBUGLOG(6, "start reverse traversal (last_pos:%u, cur:%u)",
|
973
|
-
last_pos, cur);
|
979
|
+
last_pos, cur); (void)last_pos;
|
974
980
|
assert(storeEnd < ZSTD_OPT_NUM);
|
975
981
|
DEBUGLOG(6, "last sequence copied into pos=%u (llen=%u,mlen=%u,ofc=%u)",
|
976
982
|
storeEnd, lastSequence.litlen, lastSequence.mlen, lastSequence.off);
|
@@ -1033,10 +1039,10 @@ _shortestPath: /* cur, last_pos, best_mlen, best_off have to be set */
|
|
1033
1039
|
|
1034
1040
|
size_t ZSTD_compressBlock_btopt(
|
1035
1041
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
1036
|
-
const
|
1042
|
+
const void* src, size_t srcSize)
|
1037
1043
|
{
|
1038
1044
|
DEBUGLOG(5, "ZSTD_compressBlock_btopt");
|
1039
|
-
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep,
|
1045
|
+
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_noDict);
|
1040
1046
|
}
|
1041
1047
|
|
1042
1048
|
|
@@ -1064,7 +1070,7 @@ MEM_STATIC void ZSTD_upscaleStats(optState_t* optPtr)
|
|
1064
1070
|
|
1065
1071
|
size_t ZSTD_compressBlock_btultra(
|
1066
1072
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
1067
|
-
const
|
1073
|
+
const void* src, size_t srcSize)
|
1068
1074
|
{
|
1069
1075
|
DEBUGLOG(5, "ZSTD_compressBlock_btultra (srcSize=%zu)", srcSize);
|
1070
1076
|
#if 0
|
@@ -1082,7 +1088,7 @@ size_t ZSTD_compressBlock_btultra(
|
|
1082
1088
|
assert(ms->nextToUpdate >= ms->window.dictLimit
|
1083
1089
|
&& ms->nextToUpdate <= ms->window.dictLimit + 1);
|
1084
1090
|
memcpy(tmpRep, rep, sizeof(tmpRep));
|
1085
|
-
ZSTD_compressBlock_opt_generic(ms, seqStore, tmpRep,
|
1091
|
+
ZSTD_compressBlock_opt_generic(ms, seqStore, tmpRep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict); /* generate stats into ms->opt*/
|
1086
1092
|
ZSTD_resetSeqStore(seqStore);
|
1087
1093
|
/* invalidate first scan from history */
|
1088
1094
|
ms->window.base -= srcSize;
|
@@ -1094,33 +1100,33 @@ size_t ZSTD_compressBlock_btultra(
|
|
1094
1100
|
ZSTD_upscaleStats(&ms->opt);
|
1095
1101
|
}
|
1096
1102
|
#endif
|
1097
|
-
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep,
|
1103
|
+
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict);
|
1098
1104
|
}
|
1099
1105
|
|
1100
1106
|
size_t ZSTD_compressBlock_btopt_dictMatchState(
|
1101
1107
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
1102
|
-
const
|
1108
|
+
const void* src, size_t srcSize)
|
1103
1109
|
{
|
1104
|
-
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep,
|
1110
|
+
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_dictMatchState);
|
1105
1111
|
}
|
1106
1112
|
|
1107
1113
|
size_t ZSTD_compressBlock_btultra_dictMatchState(
|
1108
1114
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
1109
|
-
const
|
1115
|
+
const void* src, size_t srcSize)
|
1110
1116
|
{
|
1111
|
-
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep,
|
1117
|
+
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_dictMatchState);
|
1112
1118
|
}
|
1113
1119
|
|
1114
1120
|
size_t ZSTD_compressBlock_btopt_extDict(
|
1115
1121
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
1116
|
-
const
|
1122
|
+
const void* src, size_t srcSize)
|
1117
1123
|
{
|
1118
|
-
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep,
|
1124
|
+
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_extDict);
|
1119
1125
|
}
|
1120
1126
|
|
1121
1127
|
size_t ZSTD_compressBlock_btultra_extDict(
|
1122
1128
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
1123
|
-
const
|
1129
|
+
const void* src, size_t srcSize)
|
1124
1130
|
{
|
1125
|
-
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep,
|
1131
|
+
return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_extDict);
|
1126
1132
|
}
|
@@ -17,30 +17,29 @@ extern "C" {
|
|
17
17
|
|
18
18
|
#include "zstd_compress_internal.h"
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
const BYTE* ip, const BYTE* iend); /* used in ZSTD_loadDictionaryContent() */
|
20
|
+
/* used in ZSTD_loadDictionaryContent() */
|
21
|
+
void ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend);
|
23
22
|
|
24
23
|
size_t ZSTD_compressBlock_btopt(
|
25
24
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
26
|
-
|
25
|
+
void const* src, size_t srcSize);
|
27
26
|
size_t ZSTD_compressBlock_btultra(
|
28
27
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
29
|
-
|
28
|
+
void const* src, size_t srcSize);
|
30
29
|
|
31
30
|
size_t ZSTD_compressBlock_btopt_dictMatchState(
|
32
31
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
33
|
-
|
32
|
+
void const* src, size_t srcSize);
|
34
33
|
size_t ZSTD_compressBlock_btultra_dictMatchState(
|
35
34
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
36
|
-
|
35
|
+
void const* src, size_t srcSize);
|
37
36
|
|
38
37
|
size_t ZSTD_compressBlock_btopt_extDict(
|
39
38
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
40
|
-
|
39
|
+
void const* src, size_t srcSize);
|
41
40
|
size_t ZSTD_compressBlock_btultra_extDict(
|
42
41
|
ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
43
|
-
|
42
|
+
void const* src, size_t srcSize);
|
44
43
|
|
45
44
|
#if defined (__cplusplus)
|
46
45
|
}
|
@@ -37,7 +37,9 @@
|
|
37
37
|
#define ZSTD_RESIZE_SEQPOOL 0
|
38
38
|
|
39
39
|
/* ====== Debug ====== */
|
40
|
-
#if defined(DEBUGLEVEL) && (DEBUGLEVEL>=2)
|
40
|
+
#if defined(DEBUGLEVEL) && (DEBUGLEVEL>=2) \
|
41
|
+
&& !defined(_MSC_VER) \
|
42
|
+
&& !defined(__MINGW32__)
|
41
43
|
|
42
44
|
# include <stdio.h>
|
43
45
|
# include <unistd.h>
|
@@ -247,8 +249,8 @@ static buffer_t ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buffer)
|
|
247
249
|
/* store buffer for later re-use, up to pool capacity */
|
248
250
|
static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)
|
249
251
|
{
|
250
|
-
if (buf.start == NULL) return; /* compatible with release on NULL */
|
251
252
|
DEBUGLOG(5, "ZSTDMT_releaseBuffer");
|
253
|
+
if (buf.start == NULL) return; /* compatible with release on NULL */
|
252
254
|
ZSTD_pthread_mutex_lock(&bufPool->poolMutex);
|
253
255
|
if (bufPool->nbBuffers < bufPool->totalBuffers) {
|
254
256
|
bufPool->bTable[bufPool->nbBuffers++] = buf; /* stored for later use */
|
@@ -318,7 +320,8 @@ static void ZSTDMT_setNbSeq(ZSTDMT_seqPool* const seqPool, size_t const nbSeq)
|
|
318
320
|
|
319
321
|
static ZSTDMT_seqPool* ZSTDMT_createSeqPool(unsigned nbWorkers, ZSTD_customMem cMem)
|
320
322
|
{
|
321
|
-
ZSTDMT_seqPool* seqPool = ZSTDMT_createBufferPool(nbWorkers, cMem);
|
323
|
+
ZSTDMT_seqPool* const seqPool = ZSTDMT_createBufferPool(nbWorkers, cMem);
|
324
|
+
if (seqPool == NULL) return NULL;
|
322
325
|
ZSTDMT_setNbSeq(seqPool, 0);
|
323
326
|
return seqPool;
|
324
327
|
}
|
@@ -539,6 +542,7 @@ static void ZSTDMT_serialState_update(serialState_t* serialState,
|
|
539
542
|
/* Wait for our turn */
|
540
543
|
ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex);
|
541
544
|
while (serialState->nextJobID < jobID) {
|
545
|
+
DEBUGLOG(5, "wait for serialState->cond");
|
542
546
|
ZSTD_pthread_cond_wait(&serialState->cond, &serialState->mutex);
|
543
547
|
}
|
544
548
|
/* A future job may error and skip our job */
|
@@ -628,32 +632,32 @@ typedef struct {
|
|
628
632
|
unsigned frameChecksumNeeded; /* used only by mtctx */
|
629
633
|
} ZSTDMT_jobDescription;
|
630
634
|
|
635
|
+
#define JOB_ERROR(e) { \
|
636
|
+
ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex); \
|
637
|
+
job->cSize = e; \
|
638
|
+
ZSTD_pthread_mutex_unlock(&job->job_mutex); \
|
639
|
+
goto _endJob; \
|
640
|
+
}
|
641
|
+
|
631
642
|
/* ZSTDMT_compressionJob() is a POOL_function type */
|
632
|
-
void ZSTDMT_compressionJob(void* jobDescription)
|
643
|
+
static void ZSTDMT_compressionJob(void* jobDescription)
|
633
644
|
{
|
634
645
|
ZSTDMT_jobDescription* const job = (ZSTDMT_jobDescription*)jobDescription;
|
635
646
|
ZSTD_CCtx_params jobParams = job->params; /* do not modify job->params ! copy it, modify the copy */
|
636
647
|
ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(job->cctxPool);
|
637
648
|
rawSeqStore_t rawSeqStore = ZSTDMT_getSeq(job->seqPool);
|
638
649
|
buffer_t dstBuff = job->dstBuff;
|
650
|
+
size_t lastCBlockSize = 0;
|
639
651
|
|
640
652
|
/* ressources */
|
641
|
-
if (cctx==NULL)
|
642
|
-
job->cSize = ERROR(memory_allocation);
|
643
|
-
goto _endJob;
|
644
|
-
}
|
653
|
+
if (cctx==NULL) JOB_ERROR(ERROR(memory_allocation));
|
645
654
|
if (dstBuff.start == NULL) { /* streaming job : doesn't provide a dstBuffer */
|
646
655
|
dstBuff = ZSTDMT_getBuffer(job->bufPool);
|
647
|
-
if (dstBuff.start==NULL)
|
648
|
-
job->cSize = ERROR(memory_allocation);
|
649
|
-
goto _endJob;
|
650
|
-
}
|
656
|
+
if (dstBuff.start==NULL) JOB_ERROR(ERROR(memory_allocation));
|
651
657
|
job->dstBuff = dstBuff; /* this value can be read in ZSTDMT_flush, when it copies the whole job */
|
652
658
|
}
|
653
|
-
if (jobParams.ldmParams.enableLdm && rawSeqStore.seq == NULL)
|
654
|
-
|
655
|
-
goto _endJob;
|
656
|
-
}
|
659
|
+
if (jobParams.ldmParams.enableLdm && rawSeqStore.seq == NULL)
|
660
|
+
JOB_ERROR(ERROR(memory_allocation));
|
657
661
|
|
658
662
|
/* Don't compute the checksum for chunks, since we compute it externally,
|
659
663
|
* but write it in the header.
|
@@ -667,30 +671,26 @@ void ZSTDMT_compressionJob(void* jobDescription)
|
|
667
671
|
if (job->cdict) {
|
668
672
|
size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, job->cdict, jobParams, job->fullFrameSize);
|
669
673
|
assert(job->firstJob); /* only allowed for first job */
|
670
|
-
if (ZSTD_isError(initError))
|
674
|
+
if (ZSTD_isError(initError)) JOB_ERROR(initError);
|
671
675
|
} else { /* srcStart points at reloaded section */
|
672
676
|
U64 const pledgedSrcSize = job->firstJob ? job->fullFrameSize : job->src.size;
|
673
677
|
{ size_t const forceWindowError = ZSTD_CCtxParam_setParameter(&jobParams, ZSTD_p_forceMaxWindow, !job->firstJob);
|
674
|
-
if (ZSTD_isError(forceWindowError))
|
675
|
-
|
676
|
-
goto _endJob;
|
677
|
-
} }
|
678
|
+
if (ZSTD_isError(forceWindowError)) JOB_ERROR(forceWindowError);
|
679
|
+
}
|
678
680
|
{ size_t const initError = ZSTD_compressBegin_advanced_internal(cctx,
|
679
681
|
job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, /* load dictionary in "content-only" mode (no header analysis) */
|
680
682
|
ZSTD_dtlm_fast,
|
681
683
|
NULL, /*cdict*/
|
682
684
|
jobParams, pledgedSrcSize);
|
683
|
-
if (ZSTD_isError(initError))
|
684
|
-
|
685
|
-
goto _endJob;
|
686
|
-
} } }
|
685
|
+
if (ZSTD_isError(initError)) JOB_ERROR(initError);
|
686
|
+
} }
|
687
687
|
|
688
688
|
/* Perform serial step as early as possible, but after CCtx initialization */
|
689
689
|
ZSTDMT_serialState_update(job->serial, cctx, rawSeqStore, job->src, job->jobID);
|
690
690
|
|
691
691
|
if (!job->firstJob) { /* flush and overwrite frame header when it's not first job */
|
692
692
|
size_t const hSize = ZSTD_compressContinue(cctx, dstBuff.start, dstBuff.capacity, job->src.start, 0);
|
693
|
-
if (ZSTD_isError(hSize))
|
693
|
+
if (ZSTD_isError(hSize)) JOB_ERROR(hSize);
|
694
694
|
DEBUGLOG(5, "ZSTDMT_compressionJob: flush and overwrite %u bytes of frame header (not first job)", (U32)hSize);
|
695
695
|
ZSTD_invalidateRepCodes(cctx);
|
696
696
|
}
|
@@ -708,7 +708,7 @@ void ZSTDMT_compressionJob(void* jobDescription)
|
|
708
708
|
assert(job->cSize == 0);
|
709
709
|
for (chunkNb = 1; chunkNb < nbChunks; chunkNb++) {
|
710
710
|
size_t const cSize = ZSTD_compressContinue(cctx, op, oend-op, ip, chunkSize);
|
711
|
-
if (ZSTD_isError(cSize))
|
711
|
+
if (ZSTD_isError(cSize)) JOB_ERROR(cSize);
|
712
712
|
ip += chunkSize;
|
713
713
|
op += cSize; assert(op < oend);
|
714
714
|
/* stats */
|
@@ -721,18 +721,16 @@ void ZSTDMT_compressionJob(void* jobDescription)
|
|
721
721
|
ZSTD_pthread_mutex_unlock(&job->job_mutex);
|
722
722
|
}
|
723
723
|
/* last block */
|
724
|
-
assert(chunkSize > 0);
|
724
|
+
assert(chunkSize > 0);
|
725
|
+
assert((chunkSize & (chunkSize - 1)) == 0); /* chunkSize must be power of 2 for mask==(chunkSize-1) to work */
|
725
726
|
if ((nbChunks > 0) | job->lastJob /*must output a "last block" flag*/ ) {
|
726
727
|
size_t const lastBlockSize1 = job->src.size & (chunkSize-1);
|
727
728
|
size_t const lastBlockSize = ((lastBlockSize1==0) & (job->src.size>=chunkSize)) ? chunkSize : lastBlockSize1;
|
728
729
|
size_t const cSize = (job->lastJob) ?
|
729
730
|
ZSTD_compressEnd (cctx, op, oend-op, ip, lastBlockSize) :
|
730
731
|
ZSTD_compressContinue(cctx, op, oend-op, ip, lastBlockSize);
|
731
|
-
if (ZSTD_isError(cSize))
|
732
|
-
|
733
|
-
ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex);
|
734
|
-
job->cSize += cSize;
|
735
|
-
ZSTD_pthread_mutex_unlock(&job->job_mutex);
|
732
|
+
if (ZSTD_isError(cSize)) JOB_ERROR(cSize);
|
733
|
+
lastCBlockSize = cSize;
|
736
734
|
} }
|
737
735
|
|
738
736
|
_endJob:
|
@@ -745,7 +743,9 @@ _endJob:
|
|
745
743
|
ZSTDMT_releaseCCtx(job->cctxPool, cctx);
|
746
744
|
/* report */
|
747
745
|
ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex);
|
748
|
-
job->
|
746
|
+
if (ZSTD_isError(job->cSize)) assert(lastCBlockSize == 0);
|
747
|
+
job->cSize += lastCBlockSize;
|
748
|
+
job->consumed = job->src.size; /* when job->consumed == job->src.size , compression job is presumed completed */
|
749
749
|
ZSTD_pthread_cond_signal(&job->job_cond);
|
750
750
|
ZSTD_pthread_mutex_unlock(&job->job_mutex);
|
751
751
|
}
|
@@ -930,7 +930,7 @@ static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* mtctx)
|
|
930
930
|
unsigned const jobID = mtctx->doneJobID & mtctx->jobIDMask;
|
931
931
|
ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[jobID].job_mutex);
|
932
932
|
while (mtctx->jobs[jobID].consumed < mtctx->jobs[jobID].src.size) {
|
933
|
-
DEBUGLOG(
|
933
|
+
DEBUGLOG(4, "waiting for jobCompleted signal from job %u", mtctx->doneJobID); /* we want to block when waiting for data to flush */
|
934
934
|
ZSTD_pthread_cond_wait(&mtctx->jobs[jobID].job_cond, &mtctx->jobs[jobID].job_mutex);
|
935
935
|
}
|
936
936
|
ZSTD_pthread_mutex_unlock(&mtctx->jobs[jobID].job_mutex);
|
@@ -1055,7 +1055,7 @@ static size_t ZSTDMT_resize(ZSTDMT_CCtx* mtctx, unsigned nbWorkers)
|
|
1055
1055
|
|
1056
1056
|
|
1057
1057
|
/*! ZSTDMT_updateCParams_whileCompressing() :
|
1058
|
-
* Updates
|
1058
|
+
* Updates a selected set of compression parameters, remaining compatible with currently active frame.
|
1059
1059
|
* New parameters will be applied to next compression job. */
|
1060
1060
|
void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_params* cctxParams)
|
1061
1061
|
{
|
@@ -1073,26 +1073,33 @@ void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_p
|
|
1073
1073
|
/* ZSTDMT_getFrameProgression():
|
1074
1074
|
* tells how much data has been consumed (input) and produced (output) for current frame.
|
1075
1075
|
* able to count progression inside worker threads.
|
1076
|
-
* Note : mutex will be acquired during statistics collection. */
|
1076
|
+
* Note : mutex will be acquired during statistics collection inside workers. */
|
1077
1077
|
ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx)
|
1078
1078
|
{
|
1079
1079
|
ZSTD_frameProgression fps;
|
1080
|
-
DEBUGLOG(
|
1081
|
-
fps.consumed = mtctx->consumed;
|
1082
|
-
fps.produced = mtctx->produced;
|
1080
|
+
DEBUGLOG(5, "ZSTDMT_getFrameProgression");
|
1083
1081
|
fps.ingested = mtctx->consumed + mtctx->inBuff.filled;
|
1082
|
+
fps.consumed = mtctx->consumed;
|
1083
|
+
fps.produced = fps.flushed = mtctx->produced;
|
1084
|
+
fps.currentJobID = mtctx->nextJobID;
|
1085
|
+
fps.nbActiveWorkers = 0;
|
1084
1086
|
{ unsigned jobNb;
|
1085
1087
|
unsigned lastJobNb = mtctx->nextJobID + mtctx->jobReady; assert(mtctx->jobReady <= 1);
|
1086
1088
|
DEBUGLOG(6, "ZSTDMT_getFrameProgression: jobs: from %u to <%u (jobReady:%u)",
|
1087
1089
|
mtctx->doneJobID, lastJobNb, mtctx->jobReady)
|
1088
1090
|
for (jobNb = mtctx->doneJobID ; jobNb < lastJobNb ; jobNb++) {
|
1089
1091
|
unsigned const wJobID = jobNb & mtctx->jobIDMask;
|
1090
|
-
|
1091
|
-
|
1092
|
+
ZSTDMT_jobDescription* jobPtr = &mtctx->jobs[wJobID];
|
1093
|
+
ZSTD_pthread_mutex_lock(&jobPtr->job_mutex);
|
1094
|
+
{ size_t const cResult = jobPtr->cSize;
|
1092
1095
|
size_t const produced = ZSTD_isError(cResult) ? 0 : cResult;
|
1093
|
-
|
1094
|
-
|
1096
|
+
size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed;
|
1097
|
+
assert(flushed <= produced);
|
1098
|
+
fps.ingested += jobPtr->src.size;
|
1099
|
+
fps.consumed += jobPtr->consumed;
|
1095
1100
|
fps.produced += produced;
|
1101
|
+
fps.flushed += flushed;
|
1102
|
+
fps.nbActiveWorkers += (jobPtr->consumed < jobPtr->src.size);
|
1096
1103
|
}
|
1097
1104
|
ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);
|
1098
1105
|
}
|
@@ -1101,6 +1108,34 @@ ZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx)
|
|
1101
1108
|
}
|
1102
1109
|
|
1103
1110
|
|
1111
|
+
size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx)
|
1112
|
+
{
|
1113
|
+
size_t toFlush;
|
1114
|
+
unsigned const jobID = mtctx->doneJobID;
|
1115
|
+
assert(jobID <= mtctx->nextJobID);
|
1116
|
+
if (jobID == mtctx->nextJobID) return 0; /* no active job => nothing to flush */
|
1117
|
+
|
1118
|
+
/* look into oldest non-fully-flushed job */
|
1119
|
+
{ unsigned const wJobID = jobID & mtctx->jobIDMask;
|
1120
|
+
ZSTDMT_jobDescription* const jobPtr = &mtctx->jobs[wJobID];
|
1121
|
+
ZSTD_pthread_mutex_lock(&jobPtr->job_mutex);
|
1122
|
+
{ size_t const cResult = jobPtr->cSize;
|
1123
|
+
size_t const produced = ZSTD_isError(cResult) ? 0 : cResult;
|
1124
|
+
size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed;
|
1125
|
+
assert(flushed <= produced);
|
1126
|
+
toFlush = produced - flushed;
|
1127
|
+
if (toFlush==0 && (jobPtr->consumed >= jobPtr->src.size)) {
|
1128
|
+
/* doneJobID is not-fully-flushed, but toFlush==0 : doneJobID should be compressing some more data */
|
1129
|
+
assert(jobPtr->consumed < jobPtr->src.size);
|
1130
|
+
}
|
1131
|
+
}
|
1132
|
+
ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);
|
1133
|
+
}
|
1134
|
+
|
1135
|
+
return toFlush;
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
|
1104
1139
|
/* ------------------------------------------ */
|
1105
1140
|
/* ===== Multi-threaded compression ===== */
|
1106
1141
|
/* ------------------------------------------ */
|
@@ -1495,7 +1530,7 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* mtctx, size_t srcSize, ZS
|
|
1495
1530
|
mtctx->jobs[jobID].jobID = mtctx->nextJobID;
|
1496
1531
|
mtctx->jobs[jobID].firstJob = (mtctx->nextJobID==0);
|
1497
1532
|
mtctx->jobs[jobID].lastJob = endFrame;
|
1498
|
-
mtctx->jobs[jobID].frameChecksumNeeded = endFrame && (mtctx->nextJobID>0)
|
1533
|
+
mtctx->jobs[jobID].frameChecksumNeeded = mtctx->params.fParams.checksumFlag && endFrame && (mtctx->nextJobID>0);
|
1499
1534
|
mtctx->jobs[jobID].dstFlushed = 0;
|
1500
1535
|
|
1501
1536
|
/* Update the round buffer pos and clear the input buffer to be reset */
|
@@ -1543,6 +1578,8 @@ static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* mtctx, size_t srcSize, ZS
|
|
1543
1578
|
|
1544
1579
|
|
1545
1580
|
/*! ZSTDMT_flushProduced() :
|
1581
|
+
* flush whatever data has been produced but not yet flushed in current job.
|
1582
|
+
* move to next job if current one is fully flushed.
|
1546
1583
|
* `output` : `pos` will be updated with amount of data flushed .
|
1547
1584
|
* `blockToFlush` : if >0, the function will block and wait if there is no data available to flush .
|
1548
1585
|
* @return : amount of data remaining within internal buffer, 0 if no more, 1 if unknown but > 0, or an error code */
|
@@ -1571,7 +1608,7 @@ static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, u
|
|
1571
1608
|
/* try to flush something */
|
1572
1609
|
{ size_t cSize = mtctx->jobs[wJobID].cSize; /* shared */
|
1573
1610
|
size_t const srcConsumed = mtctx->jobs[wJobID].consumed; /* shared */
|
1574
|
-
size_t const srcSize = mtctx->jobs[wJobID].src.size;
|
1611
|
+
size_t const srcSize = mtctx->jobs[wJobID].src.size; /* read-only, could be done after mutex lock, but no-declaration-after-statement */
|
1575
1612
|
ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);
|
1576
1613
|
if (ZSTD_isError(cSize)) {
|
1577
1614
|
DEBUGLOG(5, "ZSTDMT_flushProduced: job %u : compression error detected : %s",
|
@@ -1591,6 +1628,7 @@ static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, u
|
|
1591
1628
|
mtctx->jobs[wJobID].cSize += 4; /* can write this shared value, as worker is no longer active */
|
1592
1629
|
mtctx->jobs[wJobID].frameChecksumNeeded = 0;
|
1593
1630
|
}
|
1631
|
+
|
1594
1632
|
if (cSize > 0) { /* compression is ongoing or completed */
|
1595
1633
|
size_t const toFlush = MIN(cSize - mtctx->jobs[wJobID].dstFlushed, output->size - output->pos);
|
1596
1634
|
DEBUGLOG(5, "ZSTDMT_flushProduced: Flushing %u bytes from job %u (completion:%u/%u, generated:%u)",
|
@@ -1604,11 +1642,12 @@ static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, u
|
|
1604
1642
|
output->pos += toFlush;
|
1605
1643
|
mtctx->jobs[wJobID].dstFlushed += toFlush; /* can write : this value is only used by mtctx */
|
1606
1644
|
|
1607
|
-
if ( (srcConsumed == srcSize) /* job completed */
|
1645
|
+
if ( (srcConsumed == srcSize) /* job is completed */
|
1608
1646
|
&& (mtctx->jobs[wJobID].dstFlushed == cSize) ) { /* output buffer fully flushed => free this job position */
|
1609
1647
|
DEBUGLOG(5, "Job %u completed (%u bytes), moving to next one",
|
1610
1648
|
mtctx->doneJobID, (U32)mtctx->jobs[wJobID].dstFlushed);
|
1611
1649
|
ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[wJobID].dstBuff);
|
1650
|
+
DEBUGLOG(5, "dstBuffer released");
|
1612
1651
|
mtctx->jobs[wJobID].dstBuff = g_nullBuffer;
|
1613
1652
|
mtctx->jobs[wJobID].cSize = 0; /* ensure this job slot is considered "not started" in future check */
|
1614
1653
|
mtctx->consumed += srcSize;
|
@@ -1685,6 +1724,7 @@ static int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window)
|
|
1685
1724
|
range_t extDict;
|
1686
1725
|
range_t prefix;
|
1687
1726
|
|
1727
|
+
DEBUGLOG(5, "ZSTDMT_doesOverlapWindow");
|
1688
1728
|
extDict.start = window.dictBase + window.lowLimit;
|
1689
1729
|
extDict.size = window.dictLimit - window.lowLimit;
|
1690
1730
|
|
@@ -1705,12 +1745,13 @@ static void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, buffer_t buffer)
|
|
1705
1745
|
{
|
1706
1746
|
if (mtctx->params.ldmParams.enableLdm) {
|
1707
1747
|
ZSTD_pthread_mutex_t* mutex = &mtctx->serial.ldmWindowMutex;
|
1748
|
+
DEBUGLOG(5, "ZSTDMT_waitForLdmComplete");
|
1708
1749
|
DEBUGLOG(5, "source [0x%zx, 0x%zx)",
|
1709
1750
|
(size_t)buffer.start,
|
1710
1751
|
(size_t)buffer.start + buffer.capacity);
|
1711
1752
|
ZSTD_PTHREAD_MUTEX_LOCK(mutex);
|
1712
1753
|
while (ZSTDMT_doesOverlapWindow(buffer, mtctx->serial.ldmWindow)) {
|
1713
|
-
DEBUGLOG(
|
1754
|
+
DEBUGLOG(5, "Waiting for LDM to finish...");
|
1714
1755
|
ZSTD_pthread_cond_wait(&mtctx->serial.ldmWindowCond, mutex);
|
1715
1756
|
}
|
1716
1757
|
DEBUGLOG(6, "Done waiting for LDM to finish");
|
@@ -1730,6 +1771,7 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
|
|
1730
1771
|
size_t const target = mtctx->targetSectionSize;
|
1731
1772
|
buffer_t buffer;
|
1732
1773
|
|
1774
|
+
DEBUGLOG(5, "ZSTDMT_tryGetInputRange");
|
1733
1775
|
assert(mtctx->inBuff.buffer.start == NULL);
|
1734
1776
|
assert(mtctx->roundBuff.capacity >= target);
|
1735
1777
|
|
@@ -1743,7 +1785,7 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
|
|
1743
1785
|
buffer.start = start;
|
1744
1786
|
buffer.capacity = prefixSize;
|
1745
1787
|
if (ZSTDMT_isOverlapped(buffer, inUse)) {
|
1746
|
-
DEBUGLOG(
|
1788
|
+
DEBUGLOG(5, "Waiting for buffer...");
|
1747
1789
|
return 0;
|
1748
1790
|
}
|
1749
1791
|
ZSTDMT_waitForLdmComplete(mtctx, buffer);
|
@@ -1755,7 +1797,7 @@ static int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)
|
|
1755
1797
|
buffer.capacity = target;
|
1756
1798
|
|
1757
1799
|
if (ZSTDMT_isOverlapped(buffer, inUse)) {
|
1758
|
-
DEBUGLOG(
|
1800
|
+
DEBUGLOG(5, "Waiting for buffer...");
|
1759
1801
|
return 0;
|
1760
1802
|
}
|
1761
1803
|
assert(!ZSTDMT_isOverlapped(buffer, mtctx->inBuff.prefix));
|
@@ -1828,8 +1870,10 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
1828
1870
|
/* It is only possible for this operation to fail if there are
|
1829
1871
|
* still compression jobs ongoing.
|
1830
1872
|
*/
|
1873
|
+
DEBUGLOG(5, "ZSTDMT_tryGetInputRange failed");
|
1831
1874
|
assert(mtctx->doneJobID != mtctx->nextJobID);
|
1832
|
-
}
|
1875
|
+
} else
|
1876
|
+
DEBUGLOG(5, "ZSTDMT_tryGetInputRange completed successfully : mtctx->inBuff.buffer.start = %p", mtctx->inBuff.buffer.start);
|
1833
1877
|
}
|
1834
1878
|
if (mtctx->inBuff.buffer.start != NULL) {
|
1835
1879
|
size_t const toLoad = MIN(input->size - input->pos, mtctx->targetSectionSize - mtctx->inBuff.filled);
|
@@ -1857,6 +1901,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
1857
1901
|
/* check for potential compressed data ready to be flushed */
|
1858
1902
|
{ size_t const remainingToFlush = ZSTDMT_flushProduced(mtctx, output, !forwardInputProgress, endOp); /* block if there was no forward input progress */
|
1859
1903
|
if (input->pos < input->size) return MAX(remainingToFlush, 1); /* input not consumed : do not end flush yet */
|
1904
|
+
DEBUGLOG(5, "end of ZSTDMT_compressStream_generic: remainingToFlush = %u", (U32)remainingToFlush);
|
1860
1905
|
return remainingToFlush;
|
1861
1906
|
}
|
1862
1907
|
}
|