zstd-ruby 1.4.2.0 → 1.4.4.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/README.md +1 -1
- data/ext/zstdruby/libzstd/Makefile +0 -2
- data/ext/zstdruby/libzstd/README.md +13 -2
- data/ext/zstdruby/libzstd/common/bitstream.h +7 -2
- data/ext/zstdruby/libzstd/common/compiler.h +17 -5
- data/ext/zstdruby/libzstd/common/fse.h +1 -1
- data/ext/zstdruby/libzstd/common/fse_decompress.c +2 -0
- data/ext/zstdruby/libzstd/common/mem.h +74 -1
- data/ext/zstdruby/libzstd/common/pool.c +7 -3
- data/ext/zstdruby/libzstd/common/threading.c +46 -1
- data/ext/zstdruby/libzstd/common/threading.h +32 -1
- data/ext/zstdruby/libzstd/common/xxhash.c +8 -2
- data/ext/zstdruby/libzstd/common/zstd_internal.h +37 -58
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +644 -445
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +98 -26
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +10 -5
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +3 -3
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +535 -0
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +11 -12
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +38 -45
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +35 -31
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +4 -4
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +6 -6
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +32 -26
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +2 -0
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +16 -17
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +149 -148
- data/ext/zstdruby/libzstd/deprecated/zbuff.h +6 -5
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +7 -8
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +2 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +2 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +6 -2
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +1 -1
- data/ext/zstdruby/libzstd/libzstd.pc.in +3 -2
- data/ext/zstdruby/libzstd/zstd.h +170 -66
- data/lib/zstd-ruby/version.rb +1 -1
- data/zstd-ruby.gemspec +1 -1
- metadata +5 -4
@@ -42,15 +42,15 @@ size_t ZSTD_compressBound(size_t srcSize) {
|
|
42
42
|
* Context memory management
|
43
43
|
***************************************/
|
44
44
|
struct ZSTD_CDict_s {
|
45
|
-
void* dictBuffer;
|
46
45
|
const void* dictContent;
|
47
46
|
size_t dictContentSize;
|
48
|
-
|
49
|
-
|
47
|
+
U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */
|
48
|
+
ZSTD_cwksp workspace;
|
50
49
|
ZSTD_matchState_t matchState;
|
51
50
|
ZSTD_compressedBlockState_t cBlockState;
|
52
51
|
ZSTD_customMem customMem;
|
53
52
|
U32 dictID;
|
53
|
+
int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */
|
54
54
|
}; /* typedef'd to ZSTD_CDict within "zstd.h" */
|
55
55
|
|
56
56
|
ZSTD_CCtx* ZSTD_createCCtx(void)
|
@@ -84,23 +84,26 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
|
|
84
84
|
|
85
85
|
ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
|
86
86
|
{
|
87
|
-
|
87
|
+
ZSTD_cwksp ws;
|
88
|
+
ZSTD_CCtx* cctx;
|
88
89
|
if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL; /* minimum size */
|
89
90
|
if ((size_t)workspace & 7) return NULL; /* must be 8-aligned */
|
90
|
-
|
91
|
+
ZSTD_cwksp_init(&ws, workspace, workspaceSize);
|
92
|
+
|
93
|
+
cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx));
|
94
|
+
if (cctx == NULL) {
|
95
|
+
return NULL;
|
96
|
+
}
|
97
|
+
memset(cctx, 0, sizeof(ZSTD_CCtx));
|
98
|
+
ZSTD_cwksp_move(&cctx->workspace, &ws);
|
91
99
|
cctx->staticSize = workspaceSize;
|
92
|
-
cctx->workSpace = (void*)(cctx+1);
|
93
|
-
cctx->workSpaceSize = workspaceSize - sizeof(ZSTD_CCtx);
|
94
100
|
|
95
101
|
/* statically sized space. entropyWorkspace never moves (but prev/next block swap places) */
|
96
|
-
if (cctx->
|
97
|
-
|
98
|
-
cctx->blockState.
|
99
|
-
cctx->
|
100
|
-
|
101
|
-
void* const ptr = cctx->blockState.nextCBlock + 1;
|
102
|
-
cctx->entropyWorkspace = (U32*)ptr;
|
103
|
-
}
|
102
|
+
if (!ZSTD_cwksp_check_available(&cctx->workspace, HUF_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
|
103
|
+
cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
|
104
|
+
cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
|
105
|
+
cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(
|
106
|
+
&cctx->workspace, HUF_WORKSPACE_SIZE);
|
104
107
|
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
|
105
108
|
return cctx;
|
106
109
|
}
|
@@ -128,11 +131,11 @@ static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx)
|
|
128
131
|
{
|
129
132
|
assert(cctx != NULL);
|
130
133
|
assert(cctx->staticSize == 0);
|
131
|
-
ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL;
|
132
134
|
ZSTD_clearAllDicts(cctx);
|
133
135
|
#ifdef ZSTD_MULTITHREAD
|
134
136
|
ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;
|
135
137
|
#endif
|
138
|
+
ZSTD_cwksp_free(&cctx->workspace, cctx->customMem);
|
136
139
|
}
|
137
140
|
|
138
141
|
size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
|
@@ -140,8 +143,13 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
|
|
140
143
|
if (cctx==NULL) return 0; /* support free on NULL */
|
141
144
|
RETURN_ERROR_IF(cctx->staticSize, memory_allocation,
|
142
145
|
"not compatible with static CCtx");
|
143
|
-
|
144
|
-
|
146
|
+
{
|
147
|
+
int cctxInWorkspace = ZSTD_cwksp_owns_buffer(&cctx->workspace, cctx);
|
148
|
+
ZSTD_freeCCtxContent(cctx);
|
149
|
+
if (!cctxInWorkspace) {
|
150
|
+
ZSTD_free(cctx, cctx->customMem);
|
151
|
+
}
|
152
|
+
}
|
145
153
|
return 0;
|
146
154
|
}
|
147
155
|
|
@@ -160,7 +168,9 @@ static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx)
|
|
160
168
|
size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
|
161
169
|
{
|
162
170
|
if (cctx==NULL) return 0; /* support sizeof on NULL */
|
163
|
-
|
171
|
+
/* cctx may be in the workspace */
|
172
|
+
return (cctx->workspace.workspace == cctx ? 0 : sizeof(*cctx))
|
173
|
+
+ ZSTD_cwksp_sizeof(&cctx->workspace)
|
164
174
|
+ ZSTD_sizeof_localDict(cctx->localDict)
|
165
175
|
+ ZSTD_sizeof_mtctx(cctx);
|
166
176
|
}
|
@@ -229,23 +239,23 @@ size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_paramete
|
|
229
239
|
RETURN_ERROR_IF(!cctxParams, GENERIC);
|
230
240
|
FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
|
231
241
|
memset(cctxParams, 0, sizeof(*cctxParams));
|
242
|
+
assert(!ZSTD_checkCParams(params.cParams));
|
232
243
|
cctxParams->cParams = params.cParams;
|
233
244
|
cctxParams->fParams = params.fParams;
|
234
245
|
cctxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
|
235
|
-
assert(!ZSTD_checkCParams(params.cParams));
|
236
246
|
return 0;
|
237
247
|
}
|
238
248
|
|
239
249
|
/* ZSTD_assignParamsToCCtxParams() :
|
240
250
|
* params is presumed valid at this stage */
|
241
251
|
static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
|
242
|
-
ZSTD_CCtx_params cctxParams, ZSTD_parameters params)
|
252
|
+
const ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
|
243
253
|
{
|
244
|
-
ZSTD_CCtx_params ret = cctxParams;
|
254
|
+
ZSTD_CCtx_params ret = *cctxParams;
|
255
|
+
assert(!ZSTD_checkCParams(params.cParams));
|
245
256
|
ret.cParams = params.cParams;
|
246
257
|
ret.fParams = params.fParams;
|
247
258
|
ret.compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
|
248
|
-
assert(!ZSTD_checkCParams(params.cParams));
|
249
259
|
return ret;
|
250
260
|
}
|
251
261
|
|
@@ -378,7 +388,7 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
|
|
378
388
|
case ZSTD_c_forceAttachDict:
|
379
389
|
ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceCopy);
|
380
390
|
bounds.lowerBound = ZSTD_dictDefaultAttach;
|
381
|
-
bounds.upperBound =
|
391
|
+
bounds.upperBound = ZSTD_dictForceLoad; /* note : how to ensure at compile time that this is the highest value enum ? */
|
382
392
|
return bounds;
|
383
393
|
|
384
394
|
case ZSTD_c_literalCompressionMode:
|
@@ -392,6 +402,11 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
|
|
392
402
|
bounds.upperBound = ZSTD_TARGETCBLOCKSIZE_MAX;
|
393
403
|
return bounds;
|
394
404
|
|
405
|
+
case ZSTD_c_srcSizeHint:
|
406
|
+
bounds.lowerBound = ZSTD_SRCSIZEHINT_MIN;
|
407
|
+
bounds.upperBound = ZSTD_SRCSIZEHINT_MAX;
|
408
|
+
return bounds;
|
409
|
+
|
395
410
|
default:
|
396
411
|
{ ZSTD_bounds const boundError = { ERROR(parameter_unsupported), 0, 0 };
|
397
412
|
return boundError;
|
@@ -448,6 +463,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
|
|
448
463
|
case ZSTD_c_forceAttachDict:
|
449
464
|
case ZSTD_c_literalCompressionMode:
|
450
465
|
case ZSTD_c_targetCBlockSize:
|
466
|
+
case ZSTD_c_srcSizeHint:
|
451
467
|
default:
|
452
468
|
return 0;
|
453
469
|
}
|
@@ -494,6 +510,7 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
|
|
494
510
|
case ZSTD_c_ldmMinMatch:
|
495
511
|
case ZSTD_c_ldmBucketSizeLog:
|
496
512
|
case ZSTD_c_targetCBlockSize:
|
513
|
+
case ZSTD_c_srcSizeHint:
|
497
514
|
break;
|
498
515
|
|
499
516
|
default: RETURN_ERROR(parameter_unsupported);
|
@@ -517,33 +534,33 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
|
517
534
|
if (value) { /* 0 : does not change current level */
|
518
535
|
CCtxParams->compressionLevel = value;
|
519
536
|
}
|
520
|
-
if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel;
|
537
|
+
if (CCtxParams->compressionLevel >= 0) return (size_t)CCtxParams->compressionLevel;
|
521
538
|
return 0; /* return type (size_t) cannot represent negative values */
|
522
539
|
}
|
523
540
|
|
524
541
|
case ZSTD_c_windowLog :
|
525
542
|
if (value!=0) /* 0 => use default */
|
526
543
|
BOUNDCHECK(ZSTD_c_windowLog, value);
|
527
|
-
CCtxParams->cParams.windowLog = value;
|
544
|
+
CCtxParams->cParams.windowLog = (U32)value;
|
528
545
|
return CCtxParams->cParams.windowLog;
|
529
546
|
|
530
547
|
case ZSTD_c_hashLog :
|
531
548
|
if (value!=0) /* 0 => use default */
|
532
549
|
BOUNDCHECK(ZSTD_c_hashLog, value);
|
533
|
-
CCtxParams->cParams.hashLog = value;
|
550
|
+
CCtxParams->cParams.hashLog = (U32)value;
|
534
551
|
return CCtxParams->cParams.hashLog;
|
535
552
|
|
536
553
|
case ZSTD_c_chainLog :
|
537
554
|
if (value!=0) /* 0 => use default */
|
538
555
|
BOUNDCHECK(ZSTD_c_chainLog, value);
|
539
|
-
CCtxParams->cParams.chainLog = value;
|
556
|
+
CCtxParams->cParams.chainLog = (U32)value;
|
540
557
|
return CCtxParams->cParams.chainLog;
|
541
558
|
|
542
559
|
case ZSTD_c_searchLog :
|
543
560
|
if (value!=0) /* 0 => use default */
|
544
561
|
BOUNDCHECK(ZSTD_c_searchLog, value);
|
545
|
-
CCtxParams->cParams.searchLog = value;
|
546
|
-
return value;
|
562
|
+
CCtxParams->cParams.searchLog = (U32)value;
|
563
|
+
return (size_t)value;
|
547
564
|
|
548
565
|
case ZSTD_c_minMatch :
|
549
566
|
if (value!=0) /* 0 => use default */
|
@@ -674,6 +691,12 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
|
674
691
|
CCtxParams->targetCBlockSize = value;
|
675
692
|
return CCtxParams->targetCBlockSize;
|
676
693
|
|
694
|
+
case ZSTD_c_srcSizeHint :
|
695
|
+
if (value!=0) /* 0 ==> default */
|
696
|
+
BOUNDCHECK(ZSTD_c_srcSizeHint, value);
|
697
|
+
CCtxParams->srcSizeHint = value;
|
698
|
+
return CCtxParams->srcSizeHint;
|
699
|
+
|
677
700
|
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
|
678
701
|
}
|
679
702
|
}
|
@@ -779,6 +802,9 @@ size_t ZSTD_CCtxParams_getParameter(
|
|
779
802
|
case ZSTD_c_targetCBlockSize :
|
780
803
|
*value = (int)CCtxParams->targetCBlockSize;
|
781
804
|
break;
|
805
|
+
case ZSTD_c_srcSizeHint :
|
806
|
+
*value = (int)CCtxParams->srcSizeHint;
|
807
|
+
break;
|
782
808
|
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
|
783
809
|
}
|
784
810
|
return 0;
|
@@ -1029,7 +1055,11 @@ ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
|
|
1029
1055
|
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
|
1030
1056
|
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
|
1031
1057
|
{
|
1032
|
-
ZSTD_compressionParameters cParams
|
1058
|
+
ZSTD_compressionParameters cParams;
|
1059
|
+
if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) {
|
1060
|
+
srcSizeHint = CCtxParams->srcSizeHint;
|
1061
|
+
}
|
1062
|
+
cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);
|
1033
1063
|
if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
|
1034
1064
|
if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
|
1035
1065
|
if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
|
@@ -1049,10 +1079,19 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
|
|
1049
1079
|
size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
|
1050
1080
|
size_t const hSize = ((size_t)1) << cParams->hashLog;
|
1051
1081
|
U32 const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
|
1052
|
-
size_t const h3Size = ((size_t)1) << hashLog3;
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1082
|
+
size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0;
|
1083
|
+
/* We don't use ZSTD_cwksp_alloc_size() here because the tables aren't
|
1084
|
+
* surrounded by redzones in ASAN. */
|
1085
|
+
size_t const tableSpace = chainSize * sizeof(U32)
|
1086
|
+
+ hSize * sizeof(U32)
|
1087
|
+
+ h3Size * sizeof(U32);
|
1088
|
+
size_t const optPotentialSpace =
|
1089
|
+
ZSTD_cwksp_alloc_size((MaxML+1) * sizeof(U32))
|
1090
|
+
+ ZSTD_cwksp_alloc_size((MaxLL+1) * sizeof(U32))
|
1091
|
+
+ ZSTD_cwksp_alloc_size((MaxOff+1) * sizeof(U32))
|
1092
|
+
+ ZSTD_cwksp_alloc_size((1<<Litbits) * sizeof(U32))
|
1093
|
+
+ ZSTD_cwksp_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_match_t))
|
1094
|
+
+ ZSTD_cwksp_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t));
|
1056
1095
|
size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt))
|
1057
1096
|
? optPotentialSpace
|
1058
1097
|
: 0;
|
@@ -1069,20 +1108,23 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|
1069
1108
|
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
|
1070
1109
|
U32 const divider = (cParams.minMatch==3) ? 3 : 4;
|
1071
1110
|
size_t const maxNbSeq = blockSize / divider;
|
1072
|
-
size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize
|
1073
|
-
|
1074
|
-
|
1111
|
+
size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
|
1112
|
+
+ ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef))
|
1113
|
+
+ 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
|
1114
|
+
size_t const entropySpace = ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE);
|
1115
|
+
size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
|
1075
1116
|
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
|
1076
1117
|
|
1077
1118
|
size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams);
|
1078
|
-
size_t const ldmSeqSpace = ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize) * sizeof(rawSeq);
|
1119
|
+
size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize) * sizeof(rawSeq));
|
1079
1120
|
|
1080
1121
|
size_t const neededSpace = entropySpace + blockStateSpace + tokenSpace +
|
1081
1122
|
matchStateSize + ldmSpace + ldmSeqSpace;
|
1123
|
+
size_t const cctxSpace = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx));
|
1082
1124
|
|
1083
|
-
DEBUGLOG(5, "sizeof(ZSTD_CCtx) : %u", (U32)
|
1084
|
-
DEBUGLOG(5, "estimate
|
1085
|
-
return
|
1125
|
+
DEBUGLOG(5, "sizeof(ZSTD_CCtx) : %u", (U32)cctxSpace);
|
1126
|
+
DEBUGLOG(5, "estimate workspace : %u", (U32)neededSpace);
|
1127
|
+
return cctxSpace + neededSpace;
|
1086
1128
|
}
|
1087
1129
|
}
|
1088
1130
|
|
@@ -1118,7 +1160,8 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|
1118
1160
|
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
|
1119
1161
|
size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;
|
1120
1162
|
size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;
|
1121
|
-
size_t const streamingSize = inBuffSize
|
1163
|
+
size_t const streamingSize = ZSTD_cwksp_alloc_size(inBuffSize)
|
1164
|
+
+ ZSTD_cwksp_alloc_size(outBuffSize);
|
1122
1165
|
|
1123
1166
|
return CCtxSize + streamingSize;
|
1124
1167
|
}
|
@@ -1186,17 +1229,6 @@ size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx)
|
|
1186
1229
|
return 0; /* over-simplification; could also check if context is currently running in streaming mode, and in which case, report how many bytes are left to be flushed within output buffer */
|
1187
1230
|
}
|
1188
1231
|
|
1189
|
-
|
1190
|
-
|
1191
|
-
static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
|
1192
|
-
ZSTD_compressionParameters cParams2)
|
1193
|
-
{
|
1194
|
-
return (cParams1.hashLog == cParams2.hashLog)
|
1195
|
-
& (cParams1.chainLog == cParams2.chainLog)
|
1196
|
-
& (cParams1.strategy == cParams2.strategy) /* opt parser space */
|
1197
|
-
& ((cParams1.minMatch==3) == (cParams2.minMatch==3)); /* hashlog3 space */
|
1198
|
-
}
|
1199
|
-
|
1200
1232
|
static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
|
1201
1233
|
ZSTD_compressionParameters cParams2)
|
1202
1234
|
{
|
@@ -1211,71 +1243,6 @@ static void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,
|
|
1211
1243
|
assert(cParams1.strategy == cParams2.strategy);
|
1212
1244
|
}
|
1213
1245
|
|
1214
|
-
/** The parameters are equivalent if ldm is not enabled in both sets or
|
1215
|
-
* all the parameters are equivalent. */
|
1216
|
-
static U32 ZSTD_equivalentLdmParams(ldmParams_t ldmParams1,
|
1217
|
-
ldmParams_t ldmParams2)
|
1218
|
-
{
|
1219
|
-
return (!ldmParams1.enableLdm && !ldmParams2.enableLdm) ||
|
1220
|
-
(ldmParams1.enableLdm == ldmParams2.enableLdm &&
|
1221
|
-
ldmParams1.hashLog == ldmParams2.hashLog &&
|
1222
|
-
ldmParams1.bucketSizeLog == ldmParams2.bucketSizeLog &&
|
1223
|
-
ldmParams1.minMatchLength == ldmParams2.minMatchLength &&
|
1224
|
-
ldmParams1.hashRateLog == ldmParams2.hashRateLog);
|
1225
|
-
}
|
1226
|
-
|
1227
|
-
typedef enum { ZSTDb_not_buffered, ZSTDb_buffered } ZSTD_buffered_policy_e;
|
1228
|
-
|
1229
|
-
/* ZSTD_sufficientBuff() :
|
1230
|
-
* check internal buffers exist for streaming if buffPol == ZSTDb_buffered .
|
1231
|
-
* Note : they are assumed to be correctly sized if ZSTD_equivalentCParams()==1 */
|
1232
|
-
static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t maxNbSeq1,
|
1233
|
-
size_t maxNbLit1,
|
1234
|
-
ZSTD_buffered_policy_e buffPol2,
|
1235
|
-
ZSTD_compressionParameters cParams2,
|
1236
|
-
U64 pledgedSrcSize)
|
1237
|
-
{
|
1238
|
-
size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
|
1239
|
-
size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
|
1240
|
-
size_t const maxNbSeq2 = blockSize2 / ((cParams2.minMatch == 3) ? 3 : 4);
|
1241
|
-
size_t const maxNbLit2 = blockSize2;
|
1242
|
-
size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
|
1243
|
-
DEBUGLOG(4, "ZSTD_sufficientBuff: is neededBufferSize2=%u <= bufferSize1=%u",
|
1244
|
-
(U32)neededBufferSize2, (U32)bufferSize1);
|
1245
|
-
DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbSeq2=%u <= maxNbSeq1=%u",
|
1246
|
-
(U32)maxNbSeq2, (U32)maxNbSeq1);
|
1247
|
-
DEBUGLOG(4, "ZSTD_sufficientBuff: is maxNbLit2=%u <= maxNbLit1=%u",
|
1248
|
-
(U32)maxNbLit2, (U32)maxNbLit1);
|
1249
|
-
return (maxNbLit2 <= maxNbLit1)
|
1250
|
-
& (maxNbSeq2 <= maxNbSeq1)
|
1251
|
-
& (neededBufferSize2 <= bufferSize1);
|
1252
|
-
}
|
1253
|
-
|
1254
|
-
/** Equivalence for resetCCtx purposes */
|
1255
|
-
static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
|
1256
|
-
ZSTD_CCtx_params params2,
|
1257
|
-
size_t buffSize1,
|
1258
|
-
size_t maxNbSeq1, size_t maxNbLit1,
|
1259
|
-
ZSTD_buffered_policy_e buffPol2,
|
1260
|
-
U64 pledgedSrcSize)
|
1261
|
-
{
|
1262
|
-
DEBUGLOG(4, "ZSTD_equivalentParams: pledgedSrcSize=%u", (U32)pledgedSrcSize);
|
1263
|
-
if (!ZSTD_equivalentCParams(params1.cParams, params2.cParams)) {
|
1264
|
-
DEBUGLOG(4, "ZSTD_equivalentCParams() == 0");
|
1265
|
-
return 0;
|
1266
|
-
}
|
1267
|
-
if (!ZSTD_equivalentLdmParams(params1.ldmParams, params2.ldmParams)) {
|
1268
|
-
DEBUGLOG(4, "ZSTD_equivalentLdmParams() == 0");
|
1269
|
-
return 0;
|
1270
|
-
}
|
1271
|
-
if (!ZSTD_sufficientBuff(buffSize1, maxNbSeq1, maxNbLit1, buffPol2,
|
1272
|
-
params2.cParams, pledgedSrcSize)) {
|
1273
|
-
DEBUGLOG(4, "ZSTD_sufficientBuff() == 0");
|
1274
|
-
return 0;
|
1275
|
-
}
|
1276
|
-
return 1;
|
1277
|
-
}
|
1278
|
-
|
1279
1246
|
static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
|
1280
1247
|
{
|
1281
1248
|
int i;
|
@@ -1301,87 +1268,104 @@ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
|
|
1301
1268
|
ms->dictMatchState = NULL;
|
1302
1269
|
}
|
1303
1270
|
|
1304
|
-
|
1305
|
-
*
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1271
|
+
/**
|
1272
|
+
* Indicates whether this compression proceeds directly from user-provided
|
1273
|
+
* source buffer to user-provided destination buffer (ZSTDb_not_buffered), or
|
1274
|
+
* whether the context needs to buffer the input/output (ZSTDb_buffered).
|
1275
|
+
*/
|
1276
|
+
typedef enum {
|
1277
|
+
ZSTDb_not_buffered,
|
1278
|
+
ZSTDb_buffered
|
1279
|
+
} ZSTD_buffered_policy_e;
|
1311
1280
|
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
cctx->dictID = 0;
|
1324
|
-
if (params.ldmParams.enableLdm)
|
1325
|
-
ZSTD_window_clear(&cctx->ldmState.window);
|
1326
|
-
ZSTD_referenceExternalSequences(cctx, NULL, 0);
|
1327
|
-
ZSTD_invalidateMatchState(&cctx->blockState.matchState);
|
1328
|
-
ZSTD_reset_compressedBlockState(cctx->blockState.prevCBlock);
|
1329
|
-
XXH64_reset(&cctx->xxhState, 0);
|
1330
|
-
return 0;
|
1331
|
-
}
|
1281
|
+
/**
|
1282
|
+
* Controls, for this matchState reset, whether the tables need to be cleared /
|
1283
|
+
* prepared for the coming compression (ZSTDcrp_makeClean), or whether the
|
1284
|
+
* tables can be left unclean (ZSTDcrp_leaveDirty), because we know that a
|
1285
|
+
* subsequent operation will overwrite the table space anyways (e.g., copying
|
1286
|
+
* the matchState contents in from a CDict).
|
1287
|
+
*/
|
1288
|
+
typedef enum {
|
1289
|
+
ZSTDcrp_makeClean,
|
1290
|
+
ZSTDcrp_leaveDirty
|
1291
|
+
} ZSTD_compResetPolicy_e;
|
1332
1292
|
|
1333
|
-
|
1293
|
+
/**
|
1294
|
+
* Controls, for this matchState reset, whether indexing can continue where it
|
1295
|
+
* left off (ZSTDirp_continue), or whether it needs to be restarted from zero
|
1296
|
+
* (ZSTDirp_reset).
|
1297
|
+
*/
|
1298
|
+
typedef enum {
|
1299
|
+
ZSTDirp_continue,
|
1300
|
+
ZSTDirp_reset
|
1301
|
+
} ZSTD_indexResetPolicy_e;
|
1334
1302
|
|
1335
|
-
typedef enum {
|
1303
|
+
typedef enum {
|
1304
|
+
ZSTD_resetTarget_CDict,
|
1305
|
+
ZSTD_resetTarget_CCtx
|
1306
|
+
} ZSTD_resetTarget_e;
|
1336
1307
|
|
1337
|
-
static
|
1308
|
+
static size_t
|
1338
1309
|
ZSTD_reset_matchState(ZSTD_matchState_t* ms,
|
1339
|
-
|
1310
|
+
ZSTD_cwksp* ws,
|
1340
1311
|
const ZSTD_compressionParameters* cParams,
|
1341
|
-
|
1312
|
+
const ZSTD_compResetPolicy_e crp,
|
1313
|
+
const ZSTD_indexResetPolicy_e forceResetIndex,
|
1314
|
+
const ZSTD_resetTarget_e forWho)
|
1342
1315
|
{
|
1343
1316
|
size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
|
1344
1317
|
size_t const hSize = ((size_t)1) << cParams->hashLog;
|
1345
1318
|
U32 const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
|
1346
|
-
size_t const h3Size = ((size_t)1) << hashLog3;
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1319
|
+
size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0;
|
1320
|
+
|
1321
|
+
DEBUGLOG(4, "reset indices : %u", forceResetIndex == ZSTDirp_reset);
|
1322
|
+
if (forceResetIndex == ZSTDirp_reset) {
|
1323
|
+
memset(&ms->window, 0, sizeof(ms->window));
|
1324
|
+
ms->window.dictLimit = 1; /* start from 1, so that 1st position is valid */
|
1325
|
+
ms->window.lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
|
1326
|
+
ms->window.nextSrc = ms->window.base + 1; /* see issue #1241 */
|
1327
|
+
ZSTD_cwksp_mark_tables_dirty(ws);
|
1328
|
+
}
|
1350
1329
|
|
1351
1330
|
ms->hashLog3 = hashLog3;
|
1352
|
-
|
1353
|
-
ms->window.dictLimit = 1; /* start from 1, so that 1st position is valid */
|
1354
|
-
ms->window.lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
|
1355
|
-
ms->window.nextSrc = ms->window.base + 1; /* see issue #1241 */
|
1331
|
+
|
1356
1332
|
ZSTD_invalidateMatchState(ms);
|
1357
1333
|
|
1334
|
+
assert(!ZSTD_cwksp_reserve_failed(ws)); /* check that allocation hasn't already failed */
|
1335
|
+
|
1336
|
+
ZSTD_cwksp_clear_tables(ws);
|
1337
|
+
|
1338
|
+
DEBUGLOG(5, "reserving table space");
|
1339
|
+
/* table Space */
|
1340
|
+
ms->hashTable = (U32*)ZSTD_cwksp_reserve_table(ws, hSize * sizeof(U32));
|
1341
|
+
ms->chainTable = (U32*)ZSTD_cwksp_reserve_table(ws, chainSize * sizeof(U32));
|
1342
|
+
ms->hashTable3 = (U32*)ZSTD_cwksp_reserve_table(ws, h3Size * sizeof(U32));
|
1343
|
+
RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation,
|
1344
|
+
"failed a workspace allocation in ZSTD_reset_matchState");
|
1345
|
+
|
1346
|
+
DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_leaveDirty);
|
1347
|
+
if (crp!=ZSTDcrp_leaveDirty) {
|
1348
|
+
/* reset tables only */
|
1349
|
+
ZSTD_cwksp_clean_tables(ws);
|
1350
|
+
}
|
1351
|
+
|
1358
1352
|
/* opt parser space */
|
1359
1353
|
if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) {
|
1360
1354
|
DEBUGLOG(4, "reserving optimal parser space");
|
1361
|
-
ms->opt.litFreq = (unsigned*)
|
1362
|
-
ms->opt.litLengthFreq =
|
1363
|
-
ms->opt.matchLengthFreq =
|
1364
|
-
ms->opt.offCodeFreq =
|
1365
|
-
|
1366
|
-
ms->opt.
|
1367
|
-
ptr = ms->opt.matchTable + ZSTD_OPT_NUM+1;
|
1368
|
-
ms->opt.priceTable = (ZSTD_optimal_t*)ptr;
|
1369
|
-
ptr = ms->opt.priceTable + ZSTD_OPT_NUM+1;
|
1355
|
+
ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (1<<Litbits) * sizeof(unsigned));
|
1356
|
+
ms->opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxLL+1) * sizeof(unsigned));
|
1357
|
+
ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxML+1) * sizeof(unsigned));
|
1358
|
+
ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxOff+1) * sizeof(unsigned));
|
1359
|
+
ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned(ws, (ZSTD_OPT_NUM+1) * sizeof(ZSTD_match_t));
|
1360
|
+
ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned(ws, (ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t));
|
1370
1361
|
}
|
1371
1362
|
|
1372
|
-
/* table Space */
|
1373
|
-
DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_noMemset);
|
1374
|
-
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
1375
|
-
if (crp!=ZSTDcrp_noMemset) memset(ptr, 0, tableSpace); /* reset tables only */
|
1376
|
-
ms->hashTable = (U32*)(ptr);
|
1377
|
-
ms->chainTable = ms->hashTable + hSize;
|
1378
|
-
ms->hashTable3 = ms->chainTable + chainSize;
|
1379
|
-
ptr = ms->hashTable3 + h3Size;
|
1380
|
-
|
1381
1363
|
ms->cParams = *cParams;
|
1382
1364
|
|
1383
|
-
|
1384
|
-
|
1365
|
+
RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation,
|
1366
|
+
"failed a workspace allocation in ZSTD_reset_matchState");
|
1367
|
+
|
1368
|
+
return 0;
|
1385
1369
|
}
|
1386
1370
|
|
1387
1371
|
/* ZSTD_indexTooCloseToMax() :
|
@@ -1397,13 +1381,6 @@ static int ZSTD_indexTooCloseToMax(ZSTD_window_t w)
|
|
1397
1381
|
return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN);
|
1398
1382
|
}
|
1399
1383
|
|
1400
|
-
#define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as this number of times larger than needed */
|
1401
|
-
#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128 /* when workspace is continuously too large
|
1402
|
-
* during at least this number of times,
|
1403
|
-
* context's memory usage is considered wasteful,
|
1404
|
-
* because it's sized to handle a worst case scenario which rarely happens.
|
1405
|
-
* In which case, resize it down to free some memory */
|
1406
|
-
|
1407
1384
|
/*! ZSTD_resetCCtx_internal() :
|
1408
1385
|
note : `params` are assumed fully validated at this stage */
|
1409
1386
|
static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
@@ -1412,30 +1389,12 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
1412
1389
|
ZSTD_compResetPolicy_e const crp,
|
1413
1390
|
ZSTD_buffered_policy_e const zbuff)
|
1414
1391
|
{
|
1392
|
+
ZSTD_cwksp* const ws = &zc->workspace;
|
1415
1393
|
DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u",
|
1416
1394
|
(U32)pledgedSrcSize, params.cParams.windowLog);
|
1417
1395
|
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
1418
1396
|
|
1419
|
-
|
1420
|
-
if (ZSTD_equivalentParams(zc->appliedParams, params,
|
1421
|
-
zc->inBuffSize,
|
1422
|
-
zc->seqStore.maxNbSeq, zc->seqStore.maxNbLit,
|
1423
|
-
zbuff, pledgedSrcSize) ) {
|
1424
|
-
DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> consider continue mode");
|
1425
|
-
zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0); /* if it was too large, it still is */
|
1426
|
-
if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION) {
|
1427
|
-
DEBUGLOG(4, "continue mode confirmed (wLog1=%u, blockSize1=%zu)",
|
1428
|
-
zc->appliedParams.cParams.windowLog, zc->blockSize);
|
1429
|
-
if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) {
|
1430
|
-
/* prefer a reset, faster than a rescale */
|
1431
|
-
ZSTD_reset_matchState(&zc->blockState.matchState,
|
1432
|
-
zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32,
|
1433
|
-
¶ms.cParams,
|
1434
|
-
crp, ZSTD_resetTarget_CCtx);
|
1435
|
-
}
|
1436
|
-
return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
|
1437
|
-
} } }
|
1438
|
-
DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
|
1397
|
+
zc->isFirstBlock = 1;
|
1439
1398
|
|
1440
1399
|
if (params.ldmParams.enableLdm) {
|
1441
1400
|
/* Adjust long distance matching parameters */
|
@@ -1449,58 +1408,74 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
1449
1408
|
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
|
1450
1409
|
U32 const divider = (params.cParams.minMatch==3) ? 3 : 4;
|
1451
1410
|
size_t const maxNbSeq = blockSize / divider;
|
1452
|
-
size_t const tokenSpace = WILDCOPY_OVERLENGTH + blockSize
|
1411
|
+
size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
|
1412
|
+
+ ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef))
|
1413
|
+
+ 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
|
1453
1414
|
size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
|
1454
1415
|
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
|
1455
1416
|
size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1);
|
1456
1417
|
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
|
1457
|
-
void* ptr; /* used to partition workSpace */
|
1458
1418
|
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1419
|
+
ZSTD_indexResetPolicy_e needsIndexReset = ZSTDirp_continue;
|
1420
|
+
|
1421
|
+
if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) {
|
1422
|
+
needsIndexReset = ZSTDirp_reset;
|
1423
|
+
}
|
1424
|
+
|
1425
|
+
ZSTD_cwksp_bump_oversized_duration(ws, 0);
|
1426
|
+
|
1427
|
+
/* Check if workspace is large enough, alloc a new one if needed */
|
1428
|
+
{ size_t const cctxSpace = zc->staticSize ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0;
|
1429
|
+
size_t const entropySpace = ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE);
|
1430
|
+
size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
|
1431
|
+
size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize) + ZSTD_cwksp_alloc_size(buffOutSize);
|
1463
1432
|
size_t const ldmSpace = ZSTD_ldm_getTableSize(params.ldmParams);
|
1464
|
-
size_t const ldmSeqSpace = maxNbLdmSeq * sizeof(rawSeq);
|
1433
|
+
size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(maxNbLdmSeq * sizeof(rawSeq));
|
1465
1434
|
|
1466
|
-
size_t const neededSpace =
|
1467
|
-
|
1468
|
-
|
1435
|
+
size_t const neededSpace =
|
1436
|
+
cctxSpace +
|
1437
|
+
entropySpace +
|
1438
|
+
blockStateSpace +
|
1439
|
+
ldmSpace +
|
1440
|
+
ldmSeqSpace +
|
1441
|
+
matchStateSize +
|
1442
|
+
tokenSpace +
|
1443
|
+
bufferSpace;
|
1469
1444
|
|
1470
|
-
int const
|
1471
|
-
int const
|
1472
|
-
int const workSpaceWasteful = workSpaceTooLarge && (zc->workSpaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION);
|
1473
|
-
zc->workSpaceOversizedDuration = workSpaceTooLarge ? zc->workSpaceOversizedDuration+1 : 0;
|
1445
|
+
int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace;
|
1446
|
+
int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace);
|
1474
1447
|
|
1475
1448
|
DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers",
|
1476
1449
|
neededSpace>>10, matchStateSize>>10, bufferSpace>>10);
|
1477
1450
|
DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
|
1478
1451
|
|
1479
|
-
if (
|
1480
|
-
DEBUGLOG(4, "Resize
|
1481
|
-
|
1452
|
+
if (workspaceTooSmall || workspaceWasteful) {
|
1453
|
+
DEBUGLOG(4, "Resize workspaceSize from %zuKB to %zuKB",
|
1454
|
+
ZSTD_cwksp_sizeof(ws) >> 10,
|
1482
1455
|
neededSpace >> 10);
|
1483
1456
|
|
1484
1457
|
RETURN_ERROR_IF(zc->staticSize, memory_allocation, "static cctx : no resize");
|
1485
1458
|
|
1486
|
-
|
1487
|
-
ZSTD_free(zc->workSpace, zc->customMem);
|
1488
|
-
zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
|
1489
|
-
RETURN_ERROR_IF(zc->workSpace == NULL, memory_allocation);
|
1490
|
-
zc->workSpaceSize = neededSpace;
|
1491
|
-
zc->workSpaceOversizedDuration = 0;
|
1459
|
+
needsIndexReset = ZSTDirp_reset;
|
1492
1460
|
|
1461
|
+
ZSTD_cwksp_free(ws, zc->customMem);
|
1462
|
+
FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem));
|
1463
|
+
|
1464
|
+
DEBUGLOG(5, "reserving object space");
|
1493
1465
|
/* Statically sized space.
|
1494
1466
|
* entropyWorkspace never moves,
|
1495
1467
|
* though prev/next block swap places */
|
1496
|
-
assert((
|
1497
|
-
|
1498
|
-
zc->blockState.prevCBlock
|
1499
|
-
zc->blockState.nextCBlock =
|
1500
|
-
|
1501
|
-
zc->entropyWorkspace = (U32*)
|
1468
|
+
assert(ZSTD_cwksp_check_available(ws, 2 * sizeof(ZSTD_compressedBlockState_t)));
|
1469
|
+
zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
|
1470
|
+
RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock");
|
1471
|
+
zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
|
1472
|
+
RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock");
|
1473
|
+
zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, HUF_WORKSPACE_SIZE);
|
1474
|
+
RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate entropyWorkspace");
|
1502
1475
|
} }
|
1503
1476
|
|
1477
|
+
ZSTD_cwksp_clear(ws);
|
1478
|
+
|
1504
1479
|
/* init params */
|
1505
1480
|
zc->appliedParams = params;
|
1506
1481
|
zc->blockState.matchState.cParams = params.cParams;
|
@@ -1519,58 +1494,58 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
1519
1494
|
|
1520
1495
|
ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock);
|
1521
1496
|
|
1522
|
-
ptr = ZSTD_reset_matchState(&zc->blockState.matchState,
|
1523
|
-
zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32,
|
1524
|
-
¶ms.cParams,
|
1525
|
-
crp, ZSTD_resetTarget_CCtx);
|
1526
|
-
|
1527
|
-
/* ldm hash table */
|
1528
|
-
/* initialize bucketOffsets table later for pointer alignment */
|
1529
|
-
if (params.ldmParams.enableLdm) {
|
1530
|
-
size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
|
1531
|
-
memset(ptr, 0, ldmHSize * sizeof(ldmEntry_t));
|
1532
|
-
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
1533
|
-
zc->ldmState.hashTable = (ldmEntry_t*)ptr;
|
1534
|
-
ptr = zc->ldmState.hashTable + ldmHSize;
|
1535
|
-
zc->ldmSequences = (rawSeq*)ptr;
|
1536
|
-
ptr = zc->ldmSequences + maxNbLdmSeq;
|
1537
|
-
zc->maxNbLdmSequences = maxNbLdmSeq;
|
1538
|
-
|
1539
|
-
memset(&zc->ldmState.window, 0, sizeof(zc->ldmState.window));
|
1540
|
-
}
|
1541
|
-
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
1542
|
-
|
1543
|
-
/* sequences storage */
|
1544
|
-
zc->seqStore.maxNbSeq = maxNbSeq;
|
1545
|
-
zc->seqStore.sequencesStart = (seqDef*)ptr;
|
1546
|
-
ptr = zc->seqStore.sequencesStart + maxNbSeq;
|
1547
|
-
zc->seqStore.llCode = (BYTE*) ptr;
|
1548
|
-
zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
|
1549
|
-
zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
|
1550
|
-
zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
|
1551
1497
|
/* ZSTD_wildcopy() is used to copy into the literals buffer,
|
1552
1498
|
* so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes.
|
1553
1499
|
*/
|
1500
|
+
zc->seqStore.litStart = ZSTD_cwksp_reserve_buffer(ws, blockSize + WILDCOPY_OVERLENGTH);
|
1554
1501
|
zc->seqStore.maxNbLit = blockSize;
|
1555
|
-
|
1502
|
+
|
1503
|
+
/* buffers */
|
1504
|
+
zc->inBuffSize = buffInSize;
|
1505
|
+
zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize);
|
1506
|
+
zc->outBuffSize = buffOutSize;
|
1507
|
+
zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize);
|
1556
1508
|
|
1557
1509
|
/* ldm bucketOffsets table */
|
1558
1510
|
if (params.ldmParams.enableLdm) {
|
1511
|
+
/* TODO: avoid memset? */
|
1559
1512
|
size_t const ldmBucketSize =
|
1560
1513
|
((size_t)1) << (params.ldmParams.hashLog -
|
1561
1514
|
params.ldmParams.bucketSizeLog);
|
1562
|
-
|
1563
|
-
zc->ldmState.bucketOffsets
|
1564
|
-
ptr = zc->ldmState.bucketOffsets + ldmBucketSize;
|
1565
|
-
ZSTD_window_clear(&zc->ldmState.window);
|
1515
|
+
zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, ldmBucketSize);
|
1516
|
+
memset(zc->ldmState.bucketOffsets, 0, ldmBucketSize);
|
1566
1517
|
}
|
1518
|
+
|
1519
|
+
/* sequences storage */
|
1567
1520
|
ZSTD_referenceExternalSequences(zc, NULL, 0);
|
1521
|
+
zc->seqStore.maxNbSeq = maxNbSeq;
|
1522
|
+
zc->seqStore.llCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
|
1523
|
+
zc->seqStore.mlCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
|
1524
|
+
zc->seqStore.ofCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));
|
1525
|
+
zc->seqStore.sequencesStart = (seqDef*)ZSTD_cwksp_reserve_aligned(ws, maxNbSeq * sizeof(seqDef));
|
1526
|
+
|
1527
|
+
FORWARD_IF_ERROR(ZSTD_reset_matchState(
|
1528
|
+
&zc->blockState.matchState,
|
1529
|
+
ws,
|
1530
|
+
¶ms.cParams,
|
1531
|
+
crp,
|
1532
|
+
needsIndexReset,
|
1533
|
+
ZSTD_resetTarget_CCtx));
|
1568
1534
|
|
1569
|
-
/*
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1535
|
+
/* ldm hash table */
|
1536
|
+
if (params.ldmParams.enableLdm) {
|
1537
|
+
/* TODO: avoid memset? */
|
1538
|
+
size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;
|
1539
|
+
zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t));
|
1540
|
+
memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
|
1541
|
+
zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq));
|
1542
|
+
zc->maxNbLdmSequences = maxNbLdmSeq;
|
1543
|
+
|
1544
|
+
memset(&zc->ldmState.window, 0, sizeof(zc->ldmState.window));
|
1545
|
+
ZSTD_window_clear(&zc->ldmState.window);
|
1546
|
+
}
|
1547
|
+
|
1548
|
+
DEBUGLOG(3, "wksp: finished allocating, %zd bytes remain available", ZSTD_cwksp_available_space(ws));
|
1574
1549
|
|
1575
1550
|
return 0;
|
1576
1551
|
}
|
@@ -1604,15 +1579,15 @@ static const size_t attachDictSizeCutoffs[ZSTD_STRATEGY_MAX+1] = {
|
|
1604
1579
|
};
|
1605
1580
|
|
1606
1581
|
static int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict,
|
1607
|
-
ZSTD_CCtx_params params,
|
1582
|
+
const ZSTD_CCtx_params* params,
|
1608
1583
|
U64 pledgedSrcSize)
|
1609
1584
|
{
|
1610
1585
|
size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy];
|
1611
1586
|
return ( pledgedSrcSize <= cutoff
|
1612
1587
|
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
|
1613
|
-
|| params
|
1614
|
-
&& params
|
1615
|
-
&& !params
|
1588
|
+
|| params->attachDictPref == ZSTD_dictForceAttach )
|
1589
|
+
&& params->attachDictPref != ZSTD_dictForceCopy
|
1590
|
+
&& !params->forceWindow; /* dictMatchState isn't correctly
|
1616
1591
|
* handled in _enforceMaxDist */
|
1617
1592
|
}
|
1618
1593
|
|
@@ -1630,8 +1605,8 @@ ZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,
|
|
1630
1605
|
* has its own tables. */
|
1631
1606
|
params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0);
|
1632
1607
|
params.cParams.windowLog = windowLog;
|
1633
|
-
ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
1634
|
-
|
1608
|
+
FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
1609
|
+
ZSTDcrp_makeClean, zbuff));
|
1635
1610
|
assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
|
1636
1611
|
}
|
1637
1612
|
|
@@ -1679,30 +1654,36 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
|
|
1679
1654
|
/* Copy only compression parameters related to tables. */
|
1680
1655
|
params.cParams = *cdict_cParams;
|
1681
1656
|
params.cParams.windowLog = windowLog;
|
1682
|
-
ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
1683
|
-
|
1657
|
+
FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
1658
|
+
ZSTDcrp_leaveDirty, zbuff));
|
1684
1659
|
assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);
|
1685
1660
|
assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog);
|
1686
1661
|
assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog);
|
1687
1662
|
}
|
1688
1663
|
|
1664
|
+
ZSTD_cwksp_mark_tables_dirty(&cctx->workspace);
|
1665
|
+
|
1689
1666
|
/* copy tables */
|
1690
1667
|
{ size_t const chainSize = (cdict_cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict_cParams->chainLog);
|
1691
1668
|
size_t const hSize = (size_t)1 << cdict_cParams->hashLog;
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1669
|
+
|
1670
|
+
memcpy(cctx->blockState.matchState.hashTable,
|
1671
|
+
cdict->matchState.hashTable,
|
1672
|
+
hSize * sizeof(U32));
|
1673
|
+
memcpy(cctx->blockState.matchState.chainTable,
|
1674
|
+
cdict->matchState.chainTable,
|
1675
|
+
chainSize * sizeof(U32));
|
1698
1676
|
}
|
1699
1677
|
|
1700
1678
|
/* Zero the hashTable3, since the cdict never fills it */
|
1701
|
-
{
|
1679
|
+
{ int const h3log = cctx->blockState.matchState.hashLog3;
|
1680
|
+
size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
|
1702
1681
|
assert(cdict->matchState.hashLog3 == 0);
|
1703
1682
|
memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
|
1704
1683
|
}
|
1705
1684
|
|
1685
|
+
ZSTD_cwksp_mark_tables_clean(&cctx->workspace);
|
1686
|
+
|
1706
1687
|
/* copy dictionary offsets */
|
1707
1688
|
{ ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
|
1708
1689
|
ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
|
@@ -1724,7 +1705,7 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
|
|
1724
1705
|
* in-place. We decide here which strategy to use. */
|
1725
1706
|
static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
1726
1707
|
const ZSTD_CDict* cdict,
|
1727
|
-
ZSTD_CCtx_params params,
|
1708
|
+
const ZSTD_CCtx_params* params,
|
1728
1709
|
U64 pledgedSrcSize,
|
1729
1710
|
ZSTD_buffered_policy_e zbuff)
|
1730
1711
|
{
|
@@ -1734,10 +1715,10 @@ static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
|
1734
1715
|
|
1735
1716
|
if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) {
|
1736
1717
|
return ZSTD_resetCCtx_byAttachingCDict(
|
1737
|
-
cctx, cdict, params, pledgedSrcSize, zbuff);
|
1718
|
+
cctx, cdict, *params, pledgedSrcSize, zbuff);
|
1738
1719
|
} else {
|
1739
1720
|
return ZSTD_resetCCtx_byCopyingCDict(
|
1740
|
-
cctx, cdict, params, pledgedSrcSize, zbuff);
|
1721
|
+
cctx, cdict, *params, pledgedSrcSize, zbuff);
|
1741
1722
|
}
|
1742
1723
|
}
|
1743
1724
|
|
@@ -1763,7 +1744,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
|
1763
1744
|
params.cParams = srcCCtx->appliedParams.cParams;
|
1764
1745
|
params.fParams = fParams;
|
1765
1746
|
ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,
|
1766
|
-
|
1747
|
+
ZSTDcrp_leaveDirty, zbuff);
|
1767
1748
|
assert(dstCCtx->appliedParams.cParams.windowLog == srcCCtx->appliedParams.cParams.windowLog);
|
1768
1749
|
assert(dstCCtx->appliedParams.cParams.strategy == srcCCtx->appliedParams.cParams.strategy);
|
1769
1750
|
assert(dstCCtx->appliedParams.cParams.hashLog == srcCCtx->appliedParams.cParams.hashLog);
|
@@ -1771,16 +1752,27 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
|
1771
1752
|
assert(dstCCtx->blockState.matchState.hashLog3 == srcCCtx->blockState.matchState.hashLog3);
|
1772
1753
|
}
|
1773
1754
|
|
1755
|
+
ZSTD_cwksp_mark_tables_dirty(&dstCCtx->workspace);
|
1756
|
+
|
1774
1757
|
/* copy tables */
|
1775
1758
|
{ size_t const chainSize = (srcCCtx->appliedParams.cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog);
|
1776
1759
|
size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog;
|
1777
|
-
|
1778
|
-
size_t const
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1760
|
+
int const h3log = srcCCtx->blockState.matchState.hashLog3;
|
1761
|
+
size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
|
1762
|
+
|
1763
|
+
memcpy(dstCCtx->blockState.matchState.hashTable,
|
1764
|
+
srcCCtx->blockState.matchState.hashTable,
|
1765
|
+
hSize * sizeof(U32));
|
1766
|
+
memcpy(dstCCtx->blockState.matchState.chainTable,
|
1767
|
+
srcCCtx->blockState.matchState.chainTable,
|
1768
|
+
chainSize * sizeof(U32));
|
1769
|
+
memcpy(dstCCtx->blockState.matchState.hashTable3,
|
1770
|
+
srcCCtx->blockState.matchState.hashTable3,
|
1771
|
+
h3Size * sizeof(U32));
|
1782
1772
|
}
|
1783
1773
|
|
1774
|
+
ZSTD_cwksp_mark_tables_clean(&dstCCtx->workspace);
|
1775
|
+
|
1784
1776
|
/* copy dictionary offsets */
|
1785
1777
|
{
|
1786
1778
|
const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState;
|
@@ -1831,6 +1823,20 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa
|
|
1831
1823
|
int rowNb;
|
1832
1824
|
assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */
|
1833
1825
|
assert(size < (1U<<31)); /* can be casted to int */
|
1826
|
+
|
1827
|
+
#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
|
1828
|
+
/* To validate that the table re-use logic is sound, and that we don't
|
1829
|
+
* access table space that we haven't cleaned, we re-"poison" the table
|
1830
|
+
* space every time we mark it dirty.
|
1831
|
+
*
|
1832
|
+
* This function however is intended to operate on those dirty tables and
|
1833
|
+
* re-clean them. So when this function is used correctly, we can unpoison
|
1834
|
+
* the memory it operated on. This introduces a blind spot though, since
|
1835
|
+
* if we now try to operate on __actually__ poisoned memory, we will not
|
1836
|
+
* detect that. */
|
1837
|
+
__msan_unpoison(table, size * sizeof(U32));
|
1838
|
+
#endif
|
1839
|
+
|
1834
1840
|
for (rowNb=0 ; rowNb < nbRows ; rowNb++) {
|
1835
1841
|
int column;
|
1836
1842
|
for (column=0; column<ZSTD_ROWSIZE; column++) {
|
@@ -1938,7 +1944,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1938
1944
|
ZSTD_entropyCTables_t* nextEntropy,
|
1939
1945
|
const ZSTD_CCtx_params* cctxParams,
|
1940
1946
|
void* dst, size_t dstCapacity,
|
1941
|
-
void*
|
1947
|
+
void* entropyWorkspace, size_t entropyWkspSize,
|
1942
1948
|
const int bmi2)
|
1943
1949
|
{
|
1944
1950
|
const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
|
@@ -1955,7 +1961,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1955
1961
|
BYTE* const ostart = (BYTE*)dst;
|
1956
1962
|
BYTE* const oend = ostart + dstCapacity;
|
1957
1963
|
BYTE* op = ostart;
|
1958
|
-
size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
|
1964
|
+
size_t const nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
1959
1965
|
BYTE* seqHead;
|
1960
1966
|
BYTE* lastNCount = NULL;
|
1961
1967
|
|
@@ -1964,14 +1970,14 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1964
1970
|
|
1965
1971
|
/* Compress literals */
|
1966
1972
|
{ const BYTE* const literals = seqStorePtr->litStart;
|
1967
|
-
size_t const litSize = seqStorePtr->lit - literals;
|
1973
|
+
size_t const litSize = (size_t)(seqStorePtr->lit - literals);
|
1968
1974
|
size_t const cSize = ZSTD_compressLiterals(
|
1969
1975
|
&prevEntropy->huf, &nextEntropy->huf,
|
1970
1976
|
cctxParams->cParams.strategy,
|
1971
1977
|
ZSTD_disableLiteralsCompression(cctxParams),
|
1972
1978
|
op, dstCapacity,
|
1973
1979
|
literals, litSize,
|
1974
|
-
|
1980
|
+
entropyWorkspace, entropyWkspSize,
|
1975
1981
|
bmi2);
|
1976
1982
|
FORWARD_IF_ERROR(cSize);
|
1977
1983
|
assert(cSize <= dstCapacity);
|
@@ -1981,17 +1987,22 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1981
1987
|
/* Sequences Header */
|
1982
1988
|
RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/,
|
1983
1989
|
dstSize_tooSmall);
|
1984
|
-
if (nbSeq <
|
1990
|
+
if (nbSeq < 128) {
|
1985
1991
|
*op++ = (BYTE)nbSeq;
|
1986
|
-
else if (nbSeq < LONGNBSEQ)
|
1987
|
-
op[0] = (BYTE)((nbSeq>>8) + 0x80)
|
1988
|
-
|
1989
|
-
op
|
1992
|
+
} else if (nbSeq < LONGNBSEQ) {
|
1993
|
+
op[0] = (BYTE)((nbSeq>>8) + 0x80);
|
1994
|
+
op[1] = (BYTE)nbSeq;
|
1995
|
+
op+=2;
|
1996
|
+
} else {
|
1997
|
+
op[0]=0xFF;
|
1998
|
+
MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ));
|
1999
|
+
op+=3;
|
2000
|
+
}
|
1990
2001
|
assert(op <= oend);
|
1991
2002
|
if (nbSeq==0) {
|
1992
2003
|
/* Copy the old tables over as if we repeated them */
|
1993
2004
|
memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
|
1994
|
-
return op - ostart;
|
2005
|
+
return (size_t)(op - ostart);
|
1995
2006
|
}
|
1996
2007
|
|
1997
2008
|
/* seqHead : flags for FSE encoding type */
|
@@ -2002,7 +2013,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
2002
2013
|
ZSTD_seqToCodes(seqStorePtr);
|
2003
2014
|
/* build CTable for Literal Lengths */
|
2004
2015
|
{ unsigned max = MaxLL;
|
2005
|
-
size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq,
|
2016
|
+
size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
|
2006
2017
|
DEBUGLOG(5, "Building LL table");
|
2007
2018
|
nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode;
|
2008
2019
|
LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode,
|
@@ -2012,10 +2023,14 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
2012
2023
|
ZSTD_defaultAllowed, strategy);
|
2013
2024
|
assert(set_basic < set_compressed && set_rle < set_compressed);
|
2014
2025
|
assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
2015
|
-
{ size_t const countSize = ZSTD_buildCTable(
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2026
|
+
{ size_t const countSize = ZSTD_buildCTable(
|
2027
|
+
op, (size_t)(oend - op),
|
2028
|
+
CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
|
2029
|
+
count, max, llCodeTable, nbSeq,
|
2030
|
+
LL_defaultNorm, LL_defaultNormLog, MaxLL,
|
2031
|
+
prevEntropy->fse.litlengthCTable,
|
2032
|
+
sizeof(prevEntropy->fse.litlengthCTable),
|
2033
|
+
entropyWorkspace, entropyWkspSize);
|
2019
2034
|
FORWARD_IF_ERROR(countSize);
|
2020
2035
|
if (LLtype == set_compressed)
|
2021
2036
|
lastNCount = op;
|
@@ -2024,7 +2039,8 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
2024
2039
|
} }
|
2025
2040
|
/* build CTable for Offsets */
|
2026
2041
|
{ unsigned max = MaxOff;
|
2027
|
-
size_t const mostFrequent = HIST_countFast_wksp(
|
2042
|
+
size_t const mostFrequent = HIST_countFast_wksp(
|
2043
|
+
count, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
|
2028
2044
|
/* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
|
2029
2045
|
ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
|
2030
2046
|
DEBUGLOG(5, "Building OF table");
|
@@ -2035,10 +2051,14 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
2035
2051
|
OF_defaultNorm, OF_defaultNormLog,
|
2036
2052
|
defaultPolicy, strategy);
|
2037
2053
|
assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
2038
|
-
{ size_t const countSize = ZSTD_buildCTable(
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2054
|
+
{ size_t const countSize = ZSTD_buildCTable(
|
2055
|
+
op, (size_t)(oend - op),
|
2056
|
+
CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
|
2057
|
+
count, max, ofCodeTable, nbSeq,
|
2058
|
+
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
|
2059
|
+
prevEntropy->fse.offcodeCTable,
|
2060
|
+
sizeof(prevEntropy->fse.offcodeCTable),
|
2061
|
+
entropyWorkspace, entropyWkspSize);
|
2042
2062
|
FORWARD_IF_ERROR(countSize);
|
2043
2063
|
if (Offtype == set_compressed)
|
2044
2064
|
lastNCount = op;
|
@@ -2047,7 +2067,8 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
2047
2067
|
} }
|
2048
2068
|
/* build CTable for MatchLengths */
|
2049
2069
|
{ unsigned max = MaxML;
|
2050
|
-
size_t const mostFrequent = HIST_countFast_wksp(
|
2070
|
+
size_t const mostFrequent = HIST_countFast_wksp(
|
2071
|
+
count, &max, mlCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
|
2051
2072
|
DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
|
2052
2073
|
nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode;
|
2053
2074
|
MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode,
|
@@ -2056,10 +2077,14 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
2056
2077
|
ML_defaultNorm, ML_defaultNormLog,
|
2057
2078
|
ZSTD_defaultAllowed, strategy);
|
2058
2079
|
assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
2059
|
-
{ size_t const countSize = ZSTD_buildCTable(
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2080
|
+
{ size_t const countSize = ZSTD_buildCTable(
|
2081
|
+
op, (size_t)(oend - op),
|
2082
|
+
CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
|
2083
|
+
count, max, mlCodeTable, nbSeq,
|
2084
|
+
ML_defaultNorm, ML_defaultNormLog, MaxML,
|
2085
|
+
prevEntropy->fse.matchlengthCTable,
|
2086
|
+
sizeof(prevEntropy->fse.matchlengthCTable),
|
2087
|
+
entropyWorkspace, entropyWkspSize);
|
2063
2088
|
FORWARD_IF_ERROR(countSize);
|
2064
2089
|
if (MLtype == set_compressed)
|
2065
2090
|
lastNCount = op;
|
@@ -2070,7 +2095,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
2070
2095
|
*seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
|
2071
2096
|
|
2072
2097
|
{ size_t const bitstreamSize = ZSTD_encodeSequences(
|
2073
|
-
op, oend - op,
|
2098
|
+
op, (size_t)(oend - op),
|
2074
2099
|
CTable_MatchLength, mlCodeTable,
|
2075
2100
|
CTable_OffsetBits, ofCodeTable,
|
2076
2101
|
CTable_LitLength, llCodeTable,
|
@@ -2097,7 +2122,7 @@ ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
2097
2122
|
}
|
2098
2123
|
|
2099
2124
|
DEBUGLOG(5, "compressed block size : %u", (unsigned)(op - ostart));
|
2100
|
-
return op - ostart;
|
2125
|
+
return (size_t)(op - ostart);
|
2101
2126
|
}
|
2102
2127
|
|
2103
2128
|
MEM_STATIC size_t
|
@@ -2107,13 +2132,13 @@ ZSTD_compressSequences(seqStore_t* seqStorePtr,
|
|
2107
2132
|
const ZSTD_CCtx_params* cctxParams,
|
2108
2133
|
void* dst, size_t dstCapacity,
|
2109
2134
|
size_t srcSize,
|
2110
|
-
void*
|
2135
|
+
void* entropyWorkspace, size_t entropyWkspSize,
|
2111
2136
|
int bmi2)
|
2112
2137
|
{
|
2113
2138
|
size_t const cSize = ZSTD_compressSequences_internal(
|
2114
2139
|
seqStorePtr, prevEntropy, nextEntropy, cctxParams,
|
2115
2140
|
dst, dstCapacity,
|
2116
|
-
|
2141
|
+
entropyWorkspace, entropyWkspSize, bmi2);
|
2117
2142
|
if (cSize == 0) return 0;
|
2118
2143
|
/* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
|
2119
2144
|
* Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
|
@@ -2264,19 +2289,113 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
|
2264
2289
|
return ZSTDbss_compress;
|
2265
2290
|
}
|
2266
2291
|
|
2292
|
+
static void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)
|
2293
|
+
{
|
2294
|
+
const seqStore_t* seqStore = ZSTD_getSeqStore(zc);
|
2295
|
+
const seqDef* seqs = seqStore->sequencesStart;
|
2296
|
+
size_t seqsSize = seqStore->sequences - seqs;
|
2297
|
+
|
2298
|
+
ZSTD_Sequence* outSeqs = &zc->seqCollector.seqStart[zc->seqCollector.seqIndex];
|
2299
|
+
size_t i; size_t position; int repIdx;
|
2300
|
+
|
2301
|
+
assert(zc->seqCollector.seqIndex + 1 < zc->seqCollector.maxSequences);
|
2302
|
+
for (i = 0, position = 0; i < seqsSize; ++i) {
|
2303
|
+
outSeqs[i].offset = seqs[i].offset;
|
2304
|
+
outSeqs[i].litLength = seqs[i].litLength;
|
2305
|
+
outSeqs[i].matchLength = seqs[i].matchLength + MINMATCH;
|
2306
|
+
|
2307
|
+
if (i == seqStore->longLengthPos) {
|
2308
|
+
if (seqStore->longLengthID == 1) {
|
2309
|
+
outSeqs[i].litLength += 0x10000;
|
2310
|
+
} else if (seqStore->longLengthID == 2) {
|
2311
|
+
outSeqs[i].matchLength += 0x10000;
|
2312
|
+
}
|
2313
|
+
}
|
2314
|
+
|
2315
|
+
if (outSeqs[i].offset <= ZSTD_REP_NUM) {
|
2316
|
+
outSeqs[i].rep = outSeqs[i].offset;
|
2317
|
+
repIdx = (unsigned int)i - outSeqs[i].offset;
|
2318
|
+
|
2319
|
+
if (outSeqs[i].litLength == 0) {
|
2320
|
+
if (outSeqs[i].offset < 3) {
|
2321
|
+
--repIdx;
|
2322
|
+
} else {
|
2323
|
+
repIdx = (unsigned int)i - 1;
|
2324
|
+
}
|
2325
|
+
++outSeqs[i].rep;
|
2326
|
+
}
|
2327
|
+
assert(repIdx >= -3);
|
2328
|
+
outSeqs[i].offset = repIdx >= 0 ? outSeqs[repIdx].offset : repStartValue[-repIdx - 1];
|
2329
|
+
if (outSeqs[i].rep == 4) {
|
2330
|
+
--outSeqs[i].offset;
|
2331
|
+
}
|
2332
|
+
} else {
|
2333
|
+
outSeqs[i].offset -= ZSTD_REP_NUM;
|
2334
|
+
}
|
2335
|
+
|
2336
|
+
position += outSeqs[i].litLength;
|
2337
|
+
outSeqs[i].matchPos = (unsigned int)position;
|
2338
|
+
position += outSeqs[i].matchLength;
|
2339
|
+
}
|
2340
|
+
zc->seqCollector.seqIndex += seqsSize;
|
2341
|
+
}
|
2342
|
+
|
2343
|
+
size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
|
2344
|
+
size_t outSeqsSize, const void* src, size_t srcSize)
|
2345
|
+
{
|
2346
|
+
const size_t dstCapacity = ZSTD_compressBound(srcSize);
|
2347
|
+
void* dst = ZSTD_malloc(dstCapacity, ZSTD_defaultCMem);
|
2348
|
+
SeqCollector seqCollector;
|
2349
|
+
|
2350
|
+
RETURN_ERROR_IF(dst == NULL, memory_allocation);
|
2351
|
+
|
2352
|
+
seqCollector.collectSequences = 1;
|
2353
|
+
seqCollector.seqStart = outSeqs;
|
2354
|
+
seqCollector.seqIndex = 0;
|
2355
|
+
seqCollector.maxSequences = outSeqsSize;
|
2356
|
+
zc->seqCollector = seqCollector;
|
2357
|
+
|
2358
|
+
ZSTD_compress2(zc, dst, dstCapacity, src, srcSize);
|
2359
|
+
ZSTD_free(dst, ZSTD_defaultCMem);
|
2360
|
+
return zc->seqCollector.seqIndex;
|
2361
|
+
}
|
2362
|
+
|
2363
|
+
/* Returns true if the given block is a RLE block */
|
2364
|
+
static int ZSTD_isRLE(const BYTE *ip, size_t length) {
|
2365
|
+
size_t i;
|
2366
|
+
if (length < 2) return 1;
|
2367
|
+
for (i = 1; i < length; ++i) {
|
2368
|
+
if (ip[0] != ip[i]) return 0;
|
2369
|
+
}
|
2370
|
+
return 1;
|
2371
|
+
}
|
2372
|
+
|
2267
2373
|
static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
2268
2374
|
void* dst, size_t dstCapacity,
|
2269
|
-
const void* src, size_t srcSize)
|
2375
|
+
const void* src, size_t srcSize, U32 frame)
|
2270
2376
|
{
|
2377
|
+
/* This the upper bound for the length of an rle block.
|
2378
|
+
* This isn't the actual upper bound. Finding the real threshold
|
2379
|
+
* needs further investigation.
|
2380
|
+
*/
|
2381
|
+
const U32 rleMaxLength = 25;
|
2271
2382
|
size_t cSize;
|
2383
|
+
const BYTE* ip = (const BYTE*)src;
|
2384
|
+
BYTE* op = (BYTE*)dst;
|
2272
2385
|
DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
|
2273
|
-
(unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
|
2386
|
+
(unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
|
2387
|
+
(unsigned)zc->blockState.matchState.nextToUpdate);
|
2274
2388
|
|
2275
2389
|
{ const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
|
2276
2390
|
FORWARD_IF_ERROR(bss);
|
2277
2391
|
if (bss == ZSTDbss_noCompress) { cSize = 0; goto out; }
|
2278
2392
|
}
|
2279
2393
|
|
2394
|
+
if (zc->seqCollector.collectSequences) {
|
2395
|
+
ZSTD_copyBlockSequences(zc);
|
2396
|
+
return 0;
|
2397
|
+
}
|
2398
|
+
|
2280
2399
|
/* encode sequences and literals */
|
2281
2400
|
cSize = ZSTD_compressSequences(&zc->seqStore,
|
2282
2401
|
&zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
|
@@ -2286,8 +2405,21 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
|
2286
2405
|
zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */,
|
2287
2406
|
zc->bmi2);
|
2288
2407
|
|
2408
|
+
if (frame &&
|
2409
|
+
/* We don't want to emit our first block as a RLE even if it qualifies because
|
2410
|
+
* doing so will cause the decoder (cli only) to throw a "should consume all input error."
|
2411
|
+
* This is only an issue for zstd <= v1.4.3
|
2412
|
+
*/
|
2413
|
+
!zc->isFirstBlock &&
|
2414
|
+
cSize < rleMaxLength &&
|
2415
|
+
ZSTD_isRLE(ip, srcSize))
|
2416
|
+
{
|
2417
|
+
cSize = 1;
|
2418
|
+
op[0] = ip[0];
|
2419
|
+
}
|
2420
|
+
|
2289
2421
|
out:
|
2290
|
-
if (!ZSTD_isError(cSize) && cSize
|
2422
|
+
if (!ZSTD_isError(cSize) && cSize > 1) {
|
2291
2423
|
/* confirm repcodes and entropy tables when emitting a compressed block */
|
2292
2424
|
ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
|
2293
2425
|
zc->blockState.prevCBlock = zc->blockState.nextCBlock;
|
@@ -2304,7 +2436,11 @@ out:
|
|
2304
2436
|
}
|
2305
2437
|
|
2306
2438
|
|
2307
|
-
static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
|
2439
|
+
static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
|
2440
|
+
ZSTD_cwksp* ws,
|
2441
|
+
ZSTD_CCtx_params const* params,
|
2442
|
+
void const* ip,
|
2443
|
+
void const* iend)
|
2308
2444
|
{
|
2309
2445
|
if (ZSTD_window_needOverflowCorrection(ms->window, iend)) {
|
2310
2446
|
U32 const maxDist = (U32)1 << params->cParams.windowLog;
|
@@ -2313,7 +2449,9 @@ static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms, ZSTD_CCtx_params
|
|
2313
2449
|
ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
|
2314
2450
|
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
|
2315
2451
|
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
|
2452
|
+
ZSTD_cwksp_mark_tables_dirty(ws);
|
2316
2453
|
ZSTD_reduceIndex(ms, params, correction);
|
2454
|
+
ZSTD_cwksp_mark_tables_clean(ws);
|
2317
2455
|
if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
|
2318
2456
|
else ms->nextToUpdate -= correction;
|
2319
2457
|
/* invalidate dictionaries on overflow correction */
|
@@ -2322,7 +2460,6 @@ static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms, ZSTD_CCtx_params
|
|
2322
2460
|
}
|
2323
2461
|
}
|
2324
2462
|
|
2325
|
-
|
2326
2463
|
/*! ZSTD_compress_frameChunk() :
|
2327
2464
|
* Compress a chunk of data into one or multiple blocks.
|
2328
2465
|
* All blocks will be terminated, all input will be consumed.
|
@@ -2356,7 +2493,8 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
|
2356
2493
|
"not enough space to store compressed block");
|
2357
2494
|
if (remaining < blockSize) blockSize = remaining;
|
2358
2495
|
|
2359
|
-
ZSTD_overflowCorrectIfNeeded(
|
2496
|
+
ZSTD_overflowCorrectIfNeeded(
|
2497
|
+
ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize);
|
2360
2498
|
ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
|
2361
2499
|
|
2362
2500
|
/* Ensure hash/chain table insertion resumes no sooner than lowlimit */
|
@@ -2364,15 +2502,16 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
|
2364
2502
|
|
2365
2503
|
{ size_t cSize = ZSTD_compressBlock_internal(cctx,
|
2366
2504
|
op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
|
2367
|
-
ip, blockSize);
|
2505
|
+
ip, blockSize, 1 /* frame */);
|
2368
2506
|
FORWARD_IF_ERROR(cSize);
|
2369
|
-
|
2370
2507
|
if (cSize == 0) { /* block is not compressible */
|
2371
2508
|
cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
|
2372
2509
|
FORWARD_IF_ERROR(cSize);
|
2373
2510
|
} else {
|
2374
|
-
U32
|
2375
|
-
|
2511
|
+
const U32 cBlockHeader = cSize == 1 ?
|
2512
|
+
lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
|
2513
|
+
lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
|
2514
|
+
MEM_writeLE24(op, cBlockHeader);
|
2376
2515
|
cSize += ZSTD_blockHeaderSize;
|
2377
2516
|
}
|
2378
2517
|
|
@@ -2382,6 +2521,7 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
|
2382
2521
|
op += cSize;
|
2383
2522
|
assert(dstCapacity >= cSize);
|
2384
2523
|
dstCapacity -= cSize;
|
2524
|
+
cctx->isFirstBlock = 0;
|
2385
2525
|
DEBUGLOG(5, "ZSTD_compress_frameChunk: adding a block of size %u",
|
2386
2526
|
(unsigned)cSize);
|
2387
2527
|
} }
|
@@ -2392,25 +2532,25 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
|
2392
2532
|
|
2393
2533
|
|
2394
2534
|
static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
2395
|
-
ZSTD_CCtx_params params, U64 pledgedSrcSize, U32 dictID)
|
2535
|
+
const ZSTD_CCtx_params* params, U64 pledgedSrcSize, U32 dictID)
|
2396
2536
|
{ BYTE* const op = (BYTE*)dst;
|
2397
2537
|
U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
|
2398
|
-
U32 const dictIDSizeCode = params
|
2399
|
-
U32 const checksumFlag = params
|
2400
|
-
U32 const windowSize = (U32)1 << params
|
2401
|
-
U32 const singleSegment = params
|
2402
|
-
BYTE const windowLogByte = (BYTE)((params
|
2403
|
-
U32 const fcsCode = params
|
2538
|
+
U32 const dictIDSizeCode = params->fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */
|
2539
|
+
U32 const checksumFlag = params->fParams.checksumFlag>0;
|
2540
|
+
U32 const windowSize = (U32)1 << params->cParams.windowLog;
|
2541
|
+
U32 const singleSegment = params->fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
|
2542
|
+
BYTE const windowLogByte = (BYTE)((params->cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
|
2543
|
+
U32 const fcsCode = params->fParams.contentSizeFlag ?
|
2404
2544
|
(pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0; /* 0-3 */
|
2405
2545
|
BYTE const frameHeaderDescriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
|
2406
2546
|
size_t pos=0;
|
2407
2547
|
|
2408
|
-
assert(!(params
|
2548
|
+
assert(!(params->fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
|
2409
2549
|
RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall);
|
2410
2550
|
DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
|
2411
|
-
!params
|
2551
|
+
!params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);
|
2412
2552
|
|
2413
|
-
if (params
|
2553
|
+
if (params->format == ZSTD_f_zstd1) {
|
2414
2554
|
MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
|
2415
2555
|
pos = 4;
|
2416
2556
|
}
|
@@ -2476,7 +2616,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
2476
2616
|
"missing init (ZSTD_compressBegin)");
|
2477
2617
|
|
2478
2618
|
if (frame && (cctx->stage==ZSTDcs_init)) {
|
2479
|
-
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams,
|
2619
|
+
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams,
|
2480
2620
|
cctx->pledgedSrcSizePlusOne-1, cctx->dictID);
|
2481
2621
|
FORWARD_IF_ERROR(fhSize);
|
2482
2622
|
assert(fhSize <= dstCapacity);
|
@@ -2496,13 +2636,15 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
2496
2636
|
|
2497
2637
|
if (!frame) {
|
2498
2638
|
/* overflow check and correction for block mode */
|
2499
|
-
ZSTD_overflowCorrectIfNeeded(
|
2639
|
+
ZSTD_overflowCorrectIfNeeded(
|
2640
|
+
ms, &cctx->workspace, &cctx->appliedParams,
|
2641
|
+
src, (BYTE const*)src + srcSize);
|
2500
2642
|
}
|
2501
2643
|
|
2502
2644
|
DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSize);
|
2503
2645
|
{ size_t const cSize = frame ?
|
2504
2646
|
ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
|
2505
|
-
ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
|
2647
|
+
ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */);
|
2506
2648
|
FORWARD_IF_ERROR(cSize);
|
2507
2649
|
cctx->consumedSrcSize += srcSize;
|
2508
2650
|
cctx->producedCSize += (cSize + fhSize);
|
@@ -2538,8 +2680,9 @@ size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
|
|
2538
2680
|
|
2539
2681
|
size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
2540
2682
|
{
|
2541
|
-
|
2542
|
-
|
2683
|
+
DEBUGLOG(5, "ZSTD_compressBlock: srcSize = %u", (unsigned)srcSize);
|
2684
|
+
{ size_t const blockSizeMax = ZSTD_getBlockSize(cctx);
|
2685
|
+
RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong); }
|
2543
2686
|
|
2544
2687
|
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
|
2545
2688
|
}
|
@@ -2548,6 +2691,7 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
|
|
2548
2691
|
* @return : 0, or an error code
|
2549
2692
|
*/
|
2550
2693
|
static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
|
2694
|
+
ZSTD_cwksp* ws,
|
2551
2695
|
ZSTD_CCtx_params const* params,
|
2552
2696
|
const void* src, size_t srcSize,
|
2553
2697
|
ZSTD_dictTableLoadMethod_e dtlm)
|
@@ -2564,11 +2708,11 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
|
|
2564
2708
|
if (srcSize <= HASH_READ_SIZE) return 0;
|
2565
2709
|
|
2566
2710
|
while (iend - ip > HASH_READ_SIZE) {
|
2567
|
-
size_t const remaining = iend - ip;
|
2711
|
+
size_t const remaining = (size_t)(iend - ip);
|
2568
2712
|
size_t const chunk = MIN(remaining, ZSTD_CHUNKSIZE_MAX);
|
2569
2713
|
const BYTE* const ichunk = ip + chunk;
|
2570
2714
|
|
2571
|
-
ZSTD_overflowCorrectIfNeeded(ms, params, ip, ichunk);
|
2715
|
+
ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, ichunk);
|
2572
2716
|
|
2573
2717
|
switch(params->cParams.strategy)
|
2574
2718
|
{
|
@@ -2627,10 +2771,11 @@ static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSym
|
|
2627
2771
|
/*! ZSTD_loadZstdDictionary() :
|
2628
2772
|
* @return : dictID, or an error code
|
2629
2773
|
* assumptions : magic number supposed already checked
|
2630
|
-
* dictSize supposed
|
2774
|
+
* dictSize supposed >= 8
|
2631
2775
|
*/
|
2632
2776
|
static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
2633
2777
|
ZSTD_matchState_t* ms,
|
2778
|
+
ZSTD_cwksp* ws,
|
2634
2779
|
ZSTD_CCtx_params const* params,
|
2635
2780
|
const void* dict, size_t dictSize,
|
2636
2781
|
ZSTD_dictTableLoadMethod_e dtlm,
|
@@ -2643,7 +2788,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
|
2643
2788
|
size_t dictID;
|
2644
2789
|
|
2645
2790
|
ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
|
2646
|
-
assert(dictSize
|
2791
|
+
assert(dictSize >= 8);
|
2647
2792
|
assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
|
2648
2793
|
|
2649
2794
|
dictPtr += 4; /* skip magic number */
|
@@ -2726,7 +2871,8 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
|
2726
2871
|
bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
|
2727
2872
|
bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
|
2728
2873
|
bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
|
2729
|
-
FORWARD_IF_ERROR(ZSTD_loadDictionaryContent(
|
2874
|
+
FORWARD_IF_ERROR(ZSTD_loadDictionaryContent(
|
2875
|
+
ms, ws, params, dictPtr, dictContentSize, dtlm));
|
2730
2876
|
return dictID;
|
2731
2877
|
}
|
2732
2878
|
}
|
@@ -2736,6 +2882,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
|
2736
2882
|
static size_t
|
2737
2883
|
ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
|
2738
2884
|
ZSTD_matchState_t* ms,
|
2885
|
+
ZSTD_cwksp* ws,
|
2739
2886
|
const ZSTD_CCtx_params* params,
|
2740
2887
|
const void* dict, size_t dictSize,
|
2741
2888
|
ZSTD_dictContentType_e dictContentType,
|
@@ -2743,27 +2890,35 @@ ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
|
|
2743
2890
|
void* workspace)
|
2744
2891
|
{
|
2745
2892
|
DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
|
2746
|
-
if ((dict==NULL) || (dictSize
|
2893
|
+
if ((dict==NULL) || (dictSize<8)) {
|
2894
|
+
RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);
|
2895
|
+
return 0;
|
2896
|
+
}
|
2747
2897
|
|
2748
2898
|
ZSTD_reset_compressedBlockState(bs);
|
2749
2899
|
|
2750
2900
|
/* dict restricted modes */
|
2751
2901
|
if (dictContentType == ZSTD_dct_rawContent)
|
2752
|
-
return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
|
2902
|
+
return ZSTD_loadDictionaryContent(ms, ws, params, dict, dictSize, dtlm);
|
2753
2903
|
|
2754
2904
|
if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
|
2755
2905
|
if (dictContentType == ZSTD_dct_auto) {
|
2756
2906
|
DEBUGLOG(4, "raw content dictionary detected");
|
2757
|
-
return ZSTD_loadDictionaryContent(
|
2907
|
+
return ZSTD_loadDictionaryContent(
|
2908
|
+
ms, ws, params, dict, dictSize, dtlm);
|
2758
2909
|
}
|
2759
2910
|
RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);
|
2760
2911
|
assert(0); /* impossible */
|
2761
2912
|
}
|
2762
2913
|
|
2763
2914
|
/* dict as full zstd dictionary */
|
2764
|
-
return ZSTD_loadZstdDictionary(
|
2915
|
+
return ZSTD_loadZstdDictionary(
|
2916
|
+
bs, ms, ws, params, dict, dictSize, dtlm, workspace);
|
2765
2917
|
}
|
2766
2918
|
|
2919
|
+
#define ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF (128 KB)
|
2920
|
+
#define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6)
|
2921
|
+
|
2767
2922
|
/*! ZSTD_compressBegin_internal() :
|
2768
2923
|
* @return : 0, or an error code */
|
2769
2924
|
static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
@@ -2771,23 +2926,34 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
|
2771
2926
|
ZSTD_dictContentType_e dictContentType,
|
2772
2927
|
ZSTD_dictTableLoadMethod_e dtlm,
|
2773
2928
|
const ZSTD_CDict* cdict,
|
2774
|
-
ZSTD_CCtx_params params, U64 pledgedSrcSize,
|
2929
|
+
const ZSTD_CCtx_params* params, U64 pledgedSrcSize,
|
2775
2930
|
ZSTD_buffered_policy_e zbuff)
|
2776
2931
|
{
|
2777
|
-
DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params
|
2932
|
+
DEBUGLOG(4, "ZSTD_compressBegin_internal: wlog=%u", params->cParams.windowLog);
|
2778
2933
|
/* params are supposed to be fully validated at this point */
|
2779
|
-
assert(!ZSTD_isError(ZSTD_checkCParams(params
|
2934
|
+
assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
|
2780
2935
|
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
|
2781
|
-
|
2782
|
-
|
2936
|
+
if ( (cdict)
|
2937
|
+
&& (cdict->dictContentSize > 0)
|
2938
|
+
&& ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF
|
2939
|
+
|| pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER
|
2940
|
+
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
|
2941
|
+
|| cdict->compressionLevel == 0)
|
2942
|
+
&& (params->attachDictPref != ZSTD_dictForceLoad) ) {
|
2783
2943
|
return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff);
|
2784
2944
|
}
|
2785
2945
|
|
2786
|
-
FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
2787
|
-
|
2788
|
-
{ size_t const dictID =
|
2789
|
-
|
2790
|
-
|
2946
|
+
FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, *params, pledgedSrcSize,
|
2947
|
+
ZSTDcrp_makeClean, zbuff) );
|
2948
|
+
{ size_t const dictID = cdict ?
|
2949
|
+
ZSTD_compress_insertDictionary(
|
2950
|
+
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
|
2951
|
+
&cctx->workspace, params, cdict->dictContent, cdict->dictContentSize,
|
2952
|
+
dictContentType, dtlm, cctx->entropyWorkspace)
|
2953
|
+
: ZSTD_compress_insertDictionary(
|
2954
|
+
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
|
2955
|
+
&cctx->workspace, params, dict, dictSize,
|
2956
|
+
dictContentType, dtlm, cctx->entropyWorkspace);
|
2791
2957
|
FORWARD_IF_ERROR(dictID);
|
2792
2958
|
assert(dictID <= UINT_MAX);
|
2793
2959
|
cctx->dictID = (U32)dictID;
|
@@ -2800,12 +2966,12 @@ size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
|
|
2800
2966
|
ZSTD_dictContentType_e dictContentType,
|
2801
2967
|
ZSTD_dictTableLoadMethod_e dtlm,
|
2802
2968
|
const ZSTD_CDict* cdict,
|
2803
|
-
ZSTD_CCtx_params params,
|
2969
|
+
const ZSTD_CCtx_params* params,
|
2804
2970
|
unsigned long long pledgedSrcSize)
|
2805
2971
|
{
|
2806
|
-
DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params
|
2972
|
+
DEBUGLOG(4, "ZSTD_compressBegin_advanced_internal: wlog=%u", params->cParams.windowLog);
|
2807
2973
|
/* compression parameters verification and optimization */
|
2808
|
-
FORWARD_IF_ERROR( ZSTD_checkCParams(params
|
2974
|
+
FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) );
|
2809
2975
|
return ZSTD_compressBegin_internal(cctx,
|
2810
2976
|
dict, dictSize, dictContentType, dtlm,
|
2811
2977
|
cdict,
|
@@ -2820,21 +2986,21 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
|
|
2820
2986
|
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
2821
2987
|
{
|
2822
2988
|
ZSTD_CCtx_params const cctxParams =
|
2823
|
-
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
2989
|
+
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
|
2824
2990
|
return ZSTD_compressBegin_advanced_internal(cctx,
|
2825
2991
|
dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast,
|
2826
2992
|
NULL /*cdict*/,
|
2827
|
-
cctxParams, pledgedSrcSize);
|
2993
|
+
&cctxParams, pledgedSrcSize);
|
2828
2994
|
}
|
2829
2995
|
|
2830
2996
|
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
|
2831
2997
|
{
|
2832
2998
|
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
|
2833
2999
|
ZSTD_CCtx_params const cctxParams =
|
2834
|
-
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
3000
|
+
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
|
2835
3001
|
DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (unsigned)dictSize);
|
2836
3002
|
return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
|
2837
|
-
cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
|
3003
|
+
&cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
|
2838
3004
|
}
|
2839
3005
|
|
2840
3006
|
size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
|
@@ -2857,7 +3023,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
|
|
2857
3023
|
|
2858
3024
|
/* special case : empty frame */
|
2859
3025
|
if (cctx->stage == ZSTDcs_init) {
|
2860
|
-
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->appliedParams, 0, 0);
|
3026
|
+
fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0);
|
2861
3027
|
FORWARD_IF_ERROR(fhSize);
|
2862
3028
|
dstCapacity -= fhSize;
|
2863
3029
|
op += fhSize;
|
@@ -2918,13 +3084,13 @@ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
|
|
2918
3084
|
ZSTD_parameters params)
|
2919
3085
|
{
|
2920
3086
|
ZSTD_CCtx_params const cctxParams =
|
2921
|
-
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
3087
|
+
ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
|
2922
3088
|
DEBUGLOG(4, "ZSTD_compress_internal");
|
2923
3089
|
return ZSTD_compress_advanced_internal(cctx,
|
2924
3090
|
dst, dstCapacity,
|
2925
3091
|
src, srcSize,
|
2926
3092
|
dict, dictSize,
|
2927
|
-
cctxParams);
|
3093
|
+
&cctxParams);
|
2928
3094
|
}
|
2929
3095
|
|
2930
3096
|
size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
|
@@ -2948,7 +3114,7 @@ size_t ZSTD_compress_advanced_internal(
|
|
2948
3114
|
void* dst, size_t dstCapacity,
|
2949
3115
|
const void* src, size_t srcSize,
|
2950
3116
|
const void* dict,size_t dictSize,
|
2951
|
-
ZSTD_CCtx_params params)
|
3117
|
+
const ZSTD_CCtx_params* params)
|
2952
3118
|
{
|
2953
3119
|
DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (unsigned)srcSize);
|
2954
3120
|
FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
|
@@ -2964,9 +3130,9 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
|
|
2964
3130
|
int compressionLevel)
|
2965
3131
|
{
|
2966
3132
|
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize + (!srcSize), dict ? dictSize : 0);
|
2967
|
-
ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
3133
|
+
ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);
|
2968
3134
|
assert(params.fParams.contentSizeFlag == 1);
|
2969
|
-
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, cctxParams);
|
3135
|
+
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctxParams);
|
2970
3136
|
}
|
2971
3137
|
|
2972
3138
|
size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
|
@@ -3001,8 +3167,11 @@ size_t ZSTD_estimateCDictSize_advanced(
|
|
3001
3167
|
ZSTD_dictLoadMethod_e dictLoadMethod)
|
3002
3168
|
{
|
3003
3169
|
DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (unsigned)sizeof(ZSTD_CDict));
|
3004
|
-
return sizeof(ZSTD_CDict)
|
3005
|
-
|
3170
|
+
return ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))
|
3171
|
+
+ ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE)
|
3172
|
+
+ ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0)
|
3173
|
+
+ (dictLoadMethod == ZSTD_dlm_byRef ? 0
|
3174
|
+
: ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void *))));
|
3006
3175
|
}
|
3007
3176
|
|
3008
3177
|
size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)
|
@@ -3015,7 +3184,9 @@ size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
|
|
3015
3184
|
{
|
3016
3185
|
if (cdict==NULL) return 0; /* support sizeof on NULL */
|
3017
3186
|
DEBUGLOG(5, "sizeof(*cdict) : %u", (unsigned)sizeof(*cdict));
|
3018
|
-
|
3187
|
+
/* cdict may be in the workspace */
|
3188
|
+
return (cdict->workspace.workspace == cdict ? 0 : sizeof(*cdict))
|
3189
|
+
+ ZSTD_cwksp_sizeof(&cdict->workspace);
|
3019
3190
|
}
|
3020
3191
|
|
3021
3192
|
static size_t ZSTD_initCDict_internal(
|
@@ -3029,28 +3200,29 @@ static size_t ZSTD_initCDict_internal(
|
|
3029
3200
|
assert(!ZSTD_checkCParams(cParams));
|
3030
3201
|
cdict->matchState.cParams = cParams;
|
3031
3202
|
if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
|
3032
|
-
cdict->dictBuffer = NULL;
|
3033
3203
|
cdict->dictContent = dictBuffer;
|
3034
3204
|
} else {
|
3035
|
-
|
3036
|
-
cdict->dictBuffer = internalBuffer;
|
3037
|
-
cdict->dictContent = internalBuffer;
|
3205
|
+
void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*)));
|
3038
3206
|
RETURN_ERROR_IF(!internalBuffer, memory_allocation);
|
3207
|
+
cdict->dictContent = internalBuffer;
|
3039
3208
|
memcpy(internalBuffer, dictBuffer, dictSize);
|
3040
3209
|
}
|
3041
3210
|
cdict->dictContentSize = dictSize;
|
3042
3211
|
|
3212
|
+
cdict->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cdict->workspace, HUF_WORKSPACE_SIZE);
|
3213
|
+
|
3214
|
+
|
3043
3215
|
/* Reset the state to no dictionary */
|
3044
3216
|
ZSTD_reset_compressedBlockState(&cdict->cBlockState);
|
3045
|
-
|
3046
|
-
|
3047
|
-
|
3048
|
-
|
3049
|
-
|
3050
|
-
|
3051
|
-
|
3217
|
+
FORWARD_IF_ERROR(ZSTD_reset_matchState(
|
3218
|
+
&cdict->matchState,
|
3219
|
+
&cdict->workspace,
|
3220
|
+
&cParams,
|
3221
|
+
ZSTDcrp_makeClean,
|
3222
|
+
ZSTDirp_reset,
|
3223
|
+
ZSTD_resetTarget_CDict));
|
3052
3224
|
/* (Maybe) load the dictionary
|
3053
|
-
* Skips loading the dictionary if it is
|
3225
|
+
* Skips loading the dictionary if it is < 8 bytes.
|
3054
3226
|
*/
|
3055
3227
|
{ ZSTD_CCtx_params params;
|
3056
3228
|
memset(¶ms, 0, sizeof(params));
|
@@ -3058,9 +3230,9 @@ static size_t ZSTD_initCDict_internal(
|
|
3058
3230
|
params.fParams.contentSizeFlag = 1;
|
3059
3231
|
params.cParams = cParams;
|
3060
3232
|
{ size_t const dictID = ZSTD_compress_insertDictionary(
|
3061
|
-
&cdict->cBlockState, &cdict->matchState, &
|
3062
|
-
cdict->dictContent, cdict->dictContentSize,
|
3063
|
-
dictContentType, ZSTD_dtlm_full, cdict->
|
3233
|
+
&cdict->cBlockState, &cdict->matchState, &cdict->workspace,
|
3234
|
+
¶ms, cdict->dictContent, cdict->dictContentSize,
|
3235
|
+
dictContentType, ZSTD_dtlm_full, cdict->entropyWorkspace);
|
3064
3236
|
FORWARD_IF_ERROR(dictID);
|
3065
3237
|
assert(dictID <= (size_t)(U32)-1);
|
3066
3238
|
cdict->dictID = (U32)dictID;
|
@@ -3078,18 +3250,29 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
|
|
3078
3250
|
DEBUGLOG(3, "ZSTD_createCDict_advanced, mode %u", (unsigned)dictContentType);
|
3079
3251
|
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
|
3080
3252
|
|
3081
|
-
{
|
3082
|
-
|
3253
|
+
{ size_t const workspaceSize =
|
3254
|
+
ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) +
|
3255
|
+
ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) +
|
3256
|
+
ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0) +
|
3257
|
+
(dictLoadMethod == ZSTD_dlm_byRef ? 0
|
3258
|
+
: ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*))));
|
3083
3259
|
void* const workspace = ZSTD_malloc(workspaceSize, customMem);
|
3260
|
+
ZSTD_cwksp ws;
|
3261
|
+
ZSTD_CDict* cdict;
|
3084
3262
|
|
3085
|
-
if (!
|
3086
|
-
ZSTD_free(cdict, customMem);
|
3263
|
+
if (!workspace) {
|
3087
3264
|
ZSTD_free(workspace, customMem);
|
3088
3265
|
return NULL;
|
3089
3266
|
}
|
3267
|
+
|
3268
|
+
ZSTD_cwksp_init(&ws, workspace, workspaceSize);
|
3269
|
+
|
3270
|
+
cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));
|
3271
|
+
assert(cdict != NULL);
|
3272
|
+
ZSTD_cwksp_move(&cdict->workspace, &ws);
|
3090
3273
|
cdict->customMem = customMem;
|
3091
|
-
cdict->
|
3092
|
-
|
3274
|
+
cdict->compressionLevel = 0; /* signals advanced API usage */
|
3275
|
+
|
3093
3276
|
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
|
3094
3277
|
dictBuffer, dictSize,
|
3095
3278
|
dictLoadMethod, dictContentType,
|
@@ -3105,9 +3288,12 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
|
|
3105
3288
|
ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
|
3106
3289
|
{
|
3107
3290
|
ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
|
3108
|
-
|
3109
|
-
|
3110
|
-
|
3291
|
+
ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dict, dictSize,
|
3292
|
+
ZSTD_dlm_byCopy, ZSTD_dct_auto,
|
3293
|
+
cParams, ZSTD_defaultCMem);
|
3294
|
+
if (cdict)
|
3295
|
+
cdict->compressionLevel = compressionLevel == 0 ? ZSTD_CLEVEL_DEFAULT : compressionLevel;
|
3296
|
+
return cdict;
|
3111
3297
|
}
|
3112
3298
|
|
3113
3299
|
ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)
|
@@ -3122,9 +3308,11 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
|
3122
3308
|
{
|
3123
3309
|
if (cdict==NULL) return 0; /* support free on NULL */
|
3124
3310
|
{ ZSTD_customMem const cMem = cdict->customMem;
|
3125
|
-
|
3126
|
-
|
3127
|
-
|
3311
|
+
int cdictInWorkspace = ZSTD_cwksp_owns_buffer(&cdict->workspace, cdict);
|
3312
|
+
ZSTD_cwksp_free(&cdict->workspace, cMem);
|
3313
|
+
if (!cdictInWorkspace) {
|
3314
|
+
ZSTD_free(cdict, cMem);
|
3315
|
+
}
|
3128
3316
|
return 0;
|
3129
3317
|
}
|
3130
3318
|
}
|
@@ -3150,28 +3338,30 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
|
|
3150
3338
|
ZSTD_compressionParameters cParams)
|
3151
3339
|
{
|
3152
3340
|
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0);
|
3153
|
-
size_t const neededSize = sizeof(ZSTD_CDict)
|
3154
|
-
+
|
3155
|
-
|
3156
|
-
|
3341
|
+
size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))
|
3342
|
+
+ (dictLoadMethod == ZSTD_dlm_byRef ? 0
|
3343
|
+
: ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*))))
|
3344
|
+
+ ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE)
|
3345
|
+
+ matchStateSize;
|
3346
|
+
ZSTD_CDict* cdict;
|
3347
|
+
|
3157
3348
|
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
|
3349
|
+
|
3350
|
+
{
|
3351
|
+
ZSTD_cwksp ws;
|
3352
|
+
ZSTD_cwksp_init(&ws, workspace, workspaceSize);
|
3353
|
+
cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));
|
3354
|
+
if (cdict == NULL) return NULL;
|
3355
|
+
ZSTD_cwksp_move(&cdict->workspace, &ws);
|
3356
|
+
}
|
3357
|
+
|
3158
3358
|
DEBUGLOG(4, "(workspaceSize < neededSize) : (%u < %u) => %u",
|
3159
3359
|
(unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize));
|
3160
3360
|
if (workspaceSize < neededSize) return NULL;
|
3161
3361
|
|
3162
|
-
if (dictLoadMethod == ZSTD_dlm_byCopy) {
|
3163
|
-
memcpy(cdict+1, dict, dictSize);
|
3164
|
-
dict = cdict+1;
|
3165
|
-
ptr = (char*)workspace + sizeof(ZSTD_CDict) + dictSize;
|
3166
|
-
} else {
|
3167
|
-
ptr = cdict+1;
|
3168
|
-
}
|
3169
|
-
cdict->workspace = ptr;
|
3170
|
-
cdict->workspaceSize = HUF_WORKSPACE_SIZE + matchStateSize;
|
3171
|
-
|
3172
3362
|
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
|
3173
3363
|
dict, dictSize,
|
3174
|
-
|
3364
|
+
dictLoadMethod, dictContentType,
|
3175
3365
|
cParams) ))
|
3176
3366
|
return NULL;
|
3177
3367
|
|
@@ -3193,7 +3383,15 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
|
|
3193
3383
|
DEBUGLOG(4, "ZSTD_compressBegin_usingCDict_advanced");
|
3194
3384
|
RETURN_ERROR_IF(cdict==NULL, dictionary_wrong);
|
3195
3385
|
{ ZSTD_CCtx_params params = cctx->requestedParams;
|
3196
|
-
params.cParams =
|
3386
|
+
params.cParams = ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF
|
3387
|
+
|| pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER
|
3388
|
+
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
|
3389
|
+
|| cdict->compressionLevel == 0 )
|
3390
|
+
&& (params.attachDictPref != ZSTD_dictForceLoad) ?
|
3391
|
+
ZSTD_getCParamsFromCDict(cdict)
|
3392
|
+
: ZSTD_getCParams(cdict->compressionLevel,
|
3393
|
+
pledgedSrcSize,
|
3394
|
+
cdict->dictContentSize);
|
3197
3395
|
/* Increase window log to fit the entire dictionary and source if the
|
3198
3396
|
* source size is known. Limit the increase to 19, which is the
|
3199
3397
|
* window log for compression level 1 with the largest source size.
|
@@ -3207,7 +3405,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
|
|
3207
3405
|
return ZSTD_compressBegin_internal(cctx,
|
3208
3406
|
NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast,
|
3209
3407
|
cdict,
|
3210
|
-
params, pledgedSrcSize,
|
3408
|
+
¶ms, pledgedSrcSize,
|
3211
3409
|
ZSTDb_not_buffered);
|
3212
3410
|
}
|
3213
3411
|
}
|
@@ -3298,7 +3496,7 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,
|
|
3298
3496
|
FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,
|
3299
3497
|
dict, dictSize, dictContentType, ZSTD_dtlm_fast,
|
3300
3498
|
cdict,
|
3301
|
-
params, pledgedSrcSize,
|
3499
|
+
¶ms, pledgedSrcSize,
|
3302
3500
|
ZSTDb_buffered) );
|
3303
3501
|
|
3304
3502
|
cctx->inToCompress = 0;
|
@@ -3332,13 +3530,14 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pss)
|
|
3332
3530
|
* Assumption 2 : either dict, or cdict, is defined, not both */
|
3333
3531
|
size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
|
3334
3532
|
const void* dict, size_t dictSize, const ZSTD_CDict* cdict,
|
3335
|
-
ZSTD_CCtx_params params,
|
3533
|
+
const ZSTD_CCtx_params* params,
|
3534
|
+
unsigned long long pledgedSrcSize)
|
3336
3535
|
{
|
3337
3536
|
DEBUGLOG(4, "ZSTD_initCStream_internal");
|
3338
3537
|
FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
|
3339
3538
|
FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
|
3340
|
-
assert(!ZSTD_isError(ZSTD_checkCParams(params
|
3341
|
-
zcs->requestedParams = params;
|
3539
|
+
assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
|
3540
|
+
zcs->requestedParams = *params;
|
3342
3541
|
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
|
3343
3542
|
if (dict) {
|
3344
3543
|
FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
|
@@ -3377,7 +3576,7 @@ size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
|
|
3377
3576
|
/* ZSTD_initCStream_advanced() :
|
3378
3577
|
* pledgedSrcSize must be exact.
|
3379
3578
|
* if srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.
|
3380
|
-
* dict is loaded with default parameters
|
3579
|
+
* dict is loaded with default parameters ZSTD_dct_auto and ZSTD_dlm_byCopy. */
|
3381
3580
|
size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
3382
3581
|
const void* dict, size_t dictSize,
|
3383
3582
|
ZSTD_parameters params, unsigned long long pss)
|
@@ -3391,7 +3590,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
|
3391
3590
|
FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );
|
3392
3591
|
FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );
|
3393
3592
|
FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );
|
3394
|
-
zcs->requestedParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
|
3593
|
+
zcs->requestedParams = ZSTD_assignParamsToCCtxParams(&zcs->requestedParams, params);
|
3395
3594
|
FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );
|
3396
3595
|
return 0;
|
3397
3596
|
}
|
@@ -3641,7 +3840,7 @@ size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
|
|
3641
3840
|
if (cctx->mtctx == NULL) {
|
3642
3841
|
DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
|
3643
3842
|
params.nbWorkers);
|
3644
|
-
cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem);
|
3843
|
+
cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem);
|
3645
3844
|
RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation);
|
3646
3845
|
}
|
3647
3846
|
/* mt compression */
|
@@ -3769,8 +3968,8 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
3769
3968
|
{ 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */
|
3770
3969
|
{ 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */
|
3771
3970
|
{ 20, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */
|
3772
|
-
{ 21, 16, 17, 1, 5,
|
3773
|
-
{ 21, 18, 18, 1, 5,
|
3971
|
+
{ 21, 16, 17, 1, 5, 0, ZSTD_dfast }, /* level 3 */
|
3972
|
+
{ 21, 18, 18, 1, 5, 0, ZSTD_dfast }, /* level 4 */
|
3774
3973
|
{ 21, 18, 19, 2, 5, 2, ZSTD_greedy }, /* level 5 */
|
3775
3974
|
{ 21, 19, 19, 3, 5, 4, ZSTD_greedy }, /* level 6 */
|
3776
3975
|
{ 21, 19, 19, 3, 5, 8, ZSTD_lazy }, /* level 7 */
|
@@ -3794,8 +3993,8 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
3794
3993
|
/* W, C, H, S, L, T, strat */
|
3795
3994
|
{ 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
|
3796
3995
|
{ 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */
|
3797
|
-
{ 18, 14, 14, 1, 5,
|
3798
|
-
{ 18, 16, 16, 1, 4,
|
3996
|
+
{ 18, 14, 14, 1, 5, 0, ZSTD_dfast }, /* level 2 */
|
3997
|
+
{ 18, 16, 16, 1, 4, 0, ZSTD_dfast }, /* level 3 */
|
3799
3998
|
{ 18, 16, 17, 2, 5, 2, ZSTD_greedy }, /* level 4.*/
|
3800
3999
|
{ 18, 18, 18, 3, 5, 2, ZSTD_greedy }, /* level 5.*/
|
3801
4000
|
{ 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/
|
@@ -3821,8 +4020,8 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
3821
4020
|
{ 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
|
3822
4021
|
{ 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */
|
3823
4022
|
{ 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */
|
3824
|
-
{ 17, 15, 16, 2, 5,
|
3825
|
-
{ 17, 17, 17, 2, 4,
|
4023
|
+
{ 17, 15, 16, 2, 5, 0, ZSTD_dfast }, /* level 3 */
|
4024
|
+
{ 17, 17, 17, 2, 4, 0, ZSTD_dfast }, /* level 4 */
|
3826
4025
|
{ 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */
|
3827
4026
|
{ 17, 17, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */
|
3828
4027
|
{ 17, 17, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */
|
@@ -3847,7 +4046,7 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
3847
4046
|
{ 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
|
3848
4047
|
{ 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */
|
3849
4048
|
{ 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */
|
3850
|
-
{ 14, 14, 15, 2, 4,
|
4049
|
+
{ 14, 14, 15, 2, 4, 0, ZSTD_dfast }, /* level 3 */
|
3851
4050
|
{ 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4 */
|
3852
4051
|
{ 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/
|
3853
4052
|
{ 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */
|