zstdlib 0.14.0-x86-mingw32 → 0.15.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +5 -0
- data/ext/zstdlib_c/extconf.rb +1 -1
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/bits.h +92 -87
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/bitstream.h +26 -29
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/compiler.h +36 -22
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/cpu.h +1 -1
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/debug.h +0 -9
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/error_private.c +1 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/error_private.h +0 -10
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/fse.h +2 -17
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/fse_decompress.c +2 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/huf.h +0 -9
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/mem.h +7 -11
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/pool.h +0 -9
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/portability_macros.h +22 -9
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/threading.h +0 -8
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/xxhash.h +93 -19
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_deps.h +12 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_internal.h +1 -69
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_trace.h +5 -12
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/hist.c +10 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/hist.h +7 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress.c +1057 -367
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_internal.h +227 -125
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_literals.c +1 -1
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_sequences.c +7 -7
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_sequences.h +7 -6
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_superblock.c +17 -17
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_cwksp.h +41 -24
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_double_fast.c +58 -50
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_double_fast.h +4 -12
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_fast.c +91 -74
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_fast.h +4 -12
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_lazy.c +64 -64
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_lazy.h +30 -39
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_ldm.c +48 -33
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_ldm.h +6 -14
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_opt.c +55 -51
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_opt.h +8 -16
- data/ext/zstdlib_c/zstd-1.5.7/lib/compress/zstd_preSplit.c +238 -0
- data/ext/zstdlib_c/zstd-1.5.7/lib/compress/zstd_preSplit.h +33 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstdmt_compress.c +134 -93
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstdmt_compress.h +4 -15
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/huf_decompress_amd64.S +10 -3
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress.c +14 -11
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress_block.c +6 -12
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress_internal.h +5 -5
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/zdict.h +15 -8
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/zstd.h +241 -132
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/zstd_errors.h +1 -8
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzwrite.c +2 -1
- data/lib/2.4/zstdlib_c.so +0 -0
- data/lib/2.5/zstdlib_c.so +0 -0
- data/lib/2.6/zstdlib_c.so +0 -0
- data/lib/2.7/zstdlib_c.so +0 -0
- data/lib/3.0/zstdlib_c.so +0 -0
- data/lib/3.1/zstdlib_c.so +0 -0
- data/lib/3.2/zstdlib_c.so +0 -0
- data/lib/3.3/zstdlib_c.so +0 -0
- data/lib/3.4/zstdlib_c.so +0 -0
- metadata +75 -73
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/allocations.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/debug.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/entropy_common.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/pool.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/threading.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/xxhash.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/common/zstd_common.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/clevels.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/fse_compress.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/huf_compress.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_literals.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_compress_superblock.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/compress/zstd_ldm_geartab.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/huf_decompress.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_ddict.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_ddict.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/lib/decompress/zstd_decompress_block.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzclose.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzcompatibility.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzguts.h +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzlib.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/gzread.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/zstd_zlibwrapper.c +0 -0
- data/ext/zstdlib_c/{zstd-1.5.6 → zstd-1.5.7}/zlibWrapper/zstd_zlibwrapper.h +5 -5
@@ -14,6 +14,7 @@
|
|
14
14
|
#include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */
|
15
15
|
#include "../common/zstd_deps.h" /* INT_MAX, ZSTD_memset, ZSTD_memcpy */
|
16
16
|
#include "../common/mem.h"
|
17
|
+
#include "../common/error_private.h"
|
17
18
|
#include "hist.h" /* HIST_countFast_wksp */
|
18
19
|
#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
|
19
20
|
#include "../common/fse.h"
|
@@ -48,7 +49,7 @@
|
|
48
49
|
* in log format, aka 17 => 1 << 17 == 128Ki positions.
|
49
50
|
* This structure is only used in zstd_opt.
|
50
51
|
* Since allocation is centralized for all strategies, it has to be known here.
|
51
|
-
* The actual (selected) size of the hash table is then stored in
|
52
|
+
* The actual (selected) size of the hash table is then stored in ZSTD_MatchState_t.hashLog3,
|
52
53
|
* so that zstd_opt.c doesn't need to know about this constant.
|
53
54
|
*/
|
54
55
|
#ifndef ZSTD_HASHLOG3_MAX
|
@@ -82,12 +83,12 @@ struct ZSTD_CDict_s {
|
|
82
83
|
ZSTD_dictContentType_e dictContentType; /* The dictContentType the CDict was created with */
|
83
84
|
U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */
|
84
85
|
ZSTD_cwksp workspace;
|
85
|
-
|
86
|
+
ZSTD_MatchState_t matchState;
|
86
87
|
ZSTD_compressedBlockState_t cBlockState;
|
87
88
|
ZSTD_customMem customMem;
|
88
89
|
U32 dictID;
|
89
90
|
int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */
|
90
|
-
|
91
|
+
ZSTD_ParamSwitch_e useRowMatchFinder; /* Indicates whether the CDict was created with params that would use
|
91
92
|
* row-based matchfinder. Unless the cdict is reloaded, we will use
|
92
93
|
* the same greedy/lazy matchfinder at compression time.
|
93
94
|
*/
|
@@ -137,11 +138,12 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize)
|
|
137
138
|
ZSTD_cwksp_move(&cctx->workspace, &ws);
|
138
139
|
cctx->staticSize = workspaceSize;
|
139
140
|
|
140
|
-
/* statically sized space.
|
141
|
-
if (!ZSTD_cwksp_check_available(&cctx->workspace,
|
141
|
+
/* statically sized space. tmpWorkspace never moves (but prev/next block swap places) */
|
142
|
+
if (!ZSTD_cwksp_check_available(&cctx->workspace, TMP_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;
|
142
143
|
cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
|
143
144
|
cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));
|
144
|
-
cctx->
|
145
|
+
cctx->tmpWorkspace = ZSTD_cwksp_reserve_object(&cctx->workspace, TMP_WORKSPACE_SIZE);
|
146
|
+
cctx->tmpWkspSize = TMP_WORKSPACE_SIZE;
|
145
147
|
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
|
146
148
|
return cctx;
|
147
149
|
}
|
@@ -217,7 +219,7 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
|
|
217
219
|
}
|
218
220
|
|
219
221
|
/* private API call, for dictBuilder only */
|
220
|
-
const
|
222
|
+
const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
|
221
223
|
|
222
224
|
/* Returns true if the strategy supports using a row based matchfinder */
|
223
225
|
static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) {
|
@@ -227,32 +229,23 @@ static int ZSTD_rowMatchFinderSupported(const ZSTD_strategy strategy) {
|
|
227
229
|
/* Returns true if the strategy and useRowMatchFinder mode indicate that we will use the row based matchfinder
|
228
230
|
* for this compression.
|
229
231
|
*/
|
230
|
-
static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const
|
232
|
+
static int ZSTD_rowMatchFinderUsed(const ZSTD_strategy strategy, const ZSTD_ParamSwitch_e mode) {
|
231
233
|
assert(mode != ZSTD_ps_auto);
|
232
234
|
return ZSTD_rowMatchFinderSupported(strategy) && (mode == ZSTD_ps_enable);
|
233
235
|
}
|
234
236
|
|
235
237
|
/* Returns row matchfinder usage given an initial mode and cParams */
|
236
|
-
static
|
238
|
+
static ZSTD_ParamSwitch_e ZSTD_resolveRowMatchFinderMode(ZSTD_ParamSwitch_e mode,
|
237
239
|
const ZSTD_compressionParameters* const cParams) {
|
238
|
-
#if defined(ZSTD_ARCH_X86_SSE2) || defined(ZSTD_ARCH_ARM_NEON)
|
239
|
-
int const kHasSIMD128 = 1;
|
240
|
-
#else
|
241
|
-
int const kHasSIMD128 = 0;
|
242
|
-
#endif
|
243
240
|
if (mode != ZSTD_ps_auto) return mode; /* if requested enabled, but no SIMD, we still will use row matchfinder */
|
244
241
|
mode = ZSTD_ps_disable;
|
245
242
|
if (!ZSTD_rowMatchFinderSupported(cParams->strategy)) return mode;
|
246
|
-
if (
|
247
|
-
if (cParams->windowLog > 14) mode = ZSTD_ps_enable;
|
248
|
-
} else {
|
249
|
-
if (cParams->windowLog > 17) mode = ZSTD_ps_enable;
|
250
|
-
}
|
243
|
+
if (cParams->windowLog > 14) mode = ZSTD_ps_enable;
|
251
244
|
return mode;
|
252
245
|
}
|
253
246
|
|
254
247
|
/* Returns block splitter usage (generally speaking, when using slower/stronger compression modes) */
|
255
|
-
static
|
248
|
+
static ZSTD_ParamSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_ParamSwitch_e mode,
|
256
249
|
const ZSTD_compressionParameters* const cParams) {
|
257
250
|
if (mode != ZSTD_ps_auto) return mode;
|
258
251
|
return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 17) ? ZSTD_ps_enable : ZSTD_ps_disable;
|
@@ -260,7 +253,7 @@ static ZSTD_paramSwitch_e ZSTD_resolveBlockSplitterMode(ZSTD_paramSwitch_e mode,
|
|
260
253
|
|
261
254
|
/* Returns 1 if the arguments indicate that we should allocate a chainTable, 0 otherwise */
|
262
255
|
static int ZSTD_allocateChainTable(const ZSTD_strategy strategy,
|
263
|
-
const
|
256
|
+
const ZSTD_ParamSwitch_e useRowMatchFinder,
|
264
257
|
const U32 forDDSDict) {
|
265
258
|
assert(useRowMatchFinder != ZSTD_ps_auto);
|
266
259
|
/* We always should allocate a chaintable if we are allocating a matchstate for a DDS dictionary matchstate.
|
@@ -273,7 +266,7 @@ static int ZSTD_allocateChainTable(const ZSTD_strategy strategy,
|
|
273
266
|
* enable long distance matching (wlog >= 27, strategy >= btopt).
|
274
267
|
* Returns ZSTD_ps_disable otherwise.
|
275
268
|
*/
|
276
|
-
static
|
269
|
+
static ZSTD_ParamSwitch_e ZSTD_resolveEnableLdm(ZSTD_ParamSwitch_e mode,
|
277
270
|
const ZSTD_compressionParameters* const cParams) {
|
278
271
|
if (mode != ZSTD_ps_auto) return mode;
|
279
272
|
return (cParams->strategy >= ZSTD_btopt && cParams->windowLog >= 27) ? ZSTD_ps_enable : ZSTD_ps_disable;
|
@@ -292,7 +285,7 @@ static size_t ZSTD_resolveMaxBlockSize(size_t maxBlockSize) {
|
|
292
285
|
}
|
293
286
|
}
|
294
287
|
|
295
|
-
static
|
288
|
+
static ZSTD_ParamSwitch_e ZSTD_resolveExternalRepcodeSearch(ZSTD_ParamSwitch_e value, int cLevel) {
|
296
289
|
if (value != ZSTD_ps_auto) return value;
|
297
290
|
if (cLevel < 10) {
|
298
291
|
return ZSTD_ps_disable;
|
@@ -322,7 +315,7 @@ static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
|
|
322
315
|
assert(cctxParams.ldmParams.hashLog >= cctxParams.ldmParams.bucketSizeLog);
|
323
316
|
assert(cctxParams.ldmParams.hashRateLog < 32);
|
324
317
|
}
|
325
|
-
cctxParams.
|
318
|
+
cctxParams.postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams.postBlockSplitter, &cParams);
|
326
319
|
cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
|
327
320
|
cctxParams.validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams.validateSequences);
|
328
321
|
cctxParams.maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams.maxBlockSize);
|
@@ -390,13 +383,13 @@ ZSTD_CCtxParams_init_internal(ZSTD_CCtx_params* cctxParams,
|
|
390
383
|
*/
|
391
384
|
cctxParams->compressionLevel = compressionLevel;
|
392
385
|
cctxParams->useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams->useRowMatchFinder, ¶ms->cParams);
|
393
|
-
cctxParams->
|
386
|
+
cctxParams->postBlockSplitter = ZSTD_resolveBlockSplitterMode(cctxParams->postBlockSplitter, ¶ms->cParams);
|
394
387
|
cctxParams->ldmParams.enableLdm = ZSTD_resolveEnableLdm(cctxParams->ldmParams.enableLdm, ¶ms->cParams);
|
395
388
|
cctxParams->validateSequences = ZSTD_resolveExternalSequenceValidation(cctxParams->validateSequences);
|
396
389
|
cctxParams->maxBlockSize = ZSTD_resolveMaxBlockSize(cctxParams->maxBlockSize);
|
397
390
|
cctxParams->searchForExternalRepcodes = ZSTD_resolveExternalRepcodeSearch(cctxParams->searchForExternalRepcodes, compressionLevel);
|
398
391
|
DEBUGLOG(4, "ZSTD_CCtxParams_init_internal: useRowMatchFinder=%d, useBlockSplitter=%d ldm=%d",
|
399
|
-
cctxParams->useRowMatchFinder, cctxParams->
|
392
|
+
cctxParams->useRowMatchFinder, cctxParams->postBlockSplitter, cctxParams->ldmParams.enableLdm);
|
400
393
|
}
|
401
394
|
|
402
395
|
size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)
|
@@ -597,11 +590,16 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
|
|
597
590
|
bounds.upperBound = 1;
|
598
591
|
return bounds;
|
599
592
|
|
600
|
-
case
|
593
|
+
case ZSTD_c_splitAfterSequences:
|
601
594
|
bounds.lowerBound = (int)ZSTD_ps_auto;
|
602
595
|
bounds.upperBound = (int)ZSTD_ps_disable;
|
603
596
|
return bounds;
|
604
597
|
|
598
|
+
case ZSTD_c_blockSplitterLevel:
|
599
|
+
bounds.lowerBound = 0;
|
600
|
+
bounds.upperBound = ZSTD_BLOCKSPLITTER_LEVEL_MAX;
|
601
|
+
return bounds;
|
602
|
+
|
605
603
|
case ZSTD_c_useRowMatchFinder:
|
606
604
|
bounds.lowerBound = (int)ZSTD_ps_auto;
|
607
605
|
bounds.upperBound = (int)ZSTD_ps_disable;
|
@@ -627,7 +625,7 @@ ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)
|
|
627
625
|
bounds.upperBound = ZSTD_BLOCKSIZE_MAX;
|
628
626
|
return bounds;
|
629
627
|
|
630
|
-
case
|
628
|
+
case ZSTD_c_repcodeResolution:
|
631
629
|
bounds.lowerBound = (int)ZSTD_ps_auto;
|
632
630
|
bounds.upperBound = (int)ZSTD_ps_disable;
|
633
631
|
return bounds;
|
@@ -668,6 +666,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
|
|
668
666
|
case ZSTD_c_minMatch:
|
669
667
|
case ZSTD_c_targetLength:
|
670
668
|
case ZSTD_c_strategy:
|
669
|
+
case ZSTD_c_blockSplitterLevel:
|
671
670
|
return 1;
|
672
671
|
|
673
672
|
case ZSTD_c_format:
|
@@ -694,13 +693,13 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
|
|
694
693
|
case ZSTD_c_stableOutBuffer:
|
695
694
|
case ZSTD_c_blockDelimiters:
|
696
695
|
case ZSTD_c_validateSequences:
|
697
|
-
case
|
696
|
+
case ZSTD_c_splitAfterSequences:
|
698
697
|
case ZSTD_c_useRowMatchFinder:
|
699
698
|
case ZSTD_c_deterministicRefPrefix:
|
700
699
|
case ZSTD_c_prefetchCDictTables:
|
701
700
|
case ZSTD_c_enableSeqProducerFallback:
|
702
701
|
case ZSTD_c_maxBlockSize:
|
703
|
-
case
|
702
|
+
case ZSTD_c_repcodeResolution:
|
704
703
|
default:
|
705
704
|
return 0;
|
706
705
|
}
|
@@ -753,13 +752,14 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)
|
|
753
752
|
case ZSTD_c_stableOutBuffer:
|
754
753
|
case ZSTD_c_blockDelimiters:
|
755
754
|
case ZSTD_c_validateSequences:
|
756
|
-
case
|
755
|
+
case ZSTD_c_splitAfterSequences:
|
756
|
+
case ZSTD_c_blockSplitterLevel:
|
757
757
|
case ZSTD_c_useRowMatchFinder:
|
758
758
|
case ZSTD_c_deterministicRefPrefix:
|
759
759
|
case ZSTD_c_prefetchCDictTables:
|
760
760
|
case ZSTD_c_enableSeqProducerFallback:
|
761
761
|
case ZSTD_c_maxBlockSize:
|
762
|
-
case
|
762
|
+
case ZSTD_c_repcodeResolution:
|
763
763
|
break;
|
764
764
|
|
765
765
|
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
|
@@ -857,7 +857,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
|
857
857
|
}
|
858
858
|
|
859
859
|
case ZSTD_c_literalCompressionMode : {
|
860
|
-
const
|
860
|
+
const ZSTD_ParamSwitch_e lcm = (ZSTD_ParamSwitch_e)value;
|
861
861
|
BOUNDCHECK(ZSTD_c_literalCompressionMode, (int)lcm);
|
862
862
|
CCtxParams->literalCompressionMode = lcm;
|
863
863
|
return CCtxParams->literalCompressionMode;
|
@@ -883,7 +883,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
|
883
883
|
value = ZSTDMT_JOBSIZE_MIN;
|
884
884
|
FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value), "");
|
885
885
|
assert(value >= 0);
|
886
|
-
CCtxParams->jobSize = value;
|
886
|
+
CCtxParams->jobSize = (size_t)value;
|
887
887
|
return CCtxParams->jobSize;
|
888
888
|
#endif
|
889
889
|
|
@@ -913,7 +913,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
|
913
913
|
|
914
914
|
case ZSTD_c_enableLongDistanceMatching :
|
915
915
|
BOUNDCHECK(ZSTD_c_enableLongDistanceMatching, value);
|
916
|
-
CCtxParams->ldmParams.enableLdm = (
|
916
|
+
CCtxParams->ldmParams.enableLdm = (ZSTD_ParamSwitch_e)value;
|
917
917
|
return CCtxParams->ldmParams.enableLdm;
|
918
918
|
|
919
919
|
case ZSTD_c_ldmHashLog :
|
@@ -966,7 +966,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
|
966
966
|
|
967
967
|
case ZSTD_c_blockDelimiters:
|
968
968
|
BOUNDCHECK(ZSTD_c_blockDelimiters, value);
|
969
|
-
CCtxParams->blockDelimiters = (
|
969
|
+
CCtxParams->blockDelimiters = (ZSTD_SequenceFormat_e)value;
|
970
970
|
return CCtxParams->blockDelimiters;
|
971
971
|
|
972
972
|
case ZSTD_c_validateSequences:
|
@@ -974,14 +974,19 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
|
974
974
|
CCtxParams->validateSequences = value;
|
975
975
|
return (size_t)CCtxParams->validateSequences;
|
976
976
|
|
977
|
-
case
|
978
|
-
BOUNDCHECK(
|
979
|
-
CCtxParams->
|
980
|
-
return CCtxParams->
|
977
|
+
case ZSTD_c_splitAfterSequences:
|
978
|
+
BOUNDCHECK(ZSTD_c_splitAfterSequences, value);
|
979
|
+
CCtxParams->postBlockSplitter = (ZSTD_ParamSwitch_e)value;
|
980
|
+
return CCtxParams->postBlockSplitter;
|
981
|
+
|
982
|
+
case ZSTD_c_blockSplitterLevel:
|
983
|
+
BOUNDCHECK(ZSTD_c_blockSplitterLevel, value);
|
984
|
+
CCtxParams->preBlockSplitter_level = value;
|
985
|
+
return (size_t)CCtxParams->preBlockSplitter_level;
|
981
986
|
|
982
987
|
case ZSTD_c_useRowMatchFinder:
|
983
988
|
BOUNDCHECK(ZSTD_c_useRowMatchFinder, value);
|
984
|
-
CCtxParams->useRowMatchFinder = (
|
989
|
+
CCtxParams->useRowMatchFinder = (ZSTD_ParamSwitch_e)value;
|
985
990
|
return CCtxParams->useRowMatchFinder;
|
986
991
|
|
987
992
|
case ZSTD_c_deterministicRefPrefix:
|
@@ -991,7 +996,7 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
|
991
996
|
|
992
997
|
case ZSTD_c_prefetchCDictTables:
|
993
998
|
BOUNDCHECK(ZSTD_c_prefetchCDictTables, value);
|
994
|
-
CCtxParams->prefetchCDictTables = (
|
999
|
+
CCtxParams->prefetchCDictTables = (ZSTD_ParamSwitch_e)value;
|
995
1000
|
return CCtxParams->prefetchCDictTables;
|
996
1001
|
|
997
1002
|
case ZSTD_c_enableSeqProducerFallback:
|
@@ -1002,12 +1007,13 @@ size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,
|
|
1002
1007
|
case ZSTD_c_maxBlockSize:
|
1003
1008
|
if (value!=0) /* 0 ==> default */
|
1004
1009
|
BOUNDCHECK(ZSTD_c_maxBlockSize, value);
|
1005
|
-
|
1010
|
+
assert(value>=0);
|
1011
|
+
CCtxParams->maxBlockSize = (size_t)value;
|
1006
1012
|
return CCtxParams->maxBlockSize;
|
1007
1013
|
|
1008
|
-
case
|
1009
|
-
BOUNDCHECK(
|
1010
|
-
CCtxParams->searchForExternalRepcodes = (
|
1014
|
+
case ZSTD_c_repcodeResolution:
|
1015
|
+
BOUNDCHECK(ZSTD_c_repcodeResolution, value);
|
1016
|
+
CCtxParams->searchForExternalRepcodes = (ZSTD_ParamSwitch_e)value;
|
1011
1017
|
return CCtxParams->searchForExternalRepcodes;
|
1012
1018
|
|
1013
1019
|
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
|
@@ -1025,7 +1031,7 @@ size_t ZSTD_CCtxParams_getParameter(
|
|
1025
1031
|
switch(param)
|
1026
1032
|
{
|
1027
1033
|
case ZSTD_c_format :
|
1028
|
-
*value = CCtxParams->format;
|
1034
|
+
*value = (int)CCtxParams->format;
|
1029
1035
|
break;
|
1030
1036
|
case ZSTD_c_compressionLevel :
|
1031
1037
|
*value = CCtxParams->compressionLevel;
|
@@ -1040,16 +1046,16 @@ size_t ZSTD_CCtxParams_getParameter(
|
|
1040
1046
|
*value = (int)CCtxParams->cParams.chainLog;
|
1041
1047
|
break;
|
1042
1048
|
case ZSTD_c_searchLog :
|
1043
|
-
*value = CCtxParams->cParams.searchLog;
|
1049
|
+
*value = (int)CCtxParams->cParams.searchLog;
|
1044
1050
|
break;
|
1045
1051
|
case ZSTD_c_minMatch :
|
1046
|
-
*value = CCtxParams->cParams.minMatch;
|
1052
|
+
*value = (int)CCtxParams->cParams.minMatch;
|
1047
1053
|
break;
|
1048
1054
|
case ZSTD_c_targetLength :
|
1049
|
-
*value = CCtxParams->cParams.targetLength;
|
1055
|
+
*value = (int)CCtxParams->cParams.targetLength;
|
1050
1056
|
break;
|
1051
1057
|
case ZSTD_c_strategy :
|
1052
|
-
*value = (
|
1058
|
+
*value = (int)CCtxParams->cParams.strategy;
|
1053
1059
|
break;
|
1054
1060
|
case ZSTD_c_contentSizeFlag :
|
1055
1061
|
*value = CCtxParams->fParams.contentSizeFlag;
|
@@ -1064,10 +1070,10 @@ size_t ZSTD_CCtxParams_getParameter(
|
|
1064
1070
|
*value = CCtxParams->forceWindow;
|
1065
1071
|
break;
|
1066
1072
|
case ZSTD_c_forceAttachDict :
|
1067
|
-
*value = CCtxParams->attachDictPref;
|
1073
|
+
*value = (int)CCtxParams->attachDictPref;
|
1068
1074
|
break;
|
1069
1075
|
case ZSTD_c_literalCompressionMode :
|
1070
|
-
*value = CCtxParams->literalCompressionMode;
|
1076
|
+
*value = (int)CCtxParams->literalCompressionMode;
|
1071
1077
|
break;
|
1072
1078
|
case ZSTD_c_nbWorkers :
|
1073
1079
|
#ifndef ZSTD_MULTITHREAD
|
@@ -1101,19 +1107,19 @@ size_t ZSTD_CCtxParams_getParameter(
|
|
1101
1107
|
*value = CCtxParams->enableDedicatedDictSearch;
|
1102
1108
|
break;
|
1103
1109
|
case ZSTD_c_enableLongDistanceMatching :
|
1104
|
-
*value = CCtxParams->ldmParams.enableLdm;
|
1110
|
+
*value = (int)CCtxParams->ldmParams.enableLdm;
|
1105
1111
|
break;
|
1106
1112
|
case ZSTD_c_ldmHashLog :
|
1107
|
-
*value = CCtxParams->ldmParams.hashLog;
|
1113
|
+
*value = (int)CCtxParams->ldmParams.hashLog;
|
1108
1114
|
break;
|
1109
1115
|
case ZSTD_c_ldmMinMatch :
|
1110
|
-
*value = CCtxParams->ldmParams.minMatchLength;
|
1116
|
+
*value = (int)CCtxParams->ldmParams.minMatchLength;
|
1111
1117
|
break;
|
1112
1118
|
case ZSTD_c_ldmBucketSizeLog :
|
1113
|
-
*value = CCtxParams->ldmParams.bucketSizeLog;
|
1119
|
+
*value = (int)CCtxParams->ldmParams.bucketSizeLog;
|
1114
1120
|
break;
|
1115
1121
|
case ZSTD_c_ldmHashRateLog :
|
1116
|
-
*value = CCtxParams->ldmParams.hashRateLog;
|
1122
|
+
*value = (int)CCtxParams->ldmParams.hashRateLog;
|
1117
1123
|
break;
|
1118
1124
|
case ZSTD_c_targetCBlockSize :
|
1119
1125
|
*value = (int)CCtxParams->targetCBlockSize;
|
@@ -1133,8 +1139,11 @@ size_t ZSTD_CCtxParams_getParameter(
|
|
1133
1139
|
case ZSTD_c_validateSequences :
|
1134
1140
|
*value = (int)CCtxParams->validateSequences;
|
1135
1141
|
break;
|
1136
|
-
case
|
1137
|
-
*value = (int)CCtxParams->
|
1142
|
+
case ZSTD_c_splitAfterSequences :
|
1143
|
+
*value = (int)CCtxParams->postBlockSplitter;
|
1144
|
+
break;
|
1145
|
+
case ZSTD_c_blockSplitterLevel :
|
1146
|
+
*value = CCtxParams->preBlockSplitter_level;
|
1138
1147
|
break;
|
1139
1148
|
case ZSTD_c_useRowMatchFinder :
|
1140
1149
|
*value = (int)CCtxParams->useRowMatchFinder;
|
@@ -1151,7 +1160,7 @@ size_t ZSTD_CCtxParams_getParameter(
|
|
1151
1160
|
case ZSTD_c_maxBlockSize:
|
1152
1161
|
*value = (int)CCtxParams->maxBlockSize;
|
1153
1162
|
break;
|
1154
|
-
case
|
1163
|
+
case ZSTD_c_repcodeResolution:
|
1155
1164
|
*value = (int)CCtxParams->searchForExternalRepcodes;
|
1156
1165
|
break;
|
1157
1166
|
default: RETURN_ERROR(parameter_unsupported, "unknown parameter");
|
@@ -1186,13 +1195,13 @@ size_t ZSTD_CCtx_setCParams(ZSTD_CCtx* cctx, ZSTD_compressionParameters cparams)
|
|
1186
1195
|
DEBUGLOG(4, "ZSTD_CCtx_setCParams");
|
1187
1196
|
/* only update if all parameters are valid */
|
1188
1197
|
FORWARD_IF_ERROR(ZSTD_checkCParams(cparams), "");
|
1189
|
-
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, cparams.windowLog), "");
|
1190
|
-
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, cparams.chainLog), "");
|
1191
|
-
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, cparams.hashLog), "");
|
1192
|
-
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, cparams.searchLog), "");
|
1193
|
-
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, cparams.minMatch), "");
|
1194
|
-
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, cparams.targetLength), "");
|
1195
|
-
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, cparams.strategy), "");
|
1198
|
+
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_windowLog, (int)cparams.windowLog), "");
|
1199
|
+
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_chainLog, (int)cparams.chainLog), "");
|
1200
|
+
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_hashLog, (int)cparams.hashLog), "");
|
1201
|
+
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_searchLog, (int)cparams.searchLog), "");
|
1202
|
+
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, (int)cparams.minMatch), "");
|
1203
|
+
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_targetLength, (int)cparams.targetLength), "");
|
1204
|
+
FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, (int)cparams.strategy), "");
|
1196
1205
|
return 0;
|
1197
1206
|
}
|
1198
1207
|
|
@@ -1384,7 +1393,7 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
|
1384
1393
|
BOUNDCHECK(ZSTD_c_searchLog, (int)cParams.searchLog);
|
1385
1394
|
BOUNDCHECK(ZSTD_c_minMatch, (int)cParams.minMatch);
|
1386
1395
|
BOUNDCHECK(ZSTD_c_targetLength,(int)cParams.targetLength);
|
1387
|
-
BOUNDCHECK(ZSTD_c_strategy, cParams.strategy);
|
1396
|
+
BOUNDCHECK(ZSTD_c_strategy, (int)cParams.strategy);
|
1388
1397
|
return 0;
|
1389
1398
|
}
|
1390
1399
|
|
@@ -1457,15 +1466,15 @@ static U32 ZSTD_dictAndWindowLog(U32 windowLog, U64 srcSize, U64 dictSize)
|
|
1457
1466
|
* optimize `cPar` for a specified input (`srcSize` and `dictSize`).
|
1458
1467
|
* mostly downsize to reduce memory consumption and initialization latency.
|
1459
1468
|
* `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known.
|
1460
|
-
* `mode` is the mode for parameter adjustment. See docs for `
|
1469
|
+
* `mode` is the mode for parameter adjustment. See docs for `ZSTD_CParamMode_e`.
|
1461
1470
|
* note : `srcSize==0` means 0!
|
1462
1471
|
* condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */
|
1463
1472
|
static ZSTD_compressionParameters
|
1464
1473
|
ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
|
1465
1474
|
unsigned long long srcSize,
|
1466
1475
|
size_t dictSize,
|
1467
|
-
|
1468
|
-
|
1476
|
+
ZSTD_CParamMode_e mode,
|
1477
|
+
ZSTD_ParamSwitch_e useRowMatchFinder)
|
1469
1478
|
{
|
1470
1479
|
const U64 minSrcSize = 513; /* (1<<9) + 1 */
|
1471
1480
|
const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
|
@@ -1609,8 +1618,8 @@ ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
|
|
1609
1618
|
return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize, ZSTD_cpm_unknown, ZSTD_ps_auto);
|
1610
1619
|
}
|
1611
1620
|
|
1612
|
-
static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize,
|
1613
|
-
static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize,
|
1621
|
+
static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode);
|
1622
|
+
static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode);
|
1614
1623
|
|
1615
1624
|
static void ZSTD_overrideCParams(
|
1616
1625
|
ZSTD_compressionParameters* cParams,
|
@@ -1626,11 +1635,12 @@ static void ZSTD_overrideCParams(
|
|
1626
1635
|
}
|
1627
1636
|
|
1628
1637
|
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
|
1629
|
-
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize,
|
1638
|
+
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
|
1630
1639
|
{
|
1631
1640
|
ZSTD_compressionParameters cParams;
|
1632
1641
|
if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) {
|
1633
|
-
|
1642
|
+
assert(CCtxParams->srcSizeHint>=0);
|
1643
|
+
srcSizeHint = (U64)CCtxParams->srcSizeHint;
|
1634
1644
|
}
|
1635
1645
|
cParams = ZSTD_getCParams_internal(CCtxParams->compressionLevel, srcSizeHint, dictSize, mode);
|
1636
1646
|
if (CCtxParams->ldmParams.enableLdm == ZSTD_ps_enable) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
|
@@ -1642,8 +1652,8 @@ ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
|
|
1642
1652
|
|
1643
1653
|
static size_t
|
1644
1654
|
ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
|
1645
|
-
const
|
1646
|
-
const
|
1655
|
+
const ZSTD_ParamSwitch_e useRowMatchFinder,
|
1656
|
+
const int enableDedicatedDictSearch,
|
1647
1657
|
const U32 forCCtx)
|
1648
1658
|
{
|
1649
1659
|
/* chain table size should be 0 for fast or row-hash strategies */
|
@@ -1659,14 +1669,14 @@ ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
|
|
1659
1669
|
+ hSize * sizeof(U32)
|
1660
1670
|
+ h3Size * sizeof(U32);
|
1661
1671
|
size_t const optPotentialSpace =
|
1662
|
-
|
1663
|
-
+
|
1664
|
-
+
|
1665
|
-
+
|
1666
|
-
+
|
1667
|
-
+
|
1672
|
+
ZSTD_cwksp_aligned64_alloc_size((MaxML+1) * sizeof(U32))
|
1673
|
+
+ ZSTD_cwksp_aligned64_alloc_size((MaxLL+1) * sizeof(U32))
|
1674
|
+
+ ZSTD_cwksp_aligned64_alloc_size((MaxOff+1) * sizeof(U32))
|
1675
|
+
+ ZSTD_cwksp_aligned64_alloc_size((1<<Litbits) * sizeof(U32))
|
1676
|
+
+ ZSTD_cwksp_aligned64_alloc_size(ZSTD_OPT_SIZE * sizeof(ZSTD_match_t))
|
1677
|
+
+ ZSTD_cwksp_aligned64_alloc_size(ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t));
|
1668
1678
|
size_t const lazyAdditionalSpace = ZSTD_rowMatchFinderUsed(cParams->strategy, useRowMatchFinder)
|
1669
|
-
?
|
1679
|
+
? ZSTD_cwksp_aligned64_alloc_size(hSize)
|
1670
1680
|
: 0;
|
1671
1681
|
size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt))
|
1672
1682
|
? optPotentialSpace
|
@@ -1693,7 +1703,7 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
|
1693
1703
|
const ZSTD_compressionParameters* cParams,
|
1694
1704
|
const ldmParams_t* ldmParams,
|
1695
1705
|
const int isStatic,
|
1696
|
-
const
|
1706
|
+
const ZSTD_ParamSwitch_e useRowMatchFinder,
|
1697
1707
|
const size_t buffInSize,
|
1698
1708
|
const size_t buffOutSize,
|
1699
1709
|
const U64 pledgedSrcSize,
|
@@ -1704,16 +1714,16 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
|
1704
1714
|
size_t const blockSize = MIN(ZSTD_resolveMaxBlockSize(maxBlockSize), windowSize);
|
1705
1715
|
size_t const maxNbSeq = ZSTD_maxNbSeq(blockSize, cParams->minMatch, useSequenceProducer);
|
1706
1716
|
size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)
|
1707
|
-
+
|
1717
|
+
+ ZSTD_cwksp_aligned64_alloc_size(maxNbSeq * sizeof(SeqDef))
|
1708
1718
|
+ 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));
|
1709
|
-
size_t const
|
1719
|
+
size_t const tmpWorkSpace = ZSTD_cwksp_alloc_size(TMP_WORKSPACE_SIZE);
|
1710
1720
|
size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));
|
1711
1721
|
size_t const matchStateSize = ZSTD_sizeof_matchState(cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 0, /* forCCtx */ 1);
|
1712
1722
|
|
1713
1723
|
size_t const ldmSpace = ZSTD_ldm_getTableSize(*ldmParams);
|
1714
1724
|
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(*ldmParams, blockSize);
|
1715
1725
|
size_t const ldmSeqSpace = ldmParams->enableLdm == ZSTD_ps_enable ?
|
1716
|
-
|
1726
|
+
ZSTD_cwksp_aligned64_alloc_size(maxNbLdmSeq * sizeof(rawSeq)) : 0;
|
1717
1727
|
|
1718
1728
|
|
1719
1729
|
size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize)
|
@@ -1723,12 +1733,12 @@ static size_t ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
|
1723
1733
|
|
1724
1734
|
size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize);
|
1725
1735
|
size_t const externalSeqSpace = useSequenceProducer
|
1726
|
-
?
|
1736
|
+
? ZSTD_cwksp_aligned64_alloc_size(maxNbExternalSeq * sizeof(ZSTD_Sequence))
|
1727
1737
|
: 0;
|
1728
1738
|
|
1729
1739
|
size_t const neededSpace =
|
1730
1740
|
cctxSpace +
|
1731
|
-
|
1741
|
+
tmpWorkSpace +
|
1732
1742
|
blockStateSpace +
|
1733
1743
|
ldmSpace +
|
1734
1744
|
ldmSeqSpace +
|
@@ -1745,7 +1755,7 @@ size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|
1745
1755
|
{
|
1746
1756
|
ZSTD_compressionParameters const cParams =
|
1747
1757
|
ZSTD_getCParamsFromCCtxParams(params, ZSTD_CONTENTSIZE_UNKNOWN, 0, ZSTD_cpm_noAttachDict);
|
1748
|
-
|
1758
|
+
ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder,
|
1749
1759
|
&cParams);
|
1750
1760
|
|
1751
1761
|
RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, "Estimate CCtx size is supported for single-threaded compression only.");
|
@@ -1810,7 +1820,7 @@ size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)
|
|
1810
1820
|
size_t const outBuffSize = (params->outBufferMode == ZSTD_bm_buffered)
|
1811
1821
|
? ZSTD_compressBound(blockSize) + 1
|
1812
1822
|
: 0;
|
1813
|
-
|
1823
|
+
ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params->useRowMatchFinder, ¶ms->cParams);
|
1814
1824
|
|
1815
1825
|
return ZSTD_estimateCCtxSize_usingCCtxParams_internal(
|
1816
1826
|
&cParams, ¶ms->ldmParams, 1, useRowMatchFinder, inBuffSize, outBuffSize,
|
@@ -1920,7 +1930,7 @@ void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
|
|
1920
1930
|
* Invalidate all the matches in the match finder tables.
|
1921
1931
|
* Requires nextSrc and base to be set (can be NULL).
|
1922
1932
|
*/
|
1923
|
-
static void ZSTD_invalidateMatchState(
|
1933
|
+
static void ZSTD_invalidateMatchState(ZSTD_MatchState_t* ms)
|
1924
1934
|
{
|
1925
1935
|
ZSTD_window_clear(&ms->window);
|
1926
1936
|
|
@@ -1967,15 +1977,15 @@ static U64 ZSTD_bitmix(U64 val, U64 len) {
|
|
1967
1977
|
}
|
1968
1978
|
|
1969
1979
|
/* Mixes in the hashSalt and hashSaltEntropy to create a new hashSalt */
|
1970
|
-
static void ZSTD_advanceHashSalt(
|
1980
|
+
static void ZSTD_advanceHashSalt(ZSTD_MatchState_t* ms) {
|
1971
1981
|
ms->hashSalt = ZSTD_bitmix(ms->hashSalt, 8) ^ ZSTD_bitmix((U64) ms->hashSaltEntropy, 4);
|
1972
1982
|
}
|
1973
1983
|
|
1974
1984
|
static size_t
|
1975
|
-
ZSTD_reset_matchState(
|
1985
|
+
ZSTD_reset_matchState(ZSTD_MatchState_t* ms,
|
1976
1986
|
ZSTD_cwksp* ws,
|
1977
1987
|
const ZSTD_compressionParameters* cParams,
|
1978
|
-
const
|
1988
|
+
const ZSTD_ParamSwitch_e useRowMatchFinder,
|
1979
1989
|
const ZSTD_compResetPolicy_e crp,
|
1980
1990
|
const ZSTD_indexResetPolicy_e forceResetIndex,
|
1981
1991
|
const ZSTD_resetTarget_e forWho)
|
@@ -2029,7 +2039,7 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
|
|
2029
2039
|
ZSTD_advanceHashSalt(ms);
|
2030
2040
|
} else {
|
2031
2041
|
/* When we are not salting we want to always memset the memory */
|
2032
|
-
ms->tagTable = (BYTE*)
|
2042
|
+
ms->tagTable = (BYTE*) ZSTD_cwksp_reserve_aligned64(ws, tagTableSize);
|
2033
2043
|
ZSTD_memset(ms->tagTable, 0, tagTableSize);
|
2034
2044
|
ms->hashSalt = 0;
|
2035
2045
|
}
|
@@ -2043,12 +2053,12 @@ ZSTD_reset_matchState(ZSTD_matchState_t* ms,
|
|
2043
2053
|
/* opt parser space */
|
2044
2054
|
if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) {
|
2045
2055
|
DEBUGLOG(4, "reserving optimal parser space");
|
2046
|
-
ms->opt.litFreq = (unsigned*)
|
2047
|
-
ms->opt.litLengthFreq = (unsigned*)
|
2048
|
-
ms->opt.matchLengthFreq = (unsigned*)
|
2049
|
-
ms->opt.offCodeFreq = (unsigned*)
|
2050
|
-
ms->opt.matchTable = (ZSTD_match_t*)
|
2051
|
-
ms->opt.priceTable = (ZSTD_optimal_t*)
|
2056
|
+
ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (1<<Litbits) * sizeof(unsigned));
|
2057
|
+
ms->opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxLL+1) * sizeof(unsigned));
|
2058
|
+
ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxML+1) * sizeof(unsigned));
|
2059
|
+
ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned64(ws, (MaxOff+1) * sizeof(unsigned));
|
2060
|
+
ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_match_t));
|
2061
|
+
ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned64(ws, ZSTD_OPT_SIZE * sizeof(ZSTD_optimal_t));
|
2052
2062
|
}
|
2053
2063
|
|
2054
2064
|
ms->cParams = *cParams;
|
@@ -2096,7 +2106,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
2096
2106
|
{
|
2097
2107
|
ZSTD_cwksp* const ws = &zc->workspace;
|
2098
2108
|
DEBUGLOG(4, "ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u, useRowMatchFinder=%d useBlockSplitter=%d",
|
2099
|
-
(U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->
|
2109
|
+
(U32)pledgedSrcSize, params->cParams.windowLog, (int)params->useRowMatchFinder, (int)params->postBlockSplitter);
|
2100
2110
|
assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));
|
2101
2111
|
|
2102
2112
|
zc->isFirstBlock = 1;
|
@@ -2108,7 +2118,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
2108
2118
|
params = &zc->appliedParams;
|
2109
2119
|
|
2110
2120
|
assert(params->useRowMatchFinder != ZSTD_ps_auto);
|
2111
|
-
assert(params->
|
2121
|
+
assert(params->postBlockSplitter != ZSTD_ps_auto);
|
2112
2122
|
assert(params->ldmParams.enableLdm != ZSTD_ps_auto);
|
2113
2123
|
assert(params->maxBlockSize != 0);
|
2114
2124
|
if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
|
@@ -2164,15 +2174,16 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
2164
2174
|
|
2165
2175
|
DEBUGLOG(5, "reserving object space");
|
2166
2176
|
/* Statically sized space.
|
2167
|
-
*
|
2177
|
+
* tmpWorkspace never moves,
|
2168
2178
|
* though prev/next block swap places */
|
2169
2179
|
assert(ZSTD_cwksp_check_available(ws, 2 * sizeof(ZSTD_compressedBlockState_t)));
|
2170
2180
|
zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
|
2171
2181
|
RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, "couldn't allocate prevCBlock");
|
2172
2182
|
zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));
|
2173
2183
|
RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, "couldn't allocate nextCBlock");
|
2174
|
-
zc->
|
2175
|
-
RETURN_ERROR_IF(zc->
|
2184
|
+
zc->tmpWorkspace = ZSTD_cwksp_reserve_object(ws, TMP_WORKSPACE_SIZE);
|
2185
|
+
RETURN_ERROR_IF(zc->tmpWorkspace == NULL, memory_allocation, "couldn't allocate tmpWorkspace");
|
2186
|
+
zc->tmpWkspSize = TMP_WORKSPACE_SIZE;
|
2176
2187
|
} }
|
2177
2188
|
|
2178
2189
|
ZSTD_cwksp_clear(ws);
|
@@ -2187,7 +2198,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
2187
2198
|
zc->appliedParams.fParams.contentSizeFlag = 0;
|
2188
2199
|
DEBUGLOG(4, "pledged content size : %u ; flag : %u",
|
2189
2200
|
(unsigned)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag);
|
2190
|
-
zc->
|
2201
|
+
zc->blockSizeMax = blockSize;
|
2191
2202
|
|
2192
2203
|
XXH64_reset(&zc->xxhState, 0);
|
2193
2204
|
zc->stage = ZSTDcs_init;
|
@@ -2205,15 +2216,15 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
2205
2216
|
needsIndexReset,
|
2206
2217
|
ZSTD_resetTarget_CCtx), "");
|
2207
2218
|
|
2208
|
-
zc->seqStore.sequencesStart = (
|
2219
|
+
zc->seqStore.sequencesStart = (SeqDef*)ZSTD_cwksp_reserve_aligned64(ws, maxNbSeq * sizeof(SeqDef));
|
2209
2220
|
|
2210
2221
|
/* ldm hash table */
|
2211
2222
|
if (params->ldmParams.enableLdm == ZSTD_ps_enable) {
|
2212
2223
|
/* TODO: avoid memset? */
|
2213
2224
|
size_t const ldmHSize = ((size_t)1) << params->ldmParams.hashLog;
|
2214
|
-
zc->ldmState.hashTable = (ldmEntry_t*)
|
2225
|
+
zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned64(ws, ldmHSize * sizeof(ldmEntry_t));
|
2215
2226
|
ZSTD_memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));
|
2216
|
-
zc->ldmSequences = (rawSeq*)
|
2227
|
+
zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned64(ws, maxNbLdmSeq * sizeof(rawSeq));
|
2217
2228
|
zc->maxNbLdmSequences = maxNbLdmSeq;
|
2218
2229
|
|
2219
2230
|
ZSTD_window_init(&zc->ldmState.window);
|
@@ -2225,7 +2236,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
2225
2236
|
size_t const maxNbExternalSeq = ZSTD_sequenceBound(blockSize);
|
2226
2237
|
zc->extSeqBufCapacity = maxNbExternalSeq;
|
2227
2238
|
zc->extSeqBuf =
|
2228
|
-
(ZSTD_Sequence*)
|
2239
|
+
(ZSTD_Sequence*)ZSTD_cwksp_reserve_aligned64(ws, maxNbExternalSeq * sizeof(ZSTD_Sequence));
|
2229
2240
|
}
|
2230
2241
|
|
2231
2242
|
/* buffers */
|
@@ -2444,7 +2455,8 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
|
|
2444
2455
|
}
|
2445
2456
|
|
2446
2457
|
/* Zero the hashTable3, since the cdict never fills it */
|
2447
|
-
|
2458
|
+
assert(cctx->blockState.matchState.hashLog3 <= 31);
|
2459
|
+
{ U32 const h3log = cctx->blockState.matchState.hashLog3;
|
2448
2460
|
size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
|
2449
2461
|
assert(cdict->matchState.hashLog3 == 0);
|
2450
2462
|
ZSTD_memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
|
@@ -2453,8 +2465,8 @@ static size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,
|
|
2453
2465
|
ZSTD_cwksp_mark_tables_clean(&cctx->workspace);
|
2454
2466
|
|
2455
2467
|
/* copy dictionary offsets */
|
2456
|
-
{
|
2457
|
-
|
2468
|
+
{ ZSTD_MatchState_t const* srcMatchState = &cdict->matchState;
|
2469
|
+
ZSTD_MatchState_t* dstMatchState = &cctx->blockState.matchState;
|
2458
2470
|
dstMatchState->window = srcMatchState->window;
|
2459
2471
|
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
2460
2472
|
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
|
@@ -2512,10 +2524,10 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
|
2512
2524
|
/* Copy only compression parameters related to tables. */
|
2513
2525
|
params.cParams = srcCCtx->appliedParams.cParams;
|
2514
2526
|
assert(srcCCtx->appliedParams.useRowMatchFinder != ZSTD_ps_auto);
|
2515
|
-
assert(srcCCtx->appliedParams.
|
2527
|
+
assert(srcCCtx->appliedParams.postBlockSplitter != ZSTD_ps_auto);
|
2516
2528
|
assert(srcCCtx->appliedParams.ldmParams.enableLdm != ZSTD_ps_auto);
|
2517
2529
|
params.useRowMatchFinder = srcCCtx->appliedParams.useRowMatchFinder;
|
2518
|
-
params.
|
2530
|
+
params.postBlockSplitter = srcCCtx->appliedParams.postBlockSplitter;
|
2519
2531
|
params.ldmParams = srcCCtx->appliedParams.ldmParams;
|
2520
2532
|
params.fParams = fParams;
|
2521
2533
|
params.maxBlockSize = srcCCtx->appliedParams.maxBlockSize;
|
@@ -2538,7 +2550,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
|
2538
2550
|
? ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog)
|
2539
2551
|
: 0;
|
2540
2552
|
size_t const hSize = (size_t)1 << srcCCtx->appliedParams.cParams.hashLog;
|
2541
|
-
|
2553
|
+
U32 const h3log = srcCCtx->blockState.matchState.hashLog3;
|
2542
2554
|
size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;
|
2543
2555
|
|
2544
2556
|
ZSTD_memcpy(dstCCtx->blockState.matchState.hashTable,
|
@@ -2556,8 +2568,8 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
|
2556
2568
|
|
2557
2569
|
/* copy dictionary offsets */
|
2558
2570
|
{
|
2559
|
-
const
|
2560
|
-
|
2571
|
+
const ZSTD_MatchState_t* srcMatchState = &srcCCtx->blockState.matchState;
|
2572
|
+
ZSTD_MatchState_t* dstMatchState = &dstCCtx->blockState.matchState;
|
2561
2573
|
dstMatchState->window = srcMatchState->window;
|
2562
2574
|
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
2563
2575
|
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
|
@@ -2606,7 +2618,7 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa
|
|
2606
2618
|
/* Protect special index values < ZSTD_WINDOW_START_INDEX. */
|
2607
2619
|
U32 const reducerThreshold = reducerValue + ZSTD_WINDOW_START_INDEX;
|
2608
2620
|
assert((size & (ZSTD_ROWSIZE-1)) == 0); /* multiple of ZSTD_ROWSIZE */
|
2609
|
-
assert(size < (1U<<31)); /* can be
|
2621
|
+
assert(size < (1U<<31)); /* can be cast to int */
|
2610
2622
|
|
2611
2623
|
#if ZSTD_MEMORY_SANITIZER && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)
|
2612
2624
|
/* To validate that the table reuse logic is sound, and that we don't
|
@@ -2651,7 +2663,7 @@ static void ZSTD_reduceTable_btlazy2(U32* const table, U32 const size, U32 const
|
|
2651
2663
|
|
2652
2664
|
/*! ZSTD_reduceIndex() :
|
2653
2665
|
* rescale all indexes to avoid future overflow (indexes are U32) */
|
2654
|
-
static void ZSTD_reduceIndex (
|
2666
|
+
static void ZSTD_reduceIndex (ZSTD_MatchState_t* ms, ZSTD_CCtx_params const* params, const U32 reducerValue)
|
2655
2667
|
{
|
2656
2668
|
{ U32 const hSize = (U32)1 << params->cParams.hashLog;
|
2657
2669
|
ZSTD_reduceTable(ms->hashTable, hSize, reducerValue);
|
@@ -2678,9 +2690,9 @@ static void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* par
|
|
2678
2690
|
|
2679
2691
|
/* See doc/zstd_compression_format.md for detailed format description */
|
2680
2692
|
|
2681
|
-
int ZSTD_seqToCodes(const
|
2693
|
+
int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr)
|
2682
2694
|
{
|
2683
|
-
const
|
2695
|
+
const SeqDef* const sequences = seqStorePtr->sequencesStart;
|
2684
2696
|
BYTE* const llCodeTable = seqStorePtr->llCode;
|
2685
2697
|
BYTE* const ofCodeTable = seqStorePtr->ofCode;
|
2686
2698
|
BYTE* const mlCodeTable = seqStorePtr->mlCode;
|
@@ -2723,9 +2735,9 @@ static int ZSTD_useTargetCBlockSize(const ZSTD_CCtx_params* cctxParams)
|
|
2723
2735
|
* Returns 1 if true, 0 otherwise. */
|
2724
2736
|
static int ZSTD_blockSplitterEnabled(ZSTD_CCtx_params* cctxParams)
|
2725
2737
|
{
|
2726
|
-
DEBUGLOG(5, "ZSTD_blockSplitterEnabled (
|
2727
|
-
assert(cctxParams->
|
2728
|
-
return (cctxParams->
|
2738
|
+
DEBUGLOG(5, "ZSTD_blockSplitterEnabled (postBlockSplitter=%d)", cctxParams->postBlockSplitter);
|
2739
|
+
assert(cctxParams->postBlockSplitter != ZSTD_ps_auto);
|
2740
|
+
return (cctxParams->postBlockSplitter == ZSTD_ps_enable);
|
2729
2741
|
}
|
2730
2742
|
|
2731
2743
|
/* Type returned by ZSTD_buildSequencesStatistics containing finalized symbol encoding types
|
@@ -2749,7 +2761,7 @@ typedef struct {
|
|
2749
2761
|
*/
|
2750
2762
|
static ZSTD_symbolEncodingTypeStats_t
|
2751
2763
|
ZSTD_buildSequencesStatistics(
|
2752
|
-
const
|
2764
|
+
const SeqStore_t* seqStorePtr, size_t nbSeq,
|
2753
2765
|
const ZSTD_fseCTables_t* prevEntropy, ZSTD_fseCTables_t* nextEntropy,
|
2754
2766
|
BYTE* dst, const BYTE* const dstEnd,
|
2755
2767
|
ZSTD_strategy strategy, unsigned* countWorkspace,
|
@@ -2785,7 +2797,7 @@ ZSTD_buildSequencesStatistics(
|
|
2785
2797
|
assert(!(stats.LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
2786
2798
|
{ size_t const countSize = ZSTD_buildCTable(
|
2787
2799
|
op, (size_t)(oend - op),
|
2788
|
-
CTable_LitLength, LLFSELog, (
|
2800
|
+
CTable_LitLength, LLFSELog, (SymbolEncodingType_e)stats.LLtype,
|
2789
2801
|
countWorkspace, max, llCodeTable, nbSeq,
|
2790
2802
|
LL_defaultNorm, LL_defaultNormLog, MaxLL,
|
2791
2803
|
prevEntropy->litlengthCTable,
|
@@ -2806,7 +2818,7 @@ ZSTD_buildSequencesStatistics(
|
|
2806
2818
|
size_t const mostFrequent = HIST_countFast_wksp(
|
2807
2819
|
countWorkspace, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize); /* can't fail */
|
2808
2820
|
/* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
|
2809
|
-
|
2821
|
+
ZSTD_DefaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
|
2810
2822
|
DEBUGLOG(5, "Building OF table");
|
2811
2823
|
nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
|
2812
2824
|
stats.Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode,
|
@@ -2817,7 +2829,7 @@ ZSTD_buildSequencesStatistics(
|
|
2817
2829
|
assert(!(stats.Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
2818
2830
|
{ size_t const countSize = ZSTD_buildCTable(
|
2819
2831
|
op, (size_t)(oend - op),
|
2820
|
-
CTable_OffsetBits, OffFSELog, (
|
2832
|
+
CTable_OffsetBits, OffFSELog, (SymbolEncodingType_e)stats.Offtype,
|
2821
2833
|
countWorkspace, max, ofCodeTable, nbSeq,
|
2822
2834
|
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
|
2823
2835
|
prevEntropy->offcodeCTable,
|
@@ -2847,7 +2859,7 @@ ZSTD_buildSequencesStatistics(
|
|
2847
2859
|
assert(!(stats.MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
2848
2860
|
{ size_t const countSize = ZSTD_buildCTable(
|
2849
2861
|
op, (size_t)(oend - op),
|
2850
|
-
CTable_MatchLength, MLFSELog, (
|
2862
|
+
CTable_MatchLength, MLFSELog, (SymbolEncodingType_e)stats.MLtype,
|
2851
2863
|
countWorkspace, max, mlCodeTable, nbSeq,
|
2852
2864
|
ML_defaultNorm, ML_defaultNormLog, MaxML,
|
2853
2865
|
prevEntropy->matchlengthCTable,
|
@@ -2874,11 +2886,12 @@ ZSTD_buildSequencesStatistics(
|
|
2874
2886
|
#define SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO 20
|
2875
2887
|
MEM_STATIC size_t
|
2876
2888
|
ZSTD_entropyCompressSeqStore_internal(
|
2877
|
-
|
2889
|
+
void* dst, size_t dstCapacity,
|
2890
|
+
const void* literals, size_t litSize,
|
2891
|
+
const SeqStore_t* seqStorePtr,
|
2878
2892
|
const ZSTD_entropyCTables_t* prevEntropy,
|
2879
2893
|
ZSTD_entropyCTables_t* nextEntropy,
|
2880
2894
|
const ZSTD_CCtx_params* cctxParams,
|
2881
|
-
void* dst, size_t dstCapacity,
|
2882
2895
|
void* entropyWorkspace, size_t entropyWkspSize,
|
2883
2896
|
const int bmi2)
|
2884
2897
|
{
|
@@ -2887,7 +2900,7 @@ ZSTD_entropyCompressSeqStore_internal(
|
|
2887
2900
|
FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
|
2888
2901
|
FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
|
2889
2902
|
FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
|
2890
|
-
const
|
2903
|
+
const SeqDef* const sequences = seqStorePtr->sequencesStart;
|
2891
2904
|
const size_t nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
2892
2905
|
const BYTE* const ofCodeTable = seqStorePtr->ofCode;
|
2893
2906
|
const BYTE* const llCodeTable = seqStorePtr->llCode;
|
@@ -2906,12 +2919,9 @@ ZSTD_entropyCompressSeqStore_internal(
|
|
2906
2919
|
assert(entropyWkspSize >= HUF_WORKSPACE_SIZE);
|
2907
2920
|
|
2908
2921
|
/* Compress literals */
|
2909
|
-
{
|
2910
|
-
size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
2911
|
-
size_t const numLiterals = (size_t)(seqStorePtr->lit - seqStorePtr->litStart);
|
2922
|
+
{ size_t const numSequences = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
2912
2923
|
/* Base suspicion of uncompressibility on ratio of literals to sequences */
|
2913
|
-
|
2914
|
-
size_t const litSize = (size_t)(seqStorePtr->lit - literals);
|
2924
|
+
int const suspectUncompressible = (numSequences == 0) || (litSize / numSequences >= SUSPECT_UNCOMPRESSIBLE_LITERAL_RATIO);
|
2915
2925
|
|
2916
2926
|
size_t const cSize = ZSTD_compressLiterals(
|
2917
2927
|
op, dstCapacity,
|
@@ -2992,33 +3002,35 @@ ZSTD_entropyCompressSeqStore_internal(
|
|
2992
3002
|
return (size_t)(op - ostart);
|
2993
3003
|
}
|
2994
3004
|
|
2995
|
-
|
2996
|
-
|
2997
|
-
|
3005
|
+
static size_t
|
3006
|
+
ZSTD_entropyCompressSeqStore_wExtLitBuffer(
|
3007
|
+
void* dst, size_t dstCapacity,
|
3008
|
+
const void* literals, size_t litSize,
|
3009
|
+
size_t blockSize,
|
3010
|
+
const SeqStore_t* seqStorePtr,
|
2998
3011
|
const ZSTD_entropyCTables_t* prevEntropy,
|
2999
3012
|
ZSTD_entropyCTables_t* nextEntropy,
|
3000
3013
|
const ZSTD_CCtx_params* cctxParams,
|
3001
|
-
void* dst, size_t dstCapacity,
|
3002
|
-
size_t srcSize,
|
3003
3014
|
void* entropyWorkspace, size_t entropyWkspSize,
|
3004
3015
|
int bmi2)
|
3005
3016
|
{
|
3006
3017
|
size_t const cSize = ZSTD_entropyCompressSeqStore_internal(
|
3007
|
-
seqStorePtr, prevEntropy, nextEntropy, cctxParams,
|
3008
3018
|
dst, dstCapacity,
|
3019
|
+
literals, litSize,
|
3020
|
+
seqStorePtr, prevEntropy, nextEntropy, cctxParams,
|
3009
3021
|
entropyWorkspace, entropyWkspSize, bmi2);
|
3010
3022
|
if (cSize == 0) return 0;
|
3011
3023
|
/* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
|
3012
3024
|
* Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
|
3013
3025
|
*/
|
3014
|
-
if ((cSize == ERROR(dstSize_tooSmall)) & (
|
3026
|
+
if ((cSize == ERROR(dstSize_tooSmall)) & (blockSize <= dstCapacity)) {
|
3015
3027
|
DEBUGLOG(4, "not enough dstCapacity (%zu) for ZSTD_entropyCompressSeqStore_internal()=> do not compress block", dstCapacity);
|
3016
3028
|
return 0; /* block not compressed */
|
3017
3029
|
}
|
3018
3030
|
FORWARD_IF_ERROR(cSize, "ZSTD_entropyCompressSeqStore_internal failed");
|
3019
3031
|
|
3020
3032
|
/* Check compressibility */
|
3021
|
-
{ size_t const maxCSize =
|
3033
|
+
{ size_t const maxCSize = blockSize - ZSTD_minGain(blockSize, cctxParams->cParams.strategy);
|
3022
3034
|
if (cSize >= maxCSize) return 0; /* block not compressed */
|
3023
3035
|
}
|
3024
3036
|
DEBUGLOG(5, "ZSTD_entropyCompressSeqStore() cSize: %zu", cSize);
|
@@ -3029,12 +3041,34 @@ ZSTD_entropyCompressSeqStore(
|
|
3029
3041
|
return cSize;
|
3030
3042
|
}
|
3031
3043
|
|
3044
|
+
static size_t
|
3045
|
+
ZSTD_entropyCompressSeqStore(
|
3046
|
+
const SeqStore_t* seqStorePtr,
|
3047
|
+
const ZSTD_entropyCTables_t* prevEntropy,
|
3048
|
+
ZSTD_entropyCTables_t* nextEntropy,
|
3049
|
+
const ZSTD_CCtx_params* cctxParams,
|
3050
|
+
void* dst, size_t dstCapacity,
|
3051
|
+
size_t srcSize,
|
3052
|
+
void* entropyWorkspace, size_t entropyWkspSize,
|
3053
|
+
int bmi2)
|
3054
|
+
{
|
3055
|
+
return ZSTD_entropyCompressSeqStore_wExtLitBuffer(
|
3056
|
+
dst, dstCapacity,
|
3057
|
+
seqStorePtr->litStart, (size_t)(seqStorePtr->lit - seqStorePtr->litStart),
|
3058
|
+
srcSize,
|
3059
|
+
seqStorePtr,
|
3060
|
+
prevEntropy, nextEntropy,
|
3061
|
+
cctxParams,
|
3062
|
+
entropyWorkspace, entropyWkspSize,
|
3063
|
+
bmi2);
|
3064
|
+
}
|
3065
|
+
|
3032
3066
|
/* ZSTD_selectBlockCompressor() :
|
3033
3067
|
* Not static, but internal use only (used by long distance matcher)
|
3034
3068
|
* assumption : strat is a valid strategy */
|
3035
|
-
|
3069
|
+
ZSTD_BlockCompressor_f ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_ParamSwitch_e useRowMatchFinder, ZSTD_dictMode_e dictMode)
|
3036
3070
|
{
|
3037
|
-
static const
|
3071
|
+
static const ZSTD_BlockCompressor_f blockCompressor[4][ZSTD_STRATEGY_MAX+1] = {
|
3038
3072
|
{ ZSTD_compressBlock_fast /* default for 0 */,
|
3039
3073
|
ZSTD_compressBlock_fast,
|
3040
3074
|
ZSTD_COMPRESSBLOCK_DOUBLEFAST,
|
@@ -3079,13 +3113,13 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS
|
|
3079
3113
|
NULL,
|
3080
3114
|
NULL }
|
3081
3115
|
};
|
3082
|
-
|
3116
|
+
ZSTD_BlockCompressor_f selectedCompressor;
|
3083
3117
|
ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
|
3084
3118
|
|
3085
|
-
assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
|
3086
|
-
DEBUGLOG(
|
3119
|
+
assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat));
|
3120
|
+
DEBUGLOG(5, "Selected block compressor: dictMode=%d strat=%d rowMatchfinder=%d", (int)dictMode, (int)strat, (int)useRowMatchFinder);
|
3087
3121
|
if (ZSTD_rowMatchFinderUsed(strat, useRowMatchFinder)) {
|
3088
|
-
static const
|
3122
|
+
static const ZSTD_BlockCompressor_f rowBasedBlockCompressors[4][3] = {
|
3089
3123
|
{
|
3090
3124
|
ZSTD_COMPRESSBLOCK_GREEDY_ROW,
|
3091
3125
|
ZSTD_COMPRESSBLOCK_LAZY_ROW,
|
@@ -3107,7 +3141,7 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS
|
|
3107
3141
|
ZSTD_COMPRESSBLOCK_LAZY2_DEDICATEDDICTSEARCH_ROW
|
3108
3142
|
}
|
3109
3143
|
};
|
3110
|
-
DEBUGLOG(
|
3144
|
+
DEBUGLOG(5, "Selecting a row-based matchfinder");
|
3111
3145
|
assert(useRowMatchFinder != ZSTD_ps_auto);
|
3112
3146
|
selectedCompressor = rowBasedBlockCompressors[(int)dictMode][(int)strat - (int)ZSTD_greedy];
|
3113
3147
|
} else {
|
@@ -3117,14 +3151,14 @@ ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_paramS
|
|
3117
3151
|
return selectedCompressor;
|
3118
3152
|
}
|
3119
3153
|
|
3120
|
-
static void ZSTD_storeLastLiterals(
|
3154
|
+
static void ZSTD_storeLastLiterals(SeqStore_t* seqStorePtr,
|
3121
3155
|
const BYTE* anchor, size_t lastLLSize)
|
3122
3156
|
{
|
3123
3157
|
ZSTD_memcpy(seqStorePtr->lit, anchor, lastLLSize);
|
3124
3158
|
seqStorePtr->lit += lastLLSize;
|
3125
3159
|
}
|
3126
3160
|
|
3127
|
-
void ZSTD_resetSeqStore(
|
3161
|
+
void ZSTD_resetSeqStore(SeqStore_t* ssPtr)
|
3128
3162
|
{
|
3129
3163
|
ssPtr->lit = ssPtr->litStart;
|
3130
3164
|
ssPtr->sequences = ssPtr->sequencesStart;
|
@@ -3197,11 +3231,39 @@ static size_t ZSTD_fastSequenceLengthSum(ZSTD_Sequence const* seqBuf, size_t seq
|
|
3197
3231
|
return litLenSum + matchLenSum;
|
3198
3232
|
}
|
3199
3233
|
|
3200
|
-
|
3234
|
+
/**
|
3235
|
+
* Function to validate sequences produced by a block compressor.
|
3236
|
+
*/
|
3237
|
+
static void ZSTD_validateSeqStore(const SeqStore_t* seqStore, const ZSTD_compressionParameters* cParams)
|
3238
|
+
{
|
3239
|
+
#if DEBUGLEVEL >= 1
|
3240
|
+
const SeqDef* seq = seqStore->sequencesStart;
|
3241
|
+
const SeqDef* const seqEnd = seqStore->sequences;
|
3242
|
+
size_t const matchLenLowerBound = cParams->minMatch == 3 ? 3 : 4;
|
3243
|
+
for (; seq < seqEnd; ++seq) {
|
3244
|
+
const ZSTD_SequenceLength seqLength = ZSTD_getSequenceLength(seqStore, seq);
|
3245
|
+
assert(seqLength.matchLength >= matchLenLowerBound);
|
3246
|
+
(void)seqLength;
|
3247
|
+
(void)matchLenLowerBound;
|
3248
|
+
}
|
3249
|
+
#else
|
3250
|
+
(void)seqStore;
|
3251
|
+
(void)cParams;
|
3252
|
+
#endif
|
3253
|
+
}
|
3254
|
+
|
3255
|
+
static size_t
|
3256
|
+
ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx,
|
3257
|
+
ZSTD_SequencePosition* seqPos,
|
3258
|
+
const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
|
3259
|
+
const void* src, size_t blockSize,
|
3260
|
+
ZSTD_ParamSwitch_e externalRepSearch);
|
3261
|
+
|
3262
|
+
typedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_BuildSeqStore_e;
|
3201
3263
|
|
3202
3264
|
static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
3203
3265
|
{
|
3204
|
-
|
3266
|
+
ZSTD_MatchState_t* const ms = &zc->blockState.matchState;
|
3205
3267
|
DEBUGLOG(5, "ZSTD_buildSeqStore (srcSize=%zu)", srcSize);
|
3206
3268
|
assert(srcSize <= ZSTD_BLOCKSIZE_MAX);
|
3207
3269
|
/* Assert that we have correctly flushed the ctx params into the ms's copy */
|
@@ -3262,7 +3324,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
|
3262
3324
|
src, srcSize);
|
3263
3325
|
assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
|
3264
3326
|
} else if (zc->appliedParams.ldmParams.enableLdm == ZSTD_ps_enable) {
|
3265
|
-
|
3327
|
+
RawSeqStore_t ldmSeqStore = kNullRawSeqStore;
|
3266
3328
|
|
3267
3329
|
/* External matchfinder + LDM is technically possible, just not implemented yet.
|
3268
3330
|
* We need to revisit soon and implement it. */
|
@@ -3313,11 +3375,11 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
|
3313
3375
|
|
3314
3376
|
/* Return early if there is no error, since we don't need to worry about last literals */
|
3315
3377
|
if (!ZSTD_isError(nbPostProcessedSeqs)) {
|
3316
|
-
|
3378
|
+
ZSTD_SequencePosition seqPos = {0,0,0};
|
3317
3379
|
size_t const seqLenSum = ZSTD_fastSequenceLengthSum(zc->extSeqBuf, nbPostProcessedSeqs);
|
3318
3380
|
RETURN_ERROR_IF(seqLenSum > srcSize, externalSequences_invalid, "External sequences imply too large a block!");
|
3319
3381
|
FORWARD_IF_ERROR(
|
3320
|
-
|
3382
|
+
ZSTD_transferSequences_wBlockDelim(
|
3321
3383
|
zc, &seqPos,
|
3322
3384
|
zc->extSeqBuf, nbPostProcessedSeqs,
|
3323
3385
|
src, srcSize,
|
@@ -3336,7 +3398,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
|
3336
3398
|
}
|
3337
3399
|
|
3338
3400
|
/* Fallback to software matchfinder */
|
3339
|
-
{
|
3401
|
+
{ ZSTD_BlockCompressor_f const blockCompressor =
|
3340
3402
|
ZSTD_selectBlockCompressor(
|
3341
3403
|
zc->appliedParams.cParams.strategy,
|
3342
3404
|
zc->appliedParams.useRowMatchFinder,
|
@@ -3350,7 +3412,7 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
|
3350
3412
|
lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);
|
3351
3413
|
} }
|
3352
3414
|
} else { /* not long range mode and no external matchfinder */
|
3353
|
-
|
3415
|
+
ZSTD_BlockCompressor_f const blockCompressor = ZSTD_selectBlockCompressor(
|
3354
3416
|
zc->appliedParams.cParams.strategy,
|
3355
3417
|
zc->appliedParams.useRowMatchFinder,
|
3356
3418
|
dictMode);
|
@@ -3360,19 +3422,20 @@ static size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)
|
|
3360
3422
|
{ const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
|
3361
3423
|
ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);
|
3362
3424
|
} }
|
3425
|
+
ZSTD_validateSeqStore(&zc->seqStore, &zc->appliedParams.cParams);
|
3363
3426
|
return ZSTDbss_compress;
|
3364
3427
|
}
|
3365
3428
|
|
3366
|
-
static size_t ZSTD_copyBlockSequences(SeqCollector* seqCollector, const
|
3429
|
+
static size_t ZSTD_copyBlockSequences(SeqCollector* seqCollector, const SeqStore_t* seqStore, const U32 prevRepcodes[ZSTD_REP_NUM])
|
3367
3430
|
{
|
3368
|
-
const
|
3369
|
-
const size_t nbInSequences = seqStore->sequences - inSeqs;
|
3431
|
+
const SeqDef* inSeqs = seqStore->sequencesStart;
|
3432
|
+
const size_t nbInSequences = (size_t)(seqStore->sequences - inSeqs);
|
3370
3433
|
const size_t nbInLiterals = (size_t)(seqStore->lit - seqStore->litStart);
|
3371
3434
|
|
3372
3435
|
ZSTD_Sequence* outSeqs = seqCollector->seqIndex == 0 ? seqCollector->seqStart : seqCollector->seqStart + seqCollector->seqIndex;
|
3373
3436
|
const size_t nbOutSequences = nbInSequences + 1;
|
3374
3437
|
size_t nbOutLiterals = 0;
|
3375
|
-
|
3438
|
+
Repcodes_t repcodes;
|
3376
3439
|
size_t i;
|
3377
3440
|
|
3378
3441
|
/* Bounds check that we have enough space for every input sequence
|
@@ -3458,7 +3521,7 @@ size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
|
|
3458
3521
|
size_t outSeqsSize, const void* src, size_t srcSize)
|
3459
3522
|
{
|
3460
3523
|
const size_t dstCapacity = ZSTD_compressBound(srcSize);
|
3461
|
-
void* dst
|
3524
|
+
void* dst; /* Make C90 happy. */
|
3462
3525
|
SeqCollector seqCollector;
|
3463
3526
|
{
|
3464
3527
|
int targetCBlockSize;
|
@@ -3471,6 +3534,7 @@ size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
|
|
3471
3534
|
RETURN_ERROR_IF(nbWorkers != 0, parameter_unsupported, "nbWorkers != 0");
|
3472
3535
|
}
|
3473
3536
|
|
3537
|
+
dst = ZSTD_customMalloc(dstCapacity, ZSTD_defaultCMem);
|
3474
3538
|
RETURN_ERROR_IF(dst == NULL, memory_allocation, "NULL pointer!");
|
3475
3539
|
|
3476
3540
|
seqCollector.collectSequences = 1;
|
@@ -3531,7 +3595,7 @@ static int ZSTD_isRLE(const BYTE* src, size_t length) {
|
|
3531
3595
|
* This is just a heuristic based on the compressibility.
|
3532
3596
|
* It may return both false positives and false negatives.
|
3533
3597
|
*/
|
3534
|
-
static int ZSTD_maybeRLE(
|
3598
|
+
static int ZSTD_maybeRLE(SeqStore_t const* seqStore)
|
3535
3599
|
{
|
3536
3600
|
size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
|
3537
3601
|
size_t const nbLits = (size_t)(seqStore->lit - seqStore->litStart);
|
@@ -3555,7 +3619,7 @@ writeBlockHeader(void* op, size_t cSize, size_t blockSize, U32 lastBlock)
|
|
3555
3619
|
lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :
|
3556
3620
|
lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
|
3557
3621
|
MEM_writeLE24(op, cBlockHeader);
|
3558
|
-
DEBUGLOG(
|
3622
|
+
DEBUGLOG(5, "writeBlockHeader: cSize: %zu blockSize: %zu lastBlock: %u", cSize, blockSize, lastBlock);
|
3559
3623
|
}
|
3560
3624
|
|
3561
3625
|
/** ZSTD_buildBlockEntropyStats_literals() :
|
@@ -3693,7 +3757,7 @@ ZSTD_buildDummySequencesStatistics(ZSTD_fseCTables_t* nextEntropy)
|
|
3693
3757
|
* @return : size of fse tables or error code */
|
3694
3758
|
static size_t
|
3695
3759
|
ZSTD_buildBlockEntropyStats_sequences(
|
3696
|
-
const
|
3760
|
+
const SeqStore_t* seqStorePtr,
|
3697
3761
|
const ZSTD_fseCTables_t* prevEntropy,
|
3698
3762
|
ZSTD_fseCTables_t* nextEntropy,
|
3699
3763
|
const ZSTD_CCtx_params* cctxParams,
|
@@ -3717,9 +3781,9 @@ ZSTD_buildBlockEntropyStats_sequences(
|
|
3717
3781
|
entropyWorkspace, entropyWorkspaceSize)
|
3718
3782
|
: ZSTD_buildDummySequencesStatistics(nextEntropy);
|
3719
3783
|
FORWARD_IF_ERROR(stats.size, "ZSTD_buildSequencesStatistics failed!");
|
3720
|
-
fseMetadata->llType = (
|
3721
|
-
fseMetadata->ofType = (
|
3722
|
-
fseMetadata->mlType = (
|
3784
|
+
fseMetadata->llType = (SymbolEncodingType_e) stats.LLtype;
|
3785
|
+
fseMetadata->ofType = (SymbolEncodingType_e) stats.Offtype;
|
3786
|
+
fseMetadata->mlType = (SymbolEncodingType_e) stats.MLtype;
|
3723
3787
|
fseMetadata->lastCountSize = stats.lastCountSize;
|
3724
3788
|
return stats.size;
|
3725
3789
|
}
|
@@ -3732,7 +3796,7 @@ ZSTD_buildBlockEntropyStats_sequences(
|
|
3732
3796
|
* Note : also employed in superblock
|
3733
3797
|
*/
|
3734
3798
|
size_t ZSTD_buildBlockEntropyStats(
|
3735
|
-
const
|
3799
|
+
const SeqStore_t* seqStorePtr,
|
3736
3800
|
const ZSTD_entropyCTables_t* prevEntropy,
|
3737
3801
|
ZSTD_entropyCTables_t* nextEntropy,
|
3738
3802
|
const ZSTD_CCtx_params* cctxParams,
|
@@ -3790,7 +3854,7 @@ ZSTD_estimateBlockSize_literal(const BYTE* literals, size_t litSize,
|
|
3790
3854
|
|
3791
3855
|
/* Returns the size estimate for the FSE-compressed symbols (of, ml, ll) of a block */
|
3792
3856
|
static size_t
|
3793
|
-
ZSTD_estimateBlockSize_symbolType(
|
3857
|
+
ZSTD_estimateBlockSize_symbolType(SymbolEncodingType_e type,
|
3794
3858
|
const BYTE* codeTable, size_t nbSeq, unsigned maxCode,
|
3795
3859
|
const FSE_CTable* fseCTable,
|
3796
3860
|
const U8* additionalBits,
|
@@ -3881,7 +3945,7 @@ ZSTD_estimateBlockSize(const BYTE* literals, size_t litSize,
|
|
3881
3945
|
* @return: estimated compressed size of the seqStore, or a zstd error.
|
3882
3946
|
*/
|
3883
3947
|
static size_t
|
3884
|
-
ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(
|
3948
|
+
ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(SeqStore_t* seqStore, ZSTD_CCtx* zc)
|
3885
3949
|
{
|
3886
3950
|
ZSTD_entropyCTablesMetadata_t* const entropyMetadata = &zc->blockSplitCtx.entropyMetadata;
|
3887
3951
|
DEBUGLOG(6, "ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize()");
|
@@ -3890,25 +3954,25 @@ ZSTD_buildEntropyStatisticsAndEstimateSubBlockSize(seqStore_t* seqStore, ZSTD_CC
|
|
3890
3954
|
&zc->blockState.nextCBlock->entropy,
|
3891
3955
|
&zc->appliedParams,
|
3892
3956
|
entropyMetadata,
|
3893
|
-
zc->
|
3957
|
+
zc->tmpWorkspace, zc->tmpWkspSize), "");
|
3894
3958
|
return ZSTD_estimateBlockSize(
|
3895
3959
|
seqStore->litStart, (size_t)(seqStore->lit - seqStore->litStart),
|
3896
3960
|
seqStore->ofCode, seqStore->llCode, seqStore->mlCode,
|
3897
3961
|
(size_t)(seqStore->sequences - seqStore->sequencesStart),
|
3898
3962
|
&zc->blockState.nextCBlock->entropy,
|
3899
3963
|
entropyMetadata,
|
3900
|
-
zc->
|
3964
|
+
zc->tmpWorkspace, zc->tmpWkspSize,
|
3901
3965
|
(int)(entropyMetadata->hufMetadata.hType == set_compressed), 1);
|
3902
3966
|
}
|
3903
3967
|
|
3904
3968
|
/* Returns literals bytes represented in a seqStore */
|
3905
|
-
static size_t ZSTD_countSeqStoreLiteralsBytes(const
|
3969
|
+
static size_t ZSTD_countSeqStoreLiteralsBytes(const SeqStore_t* const seqStore)
|
3906
3970
|
{
|
3907
3971
|
size_t literalsBytes = 0;
|
3908
3972
|
size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
|
3909
3973
|
size_t i;
|
3910
3974
|
for (i = 0; i < nbSeqs; ++i) {
|
3911
|
-
|
3975
|
+
SeqDef const seq = seqStore->sequencesStart[i];
|
3912
3976
|
literalsBytes += seq.litLength;
|
3913
3977
|
if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_literalLength) {
|
3914
3978
|
literalsBytes += 0x10000;
|
@@ -3917,13 +3981,13 @@ static size_t ZSTD_countSeqStoreLiteralsBytes(const seqStore_t* const seqStore)
|
|
3917
3981
|
}
|
3918
3982
|
|
3919
3983
|
/* Returns match bytes represented in a seqStore */
|
3920
|
-
static size_t ZSTD_countSeqStoreMatchBytes(const
|
3984
|
+
static size_t ZSTD_countSeqStoreMatchBytes(const SeqStore_t* const seqStore)
|
3921
3985
|
{
|
3922
3986
|
size_t matchBytes = 0;
|
3923
3987
|
size_t const nbSeqs = (size_t)(seqStore->sequences - seqStore->sequencesStart);
|
3924
3988
|
size_t i;
|
3925
3989
|
for (i = 0; i < nbSeqs; ++i) {
|
3926
|
-
|
3990
|
+
SeqDef seq = seqStore->sequencesStart[i];
|
3927
3991
|
matchBytes += seq.mlBase + MINMATCH;
|
3928
3992
|
if (i == seqStore->longLengthPos && seqStore->longLengthType == ZSTD_llt_matchLength) {
|
3929
3993
|
matchBytes += 0x10000;
|
@@ -3934,8 +3998,8 @@ static size_t ZSTD_countSeqStoreMatchBytes(const seqStore_t* const seqStore)
|
|
3934
3998
|
/* Derives the seqStore that is a chunk of the originalSeqStore from [startIdx, endIdx).
|
3935
3999
|
* Stores the result in resultSeqStore.
|
3936
4000
|
*/
|
3937
|
-
static void ZSTD_deriveSeqStoreChunk(
|
3938
|
-
const
|
4001
|
+
static void ZSTD_deriveSeqStoreChunk(SeqStore_t* resultSeqStore,
|
4002
|
+
const SeqStore_t* originalSeqStore,
|
3939
4003
|
size_t startIdx, size_t endIdx)
|
3940
4004
|
{
|
3941
4005
|
*resultSeqStore = *originalSeqStore;
|
@@ -4003,13 +4067,13 @@ ZSTD_resolveRepcodeToRawOffset(const U32 rep[ZSTD_REP_NUM], const U32 offBase, c
|
|
4003
4067
|
* 4+ : real_offset+3
|
4004
4068
|
*/
|
4005
4069
|
static void
|
4006
|
-
ZSTD_seqStore_resolveOffCodes(
|
4007
|
-
const
|
4070
|
+
ZSTD_seqStore_resolveOffCodes(Repcodes_t* const dRepcodes, Repcodes_t* const cRepcodes,
|
4071
|
+
const SeqStore_t* const seqStore, U32 const nbSeq)
|
4008
4072
|
{
|
4009
4073
|
U32 idx = 0;
|
4010
4074
|
U32 const longLitLenIdx = seqStore->longLengthType == ZSTD_llt_literalLength ? seqStore->longLengthPos : nbSeq;
|
4011
4075
|
for (; idx < nbSeq; ++idx) {
|
4012
|
-
|
4076
|
+
SeqDef* const seq = seqStore->sequencesStart + idx;
|
4013
4077
|
U32 const ll0 = (seq->litLength == 0) && (idx != longLitLenIdx);
|
4014
4078
|
U32 const offBase = seq->offBase;
|
4015
4079
|
assert(offBase > 0);
|
@@ -4039,8 +4103,8 @@ ZSTD_seqStore_resolveOffCodes(repcodes_t* const dRepcodes, repcodes_t* const cRe
|
|
4039
4103
|
*/
|
4040
4104
|
static size_t
|
4041
4105
|
ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc,
|
4042
|
-
const
|
4043
|
-
|
4106
|
+
const SeqStore_t* const seqStore,
|
4107
|
+
Repcodes_t* const dRep, Repcodes_t* const cRep,
|
4044
4108
|
void* dst, size_t dstCapacity,
|
4045
4109
|
const void* src, size_t srcSize,
|
4046
4110
|
U32 lastBlock, U32 isPartition)
|
@@ -4052,7 +4116,7 @@ ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc,
|
|
4052
4116
|
size_t cSeqsSize;
|
4053
4117
|
|
4054
4118
|
/* In case of an RLE or raw block, the simulated decompression repcode history must be reset */
|
4055
|
-
|
4119
|
+
Repcodes_t const dRepOriginal = *dRep;
|
4056
4120
|
DEBUGLOG(5, "ZSTD_compressSeqStore_singleBlock");
|
4057
4121
|
if (isPartition)
|
4058
4122
|
ZSTD_seqStore_resolveOffCodes(dRep, cRep, seqStore, (U32)(seqStore->sequences - seqStore->sequencesStart));
|
@@ -4063,7 +4127,7 @@ ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc,
|
|
4063
4127
|
&zc->appliedParams,
|
4064
4128
|
op + ZSTD_blockHeaderSize, dstCapacity - ZSTD_blockHeaderSize,
|
4065
4129
|
srcSize,
|
4066
|
-
zc->
|
4130
|
+
zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */,
|
4067
4131
|
zc->bmi2);
|
4068
4132
|
FORWARD_IF_ERROR(cSeqsSize, "ZSTD_entropyCompressSeqStore failed!");
|
4069
4133
|
|
@@ -4087,18 +4151,18 @@ ZSTD_compressSeqStore_singleBlock(ZSTD_CCtx* zc,
|
|
4087
4151
|
if (cSeqsSize == 0) {
|
4088
4152
|
cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, srcSize, lastBlock);
|
4089
4153
|
FORWARD_IF_ERROR(cSize, "Nocompress block failed");
|
4090
|
-
DEBUGLOG(
|
4154
|
+
DEBUGLOG(5, "Writing out nocompress block, size: %zu", cSize);
|
4091
4155
|
*dRep = dRepOriginal; /* reset simulated decompression repcode history */
|
4092
4156
|
} else if (cSeqsSize == 1) {
|
4093
4157
|
cSize = ZSTD_rleCompressBlock(op, dstCapacity, *ip, srcSize, lastBlock);
|
4094
4158
|
FORWARD_IF_ERROR(cSize, "RLE compress block failed");
|
4095
|
-
DEBUGLOG(
|
4159
|
+
DEBUGLOG(5, "Writing out RLE block, size: %zu", cSize);
|
4096
4160
|
*dRep = dRepOriginal; /* reset simulated decompression repcode history */
|
4097
4161
|
} else {
|
4098
4162
|
ZSTD_blockState_confirmRepcodesAndEntropyTables(&zc->blockState);
|
4099
4163
|
writeBlockHeader(op, cSeqsSize, srcSize, lastBlock);
|
4100
4164
|
cSize = ZSTD_blockHeaderSize + cSeqsSize;
|
4101
|
-
DEBUGLOG(
|
4165
|
+
DEBUGLOG(5, "Writing out compressed block, size: %zu", cSize);
|
4102
4166
|
}
|
4103
4167
|
|
4104
4168
|
if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
|
@@ -4131,11 +4195,11 @@ typedef struct {
|
|
4131
4195
|
*/
|
4132
4196
|
static void
|
4133
4197
|
ZSTD_deriveBlockSplitsHelper(seqStoreSplits* splits, size_t startIdx, size_t endIdx,
|
4134
|
-
ZSTD_CCtx* zc, const
|
4198
|
+
ZSTD_CCtx* zc, const SeqStore_t* origSeqStore)
|
4135
4199
|
{
|
4136
|
-
|
4137
|
-
|
4138
|
-
|
4200
|
+
SeqStore_t* const fullSeqStoreChunk = &zc->blockSplitCtx.fullSeqStoreChunk;
|
4201
|
+
SeqStore_t* const firstHalfSeqStore = &zc->blockSplitCtx.firstHalfSeqStore;
|
4202
|
+
SeqStore_t* const secondHalfSeqStore = &zc->blockSplitCtx.secondHalfSeqStore;
|
4139
4203
|
size_t estimatedOriginalSize;
|
4140
4204
|
size_t estimatedFirstHalfSize;
|
4141
4205
|
size_t estimatedSecondHalfSize;
|
@@ -4205,8 +4269,8 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc,
|
|
4205
4269
|
size_t i = 0;
|
4206
4270
|
size_t srcBytesTotal = 0;
|
4207
4271
|
U32* const partitions = zc->blockSplitCtx.partitions; /* size == ZSTD_MAX_NB_BLOCK_SPLITS */
|
4208
|
-
|
4209
|
-
|
4272
|
+
SeqStore_t* const nextSeqStore = &zc->blockSplitCtx.nextSeqStore;
|
4273
|
+
SeqStore_t* const currSeqStore = &zc->blockSplitCtx.currSeqStore;
|
4210
4274
|
size_t const numSplits = ZSTD_deriveBlockSplits(zc, partitions, nbSeq);
|
4211
4275
|
|
4212
4276
|
/* If a block is split and some partitions are emitted as RLE/uncompressed, then repcode history
|
@@ -4223,11 +4287,11 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc,
|
|
4223
4287
|
*
|
4224
4288
|
* See ZSTD_seqStore_resolveOffCodes() for more details.
|
4225
4289
|
*/
|
4226
|
-
|
4227
|
-
|
4228
|
-
ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(
|
4229
|
-
ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(
|
4230
|
-
ZSTD_memset(nextSeqStore, 0, sizeof(
|
4290
|
+
Repcodes_t dRep;
|
4291
|
+
Repcodes_t cRep;
|
4292
|
+
ZSTD_memcpy(dRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t));
|
4293
|
+
ZSTD_memcpy(cRep.rep, zc->blockState.prevCBlock->rep, sizeof(Repcodes_t));
|
4294
|
+
ZSTD_memset(nextSeqStore, 0, sizeof(SeqStore_t));
|
4231
4295
|
|
4232
4296
|
DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)",
|
4233
4297
|
(unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,
|
@@ -4242,8 +4306,8 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc,
|
|
4242
4306
|
lastBlock, 0 /* isPartition */);
|
4243
4307
|
FORWARD_IF_ERROR(cSizeSingleBlock, "Compressing single block from splitBlock_internal() failed!");
|
4244
4308
|
DEBUGLOG(5, "ZSTD_compressBlock_splitBlock_internal: No splits");
|
4245
|
-
assert(zc->
|
4246
|
-
assert(cSizeSingleBlock <= zc->
|
4309
|
+
assert(zc->blockSizeMax <= ZSTD_BLOCKSIZE_MAX);
|
4310
|
+
assert(cSizeSingleBlock <= zc->blockSizeMax + ZSTD_blockHeaderSize);
|
4247
4311
|
return cSizeSingleBlock;
|
4248
4312
|
}
|
4249
4313
|
|
@@ -4277,12 +4341,12 @@ ZSTD_compressBlock_splitBlock_internal(ZSTD_CCtx* zc,
|
|
4277
4341
|
dstCapacity -= cSizeChunk;
|
4278
4342
|
cSize += cSizeChunk;
|
4279
4343
|
*currSeqStore = *nextSeqStore;
|
4280
|
-
assert(cSizeChunk <= zc->
|
4344
|
+
assert(cSizeChunk <= zc->blockSizeMax + ZSTD_blockHeaderSize);
|
4281
4345
|
}
|
4282
4346
|
/* cRep and dRep may have diverged during the compression.
|
4283
4347
|
* If so, we use the dRep repcodes for the next block.
|
4284
4348
|
*/
|
4285
|
-
ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(
|
4349
|
+
ZSTD_memcpy(zc->blockState.prevCBlock->rep, dRep.rep, sizeof(Repcodes_t));
|
4286
4350
|
return cSize;
|
4287
4351
|
}
|
4288
4352
|
|
@@ -4293,8 +4357,8 @@ ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc,
|
|
4293
4357
|
{
|
4294
4358
|
U32 nbSeq;
|
4295
4359
|
size_t cSize;
|
4296
|
-
DEBUGLOG(
|
4297
|
-
assert(zc->appliedParams.
|
4360
|
+
DEBUGLOG(5, "ZSTD_compressBlock_splitBlock");
|
4361
|
+
assert(zc->appliedParams.postBlockSplitter == ZSTD_ps_enable);
|
4298
4362
|
|
4299
4363
|
{ const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);
|
4300
4364
|
FORWARD_IF_ERROR(bss, "ZSTD_buildSeqStore failed");
|
@@ -4304,7 +4368,7 @@ ZSTD_compressBlock_splitBlock(ZSTD_CCtx* zc,
|
|
4304
4368
|
RETURN_ERROR_IF(zc->seqCollector.collectSequences, sequenceProducer_failed, "Uncompressible block");
|
4305
4369
|
cSize = ZSTD_noCompressBlock(dst, dstCapacity, src, srcSize, lastBlock);
|
4306
4370
|
FORWARD_IF_ERROR(cSize, "ZSTD_noCompressBlock failed");
|
4307
|
-
DEBUGLOG(
|
4371
|
+
DEBUGLOG(5, "ZSTD_compressBlock_splitBlock: Nocompress block");
|
4308
4372
|
return cSize;
|
4309
4373
|
}
|
4310
4374
|
nbSeq = (U32)(zc->seqStore.sequences - zc->seqStore.sequencesStart);
|
@@ -4353,7 +4417,7 @@ ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
|
4353
4417
|
&zc->appliedParams,
|
4354
4418
|
dst, dstCapacity,
|
4355
4419
|
srcSize,
|
4356
|
-
zc->
|
4420
|
+
zc->tmpWorkspace, zc->tmpWkspSize /* statically allocated in resetCCtx */,
|
4357
4421
|
zc->bmi2);
|
4358
4422
|
|
4359
4423
|
if (frame &&
|
@@ -4459,7 +4523,7 @@ static size_t ZSTD_compressBlock_targetCBlockSize(ZSTD_CCtx* zc,
|
|
4459
4523
|
return cSize;
|
4460
4524
|
}
|
4461
4525
|
|
4462
|
-
static void ZSTD_overflowCorrectIfNeeded(
|
4526
|
+
static void ZSTD_overflowCorrectIfNeeded(ZSTD_MatchState_t* ms,
|
4463
4527
|
ZSTD_cwksp* ws,
|
4464
4528
|
ZSTD_CCtx_params const* params,
|
4465
4529
|
void const* ip,
|
@@ -4483,6 +4547,40 @@ static void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,
|
|
4483
4547
|
}
|
4484
4548
|
}
|
4485
4549
|
|
4550
|
+
#include "zstd_preSplit.h"
|
4551
|
+
|
4552
|
+
static size_t ZSTD_optimalBlockSize(ZSTD_CCtx* cctx, const void* src, size_t srcSize, size_t blockSizeMax, int splitLevel, ZSTD_strategy strat, S64 savings)
|
4553
|
+
{
|
4554
|
+
/* split level based on compression strategy, from `fast` to `btultra2` */
|
4555
|
+
static const int splitLevels[] = { 0, 0, 1, 2, 2, 3, 3, 4, 4, 4 };
|
4556
|
+
/* note: conservatively only split full blocks (128 KB) currently.
|
4557
|
+
* While it's possible to go lower, let's keep it simple for a first implementation.
|
4558
|
+
* Besides, benefits of splitting are reduced when blocks are already small.
|
4559
|
+
*/
|
4560
|
+
if (srcSize < 128 KB || blockSizeMax < 128 KB)
|
4561
|
+
return MIN(srcSize, blockSizeMax);
|
4562
|
+
/* do not split incompressible data though:
|
4563
|
+
* require verified savings to allow pre-splitting.
|
4564
|
+
* Note: as a consequence, the first full block is not split.
|
4565
|
+
*/
|
4566
|
+
if (savings < 3) {
|
4567
|
+
DEBUGLOG(6, "don't attempt splitting: savings (%i) too low", (int)savings);
|
4568
|
+
return 128 KB;
|
4569
|
+
}
|
4570
|
+
/* apply @splitLevel, or use default value (which depends on @strat).
|
4571
|
+
* note that splitting heuristic is still conditioned by @savings >= 3,
|
4572
|
+
* so the first block will not reach this code path */
|
4573
|
+
if (splitLevel == 1) return 128 KB;
|
4574
|
+
if (splitLevel == 0) {
|
4575
|
+
assert(ZSTD_fast <= strat && strat <= ZSTD_btultra2);
|
4576
|
+
splitLevel = splitLevels[strat];
|
4577
|
+
} else {
|
4578
|
+
assert(2 <= splitLevel && splitLevel <= 6);
|
4579
|
+
splitLevel -= 2;
|
4580
|
+
}
|
4581
|
+
return ZSTD_splitBlock(src, blockSizeMax, splitLevel, cctx->tmpWorkspace, cctx->tmpWkspSize);
|
4582
|
+
}
|
4583
|
+
|
4486
4584
|
/*! ZSTD_compress_frameChunk() :
|
4487
4585
|
* Compress a chunk of data into one or multiple blocks.
|
4488
4586
|
* All blocks will be terminated, all input will be consumed.
|
@@ -4495,29 +4593,36 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
|
|
4495
4593
|
const void* src, size_t srcSize,
|
4496
4594
|
U32 lastFrameChunk)
|
4497
4595
|
{
|
4498
|
-
size_t
|
4596
|
+
size_t blockSizeMax = cctx->blockSizeMax;
|
4499
4597
|
size_t remaining = srcSize;
|
4500
4598
|
const BYTE* ip = (const BYTE*)src;
|
4501
4599
|
BYTE* const ostart = (BYTE*)dst;
|
4502
4600
|
BYTE* op = ostart;
|
4503
4601
|
U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;
|
4602
|
+
S64 savings = (S64)cctx->consumedSrcSize - (S64)cctx->producedCSize;
|
4504
4603
|
|
4505
4604
|
assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX);
|
4506
4605
|
|
4507
|
-
DEBUGLOG(
|
4606
|
+
DEBUGLOG(5, "ZSTD_compress_frameChunk (srcSize=%u, blockSizeMax=%u)", (unsigned)srcSize, (unsigned)blockSizeMax);
|
4508
4607
|
if (cctx->appliedParams.fParams.checksumFlag && srcSize)
|
4509
4608
|
XXH64_update(&cctx->xxhState, src, srcSize);
|
4510
4609
|
|
4511
4610
|
while (remaining) {
|
4512
|
-
|
4513
|
-
|
4611
|
+
ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
|
4612
|
+
size_t const blockSize = ZSTD_optimalBlockSize(cctx,
|
4613
|
+
ip, remaining,
|
4614
|
+
blockSizeMax,
|
4615
|
+
cctx->appliedParams.preBlockSplitter_level,
|
4616
|
+
cctx->appliedParams.cParams.strategy,
|
4617
|
+
savings);
|
4618
|
+
U32 const lastBlock = lastFrameChunk & (blockSize == remaining);
|
4619
|
+
assert(blockSize <= remaining);
|
4514
4620
|
|
4515
4621
|
/* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding
|
4516
4622
|
* additional 1. We need to revisit and change this logic to be more consistent */
|
4517
4623
|
RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE + 1,
|
4518
4624
|
dstSize_tooSmall,
|
4519
4625
|
"not enough space to store compressed block");
|
4520
|
-
if (remaining < blockSize) blockSize = remaining;
|
4521
4626
|
|
4522
4627
|
ZSTD_overflowCorrectIfNeeded(
|
4523
4628
|
ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize);
|
@@ -4555,6 +4660,21 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
|
|
4555
4660
|
}
|
4556
4661
|
} /* if (ZSTD_useTargetCBlockSize(&cctx->appliedParams))*/
|
4557
4662
|
|
4663
|
+
/* @savings is employed to ensure that splitting doesn't worsen expansion of incompressible data.
|
4664
|
+
* Without splitting, the maximum expansion is 3 bytes per full block.
|
4665
|
+
* An adversarial input could attempt to fudge the split detector,
|
4666
|
+
* and make it split incompressible data, resulting in more block headers.
|
4667
|
+
* Note that, since ZSTD_COMPRESSBOUND() assumes a worst case scenario of 1KB per block,
|
4668
|
+
* and the splitter never creates blocks that small (current lower limit is 8 KB),
|
4669
|
+
* there is already no risk to expand beyond ZSTD_COMPRESSBOUND() limit.
|
4670
|
+
* But if the goal is to not expand by more than 3-bytes per 128 KB full block,
|
4671
|
+
* then yes, it becomes possible to make the block splitter oversplit incompressible data.
|
4672
|
+
* Using @savings, we enforce an even more conservative condition,
|
4673
|
+
* requiring the presence of enough savings (at least 3 bytes) to authorize splitting,
|
4674
|
+
* otherwise only full blocks are used.
|
4675
|
+
* But being conservative is fine,
|
4676
|
+
* since splitting barely compressible blocks is not fruitful anyway */
|
4677
|
+
savings += (S64)blockSize - (S64)cSize;
|
4558
4678
|
|
4559
4679
|
ip += blockSize;
|
4560
4680
|
assert(remaining >= blockSize);
|
@@ -4573,8 +4693,10 @@ static size_t ZSTD_compress_frameChunk(ZSTD_CCtx* cctx,
|
|
4573
4693
|
|
4574
4694
|
|
4575
4695
|
static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
4576
|
-
const ZSTD_CCtx_params* params,
|
4577
|
-
|
4696
|
+
const ZSTD_CCtx_params* params,
|
4697
|
+
U64 pledgedSrcSize, U32 dictID)
|
4698
|
+
{
|
4699
|
+
BYTE* const op = (BYTE*)dst;
|
4578
4700
|
U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
|
4579
4701
|
U32 const dictIDSizeCode = params->fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */
|
4580
4702
|
U32 const checksumFlag = params->fParams.checksumFlag>0;
|
@@ -4672,7 +4794,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
4672
4794
|
const void* src, size_t srcSize,
|
4673
4795
|
U32 frame, U32 lastFrameChunk)
|
4674
4796
|
{
|
4675
|
-
|
4797
|
+
ZSTD_MatchState_t* const ms = &cctx->blockState.matchState;
|
4676
4798
|
size_t fhSize = 0;
|
4677
4799
|
|
4678
4800
|
DEBUGLOG(5, "ZSTD_compressContinue_internal, stage: %u, srcSize: %u",
|
@@ -4707,7 +4829,7 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
4707
4829
|
src, (BYTE const*)src + srcSize);
|
4708
4830
|
}
|
4709
4831
|
|
4710
|
-
DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->
|
4832
|
+
DEBUGLOG(5, "ZSTD_compressContinue_internal (blockSize=%u)", (unsigned)cctx->blockSizeMax);
|
4711
4833
|
{ size_t const cSize = frame ?
|
4712
4834
|
ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
|
4713
4835
|
ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */);
|
@@ -4776,13 +4898,14 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
|
|
4776
4898
|
/*! ZSTD_loadDictionaryContent() :
|
4777
4899
|
* @return : 0, or an error code
|
4778
4900
|
*/
|
4779
|
-
static size_t
|
4780
|
-
|
4781
|
-
|
4782
|
-
|
4783
|
-
|
4784
|
-
|
4785
|
-
|
4901
|
+
static size_t
|
4902
|
+
ZSTD_loadDictionaryContent(ZSTD_MatchState_t* ms,
|
4903
|
+
ldmState_t* ls,
|
4904
|
+
ZSTD_cwksp* ws,
|
4905
|
+
ZSTD_CCtx_params const* params,
|
4906
|
+
const void* src, size_t srcSize,
|
4907
|
+
ZSTD_dictTableLoadMethod_e dtlm,
|
4908
|
+
ZSTD_tableFillPurpose_e tfp)
|
4786
4909
|
{
|
4787
4910
|
const BYTE* ip = (const BYTE*) src;
|
4788
4911
|
const BYTE* const iend = ip + srcSize;
|
@@ -4826,17 +4949,18 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
|
|
4826
4949
|
}
|
4827
4950
|
ZSTD_window_update(&ms->window, src, srcSize, /* forceNonContiguous */ 0);
|
4828
4951
|
|
4829
|
-
DEBUGLOG(4, "ZSTD_loadDictionaryContent
|
4952
|
+
DEBUGLOG(4, "ZSTD_loadDictionaryContent: useRowMatchFinder=%d", (int)params->useRowMatchFinder);
|
4830
4953
|
|
4831
4954
|
if (loadLdmDict) { /* Load the entire dict into LDM matchfinders. */
|
4955
|
+
DEBUGLOG(4, "ZSTD_loadDictionaryContent: Trigger loadLdmDict");
|
4832
4956
|
ZSTD_window_update(&ls->window, src, srcSize, /* forceNonContiguous */ 0);
|
4833
4957
|
ls->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ls->window.base);
|
4834
4958
|
ZSTD_ldm_fillHashTable(ls, ip, iend, ¶ms->ldmParams);
|
4959
|
+
DEBUGLOG(4, "ZSTD_loadDictionaryContent: ZSTD_ldm_fillHashTable completes");
|
4835
4960
|
}
|
4836
4961
|
|
4837
4962
|
/* If the dict is larger than we can reasonably index in our tables, only load the suffix. */
|
4838
|
-
|
4839
|
-
U32 maxDictSize = 8U << MIN(MAX(params->cParams.hashLog, params->cParams.chainLog), 28);
|
4963
|
+
{ U32 maxDictSize = 1U << MIN(MAX(params->cParams.hashLog + 3, params->cParams.chainLog + 1), 31);
|
4840
4964
|
if (srcSize > maxDictSize) {
|
4841
4965
|
ip = iend - maxDictSize;
|
4842
4966
|
src = ip;
|
@@ -4900,6 +5024,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
|
|
4900
5024
|
|| !defined(ZSTD_EXCLUDE_BTOPT_BLOCK_COMPRESSOR) \
|
4901
5025
|
|| !defined(ZSTD_EXCLUDE_BTULTRA_BLOCK_COMPRESSOR)
|
4902
5026
|
assert(srcSize >= HASH_READ_SIZE);
|
5027
|
+
DEBUGLOG(4, "Fill %u bytes into the Binary Tree", (unsigned)srcSize);
|
4903
5028
|
ZSTD_updateTree(ms, iend-HASH_READ_SIZE, iend);
|
4904
5029
|
#else
|
4905
5030
|
assert(0); /* shouldn't be called: cparams should've been adjusted. */
|
@@ -4946,7 +5071,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
|
|
4946
5071
|
{ unsigned maxSymbolValue = 255;
|
4947
5072
|
unsigned hasZeroWeights = 1;
|
4948
5073
|
size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr,
|
4949
|
-
dictEnd-dictPtr, &hasZeroWeights);
|
5074
|
+
(size_t)(dictEnd-dictPtr), &hasZeroWeights);
|
4950
5075
|
|
4951
5076
|
/* We only set the loaded table as valid if it contains all non-zero
|
4952
5077
|
* weights. Otherwise, we set it to check */
|
@@ -4958,7 +5083,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
|
|
4958
5083
|
}
|
4959
5084
|
|
4960
5085
|
{ unsigned offcodeLog;
|
4961
|
-
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
5086
|
+
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr));
|
4962
5087
|
RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
|
4963
5088
|
RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
|
4964
5089
|
/* fill all offset symbols to avoid garbage at end of table */
|
@@ -4973,7 +5098,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
|
|
4973
5098
|
|
4974
5099
|
{ short matchlengthNCount[MaxML+1];
|
4975
5100
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
|
4976
|
-
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
5101
|
+
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
|
4977
5102
|
RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
|
4978
5103
|
RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
|
4979
5104
|
RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
|
@@ -4987,7 +5112,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
|
|
4987
5112
|
|
4988
5113
|
{ short litlengthNCount[MaxLL+1];
|
4989
5114
|
unsigned litlengthMaxValue = MaxLL, litlengthLog;
|
4990
|
-
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
5115
|
+
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
|
4991
5116
|
RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
|
4992
5117
|
RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
|
4993
5118
|
RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(
|
@@ -5021,7 +5146,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
|
|
5021
5146
|
RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted, "");
|
5022
5147
|
} } }
|
5023
5148
|
|
5024
|
-
return dictPtr - (const BYTE*)dict;
|
5149
|
+
return (size_t)(dictPtr - (const BYTE*)dict);
|
5025
5150
|
}
|
5026
5151
|
|
5027
5152
|
/* Dictionary format :
|
@@ -5034,7 +5159,7 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
|
|
5034
5159
|
* dictSize supposed >= 8
|
5035
5160
|
*/
|
5036
5161
|
static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
5037
|
-
|
5162
|
+
ZSTD_MatchState_t* ms,
|
5038
5163
|
ZSTD_cwksp* ws,
|
5039
5164
|
ZSTD_CCtx_params const* params,
|
5040
5165
|
const void* dict, size_t dictSize,
|
@@ -5067,7 +5192,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
|
5067
5192
|
* @return : dictID, or an error code */
|
5068
5193
|
static size_t
|
5069
5194
|
ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
|
5070
|
-
|
5195
|
+
ZSTD_MatchState_t* ms,
|
5071
5196
|
ldmState_t* ls,
|
5072
5197
|
ZSTD_cwksp* ws,
|
5073
5198
|
const ZSTD_CCtx_params* params,
|
@@ -5144,11 +5269,11 @@ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
|
5144
5269
|
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
|
5145
5270
|
&cctx->ldmState, &cctx->workspace, &cctx->appliedParams, cdict->dictContent,
|
5146
5271
|
cdict->dictContentSize, cdict->dictContentType, dtlm,
|
5147
|
-
ZSTD_tfp_forCCtx, cctx->
|
5272
|
+
ZSTD_tfp_forCCtx, cctx->tmpWorkspace)
|
5148
5273
|
: ZSTD_compress_insertDictionary(
|
5149
5274
|
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
|
5150
5275
|
&cctx->ldmState, &cctx->workspace, &cctx->appliedParams, dict, dictSize,
|
5151
|
-
dictContentType, dtlm, ZSTD_tfp_forCCtx, cctx->
|
5276
|
+
dictContentType, dtlm, ZSTD_tfp_forCCtx, cctx->tmpWorkspace);
|
5152
5277
|
FORWARD_IF_ERROR(dictID, "ZSTD_compress_insertDictionary failed");
|
5153
5278
|
assert(dictID <= UINT_MAX);
|
5154
5279
|
cctx->dictID = (U32)dictID;
|
@@ -5252,7 +5377,7 @@ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
|
|
5252
5377
|
}
|
5253
5378
|
|
5254
5379
|
cctx->stage = ZSTDcs_created; /* return to "created but no init" status */
|
5255
|
-
return op-ostart;
|
5380
|
+
return (size_t)(op-ostart);
|
5256
5381
|
}
|
5257
5382
|
|
5258
5383
|
void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize)
|
@@ -5476,14 +5601,16 @@ static size_t ZSTD_initCDict_internal(
|
|
5476
5601
|
return 0;
|
5477
5602
|
}
|
5478
5603
|
|
5479
|
-
static ZSTD_CDict*
|
5480
|
-
|
5481
|
-
|
5482
|
-
|
5483
|
-
|
5484
|
-
|
5604
|
+
static ZSTD_CDict*
|
5605
|
+
ZSTD_createCDict_advanced_internal(size_t dictSize,
|
5606
|
+
ZSTD_dictLoadMethod_e dictLoadMethod,
|
5607
|
+
ZSTD_compressionParameters cParams,
|
5608
|
+
ZSTD_ParamSwitch_e useRowMatchFinder,
|
5609
|
+
int enableDedicatedDictSearch,
|
5610
|
+
ZSTD_customMem customMem)
|
5485
5611
|
{
|
5486
5612
|
if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
|
5613
|
+
DEBUGLOG(3, "ZSTD_createCDict_advanced_internal (dictSize=%u)", (unsigned)dictSize);
|
5487
5614
|
|
5488
5615
|
{ size_t const workspaceSize =
|
5489
5616
|
ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) +
|
@@ -5520,6 +5647,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,
|
|
5520
5647
|
{
|
5521
5648
|
ZSTD_CCtx_params cctxParams;
|
5522
5649
|
ZSTD_memset(&cctxParams, 0, sizeof(cctxParams));
|
5650
|
+
DEBUGLOG(3, "ZSTD_createCDict_advanced, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType);
|
5523
5651
|
ZSTD_CCtxParams_init(&cctxParams, 0);
|
5524
5652
|
cctxParams.cParams = cParams;
|
5525
5653
|
cctxParams.customMem = customMem;
|
@@ -5540,7 +5668,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced2(
|
|
5540
5668
|
ZSTD_compressionParameters cParams;
|
5541
5669
|
ZSTD_CDict* cdict;
|
5542
5670
|
|
5543
|
-
DEBUGLOG(3, "ZSTD_createCDict_advanced2, mode
|
5671
|
+
DEBUGLOG(3, "ZSTD_createCDict_advanced2, dictSize=%u, mode=%u", (unsigned)dictSize, (unsigned)dictContentType);
|
5544
5672
|
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
|
5545
5673
|
|
5546
5674
|
if (cctxParams.enableDedicatedDictSearch) {
|
@@ -5559,7 +5687,7 @@ ZSTD_CDict* ZSTD_createCDict_advanced2(
|
|
5559
5687
|
&cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, dictSize, ZSTD_cpm_createCDict);
|
5560
5688
|
}
|
5561
5689
|
|
5562
|
-
DEBUGLOG(3, "ZSTD_createCDict_advanced2:
|
5690
|
+
DEBUGLOG(3, "ZSTD_createCDict_advanced2: DedicatedDictSearch=%u", cctxParams.enableDedicatedDictSearch);
|
5563
5691
|
cctxParams.cParams = cParams;
|
5564
5692
|
cctxParams.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(cctxParams.useRowMatchFinder, &cParams);
|
5565
5693
|
|
@@ -5622,7 +5750,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
|
5622
5750
|
* workspaceSize: Use ZSTD_estimateCDictSize()
|
5623
5751
|
* to determine how large workspace must be.
|
5624
5752
|
* cParams : use ZSTD_getCParams() to transform a compression level
|
5625
|
-
* into its
|
5753
|
+
* into its relevant cParams.
|
5626
5754
|
* @return : pointer to ZSTD_CDict*, or NULL if error (size too small)
|
5627
5755
|
* Note : there is no corresponding "free" function.
|
5628
5756
|
* Since workspace was allocated externally, it must be freed externally.
|
@@ -5634,7 +5762,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
|
|
5634
5762
|
ZSTD_dictContentType_e dictContentType,
|
5635
5763
|
ZSTD_compressionParameters cParams)
|
5636
5764
|
{
|
5637
|
-
|
5765
|
+
ZSTD_ParamSwitch_e const useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(ZSTD_ps_auto, &cParams);
|
5638
5766
|
/* enableDedicatedDictSearch == 1 ensures matchstate is not too small in case this CDict will be used for DDS + row hash */
|
5639
5767
|
size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, useRowMatchFinder, /* enableDedicatedDictSearch */ 1, /* forCCtx */ 0);
|
5640
5768
|
size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))
|
@@ -5645,6 +5773,7 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
|
|
5645
5773
|
ZSTD_CDict* cdict;
|
5646
5774
|
ZSTD_CCtx_params params;
|
5647
5775
|
|
5776
|
+
DEBUGLOG(4, "ZSTD_initStaticCDict (dictSize==%u)", (unsigned)dictSize);
|
5648
5777
|
if ((size_t)workspace & 7) return NULL; /* 8-aligned */
|
5649
5778
|
|
5650
5779
|
{
|
@@ -5655,8 +5784,6 @@ const ZSTD_CDict* ZSTD_initStaticCDict(
|
|
5655
5784
|
ZSTD_cwksp_move(&cdict->workspace, &ws);
|
5656
5785
|
}
|
5657
5786
|
|
5658
|
-
DEBUGLOG(4, "(workspaceSize < neededSize) : (%u < %u) => %u",
|
5659
|
-
(unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize));
|
5660
5787
|
if (workspaceSize < neededSize) return NULL;
|
5661
5788
|
|
5662
5789
|
ZSTD_CCtxParams_init(¶ms, 0);
|
@@ -5829,7 +5956,7 @@ size_t ZSTD_CStreamOutSize(void)
|
|
5829
5956
|
return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
|
5830
5957
|
}
|
5831
5958
|
|
5832
|
-
static
|
5959
|
+
static ZSTD_CParamMode_e ZSTD_getCParamMode(ZSTD_CDict const* cdict, ZSTD_CCtx_params const* params, U64 pledgedSrcSize)
|
5833
5960
|
{
|
5834
5961
|
if (cdict != NULL && ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize))
|
5835
5962
|
return ZSTD_cpm_attachDict;
|
@@ -5961,11 +6088,11 @@ size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
|
|
5961
6088
|
static size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx)
|
5962
6089
|
{
|
5963
6090
|
if (cctx->appliedParams.inBufferMode == ZSTD_bm_stable) {
|
5964
|
-
return cctx->
|
6091
|
+
return cctx->blockSizeMax - cctx->stableIn_notConsumed;
|
5965
6092
|
}
|
5966
6093
|
assert(cctx->appliedParams.inBufferMode == ZSTD_bm_buffered);
|
5967
6094
|
{ size_t hintInSize = cctx->inBuffTarget - cctx->inBuffPos;
|
5968
|
-
if (hintInSize==0) hintInSize = cctx->
|
6095
|
+
if (hintInSize==0) hintInSize = cctx->blockSizeMax;
|
5969
6096
|
return hintInSize;
|
5970
6097
|
}
|
5971
6098
|
}
|
@@ -6017,12 +6144,13 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
6017
6144
|
|
6018
6145
|
case zcss_load:
|
6019
6146
|
if ( (flushMode == ZSTD_e_end)
|
6020
|
-
&& ( (size_t)(oend-op) >= ZSTD_compressBound(iend-ip) /* Enough output space */
|
6147
|
+
&& ( (size_t)(oend-op) >= ZSTD_compressBound((size_t)(iend-ip)) /* Enough output space */
|
6021
6148
|
|| zcs->appliedParams.outBufferMode == ZSTD_bm_stable) /* OR we are allowed to return dstSizeTooSmall */
|
6022
6149
|
&& (zcs->inBuffPos == 0) ) {
|
6023
6150
|
/* shortcut to compression pass directly into output buffer */
|
6024
6151
|
size_t const cSize = ZSTD_compressEnd_public(zcs,
|
6025
|
-
op, oend-op,
|
6152
|
+
op, (size_t)(oend-op),
|
6153
|
+
ip, (size_t)(iend-ip));
|
6026
6154
|
DEBUGLOG(4, "ZSTD_compressEnd : cSize=%u", (unsigned)cSize);
|
6027
6155
|
FORWARD_IF_ERROR(cSize, "ZSTD_compressEnd failed");
|
6028
6156
|
ip = iend;
|
@@ -6036,7 +6164,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
6036
6164
|
size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
|
6037
6165
|
size_t const loaded = ZSTD_limitCopy(
|
6038
6166
|
zcs->inBuff + zcs->inBuffPos, toLoad,
|
6039
|
-
ip, iend-ip);
|
6167
|
+
ip, (size_t)(iend-ip));
|
6040
6168
|
zcs->inBuffPos += loaded;
|
6041
6169
|
if (ip) ip += loaded;
|
6042
6170
|
if ( (flushMode == ZSTD_e_continue)
|
@@ -6052,7 +6180,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
6052
6180
|
} else {
|
6053
6181
|
assert(zcs->appliedParams.inBufferMode == ZSTD_bm_stable);
|
6054
6182
|
if ( (flushMode == ZSTD_e_continue)
|
6055
|
-
&& ( (size_t)(iend - ip) < zcs->
|
6183
|
+
&& ( (size_t)(iend - ip) < zcs->blockSizeMax) ) {
|
6056
6184
|
/* can't compress a full block : stop here */
|
6057
6185
|
zcs->stableIn_notConsumed = (size_t)(iend - ip);
|
6058
6186
|
ip = iend; /* pretend to have consumed input */
|
@@ -6069,9 +6197,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
6069
6197
|
{ int const inputBuffered = (zcs->appliedParams.inBufferMode == ZSTD_bm_buffered);
|
6070
6198
|
void* cDst;
|
6071
6199
|
size_t cSize;
|
6072
|
-
size_t oSize = oend-op;
|
6200
|
+
size_t oSize = (size_t)(oend-op);
|
6073
6201
|
size_t const iSize = inputBuffered ? zcs->inBuffPos - zcs->inToCompress
|
6074
|
-
: MIN((size_t)(iend - ip), zcs->
|
6202
|
+
: MIN((size_t)(iend - ip), zcs->blockSizeMax);
|
6075
6203
|
if (oSize >= ZSTD_compressBound(iSize) || zcs->appliedParams.outBufferMode == ZSTD_bm_stable)
|
6076
6204
|
cDst = op; /* compress into output buffer, to skip flush stage */
|
6077
6205
|
else
|
@@ -6086,9 +6214,9 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
6086
6214
|
FORWARD_IF_ERROR(cSize, "%s", lastBlock ? "ZSTD_compressEnd failed" : "ZSTD_compressContinue failed");
|
6087
6215
|
zcs->frameEnded = lastBlock;
|
6088
6216
|
/* prepare next block */
|
6089
|
-
zcs->inBuffTarget = zcs->inBuffPos + zcs->
|
6217
|
+
zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSizeMax;
|
6090
6218
|
if (zcs->inBuffTarget > zcs->inBuffSize)
|
6091
|
-
zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->
|
6219
|
+
zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSizeMax;
|
6092
6220
|
DEBUGLOG(5, "inBuffTarget:%u / inBuffSize:%u",
|
6093
6221
|
(unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize);
|
6094
6222
|
if (!lastBlock)
|
@@ -6152,8 +6280,8 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
6152
6280
|
}
|
6153
6281
|
}
|
6154
6282
|
|
6155
|
-
input->pos = ip - istart;
|
6156
|
-
output->pos = op - ostart;
|
6283
|
+
input->pos = (size_t)(ip - istart);
|
6284
|
+
output->pos = (size_t)(op - ostart);
|
6157
6285
|
if (zcs->frameEnded) return 0;
|
6158
6286
|
return ZSTD_nextInputSizeHint(zcs);
|
6159
6287
|
}
|
@@ -6213,6 +6341,11 @@ static size_t ZSTD_checkBufferStability(ZSTD_CCtx const* cctx,
|
|
6213
6341
|
return 0;
|
6214
6342
|
}
|
6215
6343
|
|
6344
|
+
/*
|
6345
|
+
* If @endOp == ZSTD_e_end, @inSize becomes pledgedSrcSize.
|
6346
|
+
* Otherwise, it's ignored.
|
6347
|
+
* @return: 0 on success, or a ZSTD_error code otherwise.
|
6348
|
+
*/
|
6216
6349
|
static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
|
6217
6350
|
ZSTD_EndDirective endOp,
|
6218
6351
|
size_t inSize)
|
@@ -6229,19 +6362,19 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
|
|
6229
6362
|
*/
|
6230
6363
|
params.compressionLevel = cctx->cdict->compressionLevel;
|
6231
6364
|
}
|
6232
|
-
DEBUGLOG(4, "
|
6365
|
+
DEBUGLOG(4, "ZSTD_CCtx_init_compressStream2 : transparent init stage");
|
6233
6366
|
if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = inSize + 1; /* auto-determine pledgedSrcSize */
|
6234
6367
|
|
6235
6368
|
{ size_t const dictSize = prefixDict.dict
|
6236
6369
|
? prefixDict.dictSize
|
6237
6370
|
: (cctx->cdict ? cctx->cdict->dictContentSize : 0);
|
6238
|
-
|
6371
|
+
ZSTD_CParamMode_e const mode = ZSTD_getCParamMode(cctx->cdict, ¶ms, cctx->pledgedSrcSizePlusOne - 1);
|
6239
6372
|
params.cParams = ZSTD_getCParamsFromCCtxParams(
|
6240
6373
|
¶ms, cctx->pledgedSrcSizePlusOne-1,
|
6241
6374
|
dictSize, mode);
|
6242
6375
|
}
|
6243
6376
|
|
6244
|
-
params.
|
6377
|
+
params.postBlockSplitter = ZSTD_resolveBlockSplitterMode(params.postBlockSplitter, ¶ms.cParams);
|
6245
6378
|
params.ldmParams.enableLdm = ZSTD_resolveEnableLdm(params.ldmParams.enableLdm, ¶ms.cParams);
|
6246
6379
|
params.useRowMatchFinder = ZSTD_resolveRowMatchFinderMode(params.useRowMatchFinder, ¶ms.cParams);
|
6247
6380
|
params.validateSequences = ZSTD_resolveExternalSequenceValidation(params.validateSequences);
|
@@ -6260,9 +6393,9 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
|
|
6260
6393
|
params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
|
6261
6394
|
}
|
6262
6395
|
if (params.nbWorkers > 0) {
|
6263
|
-
#if ZSTD_TRACE
|
6396
|
+
# if ZSTD_TRACE
|
6264
6397
|
cctx->traceCtx = (ZSTD_trace_compress_begin != NULL) ? ZSTD_trace_compress_begin(cctx) : 0;
|
6265
|
-
#endif
|
6398
|
+
# endif
|
6266
6399
|
/* mt context creation */
|
6267
6400
|
if (cctx->mtctx == NULL) {
|
6268
6401
|
DEBUGLOG(4, "ZSTD_compressStream2: creating new mtctx for nbWorkers=%u",
|
@@ -6298,7 +6431,7 @@ static size_t ZSTD_CCtx_init_compressStream2(ZSTD_CCtx* cctx,
|
|
6298
6431
|
/* for small input: avoid automatic flush on reaching end of block, since
|
6299
6432
|
* it would require to add a 3-bytes null block to end frame
|
6300
6433
|
*/
|
6301
|
-
cctx->inBuffTarget = cctx->
|
6434
|
+
cctx->inBuffTarget = cctx->blockSizeMax + (cctx->blockSizeMax == pledgedSrcSize);
|
6302
6435
|
} else {
|
6303
6436
|
cctx->inBuffTarget = 0;
|
6304
6437
|
}
|
@@ -6464,11 +6597,11 @@ size_t ZSTD_compress2(ZSTD_CCtx* cctx,
|
|
6464
6597
|
}
|
6465
6598
|
|
6466
6599
|
/* ZSTD_validateSequence() :
|
6467
|
-
* @
|
6600
|
+
* @offBase : must use the format required by ZSTD_storeSeq()
|
6468
6601
|
* @returns a ZSTD error code if sequence is not valid
|
6469
6602
|
*/
|
6470
6603
|
static size_t
|
6471
|
-
ZSTD_validateSequence(U32
|
6604
|
+
ZSTD_validateSequence(U32 offBase, U32 matchLength, U32 minMatch,
|
6472
6605
|
size_t posInSrc, U32 windowLog, size_t dictSize, int useSequenceProducer)
|
6473
6606
|
{
|
6474
6607
|
U32 const windowSize = 1u << windowLog;
|
@@ -6479,7 +6612,7 @@ ZSTD_validateSequence(U32 offCode, U32 matchLength, U32 minMatch,
|
|
6479
6612
|
*/
|
6480
6613
|
size_t const offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize;
|
6481
6614
|
size_t const matchLenLowerBound = (minMatch == 3 || useSequenceProducer) ? 3 : 4;
|
6482
|
-
RETURN_ERROR_IF(
|
6615
|
+
RETURN_ERROR_IF(offBase > OFFSET_TO_OFFBASE(offsetBound), externalSequences_invalid, "Offset too large!");
|
6483
6616
|
/* Validate maxNbSeq is large enough for the given matchLength and minMatch */
|
6484
6617
|
RETURN_ERROR_IF(matchLength < matchLenLowerBound, externalSequences_invalid, "Matchlength too small for the minMatch");
|
6485
6618
|
return 0;
|
@@ -6502,21 +6635,27 @@ static U32 ZSTD_finalizeOffBase(U32 rawOffset, const U32 rep[ZSTD_REP_NUM], U32
|
|
6502
6635
|
return offBase;
|
6503
6636
|
}
|
6504
6637
|
|
6505
|
-
|
6506
|
-
|
6507
|
-
|
6508
|
-
|
6509
|
-
|
6510
|
-
|
6638
|
+
/* This function scans through an array of ZSTD_Sequence,
|
6639
|
+
* storing the sequences it reads, until it reaches a block delimiter.
|
6640
|
+
* Note that the block delimiter includes the last literals of the block.
|
6641
|
+
* @blockSize must be == sum(sequence_lengths).
|
6642
|
+
* @returns @blockSize on success, and a ZSTD_error otherwise.
|
6643
|
+
*/
|
6644
|
+
static size_t
|
6645
|
+
ZSTD_transferSequences_wBlockDelim(ZSTD_CCtx* cctx,
|
6646
|
+
ZSTD_SequencePosition* seqPos,
|
6647
|
+
const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
|
6648
|
+
const void* src, size_t blockSize,
|
6649
|
+
ZSTD_ParamSwitch_e externalRepSearch)
|
6511
6650
|
{
|
6512
6651
|
U32 idx = seqPos->idx;
|
6513
6652
|
U32 const startIdx = idx;
|
6514
6653
|
BYTE const* ip = (BYTE const*)(src);
|
6515
6654
|
const BYTE* const iend = ip + blockSize;
|
6516
|
-
|
6655
|
+
Repcodes_t updatedRepcodes;
|
6517
6656
|
U32 dictSize;
|
6518
6657
|
|
6519
|
-
DEBUGLOG(5, "
|
6658
|
+
DEBUGLOG(5, "ZSTD_transferSequences_wBlockDelim (blockSize = %zu)", blockSize);
|
6520
6659
|
|
6521
6660
|
if (cctx->cdict) {
|
6522
6661
|
dictSize = (U32)cctx->cdict->dictContentSize;
|
@@ -6525,7 +6664,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
|
|
6525
6664
|
} else {
|
6526
6665
|
dictSize = 0;
|
6527
6666
|
}
|
6528
|
-
ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(
|
6667
|
+
ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t));
|
6529
6668
|
for (; idx < inSeqsSize && (inSeqs[idx].matchLength != 0 || inSeqs[idx].offset != 0); ++idx) {
|
6530
6669
|
U32 const litLength = inSeqs[idx].litLength;
|
6531
6670
|
U32 const matchLength = inSeqs[idx].matchLength;
|
@@ -6542,8 +6681,10 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
|
|
6542
6681
|
DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength);
|
6543
6682
|
if (cctx->appliedParams.validateSequences) {
|
6544
6683
|
seqPos->posInSrc += litLength + matchLength;
|
6545
|
-
FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch,
|
6546
|
-
|
6684
|
+
FORWARD_IF_ERROR(ZSTD_validateSequence(offBase, matchLength, cctx->appliedParams.cParams.minMatch,
|
6685
|
+
seqPos->posInSrc,
|
6686
|
+
cctx->appliedParams.cParams.windowLog, dictSize,
|
6687
|
+
ZSTD_hasExtSeqProd(&cctx->appliedParams)),
|
6547
6688
|
"Sequence validation failed");
|
6548
6689
|
}
|
6549
6690
|
RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, externalSequences_invalid,
|
@@ -6551,6 +6692,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
|
|
6551
6692
|
ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength);
|
6552
6693
|
ip += matchLength + litLength;
|
6553
6694
|
}
|
6695
|
+
RETURN_ERROR_IF(idx == inSeqsSize, externalSequences_invalid, "Block delimiter not found.");
|
6554
6696
|
|
6555
6697
|
/* If we skipped repcode search while parsing, we need to update repcodes now */
|
6556
6698
|
assert(externalRepSearch != ZSTD_ps_auto);
|
@@ -6575,7 +6717,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
|
|
6575
6717
|
}
|
6576
6718
|
}
|
6577
6719
|
|
6578
|
-
ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(
|
6720
|
+
ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t));
|
6579
6721
|
|
6580
6722
|
if (inSeqs[idx].litLength) {
|
6581
6723
|
DEBUGLOG(6, "Storing last literals of size: %u", inSeqs[idx].litLength);
|
@@ -6585,21 +6727,35 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx,
|
|
6585
6727
|
}
|
6586
6728
|
RETURN_ERROR_IF(ip != iend, externalSequences_invalid, "Blocksize doesn't agree with block delimiter!");
|
6587
6729
|
seqPos->idx = idx+1;
|
6588
|
-
return
|
6730
|
+
return blockSize;
|
6589
6731
|
}
|
6590
6732
|
|
6591
|
-
|
6592
|
-
|
6593
|
-
|
6594
|
-
|
6733
|
+
/*
|
6734
|
+
* This function attempts to scan through @blockSize bytes in @src
|
6735
|
+
* represented by the sequences in @inSeqs,
|
6736
|
+
* storing any (partial) sequences.
|
6737
|
+
*
|
6738
|
+
* Occasionally, we may want to reduce the actual number of bytes consumed from @src
|
6739
|
+
* to avoid splitting a match, notably if it would produce a match smaller than MINMATCH.
|
6740
|
+
*
|
6741
|
+
* @returns the number of bytes consumed from @src, necessarily <= @blockSize.
|
6742
|
+
* Otherwise, it may return a ZSTD error if something went wrong.
|
6743
|
+
*/
|
6744
|
+
static size_t
|
6745
|
+
ZSTD_transferSequences_noDelim(ZSTD_CCtx* cctx,
|
6746
|
+
ZSTD_SequencePosition* seqPos,
|
6747
|
+
const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
|
6748
|
+
const void* src, size_t blockSize,
|
6749
|
+
ZSTD_ParamSwitch_e externalRepSearch)
|
6595
6750
|
{
|
6596
6751
|
U32 idx = seqPos->idx;
|
6597
6752
|
U32 startPosInSequence = seqPos->posInSequence;
|
6598
6753
|
U32 endPosInSequence = seqPos->posInSequence + (U32)blockSize;
|
6599
6754
|
size_t dictSize;
|
6600
|
-
BYTE const
|
6601
|
-
BYTE
|
6602
|
-
|
6755
|
+
const BYTE* const istart = (const BYTE*)(src);
|
6756
|
+
const BYTE* ip = istart;
|
6757
|
+
const BYTE* iend = istart + blockSize; /* May be adjusted if we decide to process fewer than blockSize bytes */
|
6758
|
+
Repcodes_t updatedRepcodes;
|
6603
6759
|
U32 bytesAdjustment = 0;
|
6604
6760
|
U32 finalMatchSplit = 0;
|
6605
6761
|
|
@@ -6613,9 +6769,9 @@ ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition*
|
|
6613
6769
|
} else {
|
6614
6770
|
dictSize = 0;
|
6615
6771
|
}
|
6616
|
-
DEBUGLOG(5, "
|
6772
|
+
DEBUGLOG(5, "ZSTD_transferSequences_noDelim: idx: %u PIS: %u blockSize: %zu", idx, startPosInSequence, blockSize);
|
6617
6773
|
DEBUGLOG(5, "Start seq: idx: %u (of: %u ml: %u ll: %u)", idx, inSeqs[idx].offset, inSeqs[idx].matchLength, inSeqs[idx].litLength);
|
6618
|
-
ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(
|
6774
|
+
ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t));
|
6619
6775
|
while (endPosInSequence && idx < inSeqsSize && !finalMatchSplit) {
|
6620
6776
|
const ZSTD_Sequence currSeq = inSeqs[idx];
|
6621
6777
|
U32 litLength = currSeq.litLength;
|
@@ -6696,35 +6852,40 @@ ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition*
|
|
6696
6852
|
assert(idx == inSeqsSize || endPosInSequence <= inSeqs[idx].litLength + inSeqs[idx].matchLength);
|
6697
6853
|
seqPos->idx = idx;
|
6698
6854
|
seqPos->posInSequence = endPosInSequence;
|
6699
|
-
ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(
|
6855
|
+
ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t));
|
6700
6856
|
|
6701
6857
|
iend -= bytesAdjustment;
|
6702
6858
|
if (ip != iend) {
|
6703
6859
|
/* Store any last literals */
|
6704
|
-
U32 lastLLSize = (U32)(iend - ip);
|
6860
|
+
U32 const lastLLSize = (U32)(iend - ip);
|
6705
6861
|
assert(ip <= iend);
|
6706
6862
|
DEBUGLOG(6, "Storing last literals of size: %u", lastLLSize);
|
6707
6863
|
ZSTD_storeLastLiterals(&cctx->seqStore, ip, lastLLSize);
|
6708
6864
|
seqPos->posInSrc += lastLLSize;
|
6709
6865
|
}
|
6710
6866
|
|
6711
|
-
return
|
6867
|
+
return (size_t)(iend-istart);
|
6712
6868
|
}
|
6713
6869
|
|
6714
|
-
|
6715
|
-
|
6716
|
-
|
6717
|
-
|
6870
|
+
/* @seqPos represents a position within @inSeqs,
|
6871
|
+
* it is read and updated by this function,
|
6872
|
+
* once the goal to produce a block of size @blockSize is reached.
|
6873
|
+
* @return: nb of bytes consumed from @src, necessarily <= @blockSize.
|
6874
|
+
*/
|
6875
|
+
typedef size_t (*ZSTD_SequenceCopier_f)(ZSTD_CCtx* cctx,
|
6876
|
+
ZSTD_SequencePosition* seqPos,
|
6877
|
+
const ZSTD_Sequence* const inSeqs, size_t inSeqsSize,
|
6878
|
+
const void* src, size_t blockSize,
|
6879
|
+
ZSTD_ParamSwitch_e externalRepSearch);
|
6880
|
+
|
6881
|
+
static ZSTD_SequenceCopier_f ZSTD_selectSequenceCopier(ZSTD_SequenceFormat_e mode)
|
6718
6882
|
{
|
6719
|
-
|
6720
|
-
assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, mode));
|
6883
|
+
assert(ZSTD_cParam_withinBounds(ZSTD_c_blockDelimiters, (int)mode));
|
6721
6884
|
if (mode == ZSTD_sf_explicitBlockDelimiters) {
|
6722
|
-
return
|
6723
|
-
} else if (mode == ZSTD_sf_noBlockDelimiters) {
|
6724
|
-
return ZSTD_copySequencesToSeqStoreNoBlockDelim;
|
6885
|
+
return ZSTD_transferSequences_wBlockDelim;
|
6725
6886
|
}
|
6726
|
-
assert(
|
6727
|
-
return
|
6887
|
+
assert(mode == ZSTD_sf_noBlockDelimiters);
|
6888
|
+
return ZSTD_transferSequences_noDelim;
|
6728
6889
|
}
|
6729
6890
|
|
6730
6891
|
/* Discover the size of next block by searching for the delimiter.
|
@@ -6732,7 +6893,7 @@ static ZSTD_sequenceCopier ZSTD_selectSequenceCopier(ZSTD_sequenceFormat_e mode)
|
|
6732
6893
|
* otherwise it's an input error.
|
6733
6894
|
* The block size retrieved will be later compared to ensure it remains within bounds */
|
6734
6895
|
static size_t
|
6735
|
-
blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
|
6896
|
+
blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD_SequencePosition seqPos)
|
6736
6897
|
{
|
6737
6898
|
int end = 0;
|
6738
6899
|
size_t blockSize = 0;
|
@@ -6754,20 +6915,17 @@ blockSize_explicitDelimiter(const ZSTD_Sequence* inSeqs, size_t inSeqsSize, ZSTD
|
|
6754
6915
|
return blockSize;
|
6755
6916
|
}
|
6756
6917
|
|
6757
|
-
|
6758
|
-
static size_t blockSize_noDelimiter(size_t blockSize, size_t remaining)
|
6759
|
-
{
|
6760
|
-
int const lastBlock = (remaining <= blockSize);
|
6761
|
-
return lastBlock ? remaining : blockSize;
|
6762
|
-
}
|
6763
|
-
|
6764
|
-
static size_t determine_blockSize(ZSTD_sequenceFormat_e mode,
|
6918
|
+
static size_t determine_blockSize(ZSTD_SequenceFormat_e mode,
|
6765
6919
|
size_t blockSize, size_t remaining,
|
6766
|
-
const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
|
6920
|
+
const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
|
6921
|
+
ZSTD_SequencePosition seqPos)
|
6767
6922
|
{
|
6768
6923
|
DEBUGLOG(6, "determine_blockSize : remainingSize = %zu", remaining);
|
6769
|
-
if (mode == ZSTD_sf_noBlockDelimiters)
|
6770
|
-
|
6924
|
+
if (mode == ZSTD_sf_noBlockDelimiters) {
|
6925
|
+
/* Note: more a "target" block size */
|
6926
|
+
return MIN(remaining, blockSize);
|
6927
|
+
}
|
6928
|
+
assert(mode == ZSTD_sf_explicitBlockDelimiters);
|
6771
6929
|
{ size_t const explicitBlockSize = blockSize_explicitDelimiter(inSeqs, inSeqsSize, seqPos);
|
6772
6930
|
FORWARD_IF_ERROR(explicitBlockSize, "Error while determining block size with explicit delimiters");
|
6773
6931
|
if (explicitBlockSize > blockSize)
|
@@ -6778,7 +6936,7 @@ static size_t determine_blockSize(ZSTD_sequenceFormat_e mode,
|
|
6778
6936
|
}
|
6779
6937
|
}
|
6780
6938
|
|
6781
|
-
/* Compress, block-by-block
|
6939
|
+
/* Compress all provided sequences, block-by-block.
|
6782
6940
|
*
|
6783
6941
|
* Returns the cumulative size of all compressed blocks (including their headers),
|
6784
6942
|
* otherwise a ZSTD error.
|
@@ -6791,11 +6949,11 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
|
|
6791
6949
|
{
|
6792
6950
|
size_t cSize = 0;
|
6793
6951
|
size_t remaining = srcSize;
|
6794
|
-
|
6952
|
+
ZSTD_SequencePosition seqPos = {0, 0, 0};
|
6795
6953
|
|
6796
|
-
BYTE
|
6954
|
+
const BYTE* ip = (BYTE const*)src;
|
6797
6955
|
BYTE* op = (BYTE*)dst;
|
6798
|
-
|
6956
|
+
ZSTD_SequenceCopier_f const sequenceCopier = ZSTD_selectSequenceCopier(cctx->appliedParams.blockDelimiters);
|
6799
6957
|
|
6800
6958
|
DEBUGLOG(4, "ZSTD_compressSequences_internal srcSize: %zu, inSeqsSize: %zu", srcSize, inSeqsSize);
|
6801
6959
|
/* Special case: empty frame */
|
@@ -6811,19 +6969,19 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
|
|
6811
6969
|
while (remaining) {
|
6812
6970
|
size_t compressedSeqsSize;
|
6813
6971
|
size_t cBlockSize;
|
6814
|
-
size_t additionalByteAdjustment;
|
6815
6972
|
size_t blockSize = determine_blockSize(cctx->appliedParams.blockDelimiters,
|
6816
|
-
cctx->
|
6973
|
+
cctx->blockSizeMax, remaining,
|
6817
6974
|
inSeqs, inSeqsSize, seqPos);
|
6818
6975
|
U32 const lastBlock = (blockSize == remaining);
|
6819
6976
|
FORWARD_IF_ERROR(blockSize, "Error while trying to determine block size");
|
6820
6977
|
assert(blockSize <= remaining);
|
6821
6978
|
ZSTD_resetSeqStore(&cctx->seqStore);
|
6822
|
-
DEBUGLOG(5, "Working on new block. Blocksize: %zu (total:%zu)", blockSize, (ip - (const BYTE*)src) + blockSize);
|
6823
6979
|
|
6824
|
-
|
6825
|
-
|
6826
|
-
|
6980
|
+
blockSize = sequenceCopier(cctx,
|
6981
|
+
&seqPos, inSeqs, inSeqsSize,
|
6982
|
+
ip, blockSize,
|
6983
|
+
cctx->appliedParams.searchForExternalRepcodes);
|
6984
|
+
FORWARD_IF_ERROR(blockSize, "Bad sequence copy");
|
6827
6985
|
|
6828
6986
|
/* If blocks are too small, emit as a nocompress block */
|
6829
6987
|
/* TODO: See 3090. We reduced MIN_CBLOCK_SIZE from 3 to 2 so to compensate we are adding
|
@@ -6831,7 +6989,7 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
|
|
6831
6989
|
if (blockSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1+1) {
|
6832
6990
|
cBlockSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);
|
6833
6991
|
FORWARD_IF_ERROR(cBlockSize, "Nocompress block failed");
|
6834
|
-
DEBUGLOG(5, "Block too small
|
6992
|
+
DEBUGLOG(5, "Block too small (%zu): data remains uncompressed: cSize=%zu", blockSize, cBlockSize);
|
6835
6993
|
cSize += cBlockSize;
|
6836
6994
|
ip += blockSize;
|
6837
6995
|
op += cBlockSize;
|
@@ -6846,7 +7004,7 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
|
|
6846
7004
|
&cctx->appliedParams,
|
6847
7005
|
op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize,
|
6848
7006
|
blockSize,
|
6849
|
-
cctx->
|
7007
|
+
cctx->tmpWorkspace, cctx->tmpWkspSize /* statically allocated in resetCCtx */,
|
6850
7008
|
cctx->bmi2);
|
6851
7009
|
FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed");
|
6852
7010
|
DEBUGLOG(5, "Compressed sequences size: %zu", compressedSeqsSize);
|
@@ -6854,10 +7012,10 @@ ZSTD_compressSequences_internal(ZSTD_CCtx* cctx,
|
|
6854
7012
|
if (!cctx->isFirstBlock &&
|
6855
7013
|
ZSTD_maybeRLE(&cctx->seqStore) &&
|
6856
7014
|
ZSTD_isRLE(ip, blockSize)) {
|
6857
|
-
/*
|
6858
|
-
|
6859
|
-
|
6860
|
-
|
7015
|
+
/* Note: don't emit the first block as RLE even if it qualifies because
|
7016
|
+
* doing so will cause the decoder (cli <= v1.4.3 only) to throw an (invalid) error
|
7017
|
+
* "should consume all input error."
|
7018
|
+
*/
|
6861
7019
|
compressedSeqsSize = 1;
|
6862
7020
|
}
|
6863
7021
|
|
@@ -6909,30 +7067,36 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* cctx,
|
|
6909
7067
|
{
|
6910
7068
|
BYTE* op = (BYTE*)dst;
|
6911
7069
|
size_t cSize = 0;
|
6912
|
-
size_t compressedBlocksSize = 0;
|
6913
|
-
size_t frameHeaderSize = 0;
|
6914
7070
|
|
6915
7071
|
/* Transparent initialization stage, same as compressStream2() */
|
6916
|
-
DEBUGLOG(4, "ZSTD_compressSequences (dstCapacity=%zu)", dstCapacity);
|
7072
|
+
DEBUGLOG(4, "ZSTD_compressSequences (nbSeqs=%zu,dstCapacity=%zu)", inSeqsSize, dstCapacity);
|
6917
7073
|
assert(cctx != NULL);
|
6918
7074
|
FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, srcSize), "CCtx initialization failed");
|
7075
|
+
|
6919
7076
|
/* Begin writing output, starting with frame header */
|
6920
|
-
frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity,
|
6921
|
-
|
6922
|
-
|
6923
|
-
|
7077
|
+
{ size_t const frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity,
|
7078
|
+
&cctx->appliedParams, srcSize, cctx->dictID);
|
7079
|
+
op += frameHeaderSize;
|
7080
|
+
assert(frameHeaderSize <= dstCapacity);
|
7081
|
+
dstCapacity -= frameHeaderSize;
|
7082
|
+
cSize += frameHeaderSize;
|
7083
|
+
}
|
6924
7084
|
if (cctx->appliedParams.fParams.checksumFlag && srcSize) {
|
6925
7085
|
XXH64_update(&cctx->xxhState, src, srcSize);
|
6926
7086
|
}
|
6927
|
-
|
6928
|
-
|
7087
|
+
|
7088
|
+
/* Now generate compressed blocks */
|
7089
|
+
{ size_t const cBlocksSize = ZSTD_compressSequences_internal(cctx,
|
6929
7090
|
op, dstCapacity,
|
6930
7091
|
inSeqs, inSeqsSize,
|
6931
7092
|
src, srcSize);
|
6932
|
-
|
6933
|
-
|
6934
|
-
|
7093
|
+
FORWARD_IF_ERROR(cBlocksSize, "Compressing blocks failed!");
|
7094
|
+
cSize += cBlocksSize;
|
7095
|
+
assert(cBlocksSize <= dstCapacity);
|
7096
|
+
dstCapacity -= cBlocksSize;
|
7097
|
+
}
|
6935
7098
|
|
7099
|
+
/* Complete with frame checksum, if needed */
|
6936
7100
|
if (cctx->appliedParams.fParams.checksumFlag) {
|
6937
7101
|
U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
|
6938
7102
|
RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall, "no room for checksum");
|
@@ -6945,6 +7109,530 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* cctx,
|
|
6945
7109
|
return cSize;
|
6946
7110
|
}
|
6947
7111
|
|
7112
|
+
|
7113
|
+
#if defined(__AVX2__)
|
7114
|
+
|
7115
|
+
#include <immintrin.h> /* AVX2 intrinsics */
|
7116
|
+
|
7117
|
+
/*
|
7118
|
+
* Convert 2 sequences per iteration, using AVX2 intrinsics:
|
7119
|
+
* - offset -> offBase = offset + 2
|
7120
|
+
* - litLength -> (U16) litLength
|
7121
|
+
* - matchLength -> (U16)(matchLength - 3)
|
7122
|
+
* - rep is ignored
|
7123
|
+
* Store only 8 bytes per SeqDef (offBase[4], litLength[2], mlBase[2]).
|
7124
|
+
*
|
7125
|
+
* At the end, instead of extracting two __m128i,
|
7126
|
+
* we use _mm256_permute4x64_epi64(..., 0xE8) to move lane2 into lane1,
|
7127
|
+
* then store the lower 16 bytes in one go.
|
7128
|
+
*
|
7129
|
+
* @returns 0 on succes, with no long length detected
|
7130
|
+
* @returns > 0 if there is one long length (> 65535),
|
7131
|
+
* indicating the position, and type.
|
7132
|
+
*/
|
7133
|
+
static size_t convertSequences_noRepcodes(
|
7134
|
+
SeqDef* dstSeqs,
|
7135
|
+
const ZSTD_Sequence* inSeqs,
|
7136
|
+
size_t nbSequences)
|
7137
|
+
{
|
7138
|
+
/*
|
7139
|
+
* addition:
|
7140
|
+
* For each 128-bit half: (offset+2, litLength+0, matchLength-3, rep+0)
|
7141
|
+
*/
|
7142
|
+
const __m256i addition = _mm256_setr_epi32(
|
7143
|
+
ZSTD_REP_NUM, 0, -MINMATCH, 0, /* for sequence i */
|
7144
|
+
ZSTD_REP_NUM, 0, -MINMATCH, 0 /* for sequence i+1 */
|
7145
|
+
);
|
7146
|
+
|
7147
|
+
/* limit: check if there is a long length */
|
7148
|
+
const __m256i limit = _mm256_set1_epi32(65535);
|
7149
|
+
|
7150
|
+
/*
|
7151
|
+
* shuffle mask for byte-level rearrangement in each 128-bit half:
|
7152
|
+
*
|
7153
|
+
* Input layout (after addition) per 128-bit half:
|
7154
|
+
* [ offset+2 (4 bytes) | litLength (4 bytes) | matchLength (4 bytes) | rep (4 bytes) ]
|
7155
|
+
* We only need:
|
7156
|
+
* offBase (4 bytes) = offset+2
|
7157
|
+
* litLength (2 bytes) = low 2 bytes of litLength
|
7158
|
+
* mlBase (2 bytes) = low 2 bytes of (matchLength)
|
7159
|
+
* => Bytes [0..3, 4..5, 8..9], zero the rest.
|
7160
|
+
*/
|
7161
|
+
const __m256i mask = _mm256_setr_epi8(
|
7162
|
+
/* For the lower 128 bits => sequence i */
|
7163
|
+
0, 1, 2, 3, /* offset+2 */
|
7164
|
+
4, 5, /* litLength (16 bits) */
|
7165
|
+
8, 9, /* matchLength (16 bits) */
|
7166
|
+
(BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80,
|
7167
|
+
(BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80,
|
7168
|
+
|
7169
|
+
/* For the upper 128 bits => sequence i+1 */
|
7170
|
+
16,17,18,19, /* offset+2 */
|
7171
|
+
20,21, /* litLength */
|
7172
|
+
24,25, /* matchLength */
|
7173
|
+
(BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80,
|
7174
|
+
(BYTE)0x80, (BYTE)0x80, (BYTE)0x80, (BYTE)0x80
|
7175
|
+
);
|
7176
|
+
|
7177
|
+
/*
|
7178
|
+
* Next, we'll use _mm256_permute4x64_epi64(vshf, 0xE8).
|
7179
|
+
* Explanation of 0xE8 = 11101000b => [lane0, lane2, lane2, lane3].
|
7180
|
+
* So the lower 128 bits become [lane0, lane2] => combining seq0 and seq1.
|
7181
|
+
*/
|
7182
|
+
#define PERM_LANE_0X_E8 0xE8 /* [0,2,2,3] in lane indices */
|
7183
|
+
|
7184
|
+
size_t longLen = 0, i = 0;
|
7185
|
+
|
7186
|
+
/* AVX permutation depends on the specific definition of target structures */
|
7187
|
+
ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16);
|
7188
|
+
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, offset) == 0);
|
7189
|
+
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, litLength) == 4);
|
7190
|
+
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8);
|
7191
|
+
ZSTD_STATIC_ASSERT(sizeof(SeqDef) == 8);
|
7192
|
+
ZSTD_STATIC_ASSERT(offsetof(SeqDef, offBase) == 0);
|
7193
|
+
ZSTD_STATIC_ASSERT(offsetof(SeqDef, litLength) == 4);
|
7194
|
+
ZSTD_STATIC_ASSERT(offsetof(SeqDef, mlBase) == 6);
|
7195
|
+
|
7196
|
+
/* Process 2 sequences per loop iteration */
|
7197
|
+
for (; i + 1 < nbSequences; i += 2) {
|
7198
|
+
/* Load 2 ZSTD_Sequence (32 bytes) */
|
7199
|
+
__m256i vin = _mm256_loadu_si256((const __m256i*)(const void*)&inSeqs[i]);
|
7200
|
+
|
7201
|
+
/* Add {2, 0, -3, 0} in each 128-bit half */
|
7202
|
+
__m256i vadd = _mm256_add_epi32(vin, addition);
|
7203
|
+
|
7204
|
+
/* Check for long length */
|
7205
|
+
__m256i ll_cmp = _mm256_cmpgt_epi32(vadd, limit); /* 0xFFFFFFFF for element > 65535 */
|
7206
|
+
int ll_res = _mm256_movemask_epi8(ll_cmp);
|
7207
|
+
|
7208
|
+
/* Shuffle bytes so each half gives us the 8 bytes we need */
|
7209
|
+
__m256i vshf = _mm256_shuffle_epi8(vadd, mask);
|
7210
|
+
/*
|
7211
|
+
* Now:
|
7212
|
+
* Lane0 = seq0's 8 bytes
|
7213
|
+
* Lane1 = 0
|
7214
|
+
* Lane2 = seq1's 8 bytes
|
7215
|
+
* Lane3 = 0
|
7216
|
+
*/
|
7217
|
+
|
7218
|
+
/* Permute 64-bit lanes => move Lane2 down into Lane1. */
|
7219
|
+
__m256i vperm = _mm256_permute4x64_epi64(vshf, PERM_LANE_0X_E8);
|
7220
|
+
/*
|
7221
|
+
* Now the lower 16 bytes (Lane0+Lane1) = [seq0, seq1].
|
7222
|
+
* The upper 16 bytes are [Lane2, Lane3] = [seq1, 0], but we won't use them.
|
7223
|
+
*/
|
7224
|
+
|
7225
|
+
/* Store only the lower 16 bytes => 2 SeqDef (8 bytes each) */
|
7226
|
+
_mm_storeu_si128((__m128i *)(void*)&dstSeqs[i], _mm256_castsi256_si128(vperm));
|
7227
|
+
/*
|
7228
|
+
* This writes out 16 bytes total:
|
7229
|
+
* - offset 0..7 => seq0 (offBase, litLength, mlBase)
|
7230
|
+
* - offset 8..15 => seq1 (offBase, litLength, mlBase)
|
7231
|
+
*/
|
7232
|
+
|
7233
|
+
/* check (unlikely) long lengths > 65535
|
7234
|
+
* indices for lengths correspond to bits [4..7], [8..11], [20..23], [24..27]
|
7235
|
+
* => combined mask = 0x0FF00FF0
|
7236
|
+
*/
|
7237
|
+
if (UNLIKELY((ll_res & 0x0FF00FF0) != 0)) {
|
7238
|
+
/* long length detected: let's figure out which one*/
|
7239
|
+
if (inSeqs[i].matchLength > 65535+MINMATCH) {
|
7240
|
+
assert(longLen == 0);
|
7241
|
+
longLen = i + 1;
|
7242
|
+
}
|
7243
|
+
if (inSeqs[i].litLength > 65535) {
|
7244
|
+
assert(longLen == 0);
|
7245
|
+
longLen = i + nbSequences + 1;
|
7246
|
+
}
|
7247
|
+
if (inSeqs[i+1].matchLength > 65535+MINMATCH) {
|
7248
|
+
assert(longLen == 0);
|
7249
|
+
longLen = i + 1 + 1;
|
7250
|
+
}
|
7251
|
+
if (inSeqs[i+1].litLength > 65535) {
|
7252
|
+
assert(longLen == 0);
|
7253
|
+
longLen = i + 1 + nbSequences + 1;
|
7254
|
+
}
|
7255
|
+
}
|
7256
|
+
}
|
7257
|
+
|
7258
|
+
/* Handle leftover if @nbSequences is odd */
|
7259
|
+
if (i < nbSequences) {
|
7260
|
+
/* process last sequence */
|
7261
|
+
assert(i == nbSequences - 1);
|
7262
|
+
dstSeqs[i].offBase = OFFSET_TO_OFFBASE(inSeqs[i].offset);
|
7263
|
+
dstSeqs[i].litLength = (U16)inSeqs[i].litLength;
|
7264
|
+
dstSeqs[i].mlBase = (U16)(inSeqs[i].matchLength - MINMATCH);
|
7265
|
+
/* check (unlikely) long lengths > 65535 */
|
7266
|
+
if (UNLIKELY(inSeqs[i].matchLength > 65535+MINMATCH)) {
|
7267
|
+
assert(longLen == 0);
|
7268
|
+
longLen = i + 1;
|
7269
|
+
}
|
7270
|
+
if (UNLIKELY(inSeqs[i].litLength > 65535)) {
|
7271
|
+
assert(longLen == 0);
|
7272
|
+
longLen = i + nbSequences + 1;
|
7273
|
+
}
|
7274
|
+
}
|
7275
|
+
|
7276
|
+
return longLen;
|
7277
|
+
}
|
7278
|
+
|
7279
|
+
/* the vector implementation could also be ported to SSSE3,
|
7280
|
+
* but since this implementation is targeting modern systems (>= Sapphire Rapid),
|
7281
|
+
* it's not useful to develop and maintain code for older pre-AVX2 platforms */
|
7282
|
+
|
7283
|
+
#else /* no AVX2 */
|
7284
|
+
|
7285
|
+
static size_t convertSequences_noRepcodes(
|
7286
|
+
SeqDef* dstSeqs,
|
7287
|
+
const ZSTD_Sequence* inSeqs,
|
7288
|
+
size_t nbSequences)
|
7289
|
+
{
|
7290
|
+
size_t longLen = 0;
|
7291
|
+
size_t n;
|
7292
|
+
for (n=0; n<nbSequences; n++) {
|
7293
|
+
dstSeqs[n].offBase = OFFSET_TO_OFFBASE(inSeqs[n].offset);
|
7294
|
+
dstSeqs[n].litLength = (U16)inSeqs[n].litLength;
|
7295
|
+
dstSeqs[n].mlBase = (U16)(inSeqs[n].matchLength - MINMATCH);
|
7296
|
+
/* check for long length > 65535 */
|
7297
|
+
if (UNLIKELY(inSeqs[n].matchLength > 65535+MINMATCH)) {
|
7298
|
+
assert(longLen == 0);
|
7299
|
+
longLen = n + 1;
|
7300
|
+
}
|
7301
|
+
if (UNLIKELY(inSeqs[n].litLength > 65535)) {
|
7302
|
+
assert(longLen == 0);
|
7303
|
+
longLen = n + nbSequences + 1;
|
7304
|
+
}
|
7305
|
+
}
|
7306
|
+
return longLen;
|
7307
|
+
}
|
7308
|
+
|
7309
|
+
#endif
|
7310
|
+
|
7311
|
+
/*
|
7312
|
+
* Precondition: Sequences must end on an explicit Block Delimiter
|
7313
|
+
* @return: 0 on success, or an error code.
|
7314
|
+
* Note: Sequence validation functionality has been disabled (removed).
|
7315
|
+
* This is helpful to generate a lean main pipeline, improving performance.
|
7316
|
+
* It may be re-inserted later.
|
7317
|
+
*/
|
7318
|
+
size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx,
|
7319
|
+
const ZSTD_Sequence* const inSeqs, size_t nbSequences,
|
7320
|
+
int repcodeResolution)
|
7321
|
+
{
|
7322
|
+
Repcodes_t updatedRepcodes;
|
7323
|
+
size_t seqNb = 0;
|
7324
|
+
|
7325
|
+
DEBUGLOG(5, "ZSTD_convertBlockSequences (nbSequences = %zu)", nbSequences);
|
7326
|
+
|
7327
|
+
RETURN_ERROR_IF(nbSequences >= cctx->seqStore.maxNbSeq, externalSequences_invalid,
|
7328
|
+
"Not enough memory allocated. Try adjusting ZSTD_c_minMatch.");
|
7329
|
+
|
7330
|
+
ZSTD_memcpy(updatedRepcodes.rep, cctx->blockState.prevCBlock->rep, sizeof(Repcodes_t));
|
7331
|
+
|
7332
|
+
/* check end condition */
|
7333
|
+
assert(nbSequences >= 1);
|
7334
|
+
assert(inSeqs[nbSequences-1].matchLength == 0);
|
7335
|
+
assert(inSeqs[nbSequences-1].offset == 0);
|
7336
|
+
|
7337
|
+
/* Convert Sequences from public format to internal format */
|
7338
|
+
if (!repcodeResolution) {
|
7339
|
+
size_t const longl = convertSequences_noRepcodes(cctx->seqStore.sequencesStart, inSeqs, nbSequences-1);
|
7340
|
+
cctx->seqStore.sequences = cctx->seqStore.sequencesStart + nbSequences-1;
|
7341
|
+
if (longl) {
|
7342
|
+
DEBUGLOG(5, "long length");
|
7343
|
+
assert(cctx->seqStore.longLengthType == ZSTD_llt_none);
|
7344
|
+
if (longl <= nbSequences-1) {
|
7345
|
+
DEBUGLOG(5, "long match length detected at pos %zu", longl-1);
|
7346
|
+
cctx->seqStore.longLengthType = ZSTD_llt_matchLength;
|
7347
|
+
cctx->seqStore.longLengthPos = (U32)(longl-1);
|
7348
|
+
} else {
|
7349
|
+
DEBUGLOG(5, "long literals length detected at pos %zu", longl-nbSequences);
|
7350
|
+
assert(longl <= 2* (nbSequences-1));
|
7351
|
+
cctx->seqStore.longLengthType = ZSTD_llt_literalLength;
|
7352
|
+
cctx->seqStore.longLengthPos = (U32)(longl-(nbSequences-1)-1);
|
7353
|
+
}
|
7354
|
+
}
|
7355
|
+
} else {
|
7356
|
+
for (seqNb = 0; seqNb < nbSequences - 1 ; seqNb++) {
|
7357
|
+
U32 const litLength = inSeqs[seqNb].litLength;
|
7358
|
+
U32 const matchLength = inSeqs[seqNb].matchLength;
|
7359
|
+
U32 const ll0 = (litLength == 0);
|
7360
|
+
U32 const offBase = ZSTD_finalizeOffBase(inSeqs[seqNb].offset, updatedRepcodes.rep, ll0);
|
7361
|
+
|
7362
|
+
DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength);
|
7363
|
+
ZSTD_storeSeqOnly(&cctx->seqStore, litLength, offBase, matchLength);
|
7364
|
+
ZSTD_updateRep(updatedRepcodes.rep, offBase, ll0);
|
7365
|
+
}
|
7366
|
+
}
|
7367
|
+
|
7368
|
+
/* If we skipped repcode search while parsing, we need to update repcodes now */
|
7369
|
+
if (!repcodeResolution && nbSequences > 1) {
|
7370
|
+
U32* const rep = updatedRepcodes.rep;
|
7371
|
+
|
7372
|
+
if (nbSequences >= 4) {
|
7373
|
+
U32 lastSeqIdx = (U32)nbSequences - 2; /* index of last full sequence */
|
7374
|
+
rep[2] = inSeqs[lastSeqIdx - 2].offset;
|
7375
|
+
rep[1] = inSeqs[lastSeqIdx - 1].offset;
|
7376
|
+
rep[0] = inSeqs[lastSeqIdx].offset;
|
7377
|
+
} else if (nbSequences == 3) {
|
7378
|
+
rep[2] = rep[0];
|
7379
|
+
rep[1] = inSeqs[0].offset;
|
7380
|
+
rep[0] = inSeqs[1].offset;
|
7381
|
+
} else {
|
7382
|
+
assert(nbSequences == 2);
|
7383
|
+
rep[2] = rep[1];
|
7384
|
+
rep[1] = rep[0];
|
7385
|
+
rep[0] = inSeqs[0].offset;
|
7386
|
+
}
|
7387
|
+
}
|
7388
|
+
|
7389
|
+
ZSTD_memcpy(cctx->blockState.nextCBlock->rep, updatedRepcodes.rep, sizeof(Repcodes_t));
|
7390
|
+
|
7391
|
+
return 0;
|
7392
|
+
}
|
7393
|
+
|
7394
|
+
#if defined(ZSTD_ARCH_X86_AVX2)
|
7395
|
+
|
7396
|
+
BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
|
7397
|
+
{
|
7398
|
+
size_t i;
|
7399
|
+
__m256i const zeroVec = _mm256_setzero_si256();
|
7400
|
+
__m256i sumVec = zeroVec; /* accumulates match+lit in 32-bit lanes */
|
7401
|
+
ZSTD_ALIGNED(32) U32 tmp[8]; /* temporary buffer for reduction */
|
7402
|
+
size_t mSum = 0, lSum = 0;
|
7403
|
+
ZSTD_STATIC_ASSERT(sizeof(ZSTD_Sequence) == 16);
|
7404
|
+
|
7405
|
+
/* Process 2 structs (32 bytes) at a time */
|
7406
|
+
for (i = 0; i + 2 <= nbSeqs; i += 2) {
|
7407
|
+
/* Load two consecutive ZSTD_Sequence (8×4 = 32 bytes) */
|
7408
|
+
__m256i data = _mm256_loadu_si256((const __m256i*)(const void*)&seqs[i]);
|
7409
|
+
/* check end of block signal */
|
7410
|
+
__m256i cmp = _mm256_cmpeq_epi32(data, zeroVec);
|
7411
|
+
int cmp_res = _mm256_movemask_epi8(cmp);
|
7412
|
+
/* indices for match lengths correspond to bits [8..11], [24..27]
|
7413
|
+
* => combined mask = 0x0F000F00 */
|
7414
|
+
ZSTD_STATIC_ASSERT(offsetof(ZSTD_Sequence, matchLength) == 8);
|
7415
|
+
if (cmp_res & 0x0F000F00) break;
|
7416
|
+
/* Accumulate in sumVec */
|
7417
|
+
sumVec = _mm256_add_epi32(sumVec, data);
|
7418
|
+
}
|
7419
|
+
|
7420
|
+
/* Horizontal reduction */
|
7421
|
+
_mm256_store_si256((__m256i*)tmp, sumVec);
|
7422
|
+
lSum = tmp[1] + tmp[5];
|
7423
|
+
mSum = tmp[2] + tmp[6];
|
7424
|
+
|
7425
|
+
/* Handle the leftover */
|
7426
|
+
for (; i < nbSeqs; i++) {
|
7427
|
+
lSum += seqs[i].litLength;
|
7428
|
+
mSum += seqs[i].matchLength;
|
7429
|
+
if (seqs[i].matchLength == 0) break; /* end of block */
|
7430
|
+
}
|
7431
|
+
|
7432
|
+
if (i==nbSeqs) {
|
7433
|
+
/* reaching end of sequences: end of block signal was not present */
|
7434
|
+
BlockSummary bs;
|
7435
|
+
bs.nbSequences = ERROR(externalSequences_invalid);
|
7436
|
+
return bs;
|
7437
|
+
}
|
7438
|
+
{ BlockSummary bs;
|
7439
|
+
bs.nbSequences = i+1;
|
7440
|
+
bs.blockSize = lSum + mSum;
|
7441
|
+
bs.litSize = lSum;
|
7442
|
+
return bs;
|
7443
|
+
}
|
7444
|
+
}
|
7445
|
+
|
7446
|
+
#else
|
7447
|
+
|
7448
|
+
BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs)
|
7449
|
+
{
|
7450
|
+
size_t totalMatchSize = 0;
|
7451
|
+
size_t litSize = 0;
|
7452
|
+
size_t n;
|
7453
|
+
assert(seqs);
|
7454
|
+
for (n=0; n<nbSeqs; n++) {
|
7455
|
+
totalMatchSize += seqs[n].matchLength;
|
7456
|
+
litSize += seqs[n].litLength;
|
7457
|
+
if (seqs[n].matchLength == 0) {
|
7458
|
+
assert(seqs[n].offset == 0);
|
7459
|
+
break;
|
7460
|
+
}
|
7461
|
+
}
|
7462
|
+
if (n==nbSeqs) {
|
7463
|
+
BlockSummary bs;
|
7464
|
+
bs.nbSequences = ERROR(externalSequences_invalid);
|
7465
|
+
return bs;
|
7466
|
+
}
|
7467
|
+
{ BlockSummary bs;
|
7468
|
+
bs.nbSequences = n+1;
|
7469
|
+
bs.blockSize = litSize + totalMatchSize;
|
7470
|
+
bs.litSize = litSize;
|
7471
|
+
return bs;
|
7472
|
+
}
|
7473
|
+
}
|
7474
|
+
#endif
|
7475
|
+
|
7476
|
+
|
7477
|
+
static size_t
|
7478
|
+
ZSTD_compressSequencesAndLiterals_internal(ZSTD_CCtx* cctx,
|
7479
|
+
void* dst, size_t dstCapacity,
|
7480
|
+
const ZSTD_Sequence* inSeqs, size_t nbSequences,
|
7481
|
+
const void* literals, size_t litSize, size_t srcSize)
|
7482
|
+
{
|
7483
|
+
size_t remaining = srcSize;
|
7484
|
+
size_t cSize = 0;
|
7485
|
+
BYTE* op = (BYTE*)dst;
|
7486
|
+
int const repcodeResolution = (cctx->appliedParams.searchForExternalRepcodes == ZSTD_ps_enable);
|
7487
|
+
assert(cctx->appliedParams.searchForExternalRepcodes != ZSTD_ps_auto);
|
7488
|
+
|
7489
|
+
DEBUGLOG(4, "ZSTD_compressSequencesAndLiterals_internal: nbSeqs=%zu, litSize=%zu", nbSequences, litSize);
|
7490
|
+
RETURN_ERROR_IF(nbSequences == 0, externalSequences_invalid, "Requires at least 1 end-of-block");
|
7491
|
+
|
7492
|
+
/* Special case: empty frame */
|
7493
|
+
if ((nbSequences == 1) && (inSeqs[0].litLength == 0)) {
|
7494
|
+
U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1);
|
7495
|
+
RETURN_ERROR_IF(dstCapacity<3, dstSize_tooSmall, "No room for empty frame block header");
|
7496
|
+
MEM_writeLE24(op, cBlockHeader24);
|
7497
|
+
op += ZSTD_blockHeaderSize;
|
7498
|
+
dstCapacity -= ZSTD_blockHeaderSize;
|
7499
|
+
cSize += ZSTD_blockHeaderSize;
|
7500
|
+
}
|
7501
|
+
|
7502
|
+
while (nbSequences) {
|
7503
|
+
size_t compressedSeqsSize, cBlockSize, conversionStatus;
|
7504
|
+
BlockSummary const block = ZSTD_get1BlockSummary(inSeqs, nbSequences);
|
7505
|
+
U32 const lastBlock = (block.nbSequences == nbSequences);
|
7506
|
+
FORWARD_IF_ERROR(block.nbSequences, "Error while trying to determine nb of sequences for a block");
|
7507
|
+
assert(block.nbSequences <= nbSequences);
|
7508
|
+
RETURN_ERROR_IF(block.litSize > litSize, externalSequences_invalid, "discrepancy: Sequences require more literals than present in buffer");
|
7509
|
+
ZSTD_resetSeqStore(&cctx->seqStore);
|
7510
|
+
|
7511
|
+
conversionStatus = ZSTD_convertBlockSequences(cctx,
|
7512
|
+
inSeqs, block.nbSequences,
|
7513
|
+
repcodeResolution);
|
7514
|
+
FORWARD_IF_ERROR(conversionStatus, "Bad sequence conversion");
|
7515
|
+
inSeqs += block.nbSequences;
|
7516
|
+
nbSequences -= block.nbSequences;
|
7517
|
+
remaining -= block.blockSize;
|
7518
|
+
|
7519
|
+
/* Note: when blockSize is very small, other variant send it uncompressed.
|
7520
|
+
* Here, we still send the sequences, because we don't have the original source to send it uncompressed.
|
7521
|
+
* One could imagine in theory reproducing the source from the sequences,
|
7522
|
+
* but that's complex and costly memory intensive, and goes against the objectives of this variant. */
|
7523
|
+
|
7524
|
+
RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall, "not enough dstCapacity to write a new compressed block");
|
7525
|
+
|
7526
|
+
compressedSeqsSize = ZSTD_entropyCompressSeqStore_internal(
|
7527
|
+
op + ZSTD_blockHeaderSize /* Leave space for block header */, dstCapacity - ZSTD_blockHeaderSize,
|
7528
|
+
literals, block.litSize,
|
7529
|
+
&cctx->seqStore,
|
7530
|
+
&cctx->blockState.prevCBlock->entropy, &cctx->blockState.nextCBlock->entropy,
|
7531
|
+
&cctx->appliedParams,
|
7532
|
+
cctx->tmpWorkspace, cctx->tmpWkspSize /* statically allocated in resetCCtx */,
|
7533
|
+
cctx->bmi2);
|
7534
|
+
FORWARD_IF_ERROR(compressedSeqsSize, "Compressing sequences of block failed");
|
7535
|
+
/* note: the spec forbids for any compressed block to be larger than maximum block size */
|
7536
|
+
if (compressedSeqsSize > cctx->blockSizeMax) compressedSeqsSize = 0;
|
7537
|
+
DEBUGLOG(5, "Compressed sequences size: %zu", compressedSeqsSize);
|
7538
|
+
litSize -= block.litSize;
|
7539
|
+
literals = (const char*)literals + block.litSize;
|
7540
|
+
|
7541
|
+
/* Note: difficult to check source for RLE block when only Literals are provided,
|
7542
|
+
* but it could be considered from analyzing the sequence directly */
|
7543
|
+
|
7544
|
+
if (compressedSeqsSize == 0) {
|
7545
|
+
/* Sending uncompressed blocks is out of reach, because the source is not provided.
|
7546
|
+
* In theory, one could use the sequences to regenerate the source, like a decompressor,
|
7547
|
+
* but it's complex, and memory hungry, killing the purpose of this variant.
|
7548
|
+
* Current outcome: generate an error code.
|
7549
|
+
*/
|
7550
|
+
RETURN_ERROR(cannotProduce_uncompressedBlock, "ZSTD_compressSequencesAndLiterals cannot generate an uncompressed block");
|
7551
|
+
} else {
|
7552
|
+
U32 cBlockHeader;
|
7553
|
+
assert(compressedSeqsSize > 1); /* no RLE */
|
7554
|
+
/* Error checking and repcodes update */
|
7555
|
+
ZSTD_blockState_confirmRepcodesAndEntropyTables(&cctx->blockState);
|
7556
|
+
if (cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)
|
7557
|
+
cctx->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;
|
7558
|
+
|
7559
|
+
/* Write block header into beginning of block*/
|
7560
|
+
cBlockHeader = lastBlock + (((U32)bt_compressed)<<1) + (U32)(compressedSeqsSize << 3);
|
7561
|
+
MEM_writeLE24(op, cBlockHeader);
|
7562
|
+
cBlockSize = ZSTD_blockHeaderSize + compressedSeqsSize;
|
7563
|
+
DEBUGLOG(5, "Writing out compressed block, size: %zu", cBlockSize);
|
7564
|
+
}
|
7565
|
+
|
7566
|
+
cSize += cBlockSize;
|
7567
|
+
op += cBlockSize;
|
7568
|
+
dstCapacity -= cBlockSize;
|
7569
|
+
cctx->isFirstBlock = 0;
|
7570
|
+
DEBUGLOG(5, "cSize running total: %zu (remaining dstCapacity=%zu)", cSize, dstCapacity);
|
7571
|
+
|
7572
|
+
if (lastBlock) {
|
7573
|
+
assert(nbSequences == 0);
|
7574
|
+
break;
|
7575
|
+
}
|
7576
|
+
}
|
7577
|
+
|
7578
|
+
RETURN_ERROR_IF(litSize != 0, externalSequences_invalid, "literals must be entirely and exactly consumed");
|
7579
|
+
RETURN_ERROR_IF(remaining != 0, externalSequences_invalid, "Sequences must represent a total of exactly srcSize=%zu", srcSize);
|
7580
|
+
DEBUGLOG(4, "cSize final total: %zu", cSize);
|
7581
|
+
return cSize;
|
7582
|
+
}
|
7583
|
+
|
7584
|
+
size_t
|
7585
|
+
ZSTD_compressSequencesAndLiterals(ZSTD_CCtx* cctx,
|
7586
|
+
void* dst, size_t dstCapacity,
|
7587
|
+
const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
|
7588
|
+
const void* literals, size_t litSize, size_t litCapacity,
|
7589
|
+
size_t decompressedSize)
|
7590
|
+
{
|
7591
|
+
BYTE* op = (BYTE*)dst;
|
7592
|
+
size_t cSize = 0;
|
7593
|
+
|
7594
|
+
/* Transparent initialization stage, same as compressStream2() */
|
7595
|
+
DEBUGLOG(4, "ZSTD_compressSequencesAndLiterals (dstCapacity=%zu)", dstCapacity);
|
7596
|
+
assert(cctx != NULL);
|
7597
|
+
if (litCapacity < litSize) {
|
7598
|
+
RETURN_ERROR(workSpace_tooSmall, "literals buffer is not large enough: must be at least 8 bytes larger than litSize (risk of read out-of-bound)");
|
7599
|
+
}
|
7600
|
+
FORWARD_IF_ERROR(ZSTD_CCtx_init_compressStream2(cctx, ZSTD_e_end, decompressedSize), "CCtx initialization failed");
|
7601
|
+
|
7602
|
+
if (cctx->appliedParams.blockDelimiters == ZSTD_sf_noBlockDelimiters) {
|
7603
|
+
RETURN_ERROR(frameParameter_unsupported, "This mode is only compatible with explicit delimiters");
|
7604
|
+
}
|
7605
|
+
if (cctx->appliedParams.validateSequences) {
|
7606
|
+
RETURN_ERROR(parameter_unsupported, "This mode is not compatible with Sequence validation");
|
7607
|
+
}
|
7608
|
+
if (cctx->appliedParams.fParams.checksumFlag) {
|
7609
|
+
RETURN_ERROR(frameParameter_unsupported, "this mode is not compatible with frame checksum");
|
7610
|
+
}
|
7611
|
+
|
7612
|
+
/* Begin writing output, starting with frame header */
|
7613
|
+
{ size_t const frameHeaderSize = ZSTD_writeFrameHeader(op, dstCapacity,
|
7614
|
+
&cctx->appliedParams, decompressedSize, cctx->dictID);
|
7615
|
+
op += frameHeaderSize;
|
7616
|
+
assert(frameHeaderSize <= dstCapacity);
|
7617
|
+
dstCapacity -= frameHeaderSize;
|
7618
|
+
cSize += frameHeaderSize;
|
7619
|
+
}
|
7620
|
+
|
7621
|
+
/* Now generate compressed blocks */
|
7622
|
+
{ size_t const cBlocksSize = ZSTD_compressSequencesAndLiterals_internal(cctx,
|
7623
|
+
op, dstCapacity,
|
7624
|
+
inSeqs, inSeqsSize,
|
7625
|
+
literals, litSize, decompressedSize);
|
7626
|
+
FORWARD_IF_ERROR(cBlocksSize, "Compressing blocks failed!");
|
7627
|
+
cSize += cBlocksSize;
|
7628
|
+
assert(cBlocksSize <= dstCapacity);
|
7629
|
+
dstCapacity -= cBlocksSize;
|
7630
|
+
}
|
7631
|
+
|
7632
|
+
DEBUGLOG(4, "Final compressed size: %zu", cSize);
|
7633
|
+
return cSize;
|
7634
|
+
}
|
7635
|
+
|
6948
7636
|
/*====== Finalize ======*/
|
6949
7637
|
|
6950
7638
|
static ZSTD_inBuffer inBuffer_forEndFlush(const ZSTD_CStream* zcs)
|
@@ -6963,7 +7651,6 @@ size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
|
|
6963
7651
|
return ZSTD_compressStream2(zcs, output, &input, ZSTD_e_flush);
|
6964
7652
|
}
|
6965
7653
|
|
6966
|
-
|
6967
7654
|
size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
|
6968
7655
|
{
|
6969
7656
|
ZSTD_inBuffer input = inBuffer_forEndFlush(zcs);
|
@@ -7044,7 +7731,7 @@ static void ZSTD_dedicatedDictSearch_revertCParams(
|
|
7044
7731
|
}
|
7045
7732
|
}
|
7046
7733
|
|
7047
|
-
static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize,
|
7734
|
+
static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
|
7048
7735
|
{
|
7049
7736
|
switch (mode) {
|
7050
7737
|
case ZSTD_cpm_unknown:
|
@@ -7068,8 +7755,8 @@ static U64 ZSTD_getCParamRowSize(U64 srcSizeHint, size_t dictSize, ZSTD_cParamMo
|
|
7068
7755
|
* @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.
|
7069
7756
|
* Note: srcSizeHint 0 means 0, use ZSTD_CONTENTSIZE_UNKNOWN for unknown.
|
7070
7757
|
* Use dictSize == 0 for unknown or unused.
|
7071
|
-
* Note: `mode` controls how we treat the `dictSize`. See docs for `
|
7072
|
-
static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize,
|
7758
|
+
* Note: `mode` controls how we treat the `dictSize`. See docs for `ZSTD_CParamMode_e`. */
|
7759
|
+
static ZSTD_compressionParameters ZSTD_getCParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
|
7073
7760
|
{
|
7074
7761
|
U64 const rSize = ZSTD_getCParamRowSize(srcSizeHint, dictSize, mode);
|
7075
7762
|
U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);
|
@@ -7107,7 +7794,9 @@ ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long l
|
|
7107
7794
|
* same idea as ZSTD_getCParams()
|
7108
7795
|
* @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
|
7109
7796
|
* Fields of `ZSTD_frameParameters` are set to default values */
|
7110
|
-
static ZSTD_parameters
|
7797
|
+
static ZSTD_parameters
|
7798
|
+
ZSTD_getParams_internal(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode)
|
7799
|
+
{
|
7111
7800
|
ZSTD_parameters params;
|
7112
7801
|
ZSTD_compressionParameters const cParams = ZSTD_getCParams_internal(compressionLevel, srcSizeHint, dictSize, mode);
|
7113
7802
|
DEBUGLOG(5, "ZSTD_getParams (cLevel=%i)", compressionLevel);
|
@@ -7121,7 +7810,8 @@ static ZSTD_parameters ZSTD_getParams_internal(int compressionLevel, unsigned lo
|
|
7121
7810
|
* same idea as ZSTD_getCParams()
|
7122
7811
|
* @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).
|
7123
7812
|
* Fields of `ZSTD_frameParameters` are set to default values */
|
7124
|
-
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
|
7813
|
+
ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)
|
7814
|
+
{
|
7125
7815
|
if (srcSizeHint == 0) srcSizeHint = ZSTD_CONTENTSIZE_UNKNOWN;
|
7126
7816
|
return ZSTD_getParams_internal(compressionLevel, srcSizeHint, dictSize, ZSTD_cpm_unknown);
|
7127
7817
|
}
|
@@ -7129,8 +7819,8 @@ ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeH
|
|
7129
7819
|
void ZSTD_registerSequenceProducer(
|
7130
7820
|
ZSTD_CCtx* zc,
|
7131
7821
|
void* extSeqProdState,
|
7132
|
-
ZSTD_sequenceProducer_F extSeqProdFunc
|
7133
|
-
|
7822
|
+
ZSTD_sequenceProducer_F extSeqProdFunc)
|
7823
|
+
{
|
7134
7824
|
assert(zc != NULL);
|
7135
7825
|
ZSTD_CCtxParams_registerSequenceProducer(
|
7136
7826
|
&zc->requestedParams, extSeqProdState, extSeqProdFunc
|
@@ -7140,8 +7830,8 @@ void ZSTD_registerSequenceProducer(
|
|
7140
7830
|
void ZSTD_CCtxParams_registerSequenceProducer(
|
7141
7831
|
ZSTD_CCtx_params* params,
|
7142
7832
|
void* extSeqProdState,
|
7143
|
-
ZSTD_sequenceProducer_F extSeqProdFunc
|
7144
|
-
|
7833
|
+
ZSTD_sequenceProducer_F extSeqProdFunc)
|
7834
|
+
{
|
7145
7835
|
assert(params != NULL);
|
7146
7836
|
if (extSeqProdFunc != NULL) {
|
7147
7837
|
params->extSeqProdFunc = extSeqProdFunc;
|