zstd-ruby 1.3.8.0 → 1.4.5.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 +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 */
|