zstd-ruby 1.3.8.0 → 1.4.5.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 +6 -5
- data/README.md +1 -1
- data/ext/zstdruby/libzstd/Makefile +133 -61
- data/ext/zstdruby/libzstd/README.md +51 -18
- data/ext/zstdruby/libzstd/common/bitstream.h +38 -39
- data/ext/zstdruby/libzstd/common/compiler.h +41 -6
- data/ext/zstdruby/libzstd/common/cpu.h +1 -1
- data/ext/zstdruby/libzstd/common/debug.c +11 -31
- data/ext/zstdruby/libzstd/common/debug.h +11 -31
- data/ext/zstdruby/libzstd/common/entropy_common.c +13 -33
- data/ext/zstdruby/libzstd/common/error_private.c +2 -1
- data/ext/zstdruby/libzstd/common/error_private.h +6 -2
- data/ext/zstdruby/libzstd/common/fse.h +13 -33
- data/ext/zstdruby/libzstd/common/fse_decompress.c +12 -35
- data/ext/zstdruby/libzstd/common/huf.h +15 -33
- data/ext/zstdruby/libzstd/common/mem.h +75 -2
- data/ext/zstdruby/libzstd/common/pool.c +8 -4
- data/ext/zstdruby/libzstd/common/pool.h +2 -2
- data/ext/zstdruby/libzstd/common/threading.c +52 -6
- data/ext/zstdruby/libzstd/common/threading.h +36 -4
- data/ext/zstdruby/libzstd/common/xxhash.c +25 -37
- data/ext/zstdruby/libzstd/common/xxhash.h +11 -31
- data/ext/zstdruby/libzstd/common/zstd_common.c +1 -1
- data/ext/zstdruby/libzstd/common/zstd_errors.h +2 -1
- data/ext/zstdruby/libzstd/common/zstd_internal.h +203 -22
- data/ext/zstdruby/libzstd/compress/fse_compress.c +19 -42
- data/ext/zstdruby/libzstd/compress/hist.c +15 -35
- data/ext/zstdruby/libzstd/compress/hist.h +12 -32
- data/ext/zstdruby/libzstd/compress/huf_compress.c +92 -92
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +1460 -1472
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +330 -65
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +158 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +29 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +419 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +54 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +845 -0
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +32 -0
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +525 -0
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +65 -43
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +264 -159
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +74 -42
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +33 -11
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +7 -2
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +108 -125
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +129 -93
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +46 -28
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +76 -60
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +14 -10
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +2 -2
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +471 -258
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +471 -346
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +3 -3
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +25 -4
- data/ext/zstdruby/libzstd/deprecated/zbuff.h +9 -8
- data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +2 -2
- data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -1
- data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +220 -65
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +81 -7
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +85 -56
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +43 -19
- data/ext/zstdruby/libzstd/dictBuilder/zdict.h +73 -35
- data/ext/zstdruby/libzstd/dll/example/Makefile +2 -1
- data/ext/zstdruby/libzstd/dll/example/build_package.bat +3 -2
- data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +49 -15
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +142 -117
- data/ext/zstdruby/libzstd/legacy/zstd_v01.h +13 -8
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +54 -25
- data/ext/zstdruby/libzstd/legacy/zstd_v02.h +13 -8
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +55 -25
- data/ext/zstdruby/libzstd/legacy/zstd_v03.h +13 -8
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +62 -29
- data/ext/zstdruby/libzstd/legacy/zstd_v04.h +13 -8
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +145 -109
- data/ext/zstdruby/libzstd/legacy/zstd_v05.h +14 -9
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +56 -26
- data/ext/zstdruby/libzstd/legacy/zstd_v06.h +11 -6
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +65 -28
- data/ext/zstdruby/libzstd/legacy/zstd_v07.h +11 -6
- data/ext/zstdruby/libzstd/libzstd.pc.in +3 -2
- data/ext/zstdruby/libzstd/zstd.h +921 -597
- data/lib/zstd-ruby/version.rb +1 -1
- data/zstd-ruby.gemspec +2 -2
- metadata +19 -14
- data/ext/zstdruby/libzstd/dll/libzstd.def +0 -87
|
@@ -1,5 +1,5 @@
|
|
|
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
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
/* ====== Dependencies ====== */
|
|
23
23
|
#include <string.h> /* memcpy, memset */
|
|
24
24
|
#include <limits.h> /* INT_MAX, UINT_MAX */
|
|
25
|
-
#include "
|
|
26
|
-
#include "
|
|
25
|
+
#include "../common/mem.h" /* MEM_STATIC */
|
|
26
|
+
#include "../common/pool.h" /* threadpool */
|
|
27
|
+
#include "../common/threading.h" /* mutex */
|
|
27
28
|
#include "zstd_compress_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */
|
|
28
29
|
#include "zstd_ldm.h"
|
|
29
30
|
#include "zstdmt_compress.h"
|
|
@@ -456,11 +457,17 @@ typedef struct {
|
|
|
456
457
|
* Must be acquired after the main mutex when acquiring both.
|
|
457
458
|
*/
|
|
458
459
|
ZSTD_pthread_mutex_t ldmWindowMutex;
|
|
459
|
-
ZSTD_pthread_cond_t ldmWindowCond; /* Signaled when ldmWindow is
|
|
460
|
+
ZSTD_pthread_cond_t ldmWindowCond; /* Signaled when ldmWindow is updated */
|
|
460
461
|
ZSTD_window_t ldmWindow; /* A thread-safe copy of ldmState.window */
|
|
461
462
|
} serialState_t;
|
|
462
463
|
|
|
463
|
-
static int
|
|
464
|
+
static int
|
|
465
|
+
ZSTDMT_serialState_reset(serialState_t* serialState,
|
|
466
|
+
ZSTDMT_seqPool* seqPool,
|
|
467
|
+
ZSTD_CCtx_params params,
|
|
468
|
+
size_t jobSize,
|
|
469
|
+
const void* dict, size_t const dictSize,
|
|
470
|
+
ZSTD_dictContentType_e dictContentType)
|
|
464
471
|
{
|
|
465
472
|
/* Adjust parameters */
|
|
466
473
|
if (params.ldmParams.enableLdm) {
|
|
@@ -489,8 +496,7 @@ static int ZSTDMT_serialState_reset(serialState_t* serialState, ZSTDMT_seqPool*
|
|
|
489
496
|
/* Size the seq pool tables */
|
|
490
497
|
ZSTDMT_setNbSeq(seqPool, ZSTD_ldm_getMaxNbSeq(params.ldmParams, jobSize));
|
|
491
498
|
/* Reset the window */
|
|
492
|
-
|
|
493
|
-
serialState->ldmWindow = serialState->ldmState.window;
|
|
499
|
+
ZSTD_window_init(&serialState->ldmState.window);
|
|
494
500
|
/* Resize tables and output space if necessary. */
|
|
495
501
|
if (serialState->ldmState.hashTable == NULL || serialState->params.ldmParams.hashLog < hashLog) {
|
|
496
502
|
ZSTD_free(serialState->ldmState.hashTable, cMem);
|
|
@@ -505,7 +511,24 @@ static int ZSTDMT_serialState_reset(serialState_t* serialState, ZSTDMT_seqPool*
|
|
|
505
511
|
/* Zero the tables */
|
|
506
512
|
memset(serialState->ldmState.hashTable, 0, hashSize);
|
|
507
513
|
memset(serialState->ldmState.bucketOffsets, 0, bucketSize);
|
|
514
|
+
|
|
515
|
+
/* Update window state and fill hash table with dict */
|
|
516
|
+
serialState->ldmState.loadedDictEnd = 0;
|
|
517
|
+
if (dictSize > 0) {
|
|
518
|
+
if (dictContentType == ZSTD_dct_rawContent) {
|
|
519
|
+
BYTE const* const dictEnd = (const BYTE*)dict + dictSize;
|
|
520
|
+
ZSTD_window_update(&serialState->ldmState.window, dict, dictSize);
|
|
521
|
+
ZSTD_ldm_fillHashTable(&serialState->ldmState, (const BYTE*)dict, dictEnd, ¶ms.ldmParams);
|
|
522
|
+
serialState->ldmState.loadedDictEnd = params.forceWindow ? 0 : (U32)(dictEnd - serialState->ldmState.window.base);
|
|
523
|
+
} else {
|
|
524
|
+
/* don't even load anything */
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/* Initialize serialState's copy of ldmWindow. */
|
|
529
|
+
serialState->ldmWindow = serialState->ldmState.window;
|
|
508
530
|
}
|
|
531
|
+
|
|
509
532
|
serialState->params = params;
|
|
510
533
|
serialState->params.jobSize = (U32)jobSize;
|
|
511
534
|
return 0;
|
|
@@ -647,7 +670,7 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
|
|
647
670
|
buffer_t dstBuff = job->dstBuff;
|
|
648
671
|
size_t lastCBlockSize = 0;
|
|
649
672
|
|
|
650
|
-
/*
|
|
673
|
+
/* resources */
|
|
651
674
|
if (cctx==NULL) JOB_ERROR(ERROR(memory_allocation));
|
|
652
675
|
if (dstBuff.start == NULL) { /* streaming job : doesn't provide a dstBuffer */
|
|
653
676
|
dstBuff = ZSTDMT_getBuffer(job->bufPool);
|
|
@@ -667,19 +690,19 @@ static void ZSTDMT_compressionJob(void* jobDescription)
|
|
|
667
690
|
|
|
668
691
|
/* init */
|
|
669
692
|
if (job->cdict) {
|
|
670
|
-
size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, job->cdict, jobParams, job->fullFrameSize);
|
|
693
|
+
size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, job->cdict, &jobParams, job->fullFrameSize);
|
|
671
694
|
assert(job->firstJob); /* only allowed for first job */
|
|
672
695
|
if (ZSTD_isError(initError)) JOB_ERROR(initError);
|
|
673
696
|
} else { /* srcStart points at reloaded section */
|
|
674
697
|
U64 const pledgedSrcSize = job->firstJob ? job->fullFrameSize : job->src.size;
|
|
675
|
-
{ size_t const forceWindowError =
|
|
698
|
+
{ size_t const forceWindowError = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_forceMaxWindow, !job->firstJob);
|
|
676
699
|
if (ZSTD_isError(forceWindowError)) JOB_ERROR(forceWindowError);
|
|
677
700
|
}
|
|
678
701
|
{ size_t const initError = ZSTD_compressBegin_advanced_internal(cctx,
|
|
679
702
|
job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, /* load dictionary in "content-only" mode (no header analysis) */
|
|
680
703
|
ZSTD_dtlm_fast,
|
|
681
704
|
NULL, /*cdict*/
|
|
682
|
-
jobParams, pledgedSrcSize);
|
|
705
|
+
&jobParams, pledgedSrcSize);
|
|
683
706
|
if (ZSTD_isError(initError)) JOB_ERROR(initError);
|
|
684
707
|
} }
|
|
685
708
|
|
|
@@ -864,14 +887,10 @@ static size_t ZSTDMT_expandJobsTable (ZSTDMT_CCtx* mtctx, U32 nbWorkers) {
|
|
|
864
887
|
* Internal use only */
|
|
865
888
|
size_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers)
|
|
866
889
|
{
|
|
867
|
-
|
|
868
|
-
params->nbWorkers = nbWorkers;
|
|
869
|
-
params->overlapLog = ZSTDMT_OVERLAPLOG_DEFAULT;
|
|
870
|
-
params->jobSize = 0;
|
|
871
|
-
return nbWorkers;
|
|
890
|
+
return ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, (int)nbWorkers);
|
|
872
891
|
}
|
|
873
892
|
|
|
874
|
-
ZSTDMT_CCtx*
|
|
893
|
+
MEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem)
|
|
875
894
|
{
|
|
876
895
|
ZSTDMT_CCtx* mtctx;
|
|
877
896
|
U32 nbJobs = nbWorkers + 2;
|
|
@@ -906,6 +925,17 @@ ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem)
|
|
|
906
925
|
return mtctx;
|
|
907
926
|
}
|
|
908
927
|
|
|
928
|
+
ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem)
|
|
929
|
+
{
|
|
930
|
+
#ifdef ZSTD_MULTITHREAD
|
|
931
|
+
return ZSTDMT_createCCtx_advanced_internal(nbWorkers, cMem);
|
|
932
|
+
#else
|
|
933
|
+
(void)nbWorkers;
|
|
934
|
+
(void)cMem;
|
|
935
|
+
return NULL;
|
|
936
|
+
#endif
|
|
937
|
+
}
|
|
938
|
+
|
|
909
939
|
ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbWorkers)
|
|
910
940
|
{
|
|
911
941
|
return ZSTDMT_createCCtx_advanced(nbWorkers, ZSTD_defaultCMem);
|
|
@@ -919,12 +949,18 @@ static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx)
|
|
|
919
949
|
unsigned jobID;
|
|
920
950
|
DEBUGLOG(3, "ZSTDMT_releaseAllJobResources");
|
|
921
951
|
for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) {
|
|
952
|
+
/* Copy the mutex/cond out */
|
|
953
|
+
ZSTD_pthread_mutex_t const mutex = mtctx->jobs[jobID].job_mutex;
|
|
954
|
+
ZSTD_pthread_cond_t const cond = mtctx->jobs[jobID].job_cond;
|
|
955
|
+
|
|
922
956
|
DEBUGLOG(4, "job%02u: release dst address %08X", jobID, (U32)(size_t)mtctx->jobs[jobID].dstBuff.start);
|
|
923
957
|
ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff);
|
|
924
|
-
|
|
925
|
-
|
|
958
|
+
|
|
959
|
+
/* Clear the job description, but keep the mutex/cond */
|
|
960
|
+
memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID]));
|
|
961
|
+
mtctx->jobs[jobID].job_mutex = mutex;
|
|
962
|
+
mtctx->jobs[jobID].job_cond = cond;
|
|
926
963
|
}
|
|
927
|
-
memset(mtctx->jobs, 0, (mtctx->jobIDMask+1)*sizeof(ZSTDMT_jobDescription));
|
|
928
964
|
mtctx->inBuff.buffer = g_nullBuffer;
|
|
929
965
|
mtctx->inBuff.filled = 0;
|
|
930
966
|
mtctx->allJobsCompleted = 1;
|
|
@@ -986,26 +1022,13 @@ ZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params,
|
|
|
986
1022
|
{
|
|
987
1023
|
case ZSTDMT_p_jobSize :
|
|
988
1024
|
DEBUGLOG(4, "ZSTDMT_CCtxParam_setMTCtxParameter : set jobSize to %i", value);
|
|
989
|
-
|
|
990
|
-
&& value < ZSTDMT_JOBSIZE_MIN)
|
|
991
|
-
value = ZSTDMT_JOBSIZE_MIN;
|
|
992
|
-
assert(value >= 0);
|
|
993
|
-
if (value > ZSTDMT_JOBSIZE_MAX) value = ZSTDMT_JOBSIZE_MAX;
|
|
994
|
-
params->jobSize = value;
|
|
995
|
-
return value;
|
|
996
|
-
|
|
1025
|
+
return ZSTD_CCtxParams_setParameter(params, ZSTD_c_jobSize, value);
|
|
997
1026
|
case ZSTDMT_p_overlapLog :
|
|
998
1027
|
DEBUGLOG(4, "ZSTDMT_p_overlapLog : %i", value);
|
|
999
|
-
|
|
1000
|
-
if (value > ZSTD_OVERLAPLOG_MAX) value = ZSTD_OVERLAPLOG_MAX;
|
|
1001
|
-
params->overlapLog = value;
|
|
1002
|
-
return value;
|
|
1003
|
-
|
|
1028
|
+
return ZSTD_CCtxParams_setParameter(params, ZSTD_c_overlapLog, value);
|
|
1004
1029
|
case ZSTDMT_p_rsyncable :
|
|
1005
|
-
|
|
1006
|
-
params
|
|
1007
|
-
return value;
|
|
1008
|
-
|
|
1030
|
+
DEBUGLOG(4, "ZSTD_p_rsyncable : %i", value);
|
|
1031
|
+
return ZSTD_CCtxParams_setParameter(params, ZSTD_c_rsyncable, value);
|
|
1009
1032
|
default :
|
|
1010
1033
|
return ERROR(parameter_unsupported);
|
|
1011
1034
|
}
|
|
@@ -1021,32 +1044,29 @@ size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter,
|
|
|
1021
1044
|
{
|
|
1022
1045
|
switch (parameter) {
|
|
1023
1046
|
case ZSTDMT_p_jobSize:
|
|
1024
|
-
|
|
1025
|
-
*value = (int)(mtctx->params.jobSize);
|
|
1026
|
-
break;
|
|
1047
|
+
return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_jobSize, value);
|
|
1027
1048
|
case ZSTDMT_p_overlapLog:
|
|
1028
|
-
|
|
1029
|
-
break;
|
|
1049
|
+
return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_overlapLog, value);
|
|
1030
1050
|
case ZSTDMT_p_rsyncable:
|
|
1031
|
-
|
|
1032
|
-
break;
|
|
1051
|
+
return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_rsyncable, value);
|
|
1033
1052
|
default:
|
|
1034
1053
|
return ERROR(parameter_unsupported);
|
|
1035
1054
|
}
|
|
1036
|
-
return 0;
|
|
1037
1055
|
}
|
|
1038
1056
|
|
|
1039
1057
|
/* Sets parameters relevant to the compression job,
|
|
1040
1058
|
* initializing others to default values. */
|
|
1041
|
-
static ZSTD_CCtx_params ZSTDMT_initJobCCtxParams(ZSTD_CCtx_params
|
|
1042
|
-
{
|
|
1043
|
-
ZSTD_CCtx_params jobParams;
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
jobParams.
|
|
1047
|
-
jobParams.
|
|
1048
|
-
jobParams.
|
|
1049
|
-
|
|
1059
|
+
static ZSTD_CCtx_params ZSTDMT_initJobCCtxParams(const ZSTD_CCtx_params* params)
|
|
1060
|
+
{
|
|
1061
|
+
ZSTD_CCtx_params jobParams = *params;
|
|
1062
|
+
/* Clear parameters related to multithreading */
|
|
1063
|
+
jobParams.forceWindow = 0;
|
|
1064
|
+
jobParams.nbWorkers = 0;
|
|
1065
|
+
jobParams.jobSize = 0;
|
|
1066
|
+
jobParams.overlapLog = 0;
|
|
1067
|
+
jobParams.rsyncable = 0;
|
|
1068
|
+
memset(&jobParams.ldmParams, 0, sizeof(ldmParams_t));
|
|
1069
|
+
memset(&jobParams.customMem, 0, sizeof(ZSTD_customMem));
|
|
1050
1070
|
return jobParams;
|
|
1051
1071
|
}
|
|
1052
1072
|
|
|
@@ -1056,7 +1076,7 @@ static ZSTD_CCtx_params ZSTDMT_initJobCCtxParams(ZSTD_CCtx_params const params)
|
|
|
1056
1076
|
static size_t ZSTDMT_resize(ZSTDMT_CCtx* mtctx, unsigned nbWorkers)
|
|
1057
1077
|
{
|
|
1058
1078
|
if (POOL_resize(mtctx->factory, nbWorkers)) return ERROR(memory_allocation);
|
|
1059
|
-
|
|
1079
|
+
FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbWorkers) , "");
|
|
1060
1080
|
mtctx->bufPool = ZSTDMT_expandBufferPool(mtctx->bufPool, nbWorkers);
|
|
1061
1081
|
if (mtctx->bufPool == NULL) return ERROR(memory_allocation);
|
|
1062
1082
|
mtctx->cctxPool = ZSTDMT_expandCCtxPool(mtctx->cctxPool, nbWorkers);
|
|
@@ -1078,7 +1098,7 @@ void ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_p
|
|
|
1078
1098
|
DEBUGLOG(5, "ZSTDMT_updateCParams_whileCompressing (level:%i)",
|
|
1079
1099
|
compressionLevel);
|
|
1080
1100
|
mtctx->params.compressionLevel = compressionLevel;
|
|
1081
|
-
{ ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams,
|
|
1101
|
+
{ ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, 0);
|
|
1082
1102
|
cParams.windowLog = saved_wlog;
|
|
1083
1103
|
mtctx->params.cParams = cParams;
|
|
1084
1104
|
}
|
|
@@ -1137,9 +1157,14 @@ size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx)
|
|
|
1137
1157
|
size_t const produced = ZSTD_isError(cResult) ? 0 : cResult;
|
|
1138
1158
|
size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed;
|
|
1139
1159
|
assert(flushed <= produced);
|
|
1160
|
+
assert(jobPtr->consumed <= jobPtr->src.size);
|
|
1140
1161
|
toFlush = produced - flushed;
|
|
1141
|
-
if
|
|
1142
|
-
|
|
1162
|
+
/* if toFlush==0, nothing is available to flush.
|
|
1163
|
+
* However, jobID is expected to still be active:
|
|
1164
|
+
* if jobID was already completed and fully flushed,
|
|
1165
|
+
* ZSTDMT_flushProduced() should have already moved onto next job.
|
|
1166
|
+
* Therefore, some input has not yet been consumed. */
|
|
1167
|
+
if (toFlush==0) {
|
|
1143
1168
|
assert(jobPtr->consumed < jobPtr->src.size);
|
|
1144
1169
|
}
|
|
1145
1170
|
}
|
|
@@ -1154,14 +1179,18 @@ size_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx)
|
|
|
1154
1179
|
/* ===== Multi-threaded compression ===== */
|
|
1155
1180
|
/* ------------------------------------------ */
|
|
1156
1181
|
|
|
1157
|
-
static unsigned ZSTDMT_computeTargetJobLog(ZSTD_CCtx_params
|
|
1182
|
+
static unsigned ZSTDMT_computeTargetJobLog(const ZSTD_CCtx_params* params)
|
|
1158
1183
|
{
|
|
1159
|
-
|
|
1184
|
+
unsigned jobLog;
|
|
1185
|
+
if (params->ldmParams.enableLdm) {
|
|
1160
1186
|
/* In Long Range Mode, the windowLog is typically oversized.
|
|
1161
1187
|
* In which case, it's preferable to determine the jobSize
|
|
1162
1188
|
* based on chainLog instead. */
|
|
1163
|
-
|
|
1164
|
-
|
|
1189
|
+
jobLog = MAX(21, params->cParams.chainLog + 4);
|
|
1190
|
+
} else {
|
|
1191
|
+
jobLog = MAX(20, params->cParams.windowLog + 2);
|
|
1192
|
+
}
|
|
1193
|
+
return MIN(jobLog, (unsigned)ZSTDMT_JOBLOG_MAX);
|
|
1165
1194
|
}
|
|
1166
1195
|
|
|
1167
1196
|
static int ZSTDMT_overlapLog_default(ZSTD_strategy strat)
|
|
@@ -1192,27 +1221,27 @@ static int ZSTDMT_overlapLog(int ovlog, ZSTD_strategy strat)
|
|
|
1192
1221
|
return ovlog;
|
|
1193
1222
|
}
|
|
1194
1223
|
|
|
1195
|
-
static size_t ZSTDMT_computeOverlapSize(ZSTD_CCtx_params
|
|
1224
|
+
static size_t ZSTDMT_computeOverlapSize(const ZSTD_CCtx_params* params)
|
|
1196
1225
|
{
|
|
1197
|
-
int const overlapRLog = 9 - ZSTDMT_overlapLog(params
|
|
1198
|
-
int ovLog = (overlapRLog >= 8) ? 0 : (params
|
|
1226
|
+
int const overlapRLog = 9 - ZSTDMT_overlapLog(params->overlapLog, params->cParams.strategy);
|
|
1227
|
+
int ovLog = (overlapRLog >= 8) ? 0 : (params->cParams.windowLog - overlapRLog);
|
|
1199
1228
|
assert(0 <= overlapRLog && overlapRLog <= 8);
|
|
1200
|
-
if (params
|
|
1229
|
+
if (params->ldmParams.enableLdm) {
|
|
1201
1230
|
/* In Long Range Mode, the windowLog is typically oversized.
|
|
1202
1231
|
* In which case, it's preferable to determine the jobSize
|
|
1203
1232
|
* based on chainLog instead.
|
|
1204
1233
|
* Then, ovLog becomes a fraction of the jobSize, rather than windowSize */
|
|
1205
|
-
ovLog = MIN(params
|
|
1234
|
+
ovLog = MIN(params->cParams.windowLog, ZSTDMT_computeTargetJobLog(params) - 2)
|
|
1206
1235
|
- overlapRLog;
|
|
1207
1236
|
}
|
|
1208
|
-
assert(0 <= ovLog && ovLog <=
|
|
1209
|
-
DEBUGLOG(4, "overlapLog : %i", params
|
|
1237
|
+
assert(0 <= ovLog && ovLog <= ZSTD_WINDOWLOG_MAX);
|
|
1238
|
+
DEBUGLOG(4, "overlapLog : %i", params->overlapLog);
|
|
1210
1239
|
DEBUGLOG(4, "overlap size : %i", 1 << ovLog);
|
|
1211
1240
|
return (ovLog==0) ? 0 : (size_t)1 << ovLog;
|
|
1212
1241
|
}
|
|
1213
1242
|
|
|
1214
1243
|
static unsigned
|
|
1215
|
-
ZSTDMT_computeNbJobs(ZSTD_CCtx_params params, size_t srcSize, unsigned nbWorkers)
|
|
1244
|
+
ZSTDMT_computeNbJobs(const ZSTD_CCtx_params* params, size_t srcSize, unsigned nbWorkers)
|
|
1216
1245
|
{
|
|
1217
1246
|
assert(nbWorkers>0);
|
|
1218
1247
|
{ size_t const jobSizeTarget = (size_t)1 << ZSTDMT_computeTargetJobLog(params);
|
|
@@ -1228,16 +1257,17 @@ ZSTDMT_computeNbJobs(ZSTD_CCtx_params params, size_t srcSize, unsigned nbWorkers
|
|
|
1228
1257
|
/* ZSTDMT_compress_advanced_internal() :
|
|
1229
1258
|
* This is a blocking function : it will only give back control to caller after finishing its compression job.
|
|
1230
1259
|
*/
|
|
1231
|
-
static size_t
|
|
1260
|
+
static size_t
|
|
1261
|
+
ZSTDMT_compress_advanced_internal(
|
|
1232
1262
|
ZSTDMT_CCtx* mtctx,
|
|
1233
1263
|
void* dst, size_t dstCapacity,
|
|
1234
1264
|
const void* src, size_t srcSize,
|
|
1235
1265
|
const ZSTD_CDict* cdict,
|
|
1236
1266
|
ZSTD_CCtx_params params)
|
|
1237
1267
|
{
|
|
1238
|
-
ZSTD_CCtx_params const jobParams = ZSTDMT_initJobCCtxParams(params);
|
|
1239
|
-
size_t const overlapSize = ZSTDMT_computeOverlapSize(params);
|
|
1240
|
-
unsigned const nbJobs = ZSTDMT_computeNbJobs(params, srcSize, params.nbWorkers);
|
|
1268
|
+
ZSTD_CCtx_params const jobParams = ZSTDMT_initJobCCtxParams(¶ms);
|
|
1269
|
+
size_t const overlapSize = ZSTDMT_computeOverlapSize(¶ms);
|
|
1270
|
+
unsigned const nbJobs = ZSTDMT_computeNbJobs(¶ms, srcSize, params.nbWorkers);
|
|
1241
1271
|
size_t const proposedJobSize = (srcSize + (nbJobs-1)) / nbJobs;
|
|
1242
1272
|
size_t const avgJobSize = (((proposedJobSize-1) & 0x1FFFF) < 0x7FFF) ? proposedJobSize + 0xFFFF : proposedJobSize; /* avoid too small last block */
|
|
1243
1273
|
const char* const srcStart = (const char*)src;
|
|
@@ -1255,15 +1285,16 @@ static size_t ZSTDMT_compress_advanced_internal(
|
|
|
1255
1285
|
ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];
|
|
1256
1286
|
DEBUGLOG(4, "ZSTDMT_compress_advanced_internal: fallback to single-thread mode");
|
|
1257
1287
|
if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, jobParams.fParams);
|
|
1258
|
-
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, NULL, 0, jobParams);
|
|
1288
|
+
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, NULL, 0, &jobParams);
|
|
1259
1289
|
}
|
|
1260
1290
|
|
|
1261
1291
|
assert(avgJobSize >= 256 KB); /* condition for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B), required to compress directly into Dst (no additional buffer) */
|
|
1262
1292
|
ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(avgJobSize) );
|
|
1263
|
-
|
|
1293
|
+
/* LDM doesn't even try to load the dictionary in single-ingestion mode */
|
|
1294
|
+
if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, avgJobSize, NULL, 0, ZSTD_dct_auto))
|
|
1264
1295
|
return ERROR(memory_allocation);
|
|
1265
1296
|
|
|
1266
|
-
|
|
1297
|
+
FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbJobs) , ""); /* only expands if necessary */
|
|
1267
1298
|
|
|
1268
1299
|
{ unsigned u;
|
|
1269
1300
|
for (u=0; u<nbJobs; u++) {
|
|
@@ -1396,19 +1427,19 @@ size_t ZSTDMT_initCStream_internal(
|
|
|
1396
1427
|
|
|
1397
1428
|
/* init */
|
|
1398
1429
|
if (params.nbWorkers != mtctx->params.nbWorkers)
|
|
1399
|
-
|
|
1430
|
+
FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, params.nbWorkers) , "");
|
|
1400
1431
|
|
|
1401
1432
|
if (params.jobSize != 0 && params.jobSize < ZSTDMT_JOBSIZE_MIN) params.jobSize = ZSTDMT_JOBSIZE_MIN;
|
|
1402
|
-
if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = ZSTDMT_JOBSIZE_MAX;
|
|
1433
|
+
if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = (size_t)ZSTDMT_JOBSIZE_MAX;
|
|
1403
1434
|
|
|
1404
1435
|
mtctx->singleBlockingThread = (pledgedSrcSize <= ZSTDMT_JOBSIZE_MIN); /* do not trigger multi-threading when srcSize is too small */
|
|
1405
1436
|
if (mtctx->singleBlockingThread) {
|
|
1406
|
-
ZSTD_CCtx_params const singleThreadParams = ZSTDMT_initJobCCtxParams(params);
|
|
1437
|
+
ZSTD_CCtx_params const singleThreadParams = ZSTDMT_initJobCCtxParams(¶ms);
|
|
1407
1438
|
DEBUGLOG(5, "ZSTDMT_initCStream_internal: switch to single blocking thread mode");
|
|
1408
1439
|
assert(singleThreadParams.nbWorkers == 0);
|
|
1409
1440
|
return ZSTD_initCStream_internal(mtctx->cctxPool->cctx[0],
|
|
1410
1441
|
dict, dictSize, cdict,
|
|
1411
|
-
singleThreadParams, pledgedSrcSize);
|
|
1442
|
+
&singleThreadParams, pledgedSrcSize);
|
|
1412
1443
|
}
|
|
1413
1444
|
|
|
1414
1445
|
DEBUGLOG(4, "ZSTDMT_initCStream_internal: %u workers", params.nbWorkers);
|
|
@@ -1434,12 +1465,14 @@ size_t ZSTDMT_initCStream_internal(
|
|
|
1434
1465
|
mtctx->cdict = cdict;
|
|
1435
1466
|
}
|
|
1436
1467
|
|
|
1437
|
-
mtctx->targetPrefixSize = ZSTDMT_computeOverlapSize(params);
|
|
1468
|
+
mtctx->targetPrefixSize = ZSTDMT_computeOverlapSize(¶ms);
|
|
1438
1469
|
DEBUGLOG(4, "overlapLog=%i => %u KB", params.overlapLog, (U32)(mtctx->targetPrefixSize>>10));
|
|
1439
1470
|
mtctx->targetSectionSize = params.jobSize;
|
|
1440
1471
|
if (mtctx->targetSectionSize == 0) {
|
|
1441
|
-
mtctx->targetSectionSize = 1ULL << ZSTDMT_computeTargetJobLog(params);
|
|
1472
|
+
mtctx->targetSectionSize = 1ULL << ZSTDMT_computeTargetJobLog(¶ms);
|
|
1442
1473
|
}
|
|
1474
|
+
assert(mtctx->targetSectionSize <= (size_t)ZSTDMT_JOBSIZE_MAX);
|
|
1475
|
+
|
|
1443
1476
|
if (params.rsyncable) {
|
|
1444
1477
|
/* Aim for the targetsectionSize as the average job size. */
|
|
1445
1478
|
U32 const jobSizeMB = (U32)(mtctx->targetSectionSize >> 20);
|
|
@@ -1491,7 +1524,8 @@ size_t ZSTDMT_initCStream_internal(
|
|
|
1491
1524
|
mtctx->allJobsCompleted = 0;
|
|
1492
1525
|
mtctx->consumed = 0;
|
|
1493
1526
|
mtctx->produced = 0;
|
|
1494
|
-
if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize
|
|
1527
|
+
if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize,
|
|
1528
|
+
dict, dictSize, dictContentType))
|
|
1495
1529
|
return ERROR(memory_allocation);
|
|
1496
1530
|
return 0;
|
|
1497
1531
|
}
|
|
@@ -1547,7 +1581,7 @@ size_t ZSTDMT_initCStream(ZSTDMT_CCtx* mtctx, int compressionLevel) {
|
|
|
1547
1581
|
/* ZSTDMT_writeLastEmptyBlock()
|
|
1548
1582
|
* Write a single empty block with an end-of-frame to finish a frame.
|
|
1549
1583
|
* Job must be created from streaming variant.
|
|
1550
|
-
* This function is always
|
|
1584
|
+
* This function is always successful if expected conditions are fulfilled.
|
|
1551
1585
|
*/
|
|
1552
1586
|
static void ZSTDMT_writeLastEmptyBlock(ZSTDMT_jobDescription* job)
|
|
1553
1587
|
{
|
|
@@ -1705,9 +1739,11 @@ static size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, u
|
|
|
1705
1739
|
assert(mtctx->doneJobID < mtctx->nextJobID);
|
|
1706
1740
|
assert(cSize >= mtctx->jobs[wJobID].dstFlushed);
|
|
1707
1741
|
assert(mtctx->jobs[wJobID].dstBuff.start != NULL);
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1742
|
+
if (toFlush > 0) {
|
|
1743
|
+
memcpy((char*)output->dst + output->pos,
|
|
1744
|
+
(const char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].dstFlushed,
|
|
1745
|
+
toFlush);
|
|
1746
|
+
}
|
|
1711
1747
|
output->pos += toFlush;
|
|
1712
1748
|
mtctx->jobs[wJobID].dstFlushed += toFlush; /* can write : this value is only used by mtctx */
|
|
1713
1749
|
|
|
@@ -1777,7 +1813,7 @@ static int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)
|
|
|
1777
1813
|
BYTE const* const bufferStart = (BYTE const*)buffer.start;
|
|
1778
1814
|
BYTE const* const bufferEnd = bufferStart + buffer.capacity;
|
|
1779
1815
|
BYTE const* const rangeStart = (BYTE const*)range.start;
|
|
1780
|
-
BYTE const* const rangeEnd = rangeStart + range.size;
|
|
1816
|
+
BYTE const* const rangeEnd = range.size != 0 ? rangeStart + range.size : rangeStart;
|
|
1781
1817
|
|
|
1782
1818
|
if (rangeStart == NULL || bufferStart == NULL)
|
|
1783
1819
|
return 0;
|
|
@@ -1987,7 +2023,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
|
1987
2023
|
assert(input->pos <= input->size);
|
|
1988
2024
|
|
|
1989
2025
|
if (mtctx->singleBlockingThread) { /* delegate to single-thread (synchronous) */
|
|
1990
|
-
return
|
|
2026
|
+
return ZSTD_compressStream2(mtctx->cctxPool->cctx[0], output, input, endOp);
|
|
1991
2027
|
}
|
|
1992
2028
|
|
|
1993
2029
|
if ((mtctx->frameEnded) && (endOp==ZSTD_e_continue)) {
|
|
@@ -2051,7 +2087,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
|
2051
2087
|
|| ((endOp == ZSTD_e_end) && (!mtctx->frameEnded)) ) { /* must finish the frame with a zero-size block */
|
|
2052
2088
|
size_t const jobSize = mtctx->inBuff.filled;
|
|
2053
2089
|
assert(mtctx->inBuff.filled <= mtctx->targetSectionSize);
|
|
2054
|
-
|
|
2090
|
+
FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, jobSize, endOp) , "");
|
|
2055
2091
|
}
|
|
2056
2092
|
|
|
2057
2093
|
/* check for potential compressed data ready to be flushed */
|
|
@@ -2065,7 +2101,7 @@ size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
|
|
|
2065
2101
|
|
|
2066
2102
|
size_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
|
|
2067
2103
|
{
|
|
2068
|
-
|
|
2104
|
+
FORWARD_IF_ERROR( ZSTDMT_compressStream_generic(mtctx, output, input, ZSTD_e_continue) , "");
|
|
2069
2105
|
|
|
2070
2106
|
/* recommended next input size : fill current input buffer */
|
|
2071
2107
|
return mtctx->targetSectionSize - mtctx->inBuff.filled; /* note : could be zero when input buffer is fully filled and no more availability to create new job */
|
|
@@ -2082,7 +2118,7 @@ static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* ou
|
|
|
2082
2118
|
|| ((endFrame==ZSTD_e_end) && !mtctx->frameEnded)) { /* need a last 0-size block to end frame */
|
|
2083
2119
|
DEBUGLOG(5, "ZSTDMT_flushStream_internal : create a new job (%u bytes, end:%u)",
|
|
2084
2120
|
(U32)srcSize, (U32)endFrame);
|
|
2085
|
-
|
|
2121
|
+
FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, srcSize, endFrame) , "");
|
|
2086
2122
|
}
|
|
2087
2123
|
|
|
2088
2124
|
/* check if there is any data available to flush */
|