zstd-ruby 1.3.3.0 → 1.3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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;
|