zstd-ruby 1.3.5.0 → 1.3.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/.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
|
}
|