zstd-ruby 1.3.3.0 → 1.3.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 +5 -5
- data/README.md +1 -1
- data/ext/zstdruby/libzstd/BUCK +13 -0
- data/ext/zstdruby/libzstd/README.md +32 -25
- data/ext/zstdruby/libzstd/common/bitstream.h +1 -1
- data/ext/zstdruby/libzstd/common/compiler.h +25 -0
- data/ext/zstdruby/libzstd/common/cpu.h +216 -0
- data/ext/zstdruby/libzstd/common/error_private.c +1 -0
- data/ext/zstdruby/libzstd/common/fse.h +1 -1
- data/ext/zstdruby/libzstd/common/fse_decompress.c +2 -2
- data/ext/zstdruby/libzstd/common/huf.h +114 -89
- data/ext/zstdruby/libzstd/common/pool.c +46 -17
- data/ext/zstdruby/libzstd/common/pool.h +18 -9
- data/ext/zstdruby/libzstd/common/threading.h +12 -12
- data/ext/zstdruby/libzstd/common/zstd_errors.h +16 -7
- data/ext/zstdruby/libzstd/common/zstd_internal.h +4 -5
- data/ext/zstdruby/libzstd/compress/fse_compress.c +19 -11
- data/ext/zstdruby/libzstd/compress/huf_compress.c +160 -62
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +973 -644
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +281 -34
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +80 -62
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +11 -4
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +87 -71
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +10 -6
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +333 -274
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +33 -16
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +305 -359
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +64 -21
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +194 -56
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +17 -5
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +1131 -449
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +32 -16
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +390 -290
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +777 -439
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +11 -8
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +83 -50
- data/ext/zstdruby/libzstd/dictBuilder/zdict.h +44 -43
- data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +2 -0
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +42 -118
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +2 -2
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +2 -2
- data/ext/zstdruby/libzstd/zstd.h +254 -254
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +4 -3
@@ -21,6 +21,7 @@
|
|
21
21
|
* Dependencies
|
22
22
|
***************************************/
|
23
23
|
#include <string.h> /* memset */
|
24
|
+
#include "cpu.h"
|
24
25
|
#include "mem.h"
|
25
26
|
#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
|
26
27
|
#include "fse.h"
|
@@ -49,7 +50,13 @@ struct ZSTD_CDict_s {
|
|
49
50
|
void* dictBuffer;
|
50
51
|
const void* dictContent;
|
51
52
|
size_t dictContentSize;
|
52
|
-
|
53
|
+
void* workspace;
|
54
|
+
size_t workspaceSize;
|
55
|
+
ZSTD_matchState_t matchState;
|
56
|
+
ZSTD_compressedBlockState_t cBlockState;
|
57
|
+
ZSTD_compressionParameters cParams;
|
58
|
+
ZSTD_customMem customMem;
|
59
|
+
U32 dictID;
|
53
60
|
}; /* typedef'd to ZSTD_CDict within "zstd.h" */
|
54
61
|
|
55
62
|
ZSTD_CCtx* ZSTD_createCCtx(void)
|
@@ -59,18 +66,17 @@ ZSTD_CCtx* ZSTD_createCCtx(void)
|
|
59
66
|
|
60
67
|
ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
|
61
68
|
{
|
62
|
-
ZSTD_CCtx* cctx;
|
63
|
-
|
64
|
-
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
|
65
|
-
|
66
|
-
cctx = (ZSTD_CCtx*) ZSTD_calloc(sizeof(ZSTD_CCtx), customMem);
|
67
|
-
if (!cctx) return NULL;
|
68
|
-
cctx->customMem = customMem;
|
69
|
-
cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_DEFAULT;
|
70
|
-
cctx->requestedParams.fParams.contentSizeFlag = 1;
|
71
69
|
ZSTD_STATIC_ASSERT(zcss_init==0);
|
72
70
|
ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1));
|
73
|
-
return
|
71
|
+
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
|
72
|
+
{ ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_calloc(sizeof(ZSTD_CCtx), customMem);
|
73
|
+
if (!cctx) return NULL;
|
74
|
+
cctx->customMem = customMem;
|
75
|
+
cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_DEFAULT;
|
76
|
+
cctx->requestedParams.fParams.contentSizeFlag = 1;
|
77
|
+
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
|
78
|
+
return cctx;
|
79
|
+
}
|
74
80
|
}
|
75
81
|
|
76
82
|
ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
|
@@ -83,11 +89,16 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
|
|
83
89
|
cctx->workSpace = (void*)(cctx+1);
|
84
90
|
cctx->workSpaceSize = workspaceSize - sizeof(ZSTD_CCtx);
|
85
91
|
|
86
|
-
/*
|
87
|
-
if (cctx->workSpaceSize < sizeof(
|
92
|
+
/* statically sized space. entropyWorkspace never moves (but prev/next block swap places) */
|
93
|
+
if (cctx->workSpaceSize < HUF_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t)) return NULL;
|
88
94
|
assert(((size_t)cctx->workSpace & (sizeof(void*)-1)) == 0); /* ensure correct alignment */
|
89
|
-
cctx->
|
90
|
-
|
95
|
+
cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)cctx->workSpace;
|
96
|
+
cctx->blockState.nextCBlock = cctx->blockState.prevCBlock + 1;
|
97
|
+
{
|
98
|
+
void* const ptr = cctx->blockState.nextCBlock + 1;
|
99
|
+
cctx->entropyWorkspace = (U32*)ptr;
|
100
|
+
}
|
101
|
+
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
|
91
102
|
return cctx;
|
92
103
|
}
|
93
104
|
|
@@ -95,13 +106,10 @@ size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
|
|
95
106
|
{
|
96
107
|
if (cctx==NULL) return 0; /* support free on NULL */
|
97
108
|
if (cctx->staticSize) return ERROR(memory_allocation); /* not compatible with static CCtx */
|
98
|
-
ZSTD_free(cctx->workSpace, cctx->customMem);
|
99
|
-
cctx->
|
100
|
-
ZSTD_freeCDict(cctx->cdictLocal);
|
101
|
-
cctx->cdictLocal = NULL;
|
109
|
+
ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL;
|
110
|
+
ZSTD_freeCDict(cctx->cdictLocal); cctx->cdictLocal = NULL;
|
102
111
|
#ifdef ZSTD_MULTITHREAD
|
103
|
-
ZSTDMT_freeCCtx(cctx->mtctx);
|
104
|
-
cctx->mtctx = NULL;
|
112
|
+
ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;
|
105
113
|
#endif
|
106
114
|
ZSTD_free(cctx, cctx->customMem);
|
107
115
|
return 0; /* reserved as a potential error code in the future */
|
@@ -122,10 +130,6 @@ static size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx)
|
|
122
130
|
size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
|
123
131
|
{
|
124
132
|
if (cctx==NULL) return 0; /* support sizeof on NULL */
|
125
|
-
DEBUGLOG(3, "sizeof(*cctx) : %u", (U32)sizeof(*cctx));
|
126
|
-
DEBUGLOG(3, "workSpaceSize (including streaming buffers): %u", (U32)cctx->workSpaceSize);
|
127
|
-
DEBUGLOG(3, "inner cdict : %u", (U32)ZSTD_sizeof_CDict(cctx->cdictLocal));
|
128
|
-
DEBUGLOG(3, "inner MTCTX : %u", (U32)ZSTD_sizeof_mtctx(cctx));
|
129
133
|
return sizeof(*cctx) + cctx->workSpaceSize
|
130
134
|
+ ZSTD_sizeof_CDict(cctx->cdictLocal)
|
131
135
|
+ ZSTD_sizeof_mtctx(cctx);
|
@@ -139,37 +143,19 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
|
|
139
143
|
/* private API call, for dictBuilder only */
|
140
144
|
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
|
141
145
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
{
|
156
|
-
DEBUGLOG(4, "ZSTD_cLevelToCCtxParams_srcSize: srcSize = %u",
|
157
|
-
(U32)srcSize);
|
158
|
-
CCtxParams->cParams = ZSTD_getCParamsFromCCtxParams(*CCtxParams, srcSize, 0);
|
159
|
-
CCtxParams->compressionLevel = ZSTD_CLEVEL_CUSTOM;
|
160
|
-
}
|
161
|
-
|
162
|
-
static void ZSTD_cLevelToCParams(ZSTD_CCtx* cctx)
|
163
|
-
{
|
164
|
-
DEBUGLOG(4, "ZSTD_cLevelToCParams: level=%i", cctx->requestedParams.compressionLevel);
|
165
|
-
ZSTD_cLevelToCCtxParams_srcSize(
|
166
|
-
&cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1);
|
167
|
-
}
|
168
|
-
|
169
|
-
static void ZSTD_cLevelToCCtxParams(ZSTD_CCtx_params* CCtxParams)
|
170
|
-
{
|
171
|
-
DEBUGLOG(4, "ZSTD_cLevelToCCtxParams");
|
172
|
-
ZSTD_cLevelToCCtxParams_srcSize(CCtxParams, ZSTD_CONTENTSIZE_UNKNOWN);
|
146
|
+
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
|
147
|
+
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
|
148
|
+
{
|
149
|
+
ZSTD_compressionParameters cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);
|
150
|
+
if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
|
151
|
+
if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
|
152
|
+
if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
|
153
|
+
if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
|
154
|
+
if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
|
155
|
+
if (CCtxParams->cParams.searchLength) cParams.searchLength = CCtxParams->cParams.searchLength;
|
156
|
+
if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
|
157
|
+
if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
|
158
|
+
return cParams;
|
173
159
|
}
|
174
160
|
|
175
161
|
static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
|
@@ -178,7 +164,9 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
|
|
178
164
|
ZSTD_CCtx_params cctxParams;
|
179
165
|
memset(&cctxParams, 0, sizeof(cctxParams));
|
180
166
|
cctxParams.cParams = cParams;
|
181
|
-
cctxParams.compressionLevel =
|
167
|
+
cctxParams.compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
|
168
|
+
assert(!ZSTD_checkCParams(cParams));
|
169
|
+
cctxParams.fParams.contentSizeFlag = 1;
|
182
170
|
return cctxParams;
|
183
171
|
}
|
184
172
|
|
@@ -192,6 +180,7 @@ static ZSTD_CCtx_params* ZSTD_createCCtxParams_advanced(
|
|
192
180
|
if (!params) { return NULL; }
|
193
181
|
params->customMem = customMem;
|
194
182
|
params->compressionLevel = ZSTD_CLEVEL_DEFAULT;
|
183
|
+
params->fParams.contentSizeFlag = 1;
|
195
184
|
return params;
|
196
185
|
}
|
197
186
|
|
@@ -207,36 +196,41 @@ size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)
|
|
207
196
|
return 0;
|
208
197
|
}
|
209
198
|
|
210
|
-
size_t
|
199
|
+
size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params)
|
211
200
|
{
|
212
|
-
return
|
201
|
+
return ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT);
|
213
202
|
}
|
214
203
|
|
215
|
-
size_t
|
204
|
+
size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) {
|
216
205
|
if (!cctxParams) { return ERROR(GENERIC); }
|
217
206
|
memset(cctxParams, 0, sizeof(*cctxParams));
|
218
207
|
cctxParams->compressionLevel = compressionLevel;
|
208
|
+
cctxParams->fParams.contentSizeFlag = 1;
|
219
209
|
return 0;
|
220
210
|
}
|
221
211
|
|
222
|
-
size_t
|
212
|
+
size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
|
223
213
|
{
|
224
214
|
if (!cctxParams) { return ERROR(GENERIC); }
|
225
215
|
CHECK_F( ZSTD_checkCParams(params.cParams) );
|
226
216
|
memset(cctxParams, 0, sizeof(*cctxParams));
|
227
217
|
cctxParams->cParams = params.cParams;
|
228
218
|
cctxParams->fParams = params.fParams;
|
229
|
-
cctxParams->compressionLevel =
|
219
|
+
cctxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
|
220
|
+
assert(!ZSTD_checkCParams(params.cParams));
|
230
221
|
return 0;
|
231
222
|
}
|
232
223
|
|
224
|
+
/* ZSTD_assignParamsToCCtxParams() :
|
225
|
+
* params is presumed valid at this stage */
|
233
226
|
static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
|
234
227
|
ZSTD_CCtx_params cctxParams, ZSTD_parameters params)
|
235
228
|
{
|
236
229
|
ZSTD_CCtx_params ret = cctxParams;
|
237
230
|
ret.cParams = params.cParams;
|
238
231
|
ret.fParams = params.fParams;
|
239
|
-
ret.compressionLevel =
|
232
|
+
ret.compressionLevel = ZSTD_CLEVEL_DEFAULT; /* should not matter, as all cParams are presumed properly defined */
|
233
|
+
assert(!ZSTD_checkCParams(params.cParams));
|
240
234
|
return ret;
|
241
235
|
}
|
242
236
|
|
@@ -245,10 +239,49 @@ static ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(
|
|
245
239
|
return ERROR(parameter_outOfBound); \
|
246
240
|
} }
|
247
241
|
|
242
|
+
|
243
|
+
static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
|
244
|
+
{
|
245
|
+
switch(param)
|
246
|
+
{
|
247
|
+
case ZSTD_p_compressionLevel:
|
248
|
+
case ZSTD_p_hashLog:
|
249
|
+
case ZSTD_p_chainLog:
|
250
|
+
case ZSTD_p_searchLog:
|
251
|
+
case ZSTD_p_minMatch:
|
252
|
+
case ZSTD_p_targetLength:
|
253
|
+
case ZSTD_p_compressionStrategy:
|
254
|
+
case ZSTD_p_compressLiterals:
|
255
|
+
return 1;
|
256
|
+
|
257
|
+
case ZSTD_p_format:
|
258
|
+
case ZSTD_p_windowLog:
|
259
|
+
case ZSTD_p_contentSizeFlag:
|
260
|
+
case ZSTD_p_checksumFlag:
|
261
|
+
case ZSTD_p_dictIDFlag:
|
262
|
+
case ZSTD_p_forceMaxWindow :
|
263
|
+
case ZSTD_p_nbWorkers:
|
264
|
+
case ZSTD_p_jobSize:
|
265
|
+
case ZSTD_p_overlapSizeLog:
|
266
|
+
case ZSTD_p_enableLongDistanceMatching:
|
267
|
+
case ZSTD_p_ldmHashLog:
|
268
|
+
case ZSTD_p_ldmMinMatch:
|
269
|
+
case ZSTD_p_ldmBucketSizeLog:
|
270
|
+
case ZSTD_p_ldmHashEveryLog:
|
271
|
+
default:
|
272
|
+
return 0;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
|
248
276
|
size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned value)
|
249
277
|
{
|
250
278
|
DEBUGLOG(4, "ZSTD_CCtx_setParameter (%u, %u)", (U32)param, value);
|
251
|
-
if (cctx->streamStage != zcss_init)
|
279
|
+
if (cctx->streamStage != zcss_init) {
|
280
|
+
if (ZSTD_isUpdateAuthorized(param)) {
|
281
|
+
cctx->cParamsChanged = 1;
|
282
|
+
} else {
|
283
|
+
return ERROR(stage_wrong);
|
284
|
+
} }
|
252
285
|
|
253
286
|
switch(param)
|
254
287
|
{
|
@@ -267,9 +300,9 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
|
|
267
300
|
case ZSTD_p_targetLength:
|
268
301
|
case ZSTD_p_compressionStrategy:
|
269
302
|
if (cctx->cdict) return ERROR(stage_wrong);
|
270
|
-
if (value>0) ZSTD_cLevelToCParams(cctx); /* Can optimize if srcSize is known */
|
271
303
|
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
|
272
304
|
|
305
|
+
case ZSTD_p_compressLiterals:
|
273
306
|
case ZSTD_p_contentSizeFlag:
|
274
307
|
case ZSTD_p_checksumFlag:
|
275
308
|
case ZSTD_p_dictIDFlag:
|
@@ -280,23 +313,17 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
|
|
280
313
|
* default : 0 when using a CDict, 1 when using a Prefix */
|
281
314
|
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
|
282
315
|
|
283
|
-
case
|
284
|
-
if ((value
|
316
|
+
case ZSTD_p_nbWorkers:
|
317
|
+
if ((value>0) && cctx->staticSize) {
|
285
318
|
return ERROR(parameter_unsupported); /* MT not compatible with static alloc */
|
286
319
|
}
|
287
320
|
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
|
288
321
|
|
289
322
|
case ZSTD_p_jobSize:
|
290
|
-
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
|
291
|
-
|
292
323
|
case ZSTD_p_overlapSizeLog:
|
293
324
|
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
|
294
325
|
|
295
326
|
case ZSTD_p_enableLongDistanceMatching:
|
296
|
-
if (cctx->cdict) return ERROR(stage_wrong);
|
297
|
-
if (value>0) ZSTD_cLevelToCParams(cctx);
|
298
|
-
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
|
299
|
-
|
300
327
|
case ZSTD_p_ldmHashLog:
|
301
328
|
case ZSTD_p_ldmMinMatch:
|
302
329
|
case ZSTD_p_ldmBucketSizeLog:
|
@@ -320,69 +347,62 @@ size_t ZSTD_CCtxParam_setParameter(
|
|
320
347
|
CCtxParams->format = (ZSTD_format_e)value;
|
321
348
|
return (size_t)CCtxParams->format;
|
322
349
|
|
323
|
-
case ZSTD_p_compressionLevel :
|
324
|
-
|
325
|
-
if (
|
326
|
-
|
327
|
-
|
350
|
+
case ZSTD_p_compressionLevel : {
|
351
|
+
int cLevel = (int)value; /* cast expected to restore negative sign */
|
352
|
+
if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
|
353
|
+
if (cLevel) { /* 0 : does not change current level */
|
354
|
+
CCtxParams->disableLiteralCompression = (cLevel<0); /* negative levels disable huffman */
|
355
|
+
CCtxParams->compressionLevel = cLevel;
|
356
|
+
}
|
357
|
+
if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel;
|
358
|
+
return 0; /* return type (size_t) cannot represent negative values */
|
359
|
+
}
|
328
360
|
|
329
361
|
case ZSTD_p_windowLog :
|
330
|
-
|
331
|
-
if (value) { /* 0 : does not change current windowLog */
|
362
|
+
if (value>0) /* 0 => use default */
|
332
363
|
CLAMPCHECK(value, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
|
333
|
-
|
334
|
-
CCtxParams->cParams.windowLog = value;
|
335
|
-
}
|
364
|
+
CCtxParams->cParams.windowLog = value;
|
336
365
|
return CCtxParams->cParams.windowLog;
|
337
366
|
|
338
367
|
case ZSTD_p_hashLog :
|
339
|
-
if (value)
|
368
|
+
if (value>0) /* 0 => use default */
|
340
369
|
CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
341
|
-
|
342
|
-
CCtxParams->cParams.hashLog = value;
|
343
|
-
}
|
370
|
+
CCtxParams->cParams.hashLog = value;
|
344
371
|
return CCtxParams->cParams.hashLog;
|
345
372
|
|
346
373
|
case ZSTD_p_chainLog :
|
347
|
-
if (value)
|
374
|
+
if (value>0) /* 0 => use default */
|
348
375
|
CLAMPCHECK(value, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
|
349
|
-
|
350
|
-
CCtxParams->cParams.chainLog = value;
|
351
|
-
}
|
376
|
+
CCtxParams->cParams.chainLog = value;
|
352
377
|
return CCtxParams->cParams.chainLog;
|
353
378
|
|
354
379
|
case ZSTD_p_searchLog :
|
355
|
-
if (value)
|
380
|
+
if (value>0) /* 0 => use default */
|
356
381
|
CLAMPCHECK(value, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
|
357
|
-
|
358
|
-
CCtxParams->cParams.searchLog = value;
|
359
|
-
}
|
382
|
+
CCtxParams->cParams.searchLog = value;
|
360
383
|
return value;
|
361
384
|
|
362
385
|
case ZSTD_p_minMatch :
|
363
|
-
if (value)
|
386
|
+
if (value>0) /* 0 => use default */
|
364
387
|
CLAMPCHECK(value, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
|
365
|
-
|
366
|
-
CCtxParams->cParams.searchLength = value;
|
367
|
-
}
|
388
|
+
CCtxParams->cParams.searchLength = value;
|
368
389
|
return CCtxParams->cParams.searchLength;
|
369
390
|
|
370
391
|
case ZSTD_p_targetLength :
|
371
|
-
|
372
|
-
|
373
|
-
ZSTD_cLevelToCCtxParams(CCtxParams);
|
374
|
-
CCtxParams->cParams.targetLength = value;
|
375
|
-
}
|
392
|
+
/* all values are valid. 0 => use default */
|
393
|
+
CCtxParams->cParams.targetLength = value;
|
376
394
|
return CCtxParams->cParams.targetLength;
|
377
395
|
|
378
396
|
case ZSTD_p_compressionStrategy :
|
379
|
-
if (value)
|
397
|
+
if (value>0) /* 0 => use default */
|
380
398
|
CLAMPCHECK(value, (unsigned)ZSTD_fast, (unsigned)ZSTD_btultra);
|
381
|
-
|
382
|
-
CCtxParams->cParams.strategy = (ZSTD_strategy)value;
|
383
|
-
}
|
399
|
+
CCtxParams->cParams.strategy = (ZSTD_strategy)value;
|
384
400
|
return (size_t)CCtxParams->cParams.strategy;
|
385
401
|
|
402
|
+
case ZSTD_p_compressLiterals:
|
403
|
+
CCtxParams->disableLiteralCompression = !value;
|
404
|
+
return !CCtxParams->disableLiteralCompression;
|
405
|
+
|
386
406
|
case ZSTD_p_contentSizeFlag :
|
387
407
|
/* Content size written in frame header _when known_ (default:1) */
|
388
408
|
DEBUGLOG(4, "set content size flag = %u", (value>0));
|
@@ -396,27 +416,25 @@ size_t ZSTD_CCtxParam_setParameter(
|
|
396
416
|
|
397
417
|
case ZSTD_p_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */
|
398
418
|
DEBUGLOG(4, "set dictIDFlag = %u", (value>0));
|
399
|
-
CCtxParams->fParams.noDictIDFlag =
|
419
|
+
CCtxParams->fParams.noDictIDFlag = !value;
|
400
420
|
return !CCtxParams->fParams.noDictIDFlag;
|
401
421
|
|
402
422
|
case ZSTD_p_forceMaxWindow :
|
403
423
|
CCtxParams->forceWindow = (value > 0);
|
404
424
|
return CCtxParams->forceWindow;
|
405
425
|
|
406
|
-
case
|
407
|
-
if (value == 0) return CCtxParams->nbThreads;
|
426
|
+
case ZSTD_p_nbWorkers :
|
408
427
|
#ifndef ZSTD_MULTITHREAD
|
409
|
-
if (value
|
410
|
-
return
|
428
|
+
if (value>0) return ERROR(parameter_unsupported);
|
429
|
+
return 0;
|
411
430
|
#else
|
412
|
-
return
|
431
|
+
return ZSTDMT_CCtxParam_setNbWorkers(CCtxParams, value);
|
413
432
|
#endif
|
414
433
|
|
415
434
|
case ZSTD_p_jobSize :
|
416
435
|
#ifndef ZSTD_MULTITHREAD
|
417
436
|
return ERROR(parameter_unsupported);
|
418
437
|
#else
|
419
|
-
if (CCtxParams->nbThreads <= 1) return ERROR(parameter_unsupported);
|
420
438
|
return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_jobSize, value);
|
421
439
|
#endif
|
422
440
|
|
@@ -424,44 +442,36 @@ size_t ZSTD_CCtxParam_setParameter(
|
|
424
442
|
#ifndef ZSTD_MULTITHREAD
|
425
443
|
return ERROR(parameter_unsupported);
|
426
444
|
#else
|
427
|
-
if (CCtxParams->nbThreads <= 1) return ERROR(parameter_unsupported);
|
428
445
|
return ZSTDMT_CCtxParam_setMTCtxParameter(CCtxParams, ZSTDMT_p_overlapSectionLog, value);
|
429
446
|
#endif
|
430
447
|
|
431
448
|
case ZSTD_p_enableLongDistanceMatching :
|
432
|
-
|
433
|
-
|
434
|
-
CCtxParams->cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
|
435
|
-
}
|
436
|
-
return ZSTD_ldm_initializeParameters(&CCtxParams->ldmParams, value);
|
449
|
+
CCtxParams->ldmParams.enableLdm = (value>0);
|
450
|
+
return CCtxParams->ldmParams.enableLdm;
|
437
451
|
|
438
452
|
case ZSTD_p_ldmHashLog :
|
439
|
-
if (value)
|
453
|
+
if (value>0) /* 0 ==> auto */
|
440
454
|
CLAMPCHECK(value, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
441
|
-
|
442
|
-
}
|
455
|
+
CCtxParams->ldmParams.hashLog = value;
|
443
456
|
return CCtxParams->ldmParams.hashLog;
|
444
457
|
|
445
458
|
case ZSTD_p_ldmMinMatch :
|
446
|
-
if (value)
|
459
|
+
if (value>0) /* 0 ==> default */
|
447
460
|
CLAMPCHECK(value, ZSTD_LDM_MINMATCH_MIN, ZSTD_LDM_MINMATCH_MAX);
|
448
|
-
|
449
|
-
}
|
461
|
+
CCtxParams->ldmParams.minMatchLength = value;
|
450
462
|
return CCtxParams->ldmParams.minMatchLength;
|
451
463
|
|
452
464
|
case ZSTD_p_ldmBucketSizeLog :
|
453
|
-
if (value > ZSTD_LDM_BUCKETSIZELOG_MAX)
|
465
|
+
if (value > ZSTD_LDM_BUCKETSIZELOG_MAX)
|
454
466
|
return ERROR(parameter_outOfBound);
|
455
|
-
}
|
456
467
|
CCtxParams->ldmParams.bucketSizeLog = value;
|
457
|
-
return
|
468
|
+
return CCtxParams->ldmParams.bucketSizeLog;
|
458
469
|
|
459
470
|
case ZSTD_p_ldmHashEveryLog :
|
460
|
-
if (value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN)
|
471
|
+
if (value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN)
|
461
472
|
return ERROR(parameter_outOfBound);
|
462
|
-
}
|
463
473
|
CCtxParams->ldmParams.hashEveryLog = value;
|
464
|
-
return
|
474
|
+
return CCtxParams->ldmParams.hashEveryLog;
|
465
475
|
|
466
476
|
default: return ERROR(parameter_unsupported);
|
467
477
|
}
|
@@ -470,6 +480,9 @@ size_t ZSTD_CCtxParam_setParameter(
|
|
470
480
|
/** ZSTD_CCtx_setParametersUsingCCtxParams() :
|
471
481
|
* just applies `params` into `cctx`
|
472
482
|
* no action is performed, parameters are merely stored.
|
483
|
+
* If ZSTDMT is enabled, parameters are pushed to cctx->mtctx.
|
484
|
+
* This is possible even if a compression is ongoing.
|
485
|
+
* In which case, new parameters will be applied on the fly, starting with next compression job.
|
473
486
|
*/
|
474
487
|
size_t ZSTD_CCtx_setParametersUsingCCtxParams(
|
475
488
|
ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
|
@@ -478,7 +491,6 @@ size_t ZSTD_CCtx_setParametersUsingCCtxParams(
|
|
478
491
|
if (cctx->cdict) return ERROR(stage_wrong);
|
479
492
|
|
480
493
|
cctx->requestedParams = *params;
|
481
|
-
|
482
494
|
return 0;
|
483
495
|
}
|
484
496
|
|
@@ -492,7 +504,7 @@ ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long lo
|
|
492
504
|
|
493
505
|
size_t ZSTD_CCtx_loadDictionary_advanced(
|
494
506
|
ZSTD_CCtx* cctx, const void* dict, size_t dictSize,
|
495
|
-
ZSTD_dictLoadMethod_e dictLoadMethod,
|
507
|
+
ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType)
|
496
508
|
{
|
497
509
|
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
|
498
510
|
if (cctx->staticSize) return ERROR(memory_allocation); /* no malloc for static CCtx */
|
@@ -503,10 +515,10 @@ size_t ZSTD_CCtx_loadDictionary_advanced(
|
|
503
515
|
cctx->cdict = NULL;
|
504
516
|
} else {
|
505
517
|
ZSTD_compressionParameters const cParams =
|
506
|
-
ZSTD_getCParamsFromCCtxParams(cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, dictSize);
|
518
|
+
ZSTD_getCParamsFromCCtxParams(&cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, dictSize);
|
507
519
|
cctx->cdictLocal = ZSTD_createCDict_advanced(
|
508
520
|
dict, dictSize,
|
509
|
-
dictLoadMethod,
|
521
|
+
dictLoadMethod, dictContentType,
|
510
522
|
cParams, cctx->customMem);
|
511
523
|
cctx->cdict = cctx->cdictLocal;
|
512
524
|
if (cctx->cdictLocal == NULL)
|
@@ -519,13 +531,13 @@ ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(
|
|
519
531
|
ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
|
520
532
|
{
|
521
533
|
return ZSTD_CCtx_loadDictionary_advanced(
|
522
|
-
cctx, dict, dictSize, ZSTD_dlm_byRef,
|
534
|
+
cctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto);
|
523
535
|
}
|
524
536
|
|
525
537
|
ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
|
526
538
|
{
|
527
539
|
return ZSTD_CCtx_loadDictionary_advanced(
|
528
|
-
cctx, dict, dictSize, ZSTD_dlm_byCopy,
|
540
|
+
cctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto);
|
529
541
|
}
|
530
542
|
|
531
543
|
|
@@ -539,17 +551,17 @@ size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
|
|
539
551
|
|
540
552
|
size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)
|
541
553
|
{
|
542
|
-
return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize,
|
554
|
+
return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, ZSTD_dct_rawContent);
|
543
555
|
}
|
544
556
|
|
545
557
|
size_t ZSTD_CCtx_refPrefix_advanced(
|
546
|
-
ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize,
|
558
|
+
ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
|
547
559
|
{
|
548
560
|
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
|
549
561
|
cctx->cdict = NULL; /* prefix discards any prior cdict */
|
550
562
|
cctx->prefixDict.dict = prefix;
|
551
563
|
cctx->prefixDict.dictSize = prefixSize;
|
552
|
-
cctx->prefixDict.
|
564
|
+
cctx->prefixDict.dictContentType = dictContentType;
|
553
565
|
return 0;
|
554
566
|
}
|
555
567
|
|
@@ -577,7 +589,8 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
|
577
589
|
CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
578
590
|
CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
|
579
591
|
CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
|
580
|
-
|
592
|
+
if ((U32)(cParams.targetLength) < ZSTD_TARGETLENGTH_MIN)
|
593
|
+
return ERROR(parameter_unsupported);
|
581
594
|
if ((U32)(cParams.strategy) > (U32)ZSTD_btultra)
|
582
595
|
return ERROR(parameter_unsupported);
|
583
596
|
return 0;
|
@@ -597,7 +610,7 @@ static ZSTD_compressionParameters ZSTD_clampCParams(ZSTD_compressionParameters c
|
|
597
610
|
CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
598
611
|
CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
|
599
612
|
CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
|
600
|
-
|
613
|
+
if ((U32)(cParams.targetLength) < ZSTD_TARGETLENGTH_MIN) cParams.targetLength = ZSTD_TARGETLENGTH_MIN;
|
601
614
|
if ((U32)(cParams.strategy) > (U32)ZSTD_btultra) cParams.strategy = ZSTD_btultra;
|
602
615
|
return cParams;
|
603
616
|
}
|
@@ -653,36 +666,43 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
|
|
653
666
|
return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
|
654
667
|
}
|
655
668
|
|
669
|
+
static size_t ZSTD_sizeof_matchState(ZSTD_compressionParameters const* cParams, const U32 forCCtx)
|
670
|
+
{
|
671
|
+
size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
|
672
|
+
size_t const hSize = ((size_t)1) << cParams->hashLog;
|
673
|
+
U32 const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
|
674
|
+
size_t const h3Size = ((size_t)1) << hashLog3;
|
675
|
+
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
676
|
+
size_t const optPotentialSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits)) * sizeof(U32)
|
677
|
+
+ (ZSTD_OPT_NUM+1) * (sizeof(ZSTD_match_t)+sizeof(ZSTD_optimal_t));
|
678
|
+
size_t const optSpace = (forCCtx && ((cParams->strategy == ZSTD_btopt) ||
|
679
|
+
(cParams->strategy == ZSTD_btultra)))
|
680
|
+
? optPotentialSpace
|
681
|
+
: 0;
|
682
|
+
DEBUGLOG(4, "chainSize: %u - hSize: %u - h3Size: %u",
|
683
|
+
(U32)chainSize, (U32)hSize, (U32)h3Size);
|
684
|
+
return tableSpace + optSpace;
|
685
|
+
}
|
686
|
+
|
656
687
|
size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
657
688
|
{
|
658
689
|
/* Estimate CCtx size is supported for single-threaded compression only. */
|
659
|
-
if (params->
|
690
|
+
if (params->nbWorkers > 0) { return ERROR(GENERIC); }
|
660
691
|
{ ZSTD_compressionParameters const cParams =
|
661
|
-
ZSTD_getCParamsFromCCtxParams(
|
692
|
+
ZSTD_getCParamsFromCCtxParams(params, 0, 0);
|
662
693
|
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
|
663
694
|
U32 const divider = (cParams.searchLength==3) ? 3 : 4;
|
664
695
|
size_t const maxNbSeq = blockSize / divider;
|
665
696
|
size_t const tokenSpace = blockSize + 11*maxNbSeq;
|
666
|
-
size_t const
|
667
|
-
|
668
|
-
size_t const
|
669
|
-
U32 const hashLog3 = (cParams.searchLength>3) ?
|
670
|
-
0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
|
671
|
-
size_t const h3Size = ((size_t)1) << hashLog3;
|
672
|
-
size_t const entropySpace = sizeof(ZSTD_entropyCTables_t);
|
673
|
-
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
697
|
+
size_t const entropySpace = HUF_WORKSPACE_SIZE;
|
698
|
+
size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
|
699
|
+
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);
|
674
700
|
|
675
|
-
size_t const
|
676
|
-
|
677
|
-
+ (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
|
678
|
-
size_t const optSpace = ((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btultra)) ? optBudget : 0;
|
701
|
+
size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams);
|
702
|
+
size_t const ldmSeqSpace = ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize) * sizeof(rawSeq);
|
679
703
|
|
680
|
-
size_t const
|
681
|
-
|
682
|
-
params->ldmParams.bucketSizeLog) : 0;
|
683
|
-
|
684
|
-
size_t const neededSpace = entropySpace + tableSpace + tokenSpace +
|
685
|
-
optSpace + ldmSpace;
|
704
|
+
size_t const neededSpace = entropySpace + blockStateSpace + tokenSpace +
|
705
|
+
matchStateSize + ldmSpace + ldmSeqSpace;
|
686
706
|
|
687
707
|
DEBUGLOG(5, "sizeof(ZSTD_CCtx) : %u", (U32)sizeof(ZSTD_CCtx));
|
688
708
|
DEBUGLOG(5, "estimate workSpace : %u", (U32)neededSpace);
|
@@ -696,15 +716,26 @@ size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)
|
|
696
716
|
return ZSTD_estimateCCtxSize_usingCCtxParams(¶ms);
|
697
717
|
}
|
698
718
|
|
699
|
-
size_t
|
719
|
+
static size_t ZSTD_estimateCCtxSize_internal(int compressionLevel)
|
700
720
|
{
|
701
721
|
ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
|
702
722
|
return ZSTD_estimateCCtxSize_usingCParams(cParams);
|
703
723
|
}
|
704
724
|
|
725
|
+
size_t ZSTD_estimateCCtxSize(int compressionLevel)
|
726
|
+
{
|
727
|
+
int level;
|
728
|
+
size_t memBudget = 0;
|
729
|
+
for (level=1; level<=compressionLevel; level++) {
|
730
|
+
size_t const newMB = ZSTD_estimateCCtxSize_internal(level);
|
731
|
+
if (newMB > memBudget) memBudget = newMB;
|
732
|
+
}
|
733
|
+
return memBudget;
|
734
|
+
}
|
735
|
+
|
705
736
|
size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
706
737
|
{
|
707
|
-
if (params->
|
738
|
+
if (params->nbWorkers > 0) { return ERROR(GENERIC); }
|
708
739
|
{ size_t const CCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);
|
709
740
|
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params->cParams.windowLog);
|
710
741
|
size_t const inBuffSize = ((size_t)1 << params->cParams.windowLog) + blockSize;
|
@@ -721,11 +752,44 @@ size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams)
|
|
721
752
|
return ZSTD_estimateCStreamSize_usingCCtxParams(¶ms);
|
722
753
|
}
|
723
754
|
|
724
|
-
size_t
|
755
|
+
static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel) {
|
725
756
|
ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
|
726
757
|
return ZSTD_estimateCStreamSize_usingCParams(cParams);
|
727
758
|
}
|
728
759
|
|
760
|
+
size_t ZSTD_estimateCStreamSize(int compressionLevel) {
|
761
|
+
int level;
|
762
|
+
size_t memBudget = 0;
|
763
|
+
for (level=1; level<=compressionLevel; level++) {
|
764
|
+
size_t const newMB = ZSTD_estimateCStreamSize_internal(level);
|
765
|
+
if (newMB > memBudget) memBudget = newMB;
|
766
|
+
}
|
767
|
+
return memBudget;
|
768
|
+
}
|
769
|
+
|
770
|
+
/* ZSTD_getFrameProgression():
|
771
|
+
* tells how much data has been consumed (input) and produced (output) for current frame.
|
772
|
+
* able to count progression inside worker threads (non-blocking mode).
|
773
|
+
*/
|
774
|
+
ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx)
|
775
|
+
{
|
776
|
+
#ifdef ZSTD_MULTITHREAD
|
777
|
+
if (cctx->appliedParams.nbWorkers > 0) {
|
778
|
+
return ZSTDMT_getFrameProgression(cctx->mtctx);
|
779
|
+
}
|
780
|
+
#endif
|
781
|
+
{ ZSTD_frameProgression fp;
|
782
|
+
size_t const buffered = (cctx->inBuff == NULL) ? 0 :
|
783
|
+
cctx->inBuffPos - cctx->inToCompress;
|
784
|
+
if (buffered) assert(cctx->inBuffPos >= cctx->inToCompress);
|
785
|
+
assert(buffered <= ZSTD_BLOCKSIZE_MAX);
|
786
|
+
fp.ingested = cctx->consumedSrcSize + buffered;
|
787
|
+
fp.consumed = cctx->consumedSrcSize;
|
788
|
+
fp.produced = cctx->producedCSize;
|
789
|
+
return fp;
|
790
|
+
} }
|
791
|
+
|
792
|
+
|
729
793
|
static U32 ZSTD_equivalentCParams(ZSTD_compressionParameters cParams1,
|
730
794
|
ZSTD_compressionParameters cParams2)
|
731
795
|
{
|
@@ -761,9 +825,9 @@ static U32 ZSTD_sufficientBuff(size_t bufferSize1, size_t blockSize1,
|
|
761
825
|
size_t const windowSize2 = MAX(1, (size_t)MIN(((U64)1 << cParams2.windowLog), pledgedSrcSize));
|
762
826
|
size_t const blockSize2 = MIN(ZSTD_BLOCKSIZE_MAX, windowSize2);
|
763
827
|
size_t const neededBufferSize2 = (buffPol2==ZSTDb_buffered) ? windowSize2 + blockSize2 : 0;
|
764
|
-
DEBUGLOG(4, "ZSTD_sufficientBuff: windowSize2=%u
|
828
|
+
DEBUGLOG(4, "ZSTD_sufficientBuff: is windowSize2=%u <= wlog1=%u",
|
765
829
|
(U32)windowSize2, cParams2.windowLog);
|
766
|
-
DEBUGLOG(4, "ZSTD_sufficientBuff: blockSize2
|
830
|
+
DEBUGLOG(4, "ZSTD_sufficientBuff: is blockSize2=%u <= blockSize1=%u",
|
767
831
|
(U32)blockSize2, (U32)blockSize1);
|
768
832
|
return (blockSize2 <= blockSize1) /* seqStore space depends on blockSize */
|
769
833
|
& (neededBufferSize2 <= bufferSize1);
|
@@ -782,37 +846,101 @@ static U32 ZSTD_equivalentParams(ZSTD_CCtx_params params1,
|
|
782
846
|
ZSTD_sufficientBuff(buffSize1, blockSize1, buffPol2, params2.cParams, pledgedSrcSize);
|
783
847
|
}
|
784
848
|
|
849
|
+
static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
|
850
|
+
{
|
851
|
+
int i;
|
852
|
+
for (i = 0; i < ZSTD_REP_NUM; ++i)
|
853
|
+
bs->rep[i] = repStartValue[i];
|
854
|
+
bs->entropy.hufCTable_repeatMode = HUF_repeat_none;
|
855
|
+
bs->entropy.offcode_repeatMode = FSE_repeat_none;
|
856
|
+
bs->entropy.matchlength_repeatMode = FSE_repeat_none;
|
857
|
+
bs->entropy.litlength_repeatMode = FSE_repeat_none;
|
858
|
+
}
|
859
|
+
|
860
|
+
/*! ZSTD_invalidateMatchState()
|
861
|
+
* Invalidate all the matches in the match finder tables.
|
862
|
+
* Requires nextSrc and base to be set (can be NULL).
|
863
|
+
*/
|
864
|
+
static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
|
865
|
+
{
|
866
|
+
ZSTD_window_clear(&ms->window);
|
867
|
+
|
868
|
+
ms->nextToUpdate = ms->window.dictLimit + 1;
|
869
|
+
ms->loadedDictEnd = 0;
|
870
|
+
ms->opt.litLengthSum = 0; /* force reset of btopt stats */
|
871
|
+
}
|
872
|
+
|
785
873
|
/*! ZSTD_continueCCtx() :
|
786
874
|
* reuse CCtx without reset (note : requires no dictionary) */
|
787
875
|
static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pledgedSrcSize)
|
788
876
|
{
|
789
|
-
U32 const end = (U32)(cctx->nextSrc - cctx->base);
|
790
877
|
size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
|
791
878
|
size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);
|
792
|
-
DEBUGLOG(4, "ZSTD_continueCCtx");
|
879
|
+
DEBUGLOG(4, "ZSTD_continueCCtx: re-use context in place");
|
793
880
|
|
794
881
|
cctx->blockSize = blockSize; /* previous block size could be different even for same windowLog, due to pledgedSrcSize */
|
795
882
|
cctx->appliedParams = params;
|
796
883
|
cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;
|
797
884
|
cctx->consumedSrcSize = 0;
|
885
|
+
cctx->producedCSize = 0;
|
798
886
|
if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
|
799
887
|
cctx->appliedParams.fParams.contentSizeFlag = 0;
|
800
888
|
DEBUGLOG(4, "pledged content size : %u ; flag : %u",
|
801
889
|
(U32)pledgedSrcSize, cctx->appliedParams.fParams.contentSizeFlag);
|
802
|
-
cctx->lowLimit = end;
|
803
|
-
cctx->dictLimit = end;
|
804
|
-
cctx->nextToUpdate = end+1;
|
805
890
|
cctx->stage = ZSTDcs_init;
|
806
891
|
cctx->dictID = 0;
|
807
|
-
|
808
|
-
|
809
|
-
cctx
|
892
|
+
if (params.ldmParams.enableLdm)
|
893
|
+
ZSTD_window_clear(&cctx->ldmState.window);
|
894
|
+
ZSTD_referenceExternalSequences(cctx, NULL, 0);
|
895
|
+
ZSTD_invalidateMatchState(&cctx->blockState.matchState);
|
896
|
+
ZSTD_reset_compressedBlockState(cctx->blockState.prevCBlock);
|
810
897
|
XXH64_reset(&cctx->xxhState, 0);
|
811
898
|
return 0;
|
812
899
|
}
|
813
900
|
|
814
901
|
typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
|
815
902
|
|
903
|
+
static void* ZSTD_reset_matchState(ZSTD_matchState_t* ms, void* ptr, ZSTD_compressionParameters const* cParams, ZSTD_compResetPolicy_e const crp, U32 const forCCtx)
|
904
|
+
{
|
905
|
+
size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
|
906
|
+
size_t const hSize = ((size_t)1) << cParams->hashLog;
|
907
|
+
U32 const hashLog3 = (forCCtx && cParams->searchLength==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;
|
908
|
+
size_t const h3Size = ((size_t)1) << hashLog3;
|
909
|
+
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
910
|
+
|
911
|
+
assert(((size_t)ptr & 3) == 0);
|
912
|
+
|
913
|
+
ms->hashLog3 = hashLog3;
|
914
|
+
memset(&ms->window, 0, sizeof(ms->window));
|
915
|
+
ZSTD_invalidateMatchState(ms);
|
916
|
+
|
917
|
+
/* opt parser space */
|
918
|
+
if (forCCtx && ((cParams->strategy == ZSTD_btopt) | (cParams->strategy == ZSTD_btultra))) {
|
919
|
+
DEBUGLOG(4, "reserving optimal parser space");
|
920
|
+
ms->opt.litFreq = (U32*)ptr;
|
921
|
+
ms->opt.litLengthFreq = ms->opt.litFreq + (1<<Litbits);
|
922
|
+
ms->opt.matchLengthFreq = ms->opt.litLengthFreq + (MaxLL+1);
|
923
|
+
ms->opt.offCodeFreq = ms->opt.matchLengthFreq + (MaxML+1);
|
924
|
+
ptr = ms->opt.offCodeFreq + (MaxOff+1);
|
925
|
+
ms->opt.matchTable = (ZSTD_match_t*)ptr;
|
926
|
+
ptr = ms->opt.matchTable + ZSTD_OPT_NUM+1;
|
927
|
+
ms->opt.priceTable = (ZSTD_optimal_t*)ptr;
|
928
|
+
ptr = ms->opt.priceTable + ZSTD_OPT_NUM+1;
|
929
|
+
}
|
930
|
+
|
931
|
+
/* table Space */
|
932
|
+
DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_noMemset);
|
933
|
+
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
934
|
+
if (crp!=ZSTDcrp_noMemset) memset(ptr, 0, tableSpace); /* reset tables only */
|
935
|
+
ms->hashTable = (U32*)(ptr);
|
936
|
+
ms->chainTable = ms->hashTable + hSize;
|
937
|
+
ms->hashTable3 = ms->chainTable + chainSize;
|
938
|
+
ptr = ms->hashTable3 + h3Size;
|
939
|
+
|
940
|
+
assert(((size_t)ptr & 3) == 0);
|
941
|
+
return ptr;
|
942
|
+
}
|
943
|
+
|
816
944
|
/*! ZSTD_resetCCtx_internal() :
|
817
945
|
note : `params` are assumed fully validated at this stage */
|
818
946
|
static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
@@ -830,19 +958,14 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
830
958
|
zbuff, pledgedSrcSize)) {
|
831
959
|
DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%u)",
|
832
960
|
zc->appliedParams.cParams.windowLog, (U32)zc->blockSize);
|
833
|
-
assert(!(params.ldmParams.enableLdm &&
|
834
|
-
params.ldmParams.hashEveryLog == ZSTD_LDM_HASHEVERYLOG_NOTSET));
|
835
|
-
zc->entropy->hufCTable_repeatMode = HUF_repeat_none;
|
836
|
-
zc->entropy->offcode_repeatMode = FSE_repeat_none;
|
837
|
-
zc->entropy->matchlength_repeatMode = FSE_repeat_none;
|
838
|
-
zc->entropy->litlength_repeatMode = FSE_repeat_none;
|
839
961
|
return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
|
840
962
|
} }
|
841
963
|
DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
|
842
964
|
|
843
965
|
if (params.ldmParams.enableLdm) {
|
844
966
|
/* Adjust long distance matching parameters */
|
845
|
-
|
967
|
+
params.ldmParams.windowLog = params.cParams.windowLog;
|
968
|
+
ZSTD_ldm_adjustParameters(¶ms.ldmParams, ¶ms.cParams);
|
846
969
|
assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
|
847
970
|
assert(params.ldmParams.hashEveryLog < 32);
|
848
971
|
zc->ldmState.hashPower =
|
@@ -854,34 +977,25 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
854
977
|
U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
|
855
978
|
size_t const maxNbSeq = blockSize / divider;
|
856
979
|
size_t const tokenSpace = blockSize + 11*maxNbSeq;
|
857
|
-
size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ?
|
858
|
-
0 : ((size_t)1 << params.cParams.chainLog);
|
859
|
-
size_t const hSize = ((size_t)1) << params.cParams.hashLog;
|
860
|
-
U32 const hashLog3 = (params.cParams.searchLength>3) ?
|
861
|
-
0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
|
862
|
-
size_t const h3Size = ((size_t)1) << hashLog3;
|
863
|
-
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
864
980
|
size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;
|
865
981
|
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
|
982
|
+
size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1);
|
983
|
+
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
|
866
984
|
void* ptr;
|
867
985
|
|
868
986
|
/* Check if workSpace is large enough, alloc a new one if needed */
|
869
|
-
{ size_t const entropySpace =
|
870
|
-
size_t const
|
871
|
-
+ (ZSTD_OPT_NUM+1) * (sizeof(ZSTD_match_t)+sizeof(ZSTD_optimal_t));
|
872
|
-
size_t const optSpace = ( (params.cParams.strategy == ZSTD_btopt)
|
873
|
-
|| (params.cParams.strategy == ZSTD_btultra)) ?
|
874
|
-
optPotentialSpace : 0;
|
987
|
+
{ size_t const entropySpace = HUF_WORKSPACE_SIZE;
|
988
|
+
size_t const blockStateSpace = 2 * sizeof(ZSTD_compressedBlockState_t);
|
875
989
|
size_t const bufferSpace = buffInSize + buffOutSize;
|
876
|
-
size_t const ldmSpace = params.ldmParams
|
877
|
-
|
878
|
-
|
879
|
-
size_t const neededSpace = entropySpace +
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
990
|
+
size_t const ldmSpace = ZSTD_ldm_getTableSize(params.ldmParams);
|
991
|
+
size_t const ldmSeqSpace = maxNbLdmSeq * sizeof(rawSeq);
|
992
|
+
|
993
|
+
size_t const neededSpace = entropySpace + blockStateSpace + ldmSpace +
|
994
|
+
ldmSeqSpace + matchStateSize + tokenSpace +
|
995
|
+
bufferSpace;
|
996
|
+
DEBUGLOG(4, "Need %uKB workspace, including %uKB for match state, and %uKB for buffers",
|
997
|
+
(U32)(neededSpace>>10), (U32)(matchStateSize>>10), (U32)(bufferSpace>>10));
|
998
|
+
DEBUGLOG(4, "windowSize: %u - blockSize: %u", (U32)windowSize, (U32)blockSize);
|
885
999
|
|
886
1000
|
if (zc->workSpaceSize < neededSpace) { /* too small : resize */
|
887
1001
|
DEBUGLOG(4, "Need to update workSpaceSize from %uK to %uK",
|
@@ -897,16 +1011,20 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
897
1011
|
zc->workSpaceSize = neededSpace;
|
898
1012
|
ptr = zc->workSpace;
|
899
1013
|
|
900
|
-
/*
|
1014
|
+
/* Statically sized space. entropyWorkspace never moves (but prev/next block swap places) */
|
901
1015
|
assert(((size_t)zc->workSpace & 3) == 0); /* ensure correct alignment */
|
902
|
-
assert(zc->workSpaceSize >= sizeof(
|
903
|
-
zc->
|
1016
|
+
assert(zc->workSpaceSize >= 2 * sizeof(ZSTD_compressedBlockState_t));
|
1017
|
+
zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)zc->workSpace;
|
1018
|
+
zc->blockState.nextCBlock = zc->blockState.prevCBlock + 1;
|
1019
|
+
ptr = zc->blockState.nextCBlock + 1;
|
1020
|
+
zc->entropyWorkspace = (U32*)ptr;
|
904
1021
|
} }
|
905
1022
|
|
906
1023
|
/* init params */
|
907
1024
|
zc->appliedParams = params;
|
908
1025
|
zc->pledgedSrcSizePlusOne = pledgedSrcSize+1;
|
909
1026
|
zc->consumedSrcSize = 0;
|
1027
|
+
zc->producedCSize = 0;
|
910
1028
|
if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)
|
911
1029
|
zc->appliedParams.fParams.contentSizeFlag = 0;
|
912
1030
|
DEBUGLOG(4, "pledged content size : %u ; flag : %u",
|
@@ -916,37 +1034,10 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
916
1034
|
XXH64_reset(&zc->xxhState, 0);
|
917
1035
|
zc->stage = ZSTDcs_init;
|
918
1036
|
zc->dictID = 0;
|
919
|
-
|
920
|
-
zc->
|
921
|
-
|
922
|
-
zc->
|
923
|
-
zc->entropy->litlength_repeatMode = FSE_repeat_none;
|
924
|
-
zc->nextToUpdate = 1;
|
925
|
-
zc->nextSrc = NULL;
|
926
|
-
zc->base = NULL;
|
927
|
-
zc->dictBase = NULL;
|
928
|
-
zc->dictLimit = 0;
|
929
|
-
zc->lowLimit = 0;
|
930
|
-
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->seqStore.rep[i] = repStartValue[i]; }
|
931
|
-
zc->hashLog3 = hashLog3;
|
932
|
-
zc->optState.litLengthSum = 0;
|
933
|
-
|
934
|
-
ptr = zc->entropy + 1;
|
935
|
-
|
936
|
-
/* opt parser space */
|
937
|
-
if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btultra)) {
|
938
|
-
DEBUGLOG(4, "reserving optimal parser space");
|
939
|
-
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
940
|
-
zc->optState.litFreq = (U32*)ptr;
|
941
|
-
zc->optState.litLengthFreq = zc->optState.litFreq + (1<<Litbits);
|
942
|
-
zc->optState.matchLengthFreq = zc->optState.litLengthFreq + (MaxLL+1);
|
943
|
-
zc->optState.offCodeFreq = zc->optState.matchLengthFreq + (MaxML+1);
|
944
|
-
ptr = zc->optState.offCodeFreq + (MaxOff+1);
|
945
|
-
zc->optState.matchTable = (ZSTD_match_t*)ptr;
|
946
|
-
ptr = zc->optState.matchTable + ZSTD_OPT_NUM+1;
|
947
|
-
zc->optState.priceTable = (ZSTD_optimal_t*)ptr;
|
948
|
-
ptr = zc->optState.priceTable + ZSTD_OPT_NUM+1;
|
949
|
-
}
|
1037
|
+
|
1038
|
+
ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock);
|
1039
|
+
|
1040
|
+
ptr = zc->entropyWorkspace + HUF_WORKSPACE_SIZE_U32;
|
950
1041
|
|
951
1042
|
/* ldm hash table */
|
952
1043
|
/* initialize bucketOffsets table later for pointer alignment */
|
@@ -956,16 +1047,15 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
956
1047
|
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
957
1048
|
zc->ldmState.hashTable = (ldmEntry_t*)ptr;
|
958
1049
|
ptr = zc->ldmState.hashTable + ldmHSize;
|
1050
|
+
zc->ldmSequences = (rawSeq*)ptr;
|
1051
|
+
ptr = zc->ldmSequences + maxNbLdmSeq;
|
1052
|
+
zc->maxNbLdmSequences = maxNbLdmSeq;
|
1053
|
+
|
1054
|
+
memset(&zc->ldmState.window, 0, sizeof(zc->ldmState.window));
|
959
1055
|
}
|
1056
|
+
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
960
1057
|
|
961
|
-
/*
|
962
|
-
DEBUGLOG(4, "reset table : %u", crp!=ZSTDcrp_noMemset);
|
963
|
-
if (crp!=ZSTDcrp_noMemset) memset(ptr, 0, tableSpace); /* reset tables only */
|
964
|
-
assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
|
965
|
-
zc->hashTable = (U32*)(ptr);
|
966
|
-
zc->chainTable = zc->hashTable + hSize;
|
967
|
-
zc->hashTable3 = zc->chainTable + chainSize;
|
968
|
-
ptr = zc->hashTable3 + h3Size;
|
1058
|
+
ptr = ZSTD_reset_matchState(&zc->blockState.matchState, ptr, ¶ms.cParams, crp, /* forCCtx */ 1);
|
969
1059
|
|
970
1060
|
/* sequences storage */
|
971
1061
|
zc->seqStore.sequencesStart = (seqDef*)ptr;
|
@@ -984,7 +1074,9 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
984
1074
|
memset(ptr, 0, ldmBucketSize);
|
985
1075
|
zc->ldmState.bucketOffsets = (BYTE*)ptr;
|
986
1076
|
ptr = zc->ldmState.bucketOffsets + ldmBucketSize;
|
1077
|
+
ZSTD_window_clear(&zc->ldmState.window);
|
987
1078
|
}
|
1079
|
+
ZSTD_referenceExternalSequences(zc, NULL, 0);
|
988
1080
|
|
989
1081
|
/* buffers */
|
990
1082
|
zc->inBuffSize = buffInSize;
|
@@ -1002,9 +1094,61 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
1002
1094
|
* do not use with extDict variant ! */
|
1003
1095
|
void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
|
1004
1096
|
int i;
|
1005
|
-
for (i=0; i<ZSTD_REP_NUM; i++) cctx->
|
1097
|
+
for (i=0; i<ZSTD_REP_NUM; i++) cctx->blockState.prevCBlock->rep[i] = 0;
|
1098
|
+
assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window));
|
1006
1099
|
}
|
1007
1100
|
|
1101
|
+
static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
1102
|
+
const ZSTD_CDict* cdict,
|
1103
|
+
unsigned windowLog,
|
1104
|
+
ZSTD_frameParameters fParams,
|
1105
|
+
U64 pledgedSrcSize,
|
1106
|
+
ZSTD_buffered_policy_e zbuff)
|
1107
|
+
{
|
1108
|
+
{ ZSTD_CCtx_params params = cctx->requestedParams;
|
1109
|
+
/* Copy only compression parameters related to tables. */
|
1110
|
+
params.cParams = cdict->cParams;
|
1111
|
+
if (windowLog) params.cParams.windowLog = windowLog;
|
1112
|
+
params.fParams = fParams;
|
1113
|
+
ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
1114
|
+
ZSTDcrp_noMemset, zbuff);
|
1115
|
+
assert(cctx->appliedParams.cParams.strategy == cdict->cParams.strategy);
|
1116
|
+
assert(cctx->appliedParams.cParams.hashLog == cdict->cParams.hashLog);
|
1117
|
+
assert(cctx->appliedParams.cParams.chainLog == cdict->cParams.chainLog);
|
1118
|
+
}
|
1119
|
+
|
1120
|
+
/* copy tables */
|
1121
|
+
{ size_t const chainSize = (cdict->cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict->cParams.chainLog);
|
1122
|
+
size_t const hSize = (size_t)1 << cdict->cParams.hashLog;
|
1123
|
+
size_t const tableSpace = (chainSize + hSize) * sizeof(U32);
|
1124
|
+
assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
1125
|
+
assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize);
|
1126
|
+
assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
1127
|
+
assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize);
|
1128
|
+
memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace); /* presumes all tables follow each other */
|
1129
|
+
}
|
1130
|
+
/* Zero the hashTable3, since the cdict never fills it */
|
1131
|
+
{ size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
|
1132
|
+
assert(cdict->matchState.hashLog3 == 0);
|
1133
|
+
memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
|
1134
|
+
}
|
1135
|
+
|
1136
|
+
/* copy dictionary offsets */
|
1137
|
+
{
|
1138
|
+
ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
|
1139
|
+
ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
|
1140
|
+
dstMatchState->window = srcMatchState->window;
|
1141
|
+
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
1142
|
+
dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
|
1143
|
+
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
|
1144
|
+
}
|
1145
|
+
cctx->dictID = cdict->dictID;
|
1146
|
+
|
1147
|
+
/* copy block state */
|
1148
|
+
memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));
|
1149
|
+
|
1150
|
+
return 0;
|
1151
|
+
}
|
1008
1152
|
|
1009
1153
|
/*! ZSTD_copyCCtx_internal() :
|
1010
1154
|
* Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
|
@@ -1015,7 +1159,6 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
|
|
1015
1159
|
* @return : 0, or an error code */
|
1016
1160
|
static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
1017
1161
|
const ZSTD_CCtx* srcCCtx,
|
1018
|
-
unsigned windowLog,
|
1019
1162
|
ZSTD_frameParameters fParams,
|
1020
1163
|
U64 pledgedSrcSize,
|
1021
1164
|
ZSTD_buffered_policy_e zbuff)
|
@@ -1027,41 +1170,39 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
|
1027
1170
|
{ ZSTD_CCtx_params params = dstCCtx->requestedParams;
|
1028
1171
|
/* Copy only compression parameters related to tables. */
|
1029
1172
|
params.cParams = srcCCtx->appliedParams.cParams;
|
1030
|
-
if (windowLog) params.cParams.windowLog = windowLog;
|
1031
1173
|
params.fParams = fParams;
|
1032
1174
|
ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,
|
1033
1175
|
ZSTDcrp_noMemset, zbuff);
|
1176
|
+
assert(dstCCtx->appliedParams.cParams.windowLog == srcCCtx->appliedParams.cParams.windowLog);
|
1177
|
+
assert(dstCCtx->appliedParams.cParams.strategy == srcCCtx->appliedParams.cParams.strategy);
|
1178
|
+
assert(dstCCtx->appliedParams.cParams.hashLog == srcCCtx->appliedParams.cParams.hashLog);
|
1179
|
+
assert(dstCCtx->appliedParams.cParams.chainLog == srcCCtx->appliedParams.cParams.chainLog);
|
1180
|
+
assert(dstCCtx->blockState.matchState.hashLog3 == srcCCtx->blockState.matchState.hashLog3);
|
1034
1181
|
}
|
1035
1182
|
|
1036
1183
|
/* copy tables */
|
1037
1184
|
{ size_t const chainSize = (srcCCtx->appliedParams.cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog);
|
1038
1185
|
size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog;
|
1039
|
-
size_t const h3Size = (size_t)1 << srcCCtx->hashLog3;
|
1186
|
+
size_t const h3Size = (size_t)1 << srcCCtx->blockState.matchState.hashLog3;
|
1040
1187
|
size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
|
1041
|
-
assert((U32*)dstCCtx->chainTable == (U32*)dstCCtx->hashTable + hSize); /* chainTable must follow hashTable */
|
1042
|
-
assert((U32*)dstCCtx->hashTable3 == (U32*)dstCCtx->chainTable + chainSize);
|
1043
|
-
memcpy(dstCCtx->hashTable, srcCCtx->hashTable, tableSpace); /* presumes all tables follow each other */
|
1188
|
+
assert((U32*)dstCCtx->blockState.matchState.chainTable == (U32*)dstCCtx->blockState.matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
1189
|
+
assert((U32*)dstCCtx->blockState.matchState.hashTable3 == (U32*)dstCCtx->blockState.matchState.chainTable + chainSize);
|
1190
|
+
memcpy(dstCCtx->blockState.matchState.hashTable, srcCCtx->blockState.matchState.hashTable, tableSpace); /* presumes all tables follow each other */
|
1044
1191
|
}
|
1045
1192
|
|
1046
1193
|
/* copy dictionary offsets */
|
1047
|
-
dstCCtx->nextToUpdate = srcCCtx->nextToUpdate;
|
1048
|
-
dstCCtx->nextToUpdate3= srcCCtx->nextToUpdate3;
|
1049
|
-
dstCCtx->nextSrc = srcCCtx->nextSrc;
|
1050
|
-
dstCCtx->base = srcCCtx->base;
|
1051
|
-
dstCCtx->dictBase = srcCCtx->dictBase;
|
1052
|
-
dstCCtx->dictLimit = srcCCtx->dictLimit;
|
1053
|
-
dstCCtx->lowLimit = srcCCtx->lowLimit;
|
1054
|
-
dstCCtx->loadedDictEnd= srcCCtx->loadedDictEnd;
|
1055
|
-
dstCCtx->dictID = srcCCtx->dictID;
|
1056
|
-
|
1057
|
-
/* copy entropy tables */
|
1058
|
-
memcpy(dstCCtx->entropy, srcCCtx->entropy, sizeof(ZSTD_entropyCTables_t));
|
1059
|
-
/* copy repcodes */
|
1060
1194
|
{
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1195
|
+
ZSTD_matchState_t const* srcMatchState = &srcCCtx->blockState.matchState;
|
1196
|
+
ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;
|
1197
|
+
dstMatchState->window = srcMatchState->window;
|
1198
|
+
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
1199
|
+
dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
|
1200
|
+
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
|
1064
1201
|
}
|
1202
|
+
dstCCtx->dictID = srcCCtx->dictID;
|
1203
|
+
|
1204
|
+
/* copy block state */
|
1205
|
+
memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock));
|
1065
1206
|
|
1066
1207
|
return 0;
|
1067
1208
|
}
|
@@ -1080,51 +1221,69 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long
|
|
1080
1221
|
fParams.contentSizeFlag = (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN);
|
1081
1222
|
|
1082
1223
|
return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx,
|
1083
|
-
|
1224
|
+
fParams, pledgedSrcSize,
|
1084
1225
|
zbuff);
|
1085
1226
|
}
|
1086
1227
|
|
1087
1228
|
|
1229
|
+
#define ZSTD_ROWSIZE 16
|
1088
1230
|
/*! ZSTD_reduceTable() :
|
1089
|
-
* reduce table indexes by `reducerValue
|
1090
|
-
|
1231
|
+
* reduce table indexes by `reducerValue`, or squash to zero.
|
1232
|
+
* PreserveMark preserves "unsorted mark" for btlazy2 strategy.
|
1233
|
+
* It must be set to a clear 0/1 value, to remove branch during inlining.
|
1234
|
+
* Presume table size is a multiple of ZSTD_ROWSIZE
|
1235
|
+
* to help auto-vectorization */
|
1236
|
+
FORCE_INLINE_TEMPLATE void
|
1237
|
+
ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerValue, int const preserveMark)
|
1238
|
+
{
|
1239
|
+
int const nbRows = (int)size / ZSTD_ROWSIZE;
|
1240
|
+
int cellNb = 0;
|
1241
|
+
int rowNb;
|
1242
|
+
assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */
|
1243
|
+
assert(size < (1U<<31)); /* can be casted to int */
|
1244
|
+
for (rowNb=0 ; rowNb < nbRows ; rowNb++) {
|
1245
|
+
int column;
|
1246
|
+
for (column=0; column<ZSTD_ROWSIZE; column++) {
|
1247
|
+
if (preserveMark) {
|
1248
|
+
U32 const adder = (table[cellNb] == ZSTD_DUBT_UNSORTED_MARK) ? reducerValue : 0;
|
1249
|
+
table[cellNb] += adder;
|
1250
|
+
}
|
1251
|
+
if (table[cellNb] < reducerValue) table[cellNb] = 0;
|
1252
|
+
else table[cellNb] -= reducerValue;
|
1253
|
+
cellNb++;
|
1254
|
+
} }
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
static void ZSTD_reduceTable(U32* const table, U32 const size, U32 const reducerValue)
|
1091
1258
|
{
|
1092
|
-
|
1093
|
-
for (u=0 ; u < size ; u++) {
|
1094
|
-
if (table[u] < reducerValue) table[u] = 0;
|
1095
|
-
else table[u] -= reducerValue;
|
1096
|
-
}
|
1259
|
+
ZSTD_reduceTable_internal(table, size, reducerValue, 0);
|
1097
1260
|
}
|
1098
1261
|
|
1099
|
-
|
1100
|
-
* reduce table indexes by `reducerValue` */
|
1101
|
-
static void ZSTD_ldm_reduceTable(ldmEntry_t* const table, U32 const size,
|
1102
|
-
U32 const reducerValue)
|
1262
|
+
static void ZSTD_reduceTable_btlazy2(U32* const table, U32 const size, U32 const reducerValue)
|
1103
1263
|
{
|
1104
|
-
|
1105
|
-
for (u = 0; u < size; u++) {
|
1106
|
-
if (table[u].offset < reducerValue) table[u].offset = 0;
|
1107
|
-
else table[u].offset -= reducerValue;
|
1108
|
-
}
|
1264
|
+
ZSTD_reduceTable_internal(table, size, reducerValue, 1);
|
1109
1265
|
}
|
1110
1266
|
|
1111
1267
|
/*! ZSTD_reduceIndex() :
|
1112
1268
|
* rescale all indexes to avoid future overflow (indexes are U32) */
|
1113
1269
|
static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
|
1114
1270
|
{
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
ZSTD_reduceTable(zc->chainTable, chainSize, reducerValue); }
|
1271
|
+
ZSTD_matchState_t* const ms = &zc->blockState.matchState;
|
1272
|
+
{ U32 const hSize = (U32)1 << zc->appliedParams.cParams.hashLog;
|
1273
|
+
ZSTD_reduceTable(ms->hashTable, hSize, reducerValue);
|
1274
|
+
}
|
1120
1275
|
|
1121
|
-
|
1122
|
-
|
1276
|
+
if (zc->appliedParams.cParams.strategy != ZSTD_fast) {
|
1277
|
+
U32 const chainSize = (U32)1 << zc->appliedParams.cParams.chainLog;
|
1278
|
+
if (zc->appliedParams.cParams.strategy == ZSTD_btlazy2)
|
1279
|
+
ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue);
|
1280
|
+
else
|
1281
|
+
ZSTD_reduceTable(ms->chainTable, chainSize, reducerValue);
|
1282
|
+
}
|
1123
1283
|
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
}
|
1284
|
+
if (ms->hashLog3) {
|
1285
|
+
U32 const h3Size = (U32)1 << ms->hashLog3;
|
1286
|
+
ZSTD_reduceTable(ms->hashTable3, h3Size, reducerValue);
|
1128
1287
|
}
|
1129
1288
|
}
|
1130
1289
|
|
@@ -1199,10 +1358,12 @@ static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, cons
|
|
1199
1358
|
|
1200
1359
|
static size_t ZSTD_minGain(size_t srcSize) { return (srcSize >> 6) + 2; }
|
1201
1360
|
|
1202
|
-
static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t *
|
1203
|
-
|
1361
|
+
static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t const* prevEntropy,
|
1362
|
+
ZSTD_entropyCTables_t* nextEntropy,
|
1363
|
+
ZSTD_strategy strategy, int disableLiteralCompression,
|
1204
1364
|
void* dst, size_t dstCapacity,
|
1205
|
-
const void* src, size_t srcSize
|
1365
|
+
const void* src, size_t srcSize,
|
1366
|
+
U32* workspace, const int bmi2)
|
1206
1367
|
{
|
1207
1368
|
size_t const minGain = ZSTD_minGain(srcSize);
|
1208
1369
|
size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
|
@@ -1211,34 +1372,51 @@ static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t * entropy,
|
|
1211
1372
|
symbolEncodingType_e hType = set_compressed;
|
1212
1373
|
size_t cLitSize;
|
1213
1374
|
|
1375
|
+
DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i)",
|
1376
|
+
disableLiteralCompression);
|
1377
|
+
|
1378
|
+
/* Prepare nextEntropy assuming reusing the existing table */
|
1379
|
+
nextEntropy->hufCTable_repeatMode = prevEntropy->hufCTable_repeatMode;
|
1380
|
+
memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable,
|
1381
|
+
sizeof(prevEntropy->hufCTable));
|
1382
|
+
|
1383
|
+
if (disableLiteralCompression)
|
1384
|
+
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
1214
1385
|
|
1215
1386
|
/* small ? don't even attempt compression (speed opt) */
|
1216
|
-
# define
|
1217
|
-
{ size_t const minLitSize =
|
1387
|
+
# define COMPRESS_LITERALS_SIZE_MIN 63
|
1388
|
+
{ size_t const minLitSize = (prevEntropy->hufCTable_repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
|
1218
1389
|
if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
1219
1390
|
}
|
1220
1391
|
|
1221
1392
|
if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
|
1222
|
-
{ HUF_repeat repeat =
|
1393
|
+
{ HUF_repeat repeat = prevEntropy->hufCTable_repeatMode;
|
1223
1394
|
int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
|
1224
1395
|
if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
|
1225
1396
|
cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
|
1226
|
-
|
1397
|
+
workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextEntropy->hufCTable, &repeat, preferRepeat, bmi2)
|
1227
1398
|
: HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
|
1228
|
-
|
1229
|
-
if (repeat != HUF_repeat_none) {
|
1230
|
-
|
1399
|
+
workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextEntropy->hufCTable, &repeat, preferRepeat, bmi2);
|
1400
|
+
if (repeat != HUF_repeat_none) {
|
1401
|
+
/* reused the existing table */
|
1402
|
+
hType = set_repeat;
|
1403
|
+
}
|
1231
1404
|
}
|
1232
1405
|
|
1233
1406
|
if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
|
1234
|
-
|
1407
|
+
memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable, sizeof(prevEntropy->hufCTable));
|
1235
1408
|
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
1236
1409
|
}
|
1237
1410
|
if (cLitSize==1) {
|
1238
|
-
|
1411
|
+
memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable, sizeof(prevEntropy->hufCTable));
|
1239
1412
|
return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
|
1240
1413
|
}
|
1241
1414
|
|
1415
|
+
if (hType == set_compressed) {
|
1416
|
+
/* using a newly constructed table */
|
1417
|
+
nextEntropy->hufCTable_repeatMode = HUF_repeat_check;
|
1418
|
+
}
|
1419
|
+
|
1242
1420
|
/* Build header */
|
1243
1421
|
switch(lhSize)
|
1244
1422
|
{
|
@@ -1332,10 +1510,11 @@ symbolEncodingType_e ZSTD_selectEncodingType(
|
|
1332
1510
|
|
1333
1511
|
MEM_STATIC
|
1334
1512
|
size_t ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
1335
|
-
FSE_CTable*
|
1513
|
+
FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
|
1336
1514
|
U32* count, U32 max,
|
1337
1515
|
BYTE const* codeTable, size_t nbSeq,
|
1338
1516
|
S16 const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
|
1517
|
+
FSE_CTable const* prevCTable, size_t prevCTableSize,
|
1339
1518
|
void* workspace, size_t workspaceSize)
|
1340
1519
|
{
|
1341
1520
|
BYTE* op = (BYTE*)dst;
|
@@ -1344,12 +1523,13 @@ size_t ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
|
1344
1523
|
switch (type) {
|
1345
1524
|
case set_rle:
|
1346
1525
|
*op = codeTable[0];
|
1347
|
-
CHECK_F(FSE_buildCTable_rle(
|
1526
|
+
CHECK_F(FSE_buildCTable_rle(nextCTable, (BYTE)max));
|
1348
1527
|
return 1;
|
1349
1528
|
case set_repeat:
|
1529
|
+
memcpy(nextCTable, prevCTable, prevCTableSize);
|
1350
1530
|
return 0;
|
1351
1531
|
case set_basic:
|
1352
|
-
CHECK_F(FSE_buildCTable_wksp(
|
1532
|
+
CHECK_F(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, workspace, workspaceSize)); /* note : could be pre-calculated */
|
1353
1533
|
return 0;
|
1354
1534
|
case set_compressed: {
|
1355
1535
|
S16 norm[MaxSeq + 1];
|
@@ -1363,7 +1543,7 @@ size_t ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
|
1363
1543
|
CHECK_F(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max));
|
1364
1544
|
{ size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
|
1365
1545
|
if (FSE_isError(NCountSize)) return NCountSize;
|
1366
|
-
CHECK_F(FSE_buildCTable_wksp(
|
1546
|
+
CHECK_F(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, workspace, workspaceSize));
|
1367
1547
|
return NCountSize;
|
1368
1548
|
}
|
1369
1549
|
}
|
@@ -1371,8 +1551,8 @@ size_t ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
|
1371
1551
|
}
|
1372
1552
|
}
|
1373
1553
|
|
1374
|
-
|
1375
|
-
|
1554
|
+
FORCE_INLINE_TEMPLATE size_t
|
1555
|
+
ZSTD_encodeSequences_body(
|
1376
1556
|
void* dst, size_t dstCapacity,
|
1377
1557
|
FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
|
1378
1558
|
FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
|
@@ -1419,7 +1599,8 @@ size_t ZSTD_encodeSequences(
|
|
1419
1599
|
DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
|
1420
1600
|
sequences[n].litLength,
|
1421
1601
|
sequences[n].matchLength + MINMATCH,
|
1422
|
-
sequences[n].offset);
|
1602
|
+
sequences[n].offset);
|
1603
|
+
/* 32b*/ /* 64b*/
|
1423
1604
|
/* (7)*/ /* (7)*/
|
1424
1605
|
FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
|
1425
1606
|
FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
|
@@ -1445,8 +1626,11 @@ size_t ZSTD_encodeSequences(
|
|
1445
1626
|
BIT_flushBits(&blockStream); /* (7)*/
|
1446
1627
|
} }
|
1447
1628
|
|
1629
|
+
DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog);
|
1448
1630
|
FSE_flushCState(&blockStream, &stateMatchLength);
|
1631
|
+
DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog);
|
1449
1632
|
FSE_flushCState(&blockStream, &stateOffsetBits);
|
1633
|
+
DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog);
|
1450
1634
|
FSE_flushCState(&blockStream, &stateLitLength);
|
1451
1635
|
|
1452
1636
|
{ size_t const streamSize = BIT_closeCStream(&blockStream);
|
@@ -1455,16 +1639,77 @@ size_t ZSTD_encodeSequences(
|
|
1455
1639
|
}
|
1456
1640
|
}
|
1457
1641
|
|
1642
|
+
static size_t
|
1643
|
+
ZSTD_encodeSequences_default(
|
1644
|
+
void* dst, size_t dstCapacity,
|
1645
|
+
FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
|
1646
|
+
FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
|
1647
|
+
FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
|
1648
|
+
seqDef const* sequences, size_t nbSeq, int longOffsets)
|
1649
|
+
{
|
1650
|
+
return ZSTD_encodeSequences_body(dst, dstCapacity,
|
1651
|
+
CTable_MatchLength, mlCodeTable,
|
1652
|
+
CTable_OffsetBits, ofCodeTable,
|
1653
|
+
CTable_LitLength, llCodeTable,
|
1654
|
+
sequences, nbSeq, longOffsets);
|
1655
|
+
}
|
1656
|
+
|
1657
|
+
|
1658
|
+
#if DYNAMIC_BMI2
|
1659
|
+
|
1660
|
+
static TARGET_ATTRIBUTE("bmi2") size_t
|
1661
|
+
ZSTD_encodeSequences_bmi2(
|
1662
|
+
void* dst, size_t dstCapacity,
|
1663
|
+
FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
|
1664
|
+
FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
|
1665
|
+
FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
|
1666
|
+
seqDef const* sequences, size_t nbSeq, int longOffsets)
|
1667
|
+
{
|
1668
|
+
return ZSTD_encodeSequences_body(dst, dstCapacity,
|
1669
|
+
CTable_MatchLength, mlCodeTable,
|
1670
|
+
CTable_OffsetBits, ofCodeTable,
|
1671
|
+
CTable_LitLength, llCodeTable,
|
1672
|
+
sequences, nbSeq, longOffsets);
|
1673
|
+
}
|
1674
|
+
|
1675
|
+
#endif
|
1676
|
+
|
1677
|
+
size_t ZSTD_encodeSequences(
|
1678
|
+
void* dst, size_t dstCapacity,
|
1679
|
+
FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
|
1680
|
+
FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
|
1681
|
+
FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
|
1682
|
+
seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
|
1683
|
+
{
|
1684
|
+
#if DYNAMIC_BMI2
|
1685
|
+
if (bmi2) {
|
1686
|
+
return ZSTD_encodeSequences_bmi2(dst, dstCapacity,
|
1687
|
+
CTable_MatchLength, mlCodeTable,
|
1688
|
+
CTable_OffsetBits, ofCodeTable,
|
1689
|
+
CTable_LitLength, llCodeTable,
|
1690
|
+
sequences, nbSeq, longOffsets);
|
1691
|
+
}
|
1692
|
+
#endif
|
1693
|
+
(void)bmi2;
|
1694
|
+
return ZSTD_encodeSequences_default(dst, dstCapacity,
|
1695
|
+
CTable_MatchLength, mlCodeTable,
|
1696
|
+
CTable_OffsetBits, ofCodeTable,
|
1697
|
+
CTable_LitLength, llCodeTable,
|
1698
|
+
sequences, nbSeq, longOffsets);
|
1699
|
+
}
|
1700
|
+
|
1458
1701
|
MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
1459
|
-
ZSTD_entropyCTables_t*
|
1460
|
-
|
1461
|
-
|
1702
|
+
ZSTD_entropyCTables_t const* prevEntropy,
|
1703
|
+
ZSTD_entropyCTables_t* nextEntropy,
|
1704
|
+
ZSTD_CCtx_params const* cctxParams,
|
1705
|
+
void* dst, size_t dstCapacity, U32* workspace,
|
1706
|
+
const int bmi2)
|
1462
1707
|
{
|
1463
|
-
const int longOffsets = cParams
|
1708
|
+
const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
|
1464
1709
|
U32 count[MaxSeq+1];
|
1465
|
-
FSE_CTable* CTable_LitLength =
|
1466
|
-
FSE_CTable* CTable_OffsetBits =
|
1467
|
-
FSE_CTable* CTable_MatchLength =
|
1710
|
+
FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
|
1711
|
+
FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
|
1712
|
+
FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
|
1468
1713
|
U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
|
1469
1714
|
const seqDef* const sequences = seqStorePtr->sequencesStart;
|
1470
1715
|
const BYTE* const ofCodeTable = seqStorePtr->ofCode;
|
@@ -1476,13 +1721,17 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1476
1721
|
size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
|
1477
1722
|
BYTE* seqHead;
|
1478
1723
|
|
1479
|
-
ZSTD_STATIC_ASSERT(
|
1724
|
+
ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
|
1480
1725
|
|
1481
1726
|
/* Compress literals */
|
1482
1727
|
{ const BYTE* const literals = seqStorePtr->litStart;
|
1483
1728
|
size_t const litSize = seqStorePtr->lit - literals;
|
1484
1729
|
size_t const cSize = ZSTD_compressLiterals(
|
1485
|
-
|
1730
|
+
prevEntropy, nextEntropy,
|
1731
|
+
cctxParams->cParams.strategy, cctxParams->disableLiteralCompression,
|
1732
|
+
op, dstCapacity,
|
1733
|
+
literals, litSize,
|
1734
|
+
workspace, bmi2);
|
1486
1735
|
if (ZSTD_isError(cSize))
|
1487
1736
|
return cSize;
|
1488
1737
|
assert(cSize <= dstCapacity);
|
@@ -1497,7 +1746,15 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1497
1746
|
op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
|
1498
1747
|
else
|
1499
1748
|
op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
|
1500
|
-
if (nbSeq==0)
|
1749
|
+
if (nbSeq==0) {
|
1750
|
+
memcpy(nextEntropy->litlengthCTable, prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable));
|
1751
|
+
nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
|
1752
|
+
memcpy(nextEntropy->offcodeCTable, prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable));
|
1753
|
+
nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
|
1754
|
+
memcpy(nextEntropy->matchlengthCTable, prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable));
|
1755
|
+
nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
|
1756
|
+
return op - ostart;
|
1757
|
+
}
|
1501
1758
|
|
1502
1759
|
/* seqHead : flags for FSE encoding type */
|
1503
1760
|
seqHead = op++;
|
@@ -1506,36 +1763,42 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1506
1763
|
ZSTD_seqToCodes(seqStorePtr);
|
1507
1764
|
/* build CTable for Literal Lengths */
|
1508
1765
|
{ U32 max = MaxLL;
|
1509
|
-
size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq,
|
1766
|
+
size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace);
|
1510
1767
|
DEBUGLOG(5, "Building LL table");
|
1511
|
-
|
1768
|
+
nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
|
1769
|
+
LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode, mostFrequent, nbSeq, LL_defaultNormLog, ZSTD_defaultAllowed);
|
1512
1770
|
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
|
1513
1771
|
count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
|
1514
|
-
|
1772
|
+
prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable),
|
1773
|
+
workspace, HUF_WORKSPACE_SIZE);
|
1515
1774
|
if (ZSTD_isError(countSize)) return countSize;
|
1516
1775
|
op += countSize;
|
1517
1776
|
} }
|
1518
1777
|
/* build CTable for Offsets */
|
1519
1778
|
{ U32 max = MaxOff;
|
1520
|
-
size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq,
|
1779
|
+
size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace);
|
1521
1780
|
/* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
|
1522
1781
|
ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
|
1523
1782
|
DEBUGLOG(5, "Building OF table");
|
1524
|
-
|
1783
|
+
nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
|
1784
|
+
Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode, mostFrequent, nbSeq, OF_defaultNormLog, defaultPolicy);
|
1525
1785
|
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
|
1526
1786
|
count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
|
1527
|
-
|
1787
|
+
prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable),
|
1788
|
+
workspace, HUF_WORKSPACE_SIZE);
|
1528
1789
|
if (ZSTD_isError(countSize)) return countSize;
|
1529
1790
|
op += countSize;
|
1530
1791
|
} }
|
1531
1792
|
/* build CTable for MatchLengths */
|
1532
1793
|
{ U32 max = MaxML;
|
1533
|
-
size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq,
|
1794
|
+
size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace);
|
1534
1795
|
DEBUGLOG(5, "Building ML table");
|
1535
|
-
|
1796
|
+
nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
|
1797
|
+
MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode, mostFrequent, nbSeq, ML_defaultNormLog, ZSTD_defaultAllowed);
|
1536
1798
|
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
|
1537
1799
|
count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
|
1538
|
-
|
1800
|
+
prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable),
|
1801
|
+
workspace, HUF_WORKSPACE_SIZE);
|
1539
1802
|
if (ZSTD_isError(countSize)) return countSize;
|
1540
1803
|
op += countSize;
|
1541
1804
|
} }
|
@@ -1548,7 +1811,7 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1548
1811
|
CTable_OffsetBits, ofCodeTable,
|
1549
1812
|
CTable_LitLength, llCodeTable,
|
1550
1813
|
sequences, nbSeq,
|
1551
|
-
longOffsets);
|
1814
|
+
longOffsets, bmi2);
|
1552
1815
|
if (ZSTD_isError(bitstreamSize)) return bitstreamSize;
|
1553
1816
|
op += bitstreamSize;
|
1554
1817
|
}
|
@@ -1557,48 +1820,40 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1557
1820
|
}
|
1558
1821
|
|
1559
1822
|
MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
|
1560
|
-
ZSTD_entropyCTables_t*
|
1561
|
-
|
1823
|
+
ZSTD_entropyCTables_t const* prevEntropy,
|
1824
|
+
ZSTD_entropyCTables_t* nextEntropy,
|
1825
|
+
ZSTD_CCtx_params const* cctxParams,
|
1562
1826
|
void* dst, size_t dstCapacity,
|
1563
|
-
size_t srcSize)
|
1827
|
+
size_t srcSize, U32* workspace, int bmi2)
|
1564
1828
|
{
|
1565
|
-
size_t const cSize = ZSTD_compressSequences_internal(
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
* be compressible, so fall back to
|
1829
|
+
size_t const cSize = ZSTD_compressSequences_internal(
|
1830
|
+
seqStorePtr, prevEntropy, nextEntropy, cctxParams, dst, dstCapacity,
|
1831
|
+
workspace, bmi2);
|
1832
|
+
/* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
|
1833
|
+
* Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
|
1570
1834
|
*/
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1835
|
+
if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))
|
1836
|
+
return 0; /* block not compressed */
|
1837
|
+
if (ZSTD_isError(cSize)) return cSize;
|
1838
|
+
|
1839
|
+
/* Check compressibility */
|
1840
|
+
{ size_t const maxCSize = srcSize - ZSTD_minGain(srcSize); /* note : fixed formula, maybe should depend on compression level, or strategy */
|
1841
|
+
if (cSize >= maxCSize) return 0; /* block not compressed */
|
1842
|
+
}
|
1843
|
+
|
1574
1844
|
/* We check that dictionaries have offset codes available for the first
|
1575
1845
|
* block. After the first block, the offcode table might not have large
|
1576
1846
|
* enough codes to represent the offsets in the data.
|
1577
1847
|
*/
|
1578
|
-
if (
|
1579
|
-
|
1580
|
-
|
1581
|
-
/* Check compressibility */
|
1582
|
-
{ size_t const minGain = ZSTD_minGain(srcSize); /* note : fixed formula, maybe should depend on compression level, or strategy */
|
1583
|
-
size_t const maxCSize = srcSize - minGain;
|
1584
|
-
if (cSize >= maxCSize || uncompressibleError) {
|
1585
|
-
entropy->hufCTable_repeatMode = HUF_repeat_none;
|
1586
|
-
entropy->offcode_repeatMode = FSE_repeat_none;
|
1587
|
-
entropy->matchlength_repeatMode = FSE_repeat_none;
|
1588
|
-
entropy->litlength_repeatMode = FSE_repeat_none;
|
1589
|
-
return 0; /* block not compressed */
|
1590
|
-
} }
|
1591
|
-
assert(!ZSTD_isError(cSize));
|
1848
|
+
if (nextEntropy->offcode_repeatMode == FSE_repeat_valid)
|
1849
|
+
nextEntropy->offcode_repeatMode = FSE_repeat_check;
|
1592
1850
|
|
1593
|
-
/* block is compressed => confirm repcodes in history */
|
1594
|
-
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) seqStorePtr->rep[i] = seqStorePtr->repToConfirm[i]; }
|
1595
1851
|
return cSize;
|
1596
1852
|
}
|
1597
1853
|
|
1598
1854
|
/* ZSTD_selectBlockCompressor() :
|
1599
1855
|
* Not static, but internal use only (used by long distance matcher)
|
1600
1856
|
* assumption : strat is a valid strategy */
|
1601
|
-
typedef size_t (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize);
|
1602
1857
|
ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
|
1603
1858
|
{
|
1604
1859
|
static const ZSTD_blockCompressor blockCompressor[2][(unsigned)ZSTD_btultra+1] = {
|
@@ -1632,32 +1887,83 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
|
|
1632
1887
|
ssPtr->longLengthID = 0;
|
1633
1888
|
}
|
1634
1889
|
|
1635
|
-
static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
1890
|
+
static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
1891
|
+
void* dst, size_t dstCapacity,
|
1892
|
+
const void* src, size_t srcSize)
|
1636
1893
|
{
|
1637
|
-
|
1638
|
-
|
1894
|
+
ZSTD_matchState_t* const ms = &zc->blockState.matchState;
|
1895
|
+
DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
|
1896
|
+
(U32)dstCapacity, ms->window.dictLimit, ms->nextToUpdate);
|
1897
|
+
if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
|
1898
|
+
ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.searchLength);
|
1639
1899
|
return 0; /* don't even attempt compression below a certain srcSize */
|
1900
|
+
}
|
1640
1901
|
ZSTD_resetSeqStore(&(zc->seqStore));
|
1641
1902
|
|
1642
1903
|
/* limited update after a very long match */
|
1643
|
-
{ const BYTE* const base =
|
1904
|
+
{ const BYTE* const base = ms->window.base;
|
1644
1905
|
const BYTE* const istart = (const BYTE*)src;
|
1645
1906
|
const U32 current = (U32)(istart-base);
|
1646
|
-
if (current >
|
1647
|
-
|
1907
|
+
if (current > ms->nextToUpdate + 384)
|
1908
|
+
ms->nextToUpdate = current - MIN(192, (U32)(current - ms->nextToUpdate - 384));
|
1648
1909
|
}
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1910
|
+
|
1911
|
+
/* select and store sequences */
|
1912
|
+
{ U32 const extDict = ZSTD_window_hasExtDict(ms->window);
|
1913
|
+
size_t lastLLSize;
|
1914
|
+
{ int i;
|
1915
|
+
for (i = 0; i < ZSTD_REP_NUM; ++i)
|
1916
|
+
zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i];
|
1917
|
+
}
|
1918
|
+
if (zc->externSeqStore.pos < zc->externSeqStore.size) {
|
1919
|
+
assert(!zc->appliedParams.ldmParams.enableLdm);
|
1920
|
+
/* Updates ldmSeqStore.pos */
|
1921
|
+
lastLLSize =
|
1922
|
+
ZSTD_ldm_blockCompress(&zc->externSeqStore,
|
1923
|
+
ms, &zc->seqStore,
|
1924
|
+
zc->blockState.nextCBlock->rep,
|
1925
|
+
&zc->appliedParams.cParams,
|
1926
|
+
src, srcSize, extDict);
|
1927
|
+
assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
|
1928
|
+
} else if (zc->appliedParams.ldmParams.enableLdm) {
|
1929
|
+
rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0};
|
1930
|
+
|
1931
|
+
ldmSeqStore.seq = zc->ldmSequences;
|
1932
|
+
ldmSeqStore.capacity = zc->maxNbLdmSequences;
|
1933
|
+
/* Updates ldmSeqStore.size */
|
1934
|
+
CHECK_F(ZSTD_ldm_generateSequences(&zc->ldmState, &ldmSeqStore,
|
1935
|
+
&zc->appliedParams.ldmParams,
|
1936
|
+
src, srcSize));
|
1937
|
+
/* Updates ldmSeqStore.pos */
|
1938
|
+
lastLLSize =
|
1939
|
+
ZSTD_ldm_blockCompress(&ldmSeqStore,
|
1940
|
+
ms, &zc->seqStore,
|
1941
|
+
zc->blockState.nextCBlock->rep,
|
1942
|
+
&zc->appliedParams.cParams,
|
1943
|
+
src, srcSize, extDict);
|
1944
|
+
assert(ldmSeqStore.pos == ldmSeqStore.size);
|
1945
|
+
} else { /* not long range mode */
|
1946
|
+
ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, extDict);
|
1947
|
+
lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, &zc->appliedParams.cParams, src, srcSize);
|
1948
|
+
}
|
1949
|
+
{ const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
|
1950
|
+
ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
|
1951
|
+
} }
|
1952
|
+
|
1953
|
+
/* encode sequences and literals */
|
1954
|
+
{ size_t const cSize = ZSTD_compressSequences(&zc->seqStore,
|
1955
|
+
&zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,
|
1956
|
+
&zc->appliedParams,
|
1957
|
+
dst, dstCapacity,
|
1958
|
+
srcSize, zc->entropyWorkspace, zc->bmi2);
|
1959
|
+
if (ZSTD_isError(cSize) || cSize == 0) return cSize;
|
1960
|
+
/* confirm repcodes and entropy tables */
|
1961
|
+
{ ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;
|
1962
|
+
zc->blockState.prevCBlock = zc->blockState.nextCBlock;
|
1963
|
+
zc->blockState.nextCBlock = tmp;
|
1964
|
+
}
|
1965
|
+
return cSize;
|
1658
1966
|
}
|
1659
|
-
/* encode */
|
1660
|
-
return ZSTD_compressSequences(&zc->seqStore, zc->entropy, &zc->appliedParams.cParams, dst, dstCapacity, srcSize);
|
1661
1967
|
}
|
1662
1968
|
|
1663
1969
|
|
@@ -1686,54 +1992,27 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
|
1686
1992
|
XXH64_update(&cctx->xxhState, src, srcSize);
|
1687
1993
|
|
1688
1994
|
while (remaining) {
|
1995
|
+
ZSTD_matchState_t* const ms = &cctx->blockState.matchState;
|
1689
1996
|
U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
|
1690
1997
|
|
1691
1998
|
if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE)
|
1692
1999
|
return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
|
1693
2000
|
if (remaining < blockSize) blockSize = remaining;
|
1694
2001
|
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
* 1<<windowLog <= newCurrent < 1<<chainLog + 1<<windowLog
|
1699
|
-
*
|
1700
|
-
* current - newCurrent
|
1701
|
-
* > (3<<29 + 1<<windowLog - blockSize) - (1<<windowLog + 1<<chainLog)
|
1702
|
-
* > (3<<29 - blockSize) - (1<<chainLog)
|
1703
|
-
* > (3<<29 - blockSize) - (1<<30) (NOTE: chainLog <= 30)
|
1704
|
-
* > 1<<29 - 1<<17
|
1705
|
-
*
|
1706
|
-
* 2. (ip+blockSize - cctx->base) doesn't overflow:
|
1707
|
-
* In 32 bit mode we limit windowLog to 30 so we don't get
|
1708
|
-
* differences larger than 1<<31-1.
|
1709
|
-
* 3. cctx->lowLimit < 1<<32:
|
1710
|
-
* windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.
|
1711
|
-
*/
|
1712
|
-
if (cctx->lowLimit > (3U<<29)) {
|
1713
|
-
U32 const cycleMask = ((U32)1 << ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy)) - 1;
|
1714
|
-
U32 const current = (U32)(ip - cctx->base);
|
1715
|
-
U32 const newCurrent = (current & cycleMask) + ((U32)1 << cctx->appliedParams.cParams.windowLog);
|
1716
|
-
U32 const correction = current - newCurrent;
|
2002
|
+
if (ZSTD_window_needOverflowCorrection(ms->window, ip + blockSize)) {
|
2003
|
+
U32 const cycleLog = ZSTD_cycleLog(cctx->appliedParams.cParams.chainLog, cctx->appliedParams.cParams.strategy);
|
2004
|
+
U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip);
|
1717
2005
|
ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);
|
1718
2006
|
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);
|
1719
2007
|
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
|
1720
|
-
|
1721
|
-
assert(correction > 1<<28); /* Loose bound, should be about 1<<29 */
|
2008
|
+
|
1722
2009
|
ZSTD_reduceIndex(cctx, correction);
|
1723
|
-
|
1724
|
-
|
1725
|
-
|
1726
|
-
cctx->dictLimit -= correction;
|
1727
|
-
if (cctx->nextToUpdate < correction) cctx->nextToUpdate = 0;
|
1728
|
-
else cctx->nextToUpdate -= correction;
|
1729
|
-
DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x\n", correction, cctx->lowLimit);
|
1730
|
-
}
|
1731
|
-
/* enforce maxDist */
|
1732
|
-
if ((U32)(ip+blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) {
|
1733
|
-
U32 const newLowLimit = (U32)(ip+blockSize - cctx->base) - maxDist;
|
1734
|
-
if (cctx->lowLimit < newLowLimit) cctx->lowLimit = newLowLimit;
|
1735
|
-
if (cctx->dictLimit < cctx->lowLimit) cctx->dictLimit = cctx->lowLimit;
|
2010
|
+
if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
|
2011
|
+
else ms->nextToUpdate -= correction;
|
2012
|
+
ms->loadedDictEnd = 0;
|
1736
2013
|
}
|
2014
|
+
ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd);
|
2015
|
+
if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
|
1737
2016
|
|
1738
2017
|
{ size_t cSize = ZSTD_compressBlock_internal(cctx,
|
1739
2018
|
op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,
|
@@ -1810,16 +2089,44 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
|
1810
2089
|
return pos;
|
1811
2090
|
}
|
1812
2091
|
|
2092
|
+
/* ZSTD_writeLastEmptyBlock() :
|
2093
|
+
* output an empty Block with end-of-frame mark to complete a frame
|
2094
|
+
* @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h))
|
2095
|
+
* or an error code if `dstCapcity` is too small (<ZSTD_blockHeaderSize)
|
2096
|
+
*/
|
2097
|
+
size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity)
|
2098
|
+
{
|
2099
|
+
if (dstCapacity < ZSTD_blockHeaderSize) return ERROR(dstSize_tooSmall);
|
2100
|
+
{ U32 const cBlockHeader24 = 1 /*lastBlock*/ + (((U32)bt_raw)<<1); /* 0 size */
|
2101
|
+
MEM_writeLE24(dst, cBlockHeader24);
|
2102
|
+
return ZSTD_blockHeaderSize;
|
2103
|
+
}
|
2104
|
+
}
|
2105
|
+
|
2106
|
+
size_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq)
|
2107
|
+
{
|
2108
|
+
if (cctx->stage != ZSTDcs_init)
|
2109
|
+
return ERROR(stage_wrong);
|
2110
|
+
if (cctx->appliedParams.ldmParams.enableLdm)
|
2111
|
+
return ERROR(parameter_unsupported);
|
2112
|
+
cctx->externSeqStore.seq = seq;
|
2113
|
+
cctx->externSeqStore.size = nbSeq;
|
2114
|
+
cctx->externSeqStore.capacity = nbSeq;
|
2115
|
+
cctx->externSeqStore.pos = 0;
|
2116
|
+
return 0;
|
2117
|
+
}
|
2118
|
+
|
1813
2119
|
|
1814
2120
|
static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
1815
2121
|
void* dst, size_t dstCapacity,
|
1816
2122
|
const void* src, size_t srcSize,
|
1817
2123
|
U32 frame, U32 lastFrameChunk)
|
1818
2124
|
{
|
1819
|
-
|
2125
|
+
ZSTD_matchState_t* ms = &cctx->blockState.matchState;
|
1820
2126
|
size_t fhSize = 0;
|
1821
2127
|
|
1822
|
-
DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u",
|
2128
|
+
DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
|
2129
|
+
cctx->stage, (U32)srcSize);
|
1823
2130
|
if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */
|
1824
2131
|
|
1825
2132
|
if (frame && (cctx->stage==ZSTDcs_init)) {
|
@@ -1833,26 +2140,11 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
1833
2140
|
|
1834
2141
|
if (!srcSize) return fhSize; /* do not generate an empty block if no input */
|
1835
2142
|
|
1836
|
-
|
1837
|
-
|
1838
|
-
/* not contiguous */
|
1839
|
-
size_t const distanceFromBase = (size_t)(cctx->nextSrc - cctx->base);
|
1840
|
-
cctx->lowLimit = cctx->dictLimit;
|
1841
|
-
assert(distanceFromBase == (size_t)(U32)distanceFromBase); /* should never overflow */
|
1842
|
-
cctx->dictLimit = (U32)distanceFromBase;
|
1843
|
-
cctx->dictBase = cctx->base;
|
1844
|
-
cctx->base = ip - distanceFromBase;
|
1845
|
-
cctx->nextToUpdate = cctx->dictLimit;
|
1846
|
-
if (cctx->dictLimit - cctx->lowLimit < HASH_READ_SIZE) cctx->lowLimit = cctx->dictLimit; /* too small extDict */
|
1847
|
-
}
|
1848
|
-
cctx->nextSrc = ip + srcSize;
|
1849
|
-
|
1850
|
-
/* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
|
1851
|
-
if ((ip+srcSize > cctx->dictBase + cctx->lowLimit) & (ip < cctx->dictBase + cctx->dictLimit)) {
|
1852
|
-
ptrdiff_t const highInputIdx = (ip + srcSize) - cctx->dictBase;
|
1853
|
-
U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)cctx->dictLimit) ? cctx->dictLimit : (U32)highInputIdx;
|
1854
|
-
cctx->lowLimit = lowLimitMax;
|
2143
|
+
if (!ZSTD_window_update(&ms->window, src, srcSize)) {
|
2144
|
+
ms->nextToUpdate = ms->window.dictLimit;
|
1855
2145
|
}
|
2146
|
+
if (cctx->appliedParams.ldmParams.enableLdm)
|
2147
|
+
ZSTD_window_update(&cctx->ldmState.window, src, srcSize);
|
1856
2148
|
|
1857
2149
|
DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (U32)cctx->blockSize);
|
1858
2150
|
{ size_t const cSize = frame ?
|
@@ -1860,6 +2152,14 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
1860
2152
|
ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
|
1861
2153
|
if (ZSTD_isError(cSize)) return cSize;
|
1862
2154
|
cctx->consumedSrcSize += srcSize;
|
2155
|
+
cctx->producedCSize += (cSize + fhSize);
|
2156
|
+
if (cctx->appliedParams.fParams.contentSizeFlag) { /* control src size */
|
2157
|
+
if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) {
|
2158
|
+
DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u",
|
2159
|
+
(U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize);
|
2160
|
+
return ERROR(srcSize_wrong);
|
2161
|
+
}
|
2162
|
+
}
|
1863
2163
|
return cSize + fhSize;
|
1864
2164
|
}
|
1865
2165
|
}
|
@@ -1868,14 +2168,15 @@ size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
|
|
1868
2168
|
void* dst, size_t dstCapacity,
|
1869
2169
|
const void* src, size_t srcSize)
|
1870
2170
|
{
|
2171
|
+
DEBUGLOG(5, "ZSTD_compressContinue (srcSize=%u)", (U32)srcSize);
|
1871
2172
|
return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */);
|
1872
2173
|
}
|
1873
2174
|
|
1874
2175
|
|
1875
2176
|
size_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)
|
1876
2177
|
{
|
1877
|
-
ZSTD_compressionParameters const cParams =
|
1878
|
-
|
2178
|
+
ZSTD_compressionParameters const cParams = cctx->appliedParams.cParams;
|
2179
|
+
assert(!ZSTD_checkCParams(cParams));
|
1879
2180
|
return MIN (ZSTD_BLOCKSIZE_MAX, (U32)1 << cParams.windowLog);
|
1880
2181
|
}
|
1881
2182
|
|
@@ -1889,50 +2190,45 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
|
|
1889
2190
|
/*! ZSTD_loadDictionaryContent() :
|
1890
2191
|
* @return : 0, or an error code
|
1891
2192
|
*/
|
1892
|
-
static size_t ZSTD_loadDictionaryContent(
|
2193
|
+
static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const void* src, size_t srcSize)
|
1893
2194
|
{
|
1894
2195
|
const BYTE* const ip = (const BYTE*) src;
|
1895
2196
|
const BYTE* const iend = ip + srcSize;
|
2197
|
+
ZSTD_compressionParameters const* cParams = ¶ms->cParams;
|
1896
2198
|
|
1897
|
-
|
1898
|
-
|
1899
|
-
zc->dictLimit = (U32)(zc->nextSrc - zc->base);
|
1900
|
-
zc->dictBase = zc->base;
|
1901
|
-
zc->base = ip - zc->dictLimit;
|
1902
|
-
zc->nextToUpdate = zc->dictLimit;
|
1903
|
-
zc->loadedDictEnd = zc->appliedParams.forceWindow ? 0 : (U32)(iend - zc->base);
|
2199
|
+
ZSTD_window_update(&ms->window, src, srcSize);
|
2200
|
+
ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);
|
1904
2201
|
|
1905
|
-
zc->nextSrc = iend;
|
1906
2202
|
if (srcSize <= HASH_READ_SIZE) return 0;
|
1907
2203
|
|
1908
|
-
switch(
|
2204
|
+
switch(params->cParams.strategy)
|
1909
2205
|
{
|
1910
2206
|
case ZSTD_fast:
|
1911
|
-
ZSTD_fillHashTable
|
2207
|
+
ZSTD_fillHashTable(ms, cParams, iend);
|
1912
2208
|
break;
|
1913
2209
|
case ZSTD_dfast:
|
1914
|
-
ZSTD_fillDoubleHashTable
|
2210
|
+
ZSTD_fillDoubleHashTable(ms, cParams, iend);
|
1915
2211
|
break;
|
1916
2212
|
|
1917
2213
|
case ZSTD_greedy:
|
1918
2214
|
case ZSTD_lazy:
|
1919
2215
|
case ZSTD_lazy2:
|
1920
2216
|
if (srcSize >= HASH_READ_SIZE)
|
1921
|
-
ZSTD_insertAndFindFirstIndex(
|
2217
|
+
ZSTD_insertAndFindFirstIndex(ms, cParams, iend-HASH_READ_SIZE);
|
1922
2218
|
break;
|
1923
2219
|
|
1924
|
-
case ZSTD_btlazy2:
|
2220
|
+
case ZSTD_btlazy2: /* we want the dictionary table fully sorted */
|
1925
2221
|
case ZSTD_btopt:
|
1926
2222
|
case ZSTD_btultra:
|
1927
2223
|
if (srcSize >= HASH_READ_SIZE)
|
1928
|
-
ZSTD_updateTree(
|
2224
|
+
ZSTD_updateTree(ms, cParams, iend-HASH_READ_SIZE, iend);
|
1929
2225
|
break;
|
1930
2226
|
|
1931
2227
|
default:
|
1932
2228
|
assert(0); /* not possible : not a valid strategy id */
|
1933
2229
|
}
|
1934
2230
|
|
1935
|
-
|
2231
|
+
ms->nextToUpdate = (U32)(iend - ms->window.base);
|
1936
2232
|
return 0;
|
1937
2233
|
}
|
1938
2234
|
|
@@ -1956,25 +2252,26 @@ static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSym
|
|
1956
2252
|
* https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
|
1957
2253
|
*/
|
1958
2254
|
/*! ZSTD_loadZstdDictionary() :
|
1959
|
-
* @return :
|
2255
|
+
* @return : dictID, or an error code
|
1960
2256
|
* assumptions : magic number supposed already checked
|
1961
2257
|
* dictSize supposed > 8
|
1962
2258
|
*/
|
1963
|
-
static size_t ZSTD_loadZstdDictionary(
|
2259
|
+
static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const void* dict, size_t dictSize, void* workspace)
|
1964
2260
|
{
|
1965
2261
|
const BYTE* dictPtr = (const BYTE*)dict;
|
1966
2262
|
const BYTE* const dictEnd = dictPtr + dictSize;
|
1967
2263
|
short offcodeNCount[MaxOff+1];
|
1968
2264
|
unsigned offcodeMaxValue = MaxOff;
|
2265
|
+
size_t dictID;
|
1969
2266
|
|
1970
|
-
ZSTD_STATIC_ASSERT(
|
2267
|
+
ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
|
1971
2268
|
|
1972
2269
|
dictPtr += 4; /* skip magic number */
|
1973
|
-
|
2270
|
+
dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr);
|
1974
2271
|
dictPtr += 4;
|
1975
2272
|
|
1976
2273
|
{ unsigned maxSymbolValue = 255;
|
1977
|
-
size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)
|
2274
|
+
size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.hufCTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr);
|
1978
2275
|
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
1979
2276
|
if (maxSymbolValue < 255) return ERROR(dictionary_corrupted);
|
1980
2277
|
dictPtr += hufHeaderSize;
|
@@ -1985,7 +2282,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
|
|
1985
2282
|
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
1986
2283
|
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
1987
2284
|
/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
|
1988
|
-
CHECK_E( FSE_buildCTable_wksp(
|
2285
|
+
CHECK_E( FSE_buildCTable_wksp(bs->entropy.offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, workspace, HUF_WORKSPACE_SIZE),
|
1989
2286
|
dictionary_corrupted);
|
1990
2287
|
dictPtr += offcodeHeaderSize;
|
1991
2288
|
}
|
@@ -1997,7 +2294,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
|
|
1997
2294
|
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
1998
2295
|
/* Every match length code must have non-zero probability */
|
1999
2296
|
CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
|
2000
|
-
CHECK_E( FSE_buildCTable_wksp(
|
2297
|
+
CHECK_E( FSE_buildCTable_wksp(bs->entropy.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE),
|
2001
2298
|
dictionary_corrupted);
|
2002
2299
|
dictPtr += matchlengthHeaderSize;
|
2003
2300
|
}
|
@@ -2009,15 +2306,15 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
|
|
2009
2306
|
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
2010
2307
|
/* Every literal length code must have non-zero probability */
|
2011
2308
|
CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
|
2012
|
-
CHECK_E( FSE_buildCTable_wksp(
|
2309
|
+
CHECK_E( FSE_buildCTable_wksp(bs->entropy.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE),
|
2013
2310
|
dictionary_corrupted);
|
2014
2311
|
dictPtr += litlengthHeaderSize;
|
2015
2312
|
}
|
2016
2313
|
|
2017
2314
|
if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2315
|
+
bs->rep[0] = MEM_readLE32(dictPtr+0);
|
2316
|
+
bs->rep[1] = MEM_readLE32(dictPtr+4);
|
2317
|
+
bs->rep[2] = MEM_readLE32(dictPtr+8);
|
2021
2318
|
dictPtr += 12;
|
2022
2319
|
|
2023
2320
|
{ size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
|
@@ -2031,50 +2328,55 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t
|
|
2031
2328
|
/* All repCodes must be <= dictContentSize and != 0*/
|
2032
2329
|
{ U32 u;
|
2033
2330
|
for (u=0; u<3; u++) {
|
2034
|
-
if (
|
2035
|
-
if (
|
2331
|
+
if (bs->rep[u] == 0) return ERROR(dictionary_corrupted);
|
2332
|
+
if (bs->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
|
2036
2333
|
} }
|
2037
2334
|
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2335
|
+
bs->entropy.hufCTable_repeatMode = HUF_repeat_valid;
|
2336
|
+
bs->entropy.offcode_repeatMode = FSE_repeat_valid;
|
2337
|
+
bs->entropy.matchlength_repeatMode = FSE_repeat_valid;
|
2338
|
+
bs->entropy.litlength_repeatMode = FSE_repeat_valid;
|
2339
|
+
CHECK_F(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize));
|
2340
|
+
return dictID;
|
2043
2341
|
}
|
2044
2342
|
}
|
2045
2343
|
|
2046
2344
|
/** ZSTD_compress_insertDictionary() :
|
2047
|
-
* @return :
|
2048
|
-
static size_t ZSTD_compress_insertDictionary(
|
2345
|
+
* @return : dictID, or an error code */
|
2346
|
+
static size_t ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matchState_t* ms,
|
2347
|
+
ZSTD_CCtx_params const* params,
|
2049
2348
|
const void* dict, size_t dictSize,
|
2050
|
-
|
2349
|
+
ZSTD_dictContentType_e dictContentType,
|
2350
|
+
void* workspace)
|
2051
2351
|
{
|
2052
2352
|
DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
|
2053
2353
|
if ((dict==NULL) || (dictSize<=8)) return 0;
|
2054
2354
|
|
2355
|
+
ZSTD_reset_compressedBlockState(bs);
|
2356
|
+
|
2055
2357
|
/* dict restricted modes */
|
2056
|
-
if (
|
2057
|
-
return ZSTD_loadDictionaryContent(
|
2358
|
+
if (dictContentType == ZSTD_dct_rawContent)
|
2359
|
+
return ZSTD_loadDictionaryContent(ms, params, dict, dictSize);
|
2058
2360
|
|
2059
2361
|
if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
|
2060
|
-
if (
|
2362
|
+
if (dictContentType == ZSTD_dct_auto) {
|
2061
2363
|
DEBUGLOG(4, "raw content dictionary detected");
|
2062
|
-
return ZSTD_loadDictionaryContent(
|
2364
|
+
return ZSTD_loadDictionaryContent(ms, params, dict, dictSize);
|
2063
2365
|
}
|
2064
|
-
if (
|
2366
|
+
if (dictContentType == ZSTD_dct_fullDict)
|
2065
2367
|
return ERROR(dictionary_wrong);
|
2066
2368
|
assert(0); /* impossible */
|
2067
2369
|
}
|
2068
2370
|
|
2069
2371
|
/* dict as full zstd dictionary */
|
2070
|
-
return ZSTD_loadZstdDictionary(
|
2372
|
+
return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, workspace);
|
2071
2373
|
}
|
2072
2374
|
|
2073
2375
|
/*! ZSTD_compressBegin_internal() :
|
2074
2376
|
* @return : 0, or an error code */
|
2075
2377
|
size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
2076
2378
|
const void* dict, size_t dictSize,
|
2077
|
-
|
2379
|
+
ZSTD_dictContentType_e dictContentType,
|
2078
2380
|
const ZSTD_CDict* cdict,
|
2079
2381
|
ZSTD_CCtx_params params, U64 pledgedSrcSize,
|
2080
2382
|
ZSTD_buffered_policy_e zbuff)
|
@@ -2086,19 +2388,26 @@ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
|
2086
2388
|
|
2087
2389
|
if (cdict && cdict->dictContentSize>0) {
|
2088
2390
|
cctx->requestedParams = params;
|
2089
|
-
return
|
2090
|
-
|
2091
|
-
zbuff);
|
2391
|
+
return ZSTD_resetCCtx_usingCDict(cctx, cdict, params.cParams.windowLog,
|
2392
|
+
params.fParams, pledgedSrcSize, zbuff);
|
2092
2393
|
}
|
2093
2394
|
|
2094
2395
|
CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
2095
2396
|
ZSTDcrp_continue, zbuff) );
|
2096
|
-
|
2397
|
+
{
|
2398
|
+
size_t const dictID = ZSTD_compress_insertDictionary(
|
2399
|
+
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
|
2400
|
+
¶ms, dict, dictSize, dictContentType, cctx->entropyWorkspace);
|
2401
|
+
if (ZSTD_isError(dictID)) return dictID;
|
2402
|
+
assert(dictID <= (size_t)(U32)-1);
|
2403
|
+
cctx->dictID = (U32)dictID;
|
2404
|
+
}
|
2405
|
+
return 0;
|
2097
2406
|
}
|
2098
2407
|
|
2099
2408
|
size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
|
2100
2409
|
const void* dict, size_t dictSize,
|
2101
|
-
|
2410
|
+
ZSTD_dictContentType_e dictContentType,
|
2102
2411
|
const ZSTD_CDict* cdict,
|
2103
2412
|
ZSTD_CCtx_params params,
|
2104
2413
|
unsigned long long pledgedSrcSize)
|
@@ -2107,7 +2416,7 @@ size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
|
|
2107
2416
|
/* compression parameters verification and optimization */
|
2108
2417
|
CHECK_F( ZSTD_checkCParams(params.cParams) );
|
2109
2418
|
return ZSTD_compressBegin_internal(cctx,
|
2110
|
-
dict, dictSize,
|
2419
|
+
dict, dictSize, dictContentType,
|
2111
2420
|
cdict,
|
2112
2421
|
params, pledgedSrcSize,
|
2113
2422
|
ZSTDb_not_buffered);
|
@@ -2122,18 +2431,18 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
|
|
2122
2431
|
ZSTD_CCtx_params const cctxParams =
|
2123
2432
|
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
2124
2433
|
return ZSTD_compressBegin_advanced_internal(cctx,
|
2125
|
-
dict, dictSize,
|
2434
|
+
dict, dictSize, ZSTD_dct_auto,
|
2126
2435
|
NULL /*cdict*/,
|
2127
2436
|
cctxParams, pledgedSrcSize);
|
2128
2437
|
}
|
2129
2438
|
|
2130
2439
|
size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
|
2131
2440
|
{
|
2132
|
-
ZSTD_parameters const params = ZSTD_getParams(compressionLevel,
|
2441
|
+
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);
|
2133
2442
|
ZSTD_CCtx_params const cctxParams =
|
2134
2443
|
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
2135
|
-
DEBUGLOG(4, "ZSTD_compressBegin_usingDict");
|
2136
|
-
return ZSTD_compressBegin_internal(cctx, dict, dictSize,
|
2444
|
+
DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (U32)dictSize);
|
2445
|
+
return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, NULL,
|
2137
2446
|
cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
|
2138
2447
|
}
|
2139
2448
|
|
@@ -2152,7 +2461,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
|
|
2152
2461
|
BYTE* op = ostart;
|
2153
2462
|
size_t fhSize = 0;
|
2154
2463
|
|
2155
|
-
DEBUGLOG(
|
2464
|
+
DEBUGLOG(4, "ZSTD_writeEpilogue");
|
2156
2465
|
if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong); /* init missing */
|
2157
2466
|
|
2158
2467
|
/* special case : empty frame */
|
@@ -2176,6 +2485,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
|
|
2176
2485
|
if (cctx->appliedParams.fParams.checksumFlag) {
|
2177
2486
|
U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
|
2178
2487
|
if (dstCapacity<4) return ERROR(dstSize_tooSmall);
|
2488
|
+
DEBUGLOG(4, "ZSTD_writeEpilogue: write checksum : %08X", checksum);
|
2179
2489
|
MEM_writeLE32(op, checksum);
|
2180
2490
|
op += 4;
|
2181
2491
|
}
|
@@ -2184,7 +2494,6 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
|
|
2184
2494
|
return op-ostart;
|
2185
2495
|
}
|
2186
2496
|
|
2187
|
-
|
2188
2497
|
size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
|
2189
2498
|
void* dst, size_t dstCapacity,
|
2190
2499
|
const void* src, size_t srcSize)
|
@@ -2242,25 +2551,27 @@ size_t ZSTD_compress_advanced_internal(
|
|
2242
2551
|
const void* dict,size_t dictSize,
|
2243
2552
|
ZSTD_CCtx_params params)
|
2244
2553
|
{
|
2245
|
-
DEBUGLOG(4, "ZSTD_compress_advanced_internal"
|
2246
|
-
|
2554
|
+
DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)",
|
2555
|
+
(U32)srcSize);
|
2556
|
+
CHECK_F( ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, NULL,
|
2247
2557
|
params, srcSize, ZSTDb_not_buffered) );
|
2248
2558
|
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
|
2249
2559
|
}
|
2250
2560
|
|
2251
|
-
size_t ZSTD_compress_usingDict(ZSTD_CCtx*
|
2561
|
+
size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize,
|
2252
2562
|
const void* dict, size_t dictSize, int compressionLevel)
|
2253
2563
|
{
|
2254
|
-
ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize ? srcSize : 1, dict ? dictSize : 0);
|
2255
|
-
|
2256
|
-
|
2257
|
-
|
2258
|
-
return
|
2564
|
+
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize ? srcSize : 1, dict ? dictSize : 0);
|
2565
|
+
ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
2566
|
+
assert(params.fParams.contentSizeFlag == 1);
|
2567
|
+
ZSTD_CCtxParam_setParameter(&cctxParams, ZSTD_p_compressLiterals, compressionLevel>=0);
|
2568
|
+
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, cctxParams);
|
2259
2569
|
}
|
2260
2570
|
|
2261
|
-
size_t ZSTD_compressCCtx (ZSTD_CCtx*
|
2571
|
+
size_t ZSTD_compressCCtx (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
|
2262
2572
|
{
|
2263
|
-
|
2573
|
+
DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (U32)srcSize);
|
2574
|
+
return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
|
2264
2575
|
}
|
2265
2576
|
|
2266
2577
|
size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
|
@@ -2284,9 +2595,7 @@ size_t ZSTD_estimateCDictSize_advanced(
|
|
2284
2595
|
ZSTD_dictLoadMethod_e dictLoadMethod)
|
2285
2596
|
{
|
2286
2597
|
DEBUGLOG(5, "sizeof(ZSTD_CDict) : %u", (U32)sizeof(ZSTD_CDict));
|
2287
|
-
|
2288
|
-
(U32)ZSTD_estimateCCtxSize_usingCParams(cParams));
|
2289
|
-
return sizeof(ZSTD_CDict) + ZSTD_estimateCCtxSize_usingCParams(cParams)
|
2598
|
+
return sizeof(ZSTD_CDict) + HUF_WORKSPACE_SIZE + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0)
|
2290
2599
|
+ (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
|
2291
2600
|
}
|
2292
2601
|
|
@@ -2300,23 +2609,24 @@ size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
|
|
2300
2609
|
{
|
2301
2610
|
if (cdict==NULL) return 0; /* support sizeof on NULL */
|
2302
2611
|
DEBUGLOG(5, "sizeof(*cdict) : %u", (U32)sizeof(*cdict));
|
2303
|
-
|
2304
|
-
return ZSTD_sizeof_CCtx(cdict->refContext) + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
|
2612
|
+
return cdict->workspaceSize + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
|
2305
2613
|
}
|
2306
2614
|
|
2307
2615
|
static size_t ZSTD_initCDict_internal(
|
2308
2616
|
ZSTD_CDict* cdict,
|
2309
2617
|
const void* dictBuffer, size_t dictSize,
|
2310
2618
|
ZSTD_dictLoadMethod_e dictLoadMethod,
|
2311
|
-
|
2619
|
+
ZSTD_dictContentType_e dictContentType,
|
2312
2620
|
ZSTD_compressionParameters cParams)
|
2313
2621
|
{
|
2314
|
-
DEBUGLOG(3, "ZSTD_initCDict_internal,
|
2622
|
+
DEBUGLOG(3, "ZSTD_initCDict_internal, dictContentType %u", (U32)dictContentType);
|
2623
|
+
assert(!ZSTD_checkCParams(cParams));
|
2624
|
+
cdict->cParams = cParams;
|
2315
2625
|
if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
|
2316
2626
|
cdict->dictBuffer = NULL;
|
2317
2627
|
cdict->dictContent = dictBuffer;
|
2318
2628
|
} else {
|
2319
|
-
void* const internalBuffer = ZSTD_malloc(dictSize, cdict->
|
2629
|
+
void* const internalBuffer = ZSTD_malloc(dictSize, cdict->customMem);
|
2320
2630
|
cdict->dictBuffer = internalBuffer;
|
2321
2631
|
cdict->dictContent = internalBuffer;
|
2322
2632
|
if (!internalBuffer) return ERROR(memory_allocation);
|
@@ -2324,13 +2634,31 @@ static size_t ZSTD_initCDict_internal(
|
|
2324
2634
|
}
|
2325
2635
|
cdict->dictContentSize = dictSize;
|
2326
2636
|
|
2327
|
-
|
2328
|
-
|
2329
|
-
|
2330
|
-
|
2331
|
-
|
2332
|
-
|
2333
|
-
|
2637
|
+
/* Reset the state to no dictionary */
|
2638
|
+
ZSTD_reset_compressedBlockState(&cdict->cBlockState);
|
2639
|
+
{ void* const end = ZSTD_reset_matchState(
|
2640
|
+
&cdict->matchState,
|
2641
|
+
(U32*)cdict->workspace + HUF_WORKSPACE_SIZE_U32,
|
2642
|
+
&cParams, ZSTDcrp_continue, /* forCCtx */ 0);
|
2643
|
+
assert(end == (char*)cdict->workspace + cdict->workspaceSize);
|
2644
|
+
(void)end;
|
2645
|
+
}
|
2646
|
+
/* (Maybe) load the dictionary
|
2647
|
+
* Skips loading the dictionary if it is <= 8 bytes.
|
2648
|
+
*/
|
2649
|
+
{ ZSTD_CCtx_params params;
|
2650
|
+
memset(¶ms, 0, sizeof(params));
|
2651
|
+
params.compressionLevel = ZSTD_CLEVEL_DEFAULT;
|
2652
|
+
params.fParams.contentSizeFlag = 1;
|
2653
|
+
params.cParams = cParams;
|
2654
|
+
{ size_t const dictID = ZSTD_compress_insertDictionary(
|
2655
|
+
&cdict->cBlockState, &cdict->matchState, ¶ms,
|
2656
|
+
cdict->dictContent, cdict->dictContentSize,
|
2657
|
+
dictContentType, cdict->workspace);
|
2658
|
+
if (ZSTD_isError(dictID)) return dictID;
|
2659
|
+
assert(dictID <= (size_t)(U32)-1);
|
2660
|
+
cdict->dictID = (U32)dictID;
|
2661
|
+
}
|
2334
2662
|
}
|
2335
2663
|
|
2336
2664
|
return 0;
|
@@ -2338,24 +2666,27 @@ static size_t ZSTD_initCDict_internal(
|
|
2338
2666
|
|
2339
2667
|
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
|
2340
2668
|
ZSTD_dictLoadMethod_e dictLoadMethod,
|
2341
|
-
|
2669
|
+
ZSTD_dictContentType_e dictContentType,
|
2342
2670
|
ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
|
2343
2671
|
{
|
2344
|
-
DEBUGLOG(3, "ZSTD_createCDict_advanced, mode %u", (U32)
|
2672
|
+
DEBUGLOG(3, "ZSTD_createCDict_advanced, mode %u", (U32)dictContentType);
|
2345
2673
|
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
|
2346
2674
|
|
2347
2675
|
{ ZSTD_CDict* const cdict = (ZSTD_CDict*)ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
|
2348
|
-
|
2676
|
+
size_t const workspaceSize = HUF_WORKSPACE_SIZE + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0);
|
2677
|
+
void* const workspace = ZSTD_malloc(workspaceSize, customMem);
|
2349
2678
|
|
2350
|
-
if (!cdict || !
|
2679
|
+
if (!cdict || !workspace) {
|
2351
2680
|
ZSTD_free(cdict, customMem);
|
2352
|
-
|
2681
|
+
ZSTD_free(workspace, customMem);
|
2353
2682
|
return NULL;
|
2354
2683
|
}
|
2355
|
-
cdict->
|
2684
|
+
cdict->customMem = customMem;
|
2685
|
+
cdict->workspace = workspace;
|
2686
|
+
cdict->workspaceSize = workspaceSize;
|
2356
2687
|
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
|
2357
2688
|
dictBuffer, dictSize,
|
2358
|
-
dictLoadMethod,
|
2689
|
+
dictLoadMethod, dictContentType,
|
2359
2690
|
cParams) )) {
|
2360
2691
|
ZSTD_freeCDict(cdict);
|
2361
2692
|
return NULL;
|
@@ -2369,7 +2700,7 @@ ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionL
|
|
2369
2700
|
{
|
2370
2701
|
ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
|
2371
2702
|
return ZSTD_createCDict_advanced(dict, dictSize,
|
2372
|
-
ZSTD_dlm_byCopy,
|
2703
|
+
ZSTD_dlm_byCopy, ZSTD_dct_auto,
|
2373
2704
|
cParams, ZSTD_defaultCMem);
|
2374
2705
|
}
|
2375
2706
|
|
@@ -2377,15 +2708,15 @@ ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int
|
|
2377
2708
|
{
|
2378
2709
|
ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
|
2379
2710
|
return ZSTD_createCDict_advanced(dict, dictSize,
|
2380
|
-
ZSTD_dlm_byRef,
|
2711
|
+
ZSTD_dlm_byRef, ZSTD_dct_auto,
|
2381
2712
|
cParams, ZSTD_defaultCMem);
|
2382
2713
|
}
|
2383
2714
|
|
2384
2715
|
size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
2385
2716
|
{
|
2386
2717
|
if (cdict==NULL) return 0; /* support free on NULL */
|
2387
|
-
{ ZSTD_customMem const cMem = cdict->
|
2388
|
-
|
2718
|
+
{ ZSTD_customMem const cMem = cdict->customMem;
|
2719
|
+
ZSTD_free(cdict->workspace, cMem);
|
2389
2720
|
ZSTD_free(cdict->dictBuffer, cMem);
|
2390
2721
|
ZSTD_free(cdict, cMem);
|
2391
2722
|
return 0;
|
@@ -2405,18 +2736,18 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
|
2405
2736
|
* Note : there is no corresponding "free" function.
|
2406
2737
|
* Since workspace was allocated externally, it must be freed externally.
|
2407
2738
|
*/
|
2408
|
-
ZSTD_CDict* ZSTD_initStaticCDict(
|
2739
|
+
const ZSTD_CDict* ZSTD_initStaticCDict(
|
2740
|
+
void* workspace, size_t workspaceSize,
|
2409
2741
|
const void* dict, size_t dictSize,
|
2410
2742
|
ZSTD_dictLoadMethod_e dictLoadMethod,
|
2411
|
-
|
2743
|
+
ZSTD_dictContentType_e dictContentType,
|
2412
2744
|
ZSTD_compressionParameters cParams)
|
2413
2745
|
{
|
2414
|
-
size_t const
|
2746
|
+
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0);
|
2415
2747
|
size_t const neededSize = sizeof(ZSTD_CDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize)
|
2416
|
-
+
|
2748
|
+
+ HUF_WORKSPACE_SIZE + matchStateSize;
|
2417
2749
|
ZSTD_CDict* const cdict = (ZSTD_CDict*) workspace;
|
2418
2750
|
void* ptr;
|
2419
|
-
DEBUGLOG(4, "(size_t)workspace & 7 : %u", (U32)(size_t)workspace & 7);
|
2420
2751
|
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
|
2421
2752
|
DEBUGLOG(4, "(workspaceSize < neededSize) : (%u < %u) => %u",
|
2422
2753
|
(U32)workspaceSize, (U32)neededSize, (U32)(workspaceSize < neededSize));
|
@@ -2429,19 +2760,22 @@ ZSTD_CDict* ZSTD_initStaticCDict(void* workspace, size_t workspaceSize,
|
|
2429
2760
|
} else {
|
2430
2761
|
ptr = cdict+1;
|
2431
2762
|
}
|
2432
|
-
cdict->
|
2763
|
+
cdict->workspace = ptr;
|
2764
|
+
cdict->workspaceSize = HUF_WORKSPACE_SIZE + matchStateSize;
|
2433
2765
|
|
2434
2766
|
if (ZSTD_isError( ZSTD_initCDict_internal(cdict,
|
2435
2767
|
dict, dictSize,
|
2436
|
-
ZSTD_dlm_byRef,
|
2768
|
+
ZSTD_dlm_byRef, dictContentType,
|
2437
2769
|
cParams) ))
|
2438
2770
|
return NULL;
|
2439
2771
|
|
2440
2772
|
return cdict;
|
2441
2773
|
}
|
2442
2774
|
|
2443
|
-
ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict)
|
2444
|
-
|
2775
|
+
ZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict)
|
2776
|
+
{
|
2777
|
+
assert(cdict != NULL);
|
2778
|
+
return cdict->cParams;
|
2445
2779
|
}
|
2446
2780
|
|
2447
2781
|
/* ZSTD_compressBegin_usingCDict_advanced() :
|
@@ -2454,9 +2788,18 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
|
|
2454
2788
|
if (cdict==NULL) return ERROR(dictionary_wrong);
|
2455
2789
|
{ ZSTD_CCtx_params params = cctx->requestedParams;
|
2456
2790
|
params.cParams = ZSTD_getCParamsFromCDict(cdict);
|
2791
|
+
/* Increase window log to fit the entire dictionary and source if the
|
2792
|
+
* source size is known. Limit the increase to 19, which is the
|
2793
|
+
* window log for compression level 1 with the largest source size.
|
2794
|
+
*/
|
2795
|
+
if (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN) {
|
2796
|
+
U32 const limitedSrcSize = (U32)MIN(pledgedSrcSize, 1U << 19);
|
2797
|
+
U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1;
|
2798
|
+
params.cParams.windowLog = MAX(params.cParams.windowLog, limitedSrcLog);
|
2799
|
+
}
|
2457
2800
|
params.fParams = fParams;
|
2458
2801
|
return ZSTD_compressBegin_internal(cctx,
|
2459
|
-
NULL, 0,
|
2802
|
+
NULL, 0, ZSTD_dct_auto,
|
2460
2803
|
cdict,
|
2461
2804
|
params, pledgedSrcSize,
|
2462
2805
|
ZSTDb_not_buffered);
|
@@ -2534,29 +2877,30 @@ size_t ZSTD_CStreamOutSize(void)
|
|
2534
2877
|
return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
|
2535
2878
|
}
|
2536
2879
|
|
2537
|
-
static size_t ZSTD_resetCStream_internal(ZSTD_CStream*
|
2538
|
-
const void* const dict, size_t const dictSize,
|
2880
|
+
static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,
|
2881
|
+
const void* const dict, size_t const dictSize, ZSTD_dictContentType_e const dictContentType,
|
2539
2882
|
const ZSTD_CDict* const cdict,
|
2540
2883
|
ZSTD_CCtx_params const params, unsigned long long const pledgedSrcSize)
|
2541
2884
|
{
|
2542
|
-
DEBUGLOG(4, "ZSTD_resetCStream_internal"
|
2885
|
+
DEBUGLOG(4, "ZSTD_resetCStream_internal (disableLiteralCompression=%i)",
|
2886
|
+
params.disableLiteralCompression);
|
2543
2887
|
/* params are supposed to be fully validated at this point */
|
2544
2888
|
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
2545
2889
|
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
|
2546
2890
|
|
2547
|
-
CHECK_F( ZSTD_compressBegin_internal(
|
2548
|
-
dict, dictSize,
|
2891
|
+
CHECK_F( ZSTD_compressBegin_internal(cctx,
|
2892
|
+
dict, dictSize, dictContentType,
|
2549
2893
|
cdict,
|
2550
2894
|
params, pledgedSrcSize,
|
2551
2895
|
ZSTDb_buffered) );
|
2552
2896
|
|
2553
|
-
|
2554
|
-
|
2555
|
-
|
2556
|
-
+ (
|
2557
|
-
|
2558
|
-
|
2559
|
-
|
2897
|
+
cctx->inToCompress = 0;
|
2898
|
+
cctx->inBuffPos = 0;
|
2899
|
+
cctx->inBuffTarget = cctx->blockSize
|
2900
|
+
+ (cctx->blockSize == pledgedSrcSize); /* for small input: avoid automatic flush on reaching end of block, since it would require to add a 3-bytes null block to end frame */
|
2901
|
+
cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0;
|
2902
|
+
cctx->streamStage = zcss_load;
|
2903
|
+
cctx->frameEnded = 0;
|
2560
2904
|
return 0; /* ready to go */
|
2561
2905
|
}
|
2562
2906
|
|
@@ -2568,8 +2912,8 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
|
|
2568
2912
|
DEBUGLOG(4, "ZSTD_resetCStream: pledgedSrcSize = %u", (U32)pledgedSrcSize);
|
2569
2913
|
if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;
|
2570
2914
|
params.fParams.contentSizeFlag = 1;
|
2571
|
-
params.cParams = ZSTD_getCParamsFromCCtxParams(params, pledgedSrcSize, 0);
|
2572
|
-
return ZSTD_resetCStream_internal(zcs, NULL, 0,
|
2915
|
+
params.cParams = ZSTD_getCParamsFromCCtxParams(¶ms, pledgedSrcSize, 0);
|
2916
|
+
return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize);
|
2573
2917
|
}
|
2574
2918
|
|
2575
2919
|
/*! ZSTD_initCStream_internal() :
|
@@ -2592,7 +2936,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
|
|
2592
2936
|
}
|
2593
2937
|
ZSTD_freeCDict(zcs->cdictLocal);
|
2594
2938
|
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,
|
2595
|
-
ZSTD_dlm_byCopy,
|
2939
|
+
ZSTD_dlm_byCopy, ZSTD_dct_auto,
|
2596
2940
|
params.cParams, zcs->customMem);
|
2597
2941
|
zcs->cdict = zcs->cdictLocal;
|
2598
2942
|
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
|
@@ -2605,10 +2949,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
|
|
2605
2949
|
zcs->cdict = cdict;
|
2606
2950
|
}
|
2607
2951
|
|
2608
|
-
|
2609
|
-
zcs->requestedParams = params;
|
2610
|
-
|
2611
|
-
return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dm_auto, zcs->cdict, params, pledgedSrcSize);
|
2952
|
+
return ZSTD_resetCStream_internal(zcs, NULL, 0, ZSTD_dct_auto, zcs->cdict, params, pledgedSrcSize);
|
2612
2953
|
}
|
2613
2954
|
|
2614
2955
|
/* ZSTD_initCStream_usingCDict_advanced() :
|
@@ -2637,20 +2978,22 @@ size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
|
|
2637
2978
|
return ZSTD_initCStream_usingCDict_advanced(zcs, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN); /* note : will check that cdict != NULL */
|
2638
2979
|
}
|
2639
2980
|
|
2981
|
+
|
2640
2982
|
/* ZSTD_initCStream_advanced() :
|
2641
|
-
* pledgedSrcSize must be
|
2983
|
+
* pledgedSrcSize must be exact.
|
2642
2984
|
* if srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.
|
2643
2985
|
* dict is loaded with default parameters ZSTD_dm_auto and ZSTD_dlm_byCopy. */
|
2644
2986
|
size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
2645
2987
|
const void* dict, size_t dictSize,
|
2646
2988
|
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
2647
2989
|
{
|
2648
|
-
ZSTD_CCtx_params const cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
|
2649
2990
|
DEBUGLOG(4, "ZSTD_initCStream_advanced: pledgedSrcSize=%u, flag=%u",
|
2650
2991
|
(U32)pledgedSrcSize, params.fParams.contentSizeFlag);
|
2651
2992
|
CHECK_F( ZSTD_checkCParams(params.cParams) );
|
2652
2993
|
if ((pledgedSrcSize==0) && (params.fParams.contentSizeFlag==0)) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* for compatibility with older programs relying on this behavior. Users should now specify ZSTD_CONTENTSIZE_UNKNOWN. This line will be removed in the future. */
|
2653
|
-
|
2994
|
+
{ ZSTD_CCtx_params const cctxParams = ZSTD_assignParamsToCCtxParams(zcs->requestedParams, params);
|
2995
|
+
return ZSTD_initCStream_internal(zcs, dict, dictSize, NULL /*cdict*/, cctxParams, pledgedSrcSize);
|
2996
|
+
}
|
2654
2997
|
}
|
2655
2998
|
|
2656
2999
|
size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
|
@@ -2687,7 +3030,7 @@ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity,
|
|
2687
3030
|
|
2688
3031
|
/** ZSTD_compressStream_generic():
|
2689
3032
|
* internal function for all *compressStream*() variants and *compress_generic()
|
2690
|
-
* non-static, because can be called from
|
3033
|
+
* non-static, because can be called from zstdmt_compress.c
|
2691
3034
|
* @return : hint size for next input */
|
2692
3035
|
size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
2693
3036
|
ZSTD_outBuffer* output,
|
@@ -2862,46 +3205,56 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|
2862
3205
|
DEBUGLOG(4, "ZSTD_compress_generic : transparent init stage");
|
2863
3206
|
if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1; /* auto-fix pledgedSrcSize */
|
2864
3207
|
params.cParams = ZSTD_getCParamsFromCCtxParams(
|
2865
|
-
cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
|
3208
|
+
&cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
|
2866
3209
|
|
2867
3210
|
#ifdef ZSTD_MULTITHREAD
|
2868
|
-
if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN)
|
2869
|
-
params.
|
2870
|
-
|
2871
|
-
|
2872
|
-
|
2873
|
-
|
3211
|
+
if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
|
3212
|
+
params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
|
3213
|
+
}
|
3214
|
+
if (params.nbWorkers > 0) {
|
3215
|
+
/* mt context creation */
|
3216
|
+
if (cctx->mtctx == NULL || (params.nbWorkers != ZSTDMT_getNbWorkers(cctx->mtctx))) {
|
3217
|
+
DEBUGLOG(4, "ZSTD_compress_generic: creating new mtctx for nbWorkers=%u",
|
3218
|
+
params.nbWorkers);
|
3219
|
+
if (cctx->mtctx != NULL)
|
3220
|
+
DEBUGLOG(4, "ZSTD_compress_generic: previous nbWorkers was %u",
|
3221
|
+
ZSTDMT_getNbWorkers(cctx->mtctx));
|
2874
3222
|
ZSTDMT_freeCCtx(cctx->mtctx);
|
2875
|
-
cctx->mtctx = ZSTDMT_createCCtx_advanced(params.
|
3223
|
+
cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem);
|
2876
3224
|
if (cctx->mtctx == NULL) return ERROR(memory_allocation);
|
2877
3225
|
}
|
2878
|
-
|
3226
|
+
/* mt compression */
|
3227
|
+
DEBUGLOG(4, "call ZSTDMT_initCStream_internal as nbWorkers=%u", params.nbWorkers);
|
2879
3228
|
CHECK_F( ZSTDMT_initCStream_internal(
|
2880
3229
|
cctx->mtctx,
|
2881
|
-
prefixDict.dict, prefixDict.dictSize,
|
3230
|
+
prefixDict.dict, prefixDict.dictSize, ZSTD_dct_rawContent,
|
2882
3231
|
cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );
|
2883
3232
|
cctx->streamStage = zcss_load;
|
2884
|
-
cctx->appliedParams.
|
3233
|
+
cctx->appliedParams.nbWorkers = params.nbWorkers;
|
2885
3234
|
} else
|
2886
3235
|
#endif
|
2887
|
-
{ CHECK_F( ZSTD_resetCStream_internal(
|
2888
|
-
|
2889
|
-
|
2890
|
-
|
3236
|
+
{ CHECK_F( ZSTD_resetCStream_internal(cctx,
|
3237
|
+
prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,
|
3238
|
+
cctx->cdict,
|
3239
|
+
params, cctx->pledgedSrcSizePlusOne-1) );
|
2891
3240
|
assert(cctx->streamStage == zcss_load);
|
2892
|
-
assert(cctx->appliedParams.
|
3241
|
+
assert(cctx->appliedParams.nbWorkers == 0);
|
2893
3242
|
} }
|
2894
3243
|
|
2895
3244
|
/* compression stage */
|
2896
3245
|
#ifdef ZSTD_MULTITHREAD
|
2897
|
-
if (cctx->appliedParams.
|
2898
|
-
|
2899
|
-
|
2900
|
-
|
2901
|
-
ZSTD_startNewCompression(cctx);
|
3246
|
+
if (cctx->appliedParams.nbWorkers > 0) {
|
3247
|
+
if (cctx->cParamsChanged) {
|
3248
|
+
ZSTDMT_updateCParams_whileCompressing(cctx->mtctx, &cctx->requestedParams);
|
3249
|
+
cctx->cParamsChanged = 0;
|
2902
3250
|
}
|
2903
|
-
|
2904
|
-
|
3251
|
+
{ size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
|
3252
|
+
if ( ZSTD_isError(flushMin)
|
3253
|
+
|| (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
|
3254
|
+
ZSTD_startNewCompression(cctx);
|
3255
|
+
}
|
3256
|
+
return flushMin;
|
3257
|
+
} }
|
2905
3258
|
#endif
|
2906
3259
|
CHECK_F( ZSTD_compressStream_generic(cctx, output, input, endOp) );
|
2907
3260
|
DEBUGLOG(5, "completed ZSTD_compress_generic");
|
@@ -2927,7 +3280,7 @@ size_t ZSTD_compress_generic_simpleArgs (
|
|
2927
3280
|
/*====== Finalize ======*/
|
2928
3281
|
|
2929
3282
|
/*! ZSTD_flushStream() :
|
2930
|
-
*
|
3283
|
+
* @return : amount of data remaining to flush */
|
2931
3284
|
size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
|
2932
3285
|
{
|
2933
3286
|
ZSTD_inBuffer input = { NULL, 0, 0 };
|
@@ -2959,11 +3312,11 @@ int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
|
|
2959
3312
|
static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
|
2960
3313
|
{ /* "default" - guarantees a monotonically increasing memory budget */
|
2961
3314
|
/* W, C, H, S, L, TL, strat */
|
2962
|
-
{
|
2963
|
-
{ 19, 13, 14, 1, 7,
|
2964
|
-
{ 19, 15, 16, 1, 6,
|
2965
|
-
{ 20, 16, 17, 1, 5,
|
2966
|
-
{ 20, 17, 18, 1, 5,
|
3315
|
+
{ 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */
|
3316
|
+
{ 19, 13, 14, 1, 7, 1, ZSTD_fast }, /* level 1 */
|
3317
|
+
{ 19, 15, 16, 1, 6, 1, ZSTD_fast }, /* level 2 */
|
3318
|
+
{ 20, 16, 17, 1, 5, 8, ZSTD_dfast }, /* level 3 */
|
3319
|
+
{ 20, 17, 18, 1, 5, 8, ZSTD_dfast }, /* level 4 */
|
2967
3320
|
{ 20, 17, 18, 2, 5, 16, ZSTD_greedy }, /* level 5 */
|
2968
3321
|
{ 21, 17, 19, 2, 5, 16, ZSTD_lazy }, /* level 6 */
|
2969
3322
|
{ 21, 18, 19, 3, 5, 16, ZSTD_lazy }, /* level 7 */
|
@@ -2972,9 +3325,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
2972
3325
|
{ 21, 19, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */
|
2973
3326
|
{ 22, 20, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */
|
2974
3327
|
{ 22, 20, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 12 */
|
2975
|
-
{ 22, 21, 22,
|
2976
|
-
{ 22, 21, 22,
|
2977
|
-
{ 22,
|
3328
|
+
{ 22, 21, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */
|
3329
|
+
{ 22, 21, 22, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */
|
3330
|
+
{ 22, 22, 22, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */
|
2978
3331
|
{ 22, 21, 22, 4, 5, 48, ZSTD_btopt }, /* level 16 */
|
2979
3332
|
{ 23, 22, 22, 4, 4, 48, ZSTD_btopt }, /* level 17 */
|
2980
3333
|
{ 23, 22, 22, 5, 3, 64, ZSTD_btopt }, /* level 18 */
|
@@ -2985,8 +3338,8 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
2985
3338
|
},
|
2986
3339
|
{ /* for srcSize <= 256 KB */
|
2987
3340
|
/* W, C, H, S, L, T, strat */
|
2988
|
-
{
|
2989
|
-
{ 18, 13, 14, 1, 6,
|
3341
|
+
{ 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
|
3342
|
+
{ 18, 13, 14, 1, 6, 1, ZSTD_fast }, /* level 1 */
|
2990
3343
|
{ 18, 14, 13, 1, 5, 8, ZSTD_dfast }, /* level 2 */
|
2991
3344
|
{ 18, 16, 15, 1, 5, 8, ZSTD_dfast }, /* level 3 */
|
2992
3345
|
{ 18, 15, 17, 1, 5, 8, ZSTD_greedy }, /* level 4.*/
|
@@ -2997,8 +3350,8 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
2997
3350
|
{ 18, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
|
2998
3351
|
{ 18, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
|
2999
3352
|
{ 18, 18, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 11.*/
|
3000
|
-
{ 18, 18, 17,
|
3001
|
-
{ 18, 19, 17,
|
3353
|
+
{ 18, 18, 17, 5, 4, 8, ZSTD_btlazy2 }, /* level 12.*/
|
3354
|
+
{ 18, 19, 17, 7, 4, 8, ZSTD_btlazy2 }, /* level 13 */
|
3002
3355
|
{ 18, 18, 18, 4, 4, 16, ZSTD_btopt }, /* level 14.*/
|
3003
3356
|
{ 18, 18, 18, 4, 3, 16, ZSTD_btopt }, /* level 15.*/
|
3004
3357
|
{ 18, 19, 18, 6, 3, 32, ZSTD_btopt }, /* level 16.*/
|
@@ -3011,9 +3364,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
3011
3364
|
},
|
3012
3365
|
{ /* for srcSize <= 128 KB */
|
3013
3366
|
/* W, C, H, S, L, T, strat */
|
3014
|
-
{ 17, 12, 12, 1,
|
3015
|
-
{ 17, 12, 13, 1, 6,
|
3016
|
-
{ 17, 13, 16, 1, 5,
|
3367
|
+
{ 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* level 0 - not used */
|
3368
|
+
{ 17, 12, 13, 1, 6, 1, ZSTD_fast }, /* level 1 */
|
3369
|
+
{ 17, 13, 16, 1, 5, 1, ZSTD_fast }, /* level 2 */
|
3017
3370
|
{ 17, 16, 16, 2, 5, 8, ZSTD_dfast }, /* level 3 */
|
3018
3371
|
{ 17, 13, 15, 3, 4, 8, ZSTD_greedy }, /* level 4 */
|
3019
3372
|
{ 17, 15, 17, 4, 4, 8, ZSTD_greedy }, /* level 5 */
|
@@ -3037,9 +3390,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
3037
3390
|
},
|
3038
3391
|
{ /* for srcSize <= 16 KB */
|
3039
3392
|
/* W, C, H, S, L, T, strat */
|
3040
|
-
{ 14, 12,
|
3041
|
-
{ 14, 14, 14, 1, 6,
|
3042
|
-
{ 14, 14, 14, 1, 4,
|
3393
|
+
{ 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
|
3394
|
+
{ 14, 14, 14, 1, 6, 1, ZSTD_fast }, /* level 1 */
|
3395
|
+
{ 14, 14, 14, 1, 4, 1, ZSTD_fast }, /* level 2 */
|
3043
3396
|
{ 14, 14, 14, 1, 4, 6, ZSTD_dfast }, /* level 3.*/
|
3044
3397
|
{ 14, 14, 14, 4, 4, 6, ZSTD_greedy }, /* level 4.*/
|
3045
3398
|
{ 14, 14, 14, 3, 4, 6, ZSTD_lazy }, /* level 5.*/
|
@@ -3063,47 +3416,22 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
3063
3416
|
},
|
3064
3417
|
};
|
3065
3418
|
|
3066
|
-
#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1)
|
3067
|
-
/* This function just controls
|
3068
|
-
* the monotonic memory budget increase of ZSTD_defaultCParameters[0].
|
3069
|
-
* Run once, on first ZSTD_getCParams() usage, if ZSTD_DEBUG is enabled
|
3070
|
-
*/
|
3071
|
-
MEM_STATIC void ZSTD_check_compressionLevel_monotonicIncrease_memoryBudget(void)
|
3072
|
-
{
|
3073
|
-
int level;
|
3074
|
-
for (level=1; level<ZSTD_maxCLevel(); level++) {
|
3075
|
-
ZSTD_compressionParameters const c1 = ZSTD_defaultCParameters[0][level];
|
3076
|
-
ZSTD_compressionParameters const c2 = ZSTD_defaultCParameters[0][level+1];
|
3077
|
-
assert(c1.windowLog <= c2.windowLog);
|
3078
|
-
# define ZSTD_TABLECOST(h,c) ((1<<(h)) + (1<<(c)))
|
3079
|
-
assert(ZSTD_TABLECOST(c1.hashLog, c1.chainLog) <= ZSTD_TABLECOST(c2.hashLog, c2.chainLog));
|
3080
|
-
}
|
3081
|
-
}
|
3082
|
-
#endif
|
3083
|
-
|
3084
3419
|
/*! ZSTD_getCParams() :
|
3085
|
-
*
|
3420
|
+
* @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
|
3086
3421
|
* Size values are optional, provide 0 if not known or unused */
|
3087
3422
|
ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
|
3088
3423
|
{
|
3089
3424
|
size_t const addedSize = srcSizeHint ? 0 : 500;
|
3090
3425
|
U64 const rSize = srcSizeHint+dictSize ? srcSizeHint+dictSize+addedSize : (U64)-1;
|
3091
3426
|
U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */
|
3092
|
-
|
3093
|
-
|
3094
|
-
|
3095
|
-
if (
|
3096
|
-
|
3097
|
-
|
3098
|
-
|
3099
|
-
|
3100
|
-
|
3101
|
-
DEBUGLOG(4, "ZSTD_getCParams: cLevel=%i, srcSize=%u, dictSize=%u => table %u",
|
3102
|
-
compressionLevel, (U32)srcSizeHint, (U32)dictSize, tableID);
|
3103
|
-
if (compressionLevel <= 0) compressionLevel = ZSTD_CLEVEL_DEFAULT; /* 0 == default; no negative compressionLevel yet */
|
3104
|
-
if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
|
3105
|
-
{ ZSTD_compressionParameters const cp = ZSTD_defaultCParameters[tableID][compressionLevel];
|
3106
|
-
return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); }
|
3427
|
+
int row = compressionLevel;
|
3428
|
+
DEBUGLOG(5, "ZSTD_getCParams (cLevel=%i)", compressionLevel);
|
3429
|
+
if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT; /* 0 == default */
|
3430
|
+
if (compressionLevel < 0) row = 0; /* entry 0 is baseline for fast mode */
|
3431
|
+
if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;
|
3432
|
+
{ ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];
|
3433
|
+
if (compressionLevel < 0) cp.targetLength = (unsigned)(-compressionLevel); /* acceleration factor */
|
3434
|
+
return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize); }
|
3107
3435
|
|
3108
3436
|
}
|
3109
3437
|
|
@@ -3113,6 +3441,7 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
|
|
3113
3441
|
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {
|
3114
3442
|
ZSTD_parameters params;
|
3115
3443
|
ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSizeHint, dictSize);
|
3444
|
+
DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
|
3116
3445
|
memset(¶ms, 0, sizeof(params));
|
3117
3446
|
params.cParams = cParams;
|
3118
3447
|
params.fParams.contentSizeFlag = 1;
|