zstd-ruby 1.3.4.0 → 1.3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/zstdruby/libzstd/Makefile +56 -10
- data/ext/zstdruby/libzstd/README.md +4 -0
- data/ext/zstdruby/libzstd/common/bitstream.h +6 -19
- data/ext/zstdruby/libzstd/common/compiler.h +3 -3
- data/ext/zstdruby/libzstd/common/cpu.h +1 -2
- data/ext/zstdruby/libzstd/common/debug.c +44 -0
- data/ext/zstdruby/libzstd/common/debug.h +123 -0
- data/ext/zstdruby/libzstd/common/entropy_common.c +16 -1
- data/ext/zstdruby/libzstd/common/fse.h +45 -41
- data/ext/zstdruby/libzstd/common/fse_decompress.c +1 -1
- data/ext/zstdruby/libzstd/common/huf.h +34 -27
- data/ext/zstdruby/libzstd/common/pool.c +89 -32
- data/ext/zstdruby/libzstd/common/pool.h +29 -19
- data/ext/zstdruby/libzstd/common/zstd_common.c +0 -5
- data/ext/zstdruby/libzstd/common/zstd_internal.h +3 -37
- data/ext/zstdruby/libzstd/compress/fse_compress.c +28 -163
- data/ext/zstdruby/libzstd/compress/hist.c +195 -0
- data/ext/zstdruby/libzstd/compress/hist.h +92 -0
- data/ext/zstdruby/libzstd/compress/huf_compress.c +14 -6
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +798 -350
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +120 -34
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +247 -87
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +4 -1
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +177 -56
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +4 -1
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +331 -65
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +13 -0
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +15 -20
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +1 -2
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +503 -300
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +7 -0
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +122 -47
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +5 -5
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +325 -325
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +80 -43
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +9 -2
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +5 -5
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +12 -61
- data/ext/zstdruby/libzstd/zstd.h +137 -69
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +7 -3
@@ -0,0 +1,92 @@
|
|
1
|
+
/* ******************************************************************
|
2
|
+
hist : Histogram functions
|
3
|
+
part of Finite State Entropy project
|
4
|
+
Copyright (C) 2013-present, Yann Collet.
|
5
|
+
|
6
|
+
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
7
|
+
|
8
|
+
Redistribution and use in source and binary forms, with or without
|
9
|
+
modification, are permitted provided that the following conditions are
|
10
|
+
met:
|
11
|
+
|
12
|
+
* Redistributions of source code must retain the above copyright
|
13
|
+
notice, this list of conditions and the following disclaimer.
|
14
|
+
* Redistributions in binary form must reproduce the above
|
15
|
+
copyright notice, this list of conditions and the following disclaimer
|
16
|
+
in the documentation and/or other materials provided with the
|
17
|
+
distribution.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
20
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
21
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
22
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
23
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
24
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
25
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
26
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
27
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
28
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
You can contact the author at :
|
32
|
+
- FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
|
33
|
+
- Public forum : https://groups.google.com/forum/#!forum/lz4c
|
34
|
+
****************************************************************** */
|
35
|
+
|
36
|
+
/* --- dependencies --- */
|
37
|
+
#include <stddef.h> /* size_t */
|
38
|
+
|
39
|
+
|
40
|
+
/* --- simple histogram functions --- */
|
41
|
+
|
42
|
+
/*! HIST_count():
|
43
|
+
* Provides the precise count of each byte within a table 'count'.
|
44
|
+
* 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1).
|
45
|
+
* Updates *maxSymbolValuePtr with actual largest symbol value detected.
|
46
|
+
* @return : count of the most frequent symbol (which isn't identified).
|
47
|
+
* or an error code, which can be tested using HIST_isError().
|
48
|
+
* note : if return == srcSize, there is only one symbol.
|
49
|
+
*/
|
50
|
+
size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
|
51
|
+
const void* src, size_t srcSize);
|
52
|
+
|
53
|
+
unsigned HIST_isError(size_t code); /*< tells if a return value is an error code */
|
54
|
+
|
55
|
+
|
56
|
+
/* --- advanced histogram functions --- */
|
57
|
+
|
58
|
+
#define HIST_WKSP_SIZE_U32 1024
|
59
|
+
/** HIST_count_wksp() :
|
60
|
+
* Same as HIST_count(), but using an externally provided scratch buffer.
|
61
|
+
* Benefit is this function will use very little stack space.
|
62
|
+
* `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32
|
63
|
+
*/
|
64
|
+
size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
|
65
|
+
const void* src, size_t srcSize,
|
66
|
+
unsigned* workSpace);
|
67
|
+
|
68
|
+
/** HIST_countFast() :
|
69
|
+
* same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr.
|
70
|
+
* This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr`
|
71
|
+
*/
|
72
|
+
size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
|
73
|
+
const void* src, size_t srcSize);
|
74
|
+
|
75
|
+
/** HIST_countFast_wksp() :
|
76
|
+
* Same as HIST_countFast(), but using an externally provided scratch buffer.
|
77
|
+
* `workSpace` must be a table of unsigned of size >= HIST_WKSP_SIZE_U32
|
78
|
+
*/
|
79
|
+
size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
|
80
|
+
const void* src, size_t srcSize,
|
81
|
+
unsigned* workSpace);
|
82
|
+
|
83
|
+
/*! HIST_count_simple() :
|
84
|
+
* Same as HIST_countFast(), this function is unsafe,
|
85
|
+
* and will segfault if any value within `src` is `> *maxSymbolValuePtr`.
|
86
|
+
* It is also a bit slower for large inputs.
|
87
|
+
* However, it does not need any additional memory (not even on stack).
|
88
|
+
* @return : count of the most frequent symbol.
|
89
|
+
* Note this function doesn't produce any error (i.e. it must succeed).
|
90
|
+
*/
|
91
|
+
unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
|
92
|
+
const void* src, size_t srcSize);
|
@@ -45,8 +45,9 @@
|
|
45
45
|
****************************************************************/
|
46
46
|
#include <string.h> /* memcpy, memset */
|
47
47
|
#include <stdio.h> /* printf (debug) */
|
48
|
-
#include "bitstream.h"
|
49
48
|
#include "compiler.h"
|
49
|
+
#include "bitstream.h"
|
50
|
+
#include "hist.h"
|
50
51
|
#define FSE_STATIC_LINKING_ONLY /* FSE_optimalTableLog_internal */
|
51
52
|
#include "fse.h" /* header compression */
|
52
53
|
#define HUF_STATIC_LINKING_ONLY
|
@@ -58,7 +59,7 @@
|
|
58
59
|
* Error Management
|
59
60
|
****************************************************************/
|
60
61
|
#define HUF_isError ERR_isError
|
61
|
-
#define HUF_STATIC_ASSERT(c)
|
62
|
+
#define HUF_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */
|
62
63
|
#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
|
63
64
|
#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
|
64
65
|
|
@@ -100,9 +101,9 @@ size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable,
|
|
100
101
|
if (wtSize <= 1) return 0; /* Not compressible */
|
101
102
|
|
102
103
|
/* Scan input and build symbol stats */
|
103
|
-
{
|
104
|
+
{ unsigned const maxCount = HIST_count_simple(count, &maxSymbolValue, weightTable, wtSize); /* never fails */
|
104
105
|
if (maxCount == wtSize) return 1; /* only a single symbol in src : rle */
|
105
|
-
if (maxCount == 1) return 0;
|
106
|
+
if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
|
106
107
|
}
|
107
108
|
|
108
109
|
tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
|
@@ -216,6 +217,13 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32* maxSymbolValuePtr, const void* src
|
|
216
217
|
return readSize;
|
217
218
|
}
|
218
219
|
|
220
|
+
U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue)
|
221
|
+
{
|
222
|
+
const HUF_CElt* table = (const HUF_CElt*)symbolTable;
|
223
|
+
assert(symbolValue <= HUF_SYMBOLVALUE_MAX);
|
224
|
+
return table[symbolValue].nbBits;
|
225
|
+
}
|
226
|
+
|
219
227
|
|
220
228
|
typedef struct nodeElt_s {
|
221
229
|
U32 count;
|
@@ -660,9 +668,9 @@ static size_t HUF_compress_internal (
|
|
660
668
|
}
|
661
669
|
|
662
670
|
/* Scan input and build symbol stats */
|
663
|
-
{ CHECK_V_F(largest,
|
671
|
+
{ CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, table->count) );
|
664
672
|
if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
|
665
|
-
if (largest <= (srcSize >> 7)+
|
673
|
+
if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */
|
666
674
|
}
|
667
675
|
|
668
676
|
/* Check validity of previous table */
|
@@ -8,21 +8,13 @@
|
|
8
8
|
* You may select, at your option, one of the above-listed licenses.
|
9
9
|
*/
|
10
10
|
|
11
|
-
|
12
|
-
/*-*************************************
|
13
|
-
* Tuning parameters
|
14
|
-
***************************************/
|
15
|
-
#ifndef ZSTD_CLEVEL_DEFAULT
|
16
|
-
# define ZSTD_CLEVEL_DEFAULT 3
|
17
|
-
#endif
|
18
|
-
|
19
|
-
|
20
11
|
/*-*************************************
|
21
12
|
* Dependencies
|
22
13
|
***************************************/
|
23
14
|
#include <string.h> /* memset */
|
24
15
|
#include "cpu.h"
|
25
16
|
#include "mem.h"
|
17
|
+
#include "hist.h" /* HIST_countFast_wksp */
|
26
18
|
#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
|
27
19
|
#include "fse.h"
|
28
20
|
#define HUF_STATIC_LINKING_ONLY
|
@@ -64,17 +56,26 @@ ZSTD_CCtx* ZSTD_createCCtx(void)
|
|
64
56
|
return ZSTD_createCCtx_advanced(ZSTD_defaultCMem);
|
65
57
|
}
|
66
58
|
|
59
|
+
static void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager)
|
60
|
+
{
|
61
|
+
assert(cctx != NULL);
|
62
|
+
memset(cctx, 0, sizeof(*cctx));
|
63
|
+
cctx->customMem = memManager;
|
64
|
+
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
|
65
|
+
{ size_t const err = ZSTD_CCtx_resetParameters(cctx);
|
66
|
+
assert(!ZSTD_isError(err));
|
67
|
+
(void)err;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
67
71
|
ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
|
68
72
|
{
|
69
73
|
ZSTD_STATIC_ASSERT(zcss_init==0);
|
70
74
|
ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1));
|
71
75
|
if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
|
72
|
-
{ ZSTD_CCtx* const cctx = (ZSTD_CCtx*)
|
76
|
+
{ ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
|
73
77
|
if (!cctx) return NULL;
|
74
|
-
cctx
|
75
|
-
cctx->requestedParams.compressionLevel = ZSTD_CLEVEL_DEFAULT;
|
76
|
-
cctx->requestedParams.fParams.contentSizeFlag = 1;
|
77
|
-
cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
|
78
|
+
ZSTD_initCCtx(cctx, customMem);
|
78
79
|
return cctx;
|
79
80
|
}
|
80
81
|
}
|
@@ -102,17 +103,24 @@ ZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)
|
|
102
103
|
return cctx;
|
103
104
|
}
|
104
105
|
|
105
|
-
|
106
|
+
static void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx)
|
106
107
|
{
|
107
|
-
|
108
|
-
|
108
|
+
assert(cctx != NULL);
|
109
|
+
assert(cctx->staticSize == 0);
|
109
110
|
ZSTD_free(cctx->workSpace, cctx->customMem); cctx->workSpace = NULL;
|
110
111
|
ZSTD_freeCDict(cctx->cdictLocal); cctx->cdictLocal = NULL;
|
111
112
|
#ifdef ZSTD_MULTITHREAD
|
112
113
|
ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;
|
113
114
|
#endif
|
115
|
+
}
|
116
|
+
|
117
|
+
size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
|
118
|
+
{
|
119
|
+
if (cctx==NULL) return 0; /* support free on NULL */
|
120
|
+
if (cctx->staticSize) return ERROR(memory_allocation); /* not compatible with static CCtx */
|
121
|
+
ZSTD_freeCCtxContent(cctx);
|
114
122
|
ZSTD_free(cctx, cctx->customMem);
|
115
|
-
return 0;
|
123
|
+
return 0;
|
116
124
|
}
|
117
125
|
|
118
126
|
|
@@ -143,21 +151,6 @@ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
|
|
143
151
|
/* private API call, for dictBuilder only */
|
144
152
|
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }
|
145
153
|
|
146
|
-
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
|
147
|
-
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
|
148
|
-
{
|
149
|
-
ZSTD_compressionParameters cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);
|
150
|
-
if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
|
151
|
-
if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
|
152
|
-
if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
|
153
|
-
if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
|
154
|
-
if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
|
155
|
-
if (CCtxParams->cParams.searchLength) cParams.searchLength = CCtxParams->cParams.searchLength;
|
156
|
-
if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
|
157
|
-
if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
|
158
|
-
return cParams;
|
159
|
-
}
|
160
|
-
|
161
154
|
static ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(
|
162
155
|
ZSTD_compressionParameters cParams)
|
163
156
|
{
|
@@ -251,7 +244,6 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
|
|
251
244
|
case ZSTD_p_minMatch:
|
252
245
|
case ZSTD_p_targetLength:
|
253
246
|
case ZSTD_p_compressionStrategy:
|
254
|
-
case ZSTD_p_compressLiterals:
|
255
247
|
return 1;
|
256
248
|
|
257
249
|
case ZSTD_p_format:
|
@@ -268,6 +260,7 @@ static int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)
|
|
268
260
|
case ZSTD_p_ldmMinMatch:
|
269
261
|
case ZSTD_p_ldmBucketSizeLog:
|
270
262
|
case ZSTD_p_ldmHashEveryLog:
|
263
|
+
case ZSTD_p_forceAttachDict:
|
271
264
|
default:
|
272
265
|
return 0;
|
273
266
|
}
|
@@ -302,7 +295,6 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
|
|
302
295
|
if (cctx->cdict) return ERROR(stage_wrong);
|
303
296
|
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
|
304
297
|
|
305
|
-
case ZSTD_p_compressLiterals:
|
306
298
|
case ZSTD_p_contentSizeFlag:
|
307
299
|
case ZSTD_p_checksumFlag:
|
308
300
|
case ZSTD_p_dictIDFlag:
|
@@ -313,6 +305,9 @@ size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned v
|
|
313
305
|
* default : 0 when using a CDict, 1 when using a Prefix */
|
314
306
|
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
|
315
307
|
|
308
|
+
case ZSTD_p_forceAttachDict:
|
309
|
+
return ZSTD_CCtxParam_setParameter(&cctx->requestedParams, param, value);
|
310
|
+
|
316
311
|
case ZSTD_p_nbWorkers:
|
317
312
|
if ((value>0) && cctx->staticSize) {
|
318
313
|
return ERROR(parameter_unsupported); /* MT not compatible with static alloc */
|
@@ -351,7 +346,6 @@ size_t ZSTD_CCtxParam_setParameter(
|
|
351
346
|
int cLevel = (int)value; /* cast expected to restore negative sign */
|
352
347
|
if (cLevel > ZSTD_maxCLevel()) cLevel = ZSTD_maxCLevel();
|
353
348
|
if (cLevel) { /* 0 : does not change current level */
|
354
|
-
CCtxParams->disableLiteralCompression = (cLevel<0); /* negative levels disable huffman */
|
355
349
|
CCtxParams->compressionLevel = cLevel;
|
356
350
|
}
|
357
351
|
if (CCtxParams->compressionLevel >= 0) return CCtxParams->compressionLevel;
|
@@ -399,10 +393,6 @@ size_t ZSTD_CCtxParam_setParameter(
|
|
399
393
|
CCtxParams->cParams.strategy = (ZSTD_strategy)value;
|
400
394
|
return (size_t)CCtxParams->cParams.strategy;
|
401
395
|
|
402
|
-
case ZSTD_p_compressLiterals:
|
403
|
-
CCtxParams->disableLiteralCompression = !value;
|
404
|
-
return !CCtxParams->disableLiteralCompression;
|
405
|
-
|
406
396
|
case ZSTD_p_contentSizeFlag :
|
407
397
|
/* Content size written in frame header _when known_ (default:1) */
|
408
398
|
DEBUGLOG(4, "set content size flag = %u", (value>0));
|
@@ -423,6 +413,12 @@ size_t ZSTD_CCtxParam_setParameter(
|
|
423
413
|
CCtxParams->forceWindow = (value > 0);
|
424
414
|
return CCtxParams->forceWindow;
|
425
415
|
|
416
|
+
case ZSTD_p_forceAttachDict :
|
417
|
+
CCtxParams->attachDictPref = value ?
|
418
|
+
(value > 0 ? ZSTD_dictForceAttach : ZSTD_dictForceCopy) :
|
419
|
+
ZSTD_dictDefaultAttach;
|
420
|
+
return CCtxParams->attachDictPref;
|
421
|
+
|
426
422
|
case ZSTD_p_nbWorkers :
|
427
423
|
#ifndef ZSTD_MULTITHREAD
|
428
424
|
if (value>0) return ERROR(parameter_unsupported);
|
@@ -477,6 +473,98 @@ size_t ZSTD_CCtxParam_setParameter(
|
|
477
473
|
}
|
478
474
|
}
|
479
475
|
|
476
|
+
size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, unsigned* value)
|
477
|
+
{
|
478
|
+
return ZSTD_CCtxParam_getParameter(&cctx->requestedParams, param, value);
|
479
|
+
}
|
480
|
+
|
481
|
+
size_t ZSTD_CCtxParam_getParameter(
|
482
|
+
ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, unsigned* value)
|
483
|
+
{
|
484
|
+
switch(param)
|
485
|
+
{
|
486
|
+
case ZSTD_p_format :
|
487
|
+
*value = CCtxParams->format;
|
488
|
+
break;
|
489
|
+
case ZSTD_p_compressionLevel :
|
490
|
+
*value = CCtxParams->compressionLevel;
|
491
|
+
break;
|
492
|
+
case ZSTD_p_windowLog :
|
493
|
+
*value = CCtxParams->cParams.windowLog;
|
494
|
+
break;
|
495
|
+
case ZSTD_p_hashLog :
|
496
|
+
*value = CCtxParams->cParams.hashLog;
|
497
|
+
break;
|
498
|
+
case ZSTD_p_chainLog :
|
499
|
+
*value = CCtxParams->cParams.chainLog;
|
500
|
+
break;
|
501
|
+
case ZSTD_p_searchLog :
|
502
|
+
*value = CCtxParams->cParams.searchLog;
|
503
|
+
break;
|
504
|
+
case ZSTD_p_minMatch :
|
505
|
+
*value = CCtxParams->cParams.searchLength;
|
506
|
+
break;
|
507
|
+
case ZSTD_p_targetLength :
|
508
|
+
*value = CCtxParams->cParams.targetLength;
|
509
|
+
break;
|
510
|
+
case ZSTD_p_compressionStrategy :
|
511
|
+
*value = (unsigned)CCtxParams->cParams.strategy;
|
512
|
+
break;
|
513
|
+
case ZSTD_p_contentSizeFlag :
|
514
|
+
*value = CCtxParams->fParams.contentSizeFlag;
|
515
|
+
break;
|
516
|
+
case ZSTD_p_checksumFlag :
|
517
|
+
*value = CCtxParams->fParams.checksumFlag;
|
518
|
+
break;
|
519
|
+
case ZSTD_p_dictIDFlag :
|
520
|
+
*value = !CCtxParams->fParams.noDictIDFlag;
|
521
|
+
break;
|
522
|
+
case ZSTD_p_forceMaxWindow :
|
523
|
+
*value = CCtxParams->forceWindow;
|
524
|
+
break;
|
525
|
+
case ZSTD_p_forceAttachDict :
|
526
|
+
*value = CCtxParams->attachDictPref;
|
527
|
+
break;
|
528
|
+
case ZSTD_p_nbWorkers :
|
529
|
+
#ifndef ZSTD_MULTITHREAD
|
530
|
+
assert(CCtxParams->nbWorkers == 0);
|
531
|
+
#endif
|
532
|
+
*value = CCtxParams->nbWorkers;
|
533
|
+
break;
|
534
|
+
case ZSTD_p_jobSize :
|
535
|
+
#ifndef ZSTD_MULTITHREAD
|
536
|
+
return ERROR(parameter_unsupported);
|
537
|
+
#else
|
538
|
+
*value = CCtxParams->jobSize;
|
539
|
+
break;
|
540
|
+
#endif
|
541
|
+
case ZSTD_p_overlapSizeLog :
|
542
|
+
#ifndef ZSTD_MULTITHREAD
|
543
|
+
return ERROR(parameter_unsupported);
|
544
|
+
#else
|
545
|
+
*value = CCtxParams->overlapSizeLog;
|
546
|
+
break;
|
547
|
+
#endif
|
548
|
+
case ZSTD_p_enableLongDistanceMatching :
|
549
|
+
*value = CCtxParams->ldmParams.enableLdm;
|
550
|
+
break;
|
551
|
+
case ZSTD_p_ldmHashLog :
|
552
|
+
*value = CCtxParams->ldmParams.hashLog;
|
553
|
+
break;
|
554
|
+
case ZSTD_p_ldmMinMatch :
|
555
|
+
*value = CCtxParams->ldmParams.minMatchLength;
|
556
|
+
break;
|
557
|
+
case ZSTD_p_ldmBucketSizeLog :
|
558
|
+
*value = CCtxParams->ldmParams.bucketSizeLog;
|
559
|
+
break;
|
560
|
+
case ZSTD_p_ldmHashEveryLog :
|
561
|
+
*value = CCtxParams->ldmParams.hashEveryLog;
|
562
|
+
break;
|
563
|
+
default: return ERROR(parameter_unsupported);
|
564
|
+
}
|
565
|
+
return 0;
|
566
|
+
}
|
567
|
+
|
480
568
|
/** ZSTD_CCtx_setParametersUsingCCtxParams() :
|
481
569
|
* just applies `params` into `cctx`
|
482
570
|
* no action is performed, parameters are merely stored.
|
@@ -487,6 +575,7 @@ size_t ZSTD_CCtxParam_setParameter(
|
|
487
575
|
size_t ZSTD_CCtx_setParametersUsingCCtxParams(
|
488
576
|
ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)
|
489
577
|
{
|
578
|
+
DEBUGLOG(4, "ZSTD_CCtx_setParametersUsingCCtxParams");
|
490
579
|
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
|
491
580
|
if (cctx->cdict) return ERROR(stage_wrong);
|
492
581
|
|
@@ -565,18 +654,19 @@ size_t ZSTD_CCtx_refPrefix_advanced(
|
|
565
654
|
return 0;
|
566
655
|
}
|
567
656
|
|
568
|
-
|
657
|
+
/*! ZSTD_CCtx_reset() :
|
658
|
+
* Also dumps dictionary */
|
659
|
+
void ZSTD_CCtx_reset(ZSTD_CCtx* cctx)
|
569
660
|
{
|
570
661
|
cctx->streamStage = zcss_init;
|
571
662
|
cctx->pledgedSrcSizePlusOne = 0;
|
572
663
|
}
|
573
664
|
|
574
|
-
|
575
|
-
* Also dumps dictionary */
|
576
|
-
void ZSTD_CCtx_reset(ZSTD_CCtx* cctx)
|
665
|
+
size_t ZSTD_CCtx_resetParameters(ZSTD_CCtx* cctx)
|
577
666
|
{
|
578
|
-
|
667
|
+
if (cctx->streamStage != zcss_init) return ERROR(stage_wrong);
|
579
668
|
cctx->cdict = NULL;
|
669
|
+
return ZSTD_CCtxParams_reset(&cctx->requestedParams);
|
580
670
|
}
|
581
671
|
|
582
672
|
/** ZSTD_checkCParams() :
|
@@ -589,8 +679,6 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
|
589
679
|
CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
590
680
|
CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
|
591
681
|
CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
|
592
|
-
if ((U32)(cParams.targetLength) < ZSTD_TARGETLENGTH_MIN)
|
593
|
-
return ERROR(parameter_unsupported);
|
594
682
|
if ((U32)(cParams.strategy) > (U32)ZSTD_btultra)
|
595
683
|
return ERROR(parameter_unsupported);
|
596
684
|
return 0;
|
@@ -599,7 +687,8 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
|
599
687
|
/** ZSTD_clampCParams() :
|
600
688
|
* make CParam values within valid range.
|
601
689
|
* @return : valid CParams */
|
602
|
-
static ZSTD_compressionParameters
|
690
|
+
static ZSTD_compressionParameters
|
691
|
+
ZSTD_clampCParams(ZSTD_compressionParameters cParams)
|
603
692
|
{
|
604
693
|
# define CLAMP(val,min,max) { \
|
605
694
|
if (val<min) val=min; \
|
@@ -610,8 +699,7 @@ static ZSTD_compressionParameters ZSTD_clampCParams(ZSTD_compressionParameters c
|
|
610
699
|
CLAMP(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
|
611
700
|
CLAMP(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
|
612
701
|
CLAMP(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
|
613
|
-
|
614
|
-
if ((U32)(cParams.strategy) > (U32)ZSTD_btultra) cParams.strategy = ZSTD_btultra;
|
702
|
+
CLAMP(cParams.strategy, ZSTD_fast, ZSTD_btultra);
|
615
703
|
return cParams;
|
616
704
|
}
|
617
705
|
|
@@ -627,8 +715,11 @@ static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
|
|
627
715
|
optimize `cPar` for a given input (`srcSize` and `dictSize`).
|
628
716
|
mostly downsizing to reduce memory consumption and initialization latency.
|
629
717
|
Both `srcSize` and `dictSize` are optional (use 0 if unknown).
|
630
|
-
Note : cPar is
|
631
|
-
|
718
|
+
Note : cPar is assumed validated. Use ZSTD_checkCParams() to ensure this condition. */
|
719
|
+
static ZSTD_compressionParameters
|
720
|
+
ZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,
|
721
|
+
unsigned long long srcSize,
|
722
|
+
size_t dictSize)
|
632
723
|
{
|
633
724
|
static const U64 minSrcSize = 513; /* (1<<9) + 1 */
|
634
725
|
static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);
|
@@ -648,7 +739,7 @@ ZSTD_compressionParameters ZSTD_adjustCParams_internal(ZSTD_compressionParameter
|
|
648
739
|
ZSTD_highbit32(tSize-1) + 1;
|
649
740
|
if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
|
650
741
|
}
|
651
|
-
if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
|
742
|
+
if (cPar.hashLog > cPar.windowLog+1) cPar.hashLog = cPar.windowLog+1;
|
652
743
|
{ U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
|
653
744
|
if (cycleLog > cPar.windowLog)
|
654
745
|
cPar.chainLog -= (cycleLog - cPar.windowLog);
|
@@ -660,13 +751,34 @@ ZSTD_compressionParameters ZSTD_adjustCParams_internal(ZSTD_compressionParameter
|
|
660
751
|
return cPar;
|
661
752
|
}
|
662
753
|
|
663
|
-
ZSTD_compressionParameters
|
754
|
+
ZSTD_compressionParameters
|
755
|
+
ZSTD_adjustCParams(ZSTD_compressionParameters cPar,
|
756
|
+
unsigned long long srcSize,
|
757
|
+
size_t dictSize)
|
664
758
|
{
|
665
759
|
cPar = ZSTD_clampCParams(cPar);
|
666
760
|
return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);
|
667
761
|
}
|
668
762
|
|
669
|
-
|
763
|
+
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
|
764
|
+
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)
|
765
|
+
{
|
766
|
+
ZSTD_compressionParameters cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);
|
767
|
+
if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;
|
768
|
+
if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;
|
769
|
+
if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;
|
770
|
+
if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;
|
771
|
+
if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;
|
772
|
+
if (CCtxParams->cParams.searchLength) cParams.searchLength = CCtxParams->cParams.searchLength;
|
773
|
+
if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;
|
774
|
+
if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;
|
775
|
+
assert(!ZSTD_checkCParams(cParams));
|
776
|
+
return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize);
|
777
|
+
}
|
778
|
+
|
779
|
+
static size_t
|
780
|
+
ZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,
|
781
|
+
const U32 forCCtx)
|
670
782
|
{
|
671
783
|
size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
|
672
784
|
size_t const hSize = ((size_t)1) << cParams->hashLog;
|
@@ -752,12 +864,14 @@ size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams)
|
|
752
864
|
return ZSTD_estimateCStreamSize_usingCCtxParams(¶ms);
|
753
865
|
}
|
754
866
|
|
755
|
-
static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)
|
867
|
+
static size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)
|
868
|
+
{
|
756
869
|
ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);
|
757
870
|
return ZSTD_estimateCStreamSize_usingCParams(cParams);
|
758
871
|
}
|
759
872
|
|
760
|
-
size_t ZSTD_estimateCStreamSize(int compressionLevel)
|
873
|
+
size_t ZSTD_estimateCStreamSize(int compressionLevel)
|
874
|
+
{
|
761
875
|
int level;
|
762
876
|
size_t memBudget = 0;
|
763
877
|
for (level=1; level<=compressionLevel; level++) {
|
@@ -851,10 +965,10 @@ static void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)
|
|
851
965
|
int i;
|
852
966
|
for (i = 0; i < ZSTD_REP_NUM; ++i)
|
853
967
|
bs->rep[i] = repStartValue[i];
|
854
|
-
bs->entropy.
|
855
|
-
bs->entropy.offcode_repeatMode = FSE_repeat_none;
|
856
|
-
bs->entropy.matchlength_repeatMode = FSE_repeat_none;
|
857
|
-
bs->entropy.litlength_repeatMode = FSE_repeat_none;
|
968
|
+
bs->entropy.huf.repeatMode = HUF_repeat_none;
|
969
|
+
bs->entropy.fse.offcode_repeatMode = FSE_repeat_none;
|
970
|
+
bs->entropy.fse.matchlength_repeatMode = FSE_repeat_none;
|
971
|
+
bs->entropy.fse.litlength_repeatMode = FSE_repeat_none;
|
858
972
|
}
|
859
973
|
|
860
974
|
/*! ZSTD_invalidateMatchState()
|
@@ -866,8 +980,10 @@ static void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)
|
|
866
980
|
ZSTD_window_clear(&ms->window);
|
867
981
|
|
868
982
|
ms->nextToUpdate = ms->window.dictLimit + 1;
|
983
|
+
ms->nextToUpdate3 = ms->window.dictLimit + 1;
|
869
984
|
ms->loadedDictEnd = 0;
|
870
985
|
ms->opt.litLengthSum = 0; /* force reset of btopt stats */
|
986
|
+
ms->dictMatchState = NULL;
|
871
987
|
}
|
872
988
|
|
873
989
|
/*! ZSTD_continueCCtx() :
|
@@ -900,7 +1016,11 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_CCtx_params params, U64 pl
|
|
900
1016
|
|
901
1017
|
typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset } ZSTD_compResetPolicy_e;
|
902
1018
|
|
903
|
-
static void*
|
1019
|
+
static void*
|
1020
|
+
ZSTD_reset_matchState(ZSTD_matchState_t* ms,
|
1021
|
+
void* ptr,
|
1022
|
+
const ZSTD_compressionParameters* cParams,
|
1023
|
+
ZSTD_compResetPolicy_e const crp, U32 const forCCtx)
|
904
1024
|
{
|
905
1025
|
size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);
|
906
1026
|
size_t const hSize = ((size_t)1) << cParams->hashLog;
|
@@ -941,10 +1061,18 @@ static void* ZSTD_reset_matchState(ZSTD_matchState_t* ms, void* ptr, ZSTD_compre
|
|
941
1061
|
return ptr;
|
942
1062
|
}
|
943
1063
|
|
1064
|
+
#define ZSTD_WORKSPACETOOLARGE_FACTOR 3 /* define "workspace is too large" as this number of times larger than needed */
|
1065
|
+
#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128 /* when workspace is continuously too large
|
1066
|
+
* during at least this number of times,
|
1067
|
+
* context's memory usage is considered wasteful,
|
1068
|
+
* because it's sized to handle a worst case scenario which rarely happens.
|
1069
|
+
* In which case, resize it down to free some memory */
|
1070
|
+
|
944
1071
|
/*! ZSTD_resetCCtx_internal() :
|
945
1072
|
note : `params` are assumed fully validated at this stage */
|
946
1073
|
static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
947
|
-
ZSTD_CCtx_params params,
|
1074
|
+
ZSTD_CCtx_params params,
|
1075
|
+
U64 pledgedSrcSize,
|
948
1076
|
ZSTD_compResetPolicy_e const crp,
|
949
1077
|
ZSTD_buffered_policy_e const zbuff)
|
950
1078
|
{
|
@@ -956,20 +1084,20 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
956
1084
|
if (ZSTD_equivalentParams(zc->appliedParams, params,
|
957
1085
|
zc->inBuffSize, zc->blockSize,
|
958
1086
|
zbuff, pledgedSrcSize)) {
|
959
|
-
DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%
|
960
|
-
zc->appliedParams.cParams.windowLog,
|
961
|
-
|
1087
|
+
DEBUGLOG(4, "ZSTD_equivalentParams()==1 -> continue mode (wLog1=%u, blockSize1=%zu)",
|
1088
|
+
zc->appliedParams.cParams.windowLog, zc->blockSize);
|
1089
|
+
zc->workSpaceOversizedDuration += (zc->workSpaceOversizedDuration > 0); /* if it was too large, it still is */
|
1090
|
+
if (zc->workSpaceOversizedDuration <= ZSTD_WORKSPACETOOLARGE_MAXDURATION)
|
1091
|
+
return ZSTD_continueCCtx(zc, params, pledgedSrcSize);
|
962
1092
|
} }
|
963
1093
|
DEBUGLOG(4, "ZSTD_equivalentParams()==0 -> reset CCtx");
|
964
1094
|
|
965
1095
|
if (params.ldmParams.enableLdm) {
|
966
1096
|
/* Adjust long distance matching parameters */
|
967
|
-
params.ldmParams.windowLog = params.cParams.windowLog;
|
968
1097
|
ZSTD_ldm_adjustParameters(¶ms.ldmParams, ¶ms.cParams);
|
969
1098
|
assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);
|
970
1099
|
assert(params.ldmParams.hashEveryLog < 32);
|
971
|
-
zc->ldmState.hashPower =
|
972
|
-
ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
|
1100
|
+
zc->ldmState.hashPower = ZSTD_ldm_getHashPower(params.ldmParams.minMatchLength);
|
973
1101
|
}
|
974
1102
|
|
975
1103
|
{ size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));
|
@@ -981,7 +1109,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
981
1109
|
size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;
|
982
1110
|
size_t const matchStateSize = ZSTD_sizeof_matchState(¶ms.cParams, /* forCCtx */ 1);
|
983
1111
|
size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);
|
984
|
-
void* ptr;
|
1112
|
+
void* ptr; /* used to partition workSpace */
|
985
1113
|
|
986
1114
|
/* Check if workSpace is large enough, alloc a new one if needed */
|
987
1115
|
{ size_t const entropySpace = HUF_WORKSPACE_SIZE;
|
@@ -993,14 +1121,20 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
993
1121
|
size_t const neededSpace = entropySpace + blockStateSpace + ldmSpace +
|
994
1122
|
ldmSeqSpace + matchStateSize + tokenSpace +
|
995
1123
|
bufferSpace;
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1124
|
+
|
1125
|
+
int const workSpaceTooSmall = zc->workSpaceSize < neededSpace;
|
1126
|
+
int const workSpaceTooLarge = zc->workSpaceSize > ZSTD_WORKSPACETOOLARGE_FACTOR * neededSpace;
|
1127
|
+
int const workSpaceWasteful = workSpaceTooLarge && (zc->workSpaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION);
|
1128
|
+
zc->workSpaceOversizedDuration = workSpaceTooLarge ? zc->workSpaceOversizedDuration+1 : 0;
|
1129
|
+
|
1130
|
+
DEBUGLOG(4, "Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers",
|
1131
|
+
neededSpace>>10, matchStateSize>>10, bufferSpace>>10);
|
1132
|
+
DEBUGLOG(4, "windowSize: %zu - blockSize: %zu", windowSize, blockSize);
|
1133
|
+
|
1134
|
+
if (workSpaceTooSmall || workSpaceWasteful) {
|
1135
|
+
DEBUGLOG(4, "Need to resize workSpaceSize from %zuKB to %zuKB",
|
1136
|
+
zc->workSpaceSize >> 10,
|
1137
|
+
neededSpace >> 10);
|
1004
1138
|
/* static cctx : no resize, error out */
|
1005
1139
|
if (zc->staticSize) return ERROR(memory_allocation);
|
1006
1140
|
|
@@ -1009,9 +1143,12 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|
1009
1143
|
zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
|
1010
1144
|
if (zc->workSpace == NULL) return ERROR(memory_allocation);
|
1011
1145
|
zc->workSpaceSize = neededSpace;
|
1146
|
+
zc->workSpaceOversizedDuration = 0;
|
1012
1147
|
ptr = zc->workSpace;
|
1013
1148
|
|
1014
|
-
/* Statically sized space.
|
1149
|
+
/* Statically sized space.
|
1150
|
+
* entropyWorkspace never moves,
|
1151
|
+
* though prev/next block swap places */
|
1015
1152
|
assert(((size_t)zc->workSpace & 3) == 0); /* ensure correct alignment */
|
1016
1153
|
assert(zc->workSpaceSize >= 2 * sizeof(ZSTD_compressedBlockState_t));
|
1017
1154
|
zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)zc->workSpace;
|
@@ -1100,48 +1237,98 @@ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
|
|
1100
1237
|
|
1101
1238
|
static size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,
|
1102
1239
|
const ZSTD_CDict* cdict,
|
1103
|
-
|
1104
|
-
ZSTD_frameParameters fParams,
|
1240
|
+
ZSTD_CCtx_params params,
|
1105
1241
|
U64 pledgedSrcSize,
|
1106
1242
|
ZSTD_buffered_policy_e zbuff)
|
1107
1243
|
{
|
1108
|
-
|
1244
|
+
/* We have a choice between copying the dictionary context into the working
|
1245
|
+
* context, or referencing the dictionary context from the working context
|
1246
|
+
* in-place. We decide here which strategy to use. */
|
1247
|
+
const U64 attachDictSizeCutoffs[(unsigned)ZSTD_btultra+1] = {
|
1248
|
+
8 KB, /* unused */
|
1249
|
+
8 KB, /* ZSTD_fast */
|
1250
|
+
16 KB, /* ZSTD_dfast */
|
1251
|
+
32 KB, /* ZSTD_greedy */
|
1252
|
+
32 KB, /* ZSTD_lazy */
|
1253
|
+
32 KB, /* ZSTD_lazy2 */
|
1254
|
+
32 KB, /* ZSTD_btlazy2 */
|
1255
|
+
32 KB, /* ZSTD_btopt */
|
1256
|
+
8 KB /* ZSTD_btultra */
|
1257
|
+
};
|
1258
|
+
const int attachDict = ( pledgedSrcSize <= attachDictSizeCutoffs[cdict->cParams.strategy]
|
1259
|
+
|| pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN
|
1260
|
+
|| params.attachDictPref == ZSTD_dictForceAttach )
|
1261
|
+
&& params.attachDictPref != ZSTD_dictForceCopy
|
1262
|
+
&& !params.forceWindow /* dictMatchState isn't correctly
|
1263
|
+
* handled in _enforceMaxDist */
|
1264
|
+
&& ZSTD_equivalentCParams(cctx->appliedParams.cParams,
|
1265
|
+
cdict->cParams);
|
1266
|
+
|
1267
|
+
DEBUGLOG(4, "ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)", (U32)pledgedSrcSize);
|
1268
|
+
|
1269
|
+
|
1270
|
+
{ unsigned const windowLog = params.cParams.windowLog;
|
1271
|
+
assert(windowLog != 0);
|
1109
1272
|
/* Copy only compression parameters related to tables. */
|
1110
1273
|
params.cParams = cdict->cParams;
|
1111
|
-
|
1112
|
-
params.fParams = fParams;
|
1274
|
+
params.cParams.windowLog = windowLog;
|
1113
1275
|
ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
1114
|
-
ZSTDcrp_noMemset,
|
1276
|
+
attachDict ? ZSTDcrp_continue : ZSTDcrp_noMemset,
|
1277
|
+
zbuff);
|
1115
1278
|
assert(cctx->appliedParams.cParams.strategy == cdict->cParams.strategy);
|
1116
1279
|
assert(cctx->appliedParams.cParams.hashLog == cdict->cParams.hashLog);
|
1117
1280
|
assert(cctx->appliedParams.cParams.chainLog == cdict->cParams.chainLog);
|
1118
1281
|
}
|
1119
1282
|
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1283
|
+
if (attachDict) {
|
1284
|
+
const U32 cdictLen = (U32)( cdict->matchState.window.nextSrc
|
1285
|
+
- cdict->matchState.window.base);
|
1286
|
+
if (cdictLen == 0) {
|
1287
|
+
/* don't even attach dictionaries with no contents */
|
1288
|
+
DEBUGLOG(4, "skipping attaching empty dictionary");
|
1289
|
+
} else {
|
1290
|
+
DEBUGLOG(4, "attaching dictionary into context");
|
1291
|
+
cctx->blockState.matchState.dictMatchState = &cdict->matchState;
|
1292
|
+
|
1293
|
+
/* prep working match state so dict matches never have negative indices
|
1294
|
+
* when they are translated to the working context's index space. */
|
1295
|
+
if (cctx->blockState.matchState.window.dictLimit < cdictLen) {
|
1296
|
+
cctx->blockState.matchState.window.nextSrc =
|
1297
|
+
cctx->blockState.matchState.window.base + cdictLen;
|
1298
|
+
ZSTD_window_clear(&cctx->blockState.matchState.window);
|
1299
|
+
}
|
1300
|
+
cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit;
|
1301
|
+
}
|
1302
|
+
} else {
|
1303
|
+
DEBUGLOG(4, "copying dictionary into context");
|
1304
|
+
/* copy tables */
|
1305
|
+
{ size_t const chainSize = (cdict->cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict->cParams.chainLog);
|
1306
|
+
size_t const hSize = (size_t)1 << cdict->cParams.hashLog;
|
1307
|
+
size_t const tableSpace = (chainSize + hSize) * sizeof(U32);
|
1308
|
+
assert((U32*)cctx->blockState.matchState.chainTable == (U32*)cctx->blockState.matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
1309
|
+
assert((U32*)cctx->blockState.matchState.hashTable3 == (U32*)cctx->blockState.matchState.chainTable + chainSize);
|
1310
|
+
assert((U32*)cdict->matchState.chainTable == (U32*)cdict->matchState.hashTable + hSize); /* chainTable must follow hashTable */
|
1311
|
+
assert((U32*)cdict->matchState.hashTable3 == (U32*)cdict->matchState.chainTable + chainSize);
|
1312
|
+
memcpy(cctx->blockState.matchState.hashTable, cdict->matchState.hashTable, tableSpace); /* presumes all tables follow each other */
|
1313
|
+
}
|
1135
1314
|
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1315
|
+
/* Zero the hashTable3, since the cdict never fills it */
|
1316
|
+
{ size_t const h3Size = (size_t)1 << cctx->blockState.matchState.hashLog3;
|
1317
|
+
assert(cdict->matchState.hashLog3 == 0);
|
1318
|
+
memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));
|
1319
|
+
}
|
1320
|
+
|
1321
|
+
/* copy dictionary offsets */
|
1322
|
+
{
|
1323
|
+
ZSTD_matchState_t const* srcMatchState = &cdict->matchState;
|
1324
|
+
ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;
|
1325
|
+
dstMatchState->window = srcMatchState->window;
|
1326
|
+
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
1327
|
+
dstMatchState->nextToUpdate3= srcMatchState->nextToUpdate3;
|
1328
|
+
dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;
|
1329
|
+
}
|
1144
1330
|
}
|
1331
|
+
|
1145
1332
|
cctx->dictID = cdict->dictID;
|
1146
1333
|
|
1147
1334
|
/* copy block state */
|
@@ -1192,7 +1379,7 @@ static size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,
|
|
1192
1379
|
|
1193
1380
|
/* copy dictionary offsets */
|
1194
1381
|
{
|
1195
|
-
ZSTD_matchState_t
|
1382
|
+
const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState;
|
1196
1383
|
ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;
|
1197
1384
|
dstMatchState->window = srcMatchState->window;
|
1198
1385
|
dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;
|
@@ -1356,16 +1543,24 @@ static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, cons
|
|
1356
1543
|
}
|
1357
1544
|
|
1358
1545
|
|
1359
|
-
|
1546
|
+
/* ZSTD_minGain() :
|
1547
|
+
* minimum compression required
|
1548
|
+
* to generate a compress block or a compressed literals section.
|
1549
|
+
* note : use same formula for both situations */
|
1550
|
+
static size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
|
1551
|
+
{
|
1552
|
+
U32 const minlog = (strat==ZSTD_btultra) ? 7 : 6;
|
1553
|
+
return (srcSize >> minlog) + 2;
|
1554
|
+
}
|
1360
1555
|
|
1361
|
-
static size_t ZSTD_compressLiterals (
|
1362
|
-
|
1556
|
+
static size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
|
1557
|
+
ZSTD_hufCTables_t* nextHuf,
|
1363
1558
|
ZSTD_strategy strategy, int disableLiteralCompression,
|
1364
1559
|
void* dst, size_t dstCapacity,
|
1365
1560
|
const void* src, size_t srcSize,
|
1366
1561
|
U32* workspace, const int bmi2)
|
1367
1562
|
{
|
1368
|
-
size_t const minGain = ZSTD_minGain(srcSize);
|
1563
|
+
size_t const minGain = ZSTD_minGain(srcSize, strategy);
|
1369
1564
|
size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
|
1370
1565
|
BYTE* const ostart = (BYTE*)dst;
|
1371
1566
|
U32 singleStream = srcSize < 256;
|
@@ -1376,27 +1571,25 @@ static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t const* prevEntropy,
|
|
1376
1571
|
disableLiteralCompression);
|
1377
1572
|
|
1378
1573
|
/* Prepare nextEntropy assuming reusing the existing table */
|
1379
|
-
|
1380
|
-
memcpy(nextEntropy->hufCTable, prevEntropy->hufCTable,
|
1381
|
-
sizeof(prevEntropy->hufCTable));
|
1574
|
+
memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
1382
1575
|
|
1383
1576
|
if (disableLiteralCompression)
|
1384
1577
|
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
1385
1578
|
|
1386
1579
|
/* small ? don't even attempt compression (speed opt) */
|
1387
1580
|
# define COMPRESS_LITERALS_SIZE_MIN 63
|
1388
|
-
{ size_t const minLitSize = (
|
1581
|
+
{ size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
|
1389
1582
|
if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
1390
1583
|
}
|
1391
1584
|
|
1392
1585
|
if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
|
1393
|
-
{ HUF_repeat repeat =
|
1586
|
+
{ HUF_repeat repeat = prevHuf->repeatMode;
|
1394
1587
|
int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
|
1395
1588
|
if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
|
1396
1589
|
cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
|
1397
|
-
workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)
|
1590
|
+
workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2)
|
1398
1591
|
: HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
|
1399
|
-
workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)
|
1592
|
+
workspace, HUF_WORKSPACE_SIZE, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
|
1400
1593
|
if (repeat != HUF_repeat_none) {
|
1401
1594
|
/* reused the existing table */
|
1402
1595
|
hType = set_repeat;
|
@@ -1404,17 +1597,17 @@ static size_t ZSTD_compressLiterals (ZSTD_entropyCTables_t const* prevEntropy,
|
|
1404
1597
|
}
|
1405
1598
|
|
1406
1599
|
if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
|
1407
|
-
memcpy(
|
1600
|
+
memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
1408
1601
|
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
1409
1602
|
}
|
1410
1603
|
if (cLitSize==1) {
|
1411
|
-
memcpy(
|
1604
|
+
memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
1412
1605
|
return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
|
1413
1606
|
}
|
1414
1607
|
|
1415
1608
|
if (hType == set_compressed) {
|
1416
1609
|
/* using a newly constructed table */
|
1417
|
-
|
1610
|
+
nextHuf->repeatMode = HUF_repeat_check;
|
1418
1611
|
}
|
1419
1612
|
|
1420
1613
|
/* Build header */
|
@@ -1464,61 +1657,234 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
|
|
1464
1657
|
mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
|
1465
1658
|
}
|
1466
1659
|
|
1660
|
+
|
1661
|
+
/**
|
1662
|
+
* -log2(x / 256) lookup table for x in [0, 256).
|
1663
|
+
* If x == 0: Return 0
|
1664
|
+
* Else: Return floor(-log2(x / 256) * 256)
|
1665
|
+
*/
|
1666
|
+
static unsigned const kInverseProbabiltyLog256[256] = {
|
1667
|
+
0, 2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162,
|
1668
|
+
1130, 1100, 1073, 1047, 1024, 1001, 980, 960, 941, 923, 906, 889,
|
1669
|
+
874, 859, 844, 830, 817, 804, 791, 779, 768, 756, 745, 734,
|
1670
|
+
724, 714, 704, 694, 685, 676, 667, 658, 650, 642, 633, 626,
|
1671
|
+
618, 610, 603, 595, 588, 581, 574, 567, 561, 554, 548, 542,
|
1672
|
+
535, 529, 523, 517, 512, 506, 500, 495, 489, 484, 478, 473,
|
1673
|
+
468, 463, 458, 453, 448, 443, 438, 434, 429, 424, 420, 415,
|
1674
|
+
411, 407, 402, 398, 394, 390, 386, 382, 377, 373, 370, 366,
|
1675
|
+
362, 358, 354, 350, 347, 343, 339, 336, 332, 329, 325, 322,
|
1676
|
+
318, 315, 311, 308, 305, 302, 298, 295, 292, 289, 286, 282,
|
1677
|
+
279, 276, 273, 270, 267, 264, 261, 258, 256, 253, 250, 247,
|
1678
|
+
244, 241, 239, 236, 233, 230, 228, 225, 222, 220, 217, 215,
|
1679
|
+
212, 209, 207, 204, 202, 199, 197, 194, 192, 190, 187, 185,
|
1680
|
+
182, 180, 178, 175, 173, 171, 168, 166, 164, 162, 159, 157,
|
1681
|
+
155, 153, 151, 149, 146, 144, 142, 140, 138, 136, 134, 132,
|
1682
|
+
130, 128, 126, 123, 121, 119, 117, 115, 114, 112, 110, 108,
|
1683
|
+
106, 104, 102, 100, 98, 96, 94, 93, 91, 89, 87, 85,
|
1684
|
+
83, 82, 80, 78, 76, 74, 73, 71, 69, 67, 66, 64,
|
1685
|
+
62, 61, 59, 57, 55, 54, 52, 50, 49, 47, 46, 44,
|
1686
|
+
42, 41, 39, 37, 36, 34, 33, 31, 30, 28, 26, 25,
|
1687
|
+
23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7,
|
1688
|
+
5, 4, 2, 1,
|
1689
|
+
};
|
1690
|
+
|
1691
|
+
|
1692
|
+
/**
|
1693
|
+
* Returns the cost in bits of encoding the distribution described by count
|
1694
|
+
* using the entropy bound.
|
1695
|
+
*/
|
1696
|
+
static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total)
|
1697
|
+
{
|
1698
|
+
unsigned cost = 0;
|
1699
|
+
unsigned s;
|
1700
|
+
for (s = 0; s <= max; ++s) {
|
1701
|
+
unsigned norm = (unsigned)((256 * count[s]) / total);
|
1702
|
+
if (count[s] != 0 && norm == 0)
|
1703
|
+
norm = 1;
|
1704
|
+
assert(count[s] < total);
|
1705
|
+
cost += count[s] * kInverseProbabiltyLog256[norm];
|
1706
|
+
}
|
1707
|
+
return cost >> 8;
|
1708
|
+
}
|
1709
|
+
|
1710
|
+
|
1711
|
+
/**
|
1712
|
+
* Returns the cost in bits of encoding the distribution in count using the
|
1713
|
+
* table described by norm. The max symbol support by norm is assumed >= max.
|
1714
|
+
* norm must be valid for every symbol with non-zero probability in count.
|
1715
|
+
*/
|
1716
|
+
static size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
|
1717
|
+
unsigned const* count, unsigned const max)
|
1718
|
+
{
|
1719
|
+
unsigned const shift = 8 - accuracyLog;
|
1720
|
+
size_t cost = 0;
|
1721
|
+
unsigned s;
|
1722
|
+
assert(accuracyLog <= 8);
|
1723
|
+
for (s = 0; s <= max; ++s) {
|
1724
|
+
unsigned const normAcc = norm[s] != -1 ? norm[s] : 1;
|
1725
|
+
unsigned const norm256 = normAcc << shift;
|
1726
|
+
assert(norm256 > 0);
|
1727
|
+
assert(norm256 < 256);
|
1728
|
+
cost += count[s] * kInverseProbabiltyLog256[norm256];
|
1729
|
+
}
|
1730
|
+
return cost >> 8;
|
1731
|
+
}
|
1732
|
+
|
1733
|
+
|
1734
|
+
static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
|
1735
|
+
void const* ptr = ctable;
|
1736
|
+
U16 const* u16ptr = (U16 const*)ptr;
|
1737
|
+
U32 const maxSymbolValue = MEM_read16(u16ptr + 1);
|
1738
|
+
return maxSymbolValue;
|
1739
|
+
}
|
1740
|
+
|
1741
|
+
|
1742
|
+
/**
|
1743
|
+
* Returns the cost in bits of encoding the distribution in count using ctable.
|
1744
|
+
* Returns an error if ctable cannot represent all the symbols in count.
|
1745
|
+
*/
|
1746
|
+
static size_t ZSTD_fseBitCost(
|
1747
|
+
FSE_CTable const* ctable,
|
1748
|
+
unsigned const* count,
|
1749
|
+
unsigned const max)
|
1750
|
+
{
|
1751
|
+
unsigned const kAccuracyLog = 8;
|
1752
|
+
size_t cost = 0;
|
1753
|
+
unsigned s;
|
1754
|
+
FSE_CState_t cstate;
|
1755
|
+
FSE_initCState(&cstate, ctable);
|
1756
|
+
if (ZSTD_getFSEMaxSymbolValue(ctable) < max) {
|
1757
|
+
DEBUGLOG(5, "Repeat FSE_CTable has maxSymbolValue %u < %u",
|
1758
|
+
ZSTD_getFSEMaxSymbolValue(ctable), max);
|
1759
|
+
return ERROR(GENERIC);
|
1760
|
+
}
|
1761
|
+
for (s = 0; s <= max; ++s) {
|
1762
|
+
unsigned const tableLog = cstate.stateLog;
|
1763
|
+
unsigned const badCost = (tableLog + 1) << kAccuracyLog;
|
1764
|
+
unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);
|
1765
|
+
if (count[s] == 0)
|
1766
|
+
continue;
|
1767
|
+
if (bitCost >= badCost) {
|
1768
|
+
DEBUGLOG(5, "Repeat FSE_CTable has Prob[%u] == 0", s);
|
1769
|
+
return ERROR(GENERIC);
|
1770
|
+
}
|
1771
|
+
cost += count[s] * bitCost;
|
1772
|
+
}
|
1773
|
+
return cost >> kAccuracyLog;
|
1774
|
+
}
|
1775
|
+
|
1776
|
+
/**
|
1777
|
+
* Returns the cost in bytes of encoding the normalized count header.
|
1778
|
+
* Returns an error if any of the helper functions return an error.
|
1779
|
+
*/
|
1780
|
+
static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
|
1781
|
+
size_t const nbSeq, unsigned const FSELog)
|
1782
|
+
{
|
1783
|
+
BYTE wksp[FSE_NCOUNTBOUND];
|
1784
|
+
S16 norm[MaxSeq + 1];
|
1785
|
+
const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
|
1786
|
+
CHECK_F(FSE_normalizeCount(norm, tableLog, count, nbSeq, max));
|
1787
|
+
return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
|
1788
|
+
}
|
1789
|
+
|
1790
|
+
|
1467
1791
|
typedef enum {
|
1468
1792
|
ZSTD_defaultDisallowed = 0,
|
1469
1793
|
ZSTD_defaultAllowed = 1
|
1470
1794
|
} ZSTD_defaultPolicy_e;
|
1471
1795
|
|
1472
|
-
MEM_STATIC
|
1473
|
-
|
1474
|
-
FSE_repeat* repeatMode,
|
1475
|
-
|
1796
|
+
MEM_STATIC symbolEncodingType_e
|
1797
|
+
ZSTD_selectEncodingType(
|
1798
|
+
FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
|
1799
|
+
size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
|
1800
|
+
FSE_CTable const* prevCTable,
|
1801
|
+
short const* defaultNorm, U32 defaultNormLog,
|
1802
|
+
ZSTD_defaultPolicy_e const isDefaultAllowed,
|
1803
|
+
ZSTD_strategy const strategy)
|
1476
1804
|
{
|
1477
|
-
#define MIN_SEQ_FOR_DYNAMIC_FSE 64
|
1478
|
-
#define MAX_SEQ_FOR_STATIC_FSE 1000
|
1479
1805
|
ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);
|
1480
|
-
if (
|
1806
|
+
if (mostFrequent == nbSeq) {
|
1807
|
+
*repeatMode = FSE_repeat_none;
|
1808
|
+
if (isDefaultAllowed && nbSeq <= 2) {
|
1809
|
+
/* Prefer set_basic over set_rle when there are 2 or less symbols,
|
1810
|
+
* since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
|
1811
|
+
* If basic encoding isn't possible, always choose RLE.
|
1812
|
+
*/
|
1813
|
+
DEBUGLOG(5, "Selected set_basic");
|
1814
|
+
return set_basic;
|
1815
|
+
}
|
1481
1816
|
DEBUGLOG(5, "Selected set_rle");
|
1482
|
-
/* Prefer set_basic over set_rle when there are 2 or less symbols,
|
1483
|
-
* since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
|
1484
|
-
* If basic encoding isn't possible, always choose RLE.
|
1485
|
-
*/
|
1486
|
-
*repeatMode = FSE_repeat_check;
|
1487
1817
|
return set_rle;
|
1488
1818
|
}
|
1489
|
-
if (
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1819
|
+
if (strategy < ZSTD_lazy) {
|
1820
|
+
if (isDefaultAllowed) {
|
1821
|
+
size_t const staticFse_nbSeq_max = 1000;
|
1822
|
+
size_t const mult = 10 - strategy;
|
1823
|
+
size_t const baseLog = 3;
|
1824
|
+
size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog; /* 28-36 for offset, 56-72 for lengths */
|
1825
|
+
assert(defaultNormLog >= 5 && defaultNormLog <= 6); /* xx_DEFAULTNORMLOG */
|
1826
|
+
assert(mult <= 9 && mult >= 7);
|
1827
|
+
if ( (*repeatMode == FSE_repeat_valid)
|
1828
|
+
&& (nbSeq < staticFse_nbSeq_max) ) {
|
1829
|
+
DEBUGLOG(5, "Selected set_repeat");
|
1830
|
+
return set_repeat;
|
1831
|
+
}
|
1832
|
+
if ( (nbSeq < dynamicFse_nbSeq_min)
|
1833
|
+
|| (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) {
|
1834
|
+
DEBUGLOG(5, "Selected set_basic");
|
1835
|
+
/* The format allows default tables to be repeated, but it isn't useful.
|
1836
|
+
* When using simple heuristics to select encoding type, we don't want
|
1837
|
+
* to confuse these tables with dictionaries. When running more careful
|
1838
|
+
* analysis, we don't need to waste time checking both repeating tables
|
1839
|
+
* and default tables.
|
1840
|
+
*/
|
1841
|
+
*repeatMode = FSE_repeat_none;
|
1842
|
+
return set_basic;
|
1843
|
+
}
|
1844
|
+
}
|
1845
|
+
} else {
|
1846
|
+
size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC);
|
1847
|
+
size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC);
|
1848
|
+
size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog);
|
1849
|
+
size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq);
|
1850
|
+
|
1851
|
+
if (isDefaultAllowed) {
|
1852
|
+
assert(!ZSTD_isError(basicCost));
|
1853
|
+
assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
|
1854
|
+
}
|
1855
|
+
assert(!ZSTD_isError(NCountCost));
|
1856
|
+
assert(compressedCost < ERROR(maxCode));
|
1857
|
+
DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
|
1858
|
+
(U32)basicCost, (U32)repeatCost, (U32)compressedCost);
|
1859
|
+
if (basicCost <= repeatCost && basicCost <= compressedCost) {
|
1860
|
+
DEBUGLOG(5, "Selected set_basic");
|
1861
|
+
assert(isDefaultAllowed);
|
1862
|
+
*repeatMode = FSE_repeat_none;
|
1863
|
+
return set_basic;
|
1864
|
+
}
|
1865
|
+
if (repeatCost <= compressedCost) {
|
1866
|
+
DEBUGLOG(5, "Selected set_repeat");
|
1867
|
+
assert(!ZSTD_isError(repeatCost));
|
1868
|
+
return set_repeat;
|
1869
|
+
}
|
1870
|
+
assert(compressedCost < basicCost && compressedCost < repeatCost);
|
1505
1871
|
}
|
1506
1872
|
DEBUGLOG(5, "Selected set_compressed");
|
1507
1873
|
*repeatMode = FSE_repeat_check;
|
1508
1874
|
return set_compressed;
|
1509
1875
|
}
|
1510
1876
|
|
1511
|
-
MEM_STATIC
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1877
|
+
MEM_STATIC size_t
|
1878
|
+
ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
1879
|
+
FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
|
1880
|
+
U32* count, U32 max,
|
1881
|
+
const BYTE* codeTable, size_t nbSeq,
|
1882
|
+
const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
|
1883
|
+
const FSE_CTable* prevCTable, size_t prevCTableSize,
|
1884
|
+
void* workspace, size_t workspaceSize)
|
1519
1885
|
{
|
1520
1886
|
BYTE* op = (BYTE*)dst;
|
1521
|
-
BYTE
|
1887
|
+
const BYTE* const oend = op + dstCapacity;
|
1522
1888
|
|
1523
1889
|
switch (type) {
|
1524
1890
|
case set_rle:
|
@@ -1706,10 +2072,11 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1706
2072
|
const int bmi2)
|
1707
2073
|
{
|
1708
2074
|
const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;
|
2075
|
+
ZSTD_strategy const strategy = cctxParams->cParams.strategy;
|
1709
2076
|
U32 count[MaxSeq+1];
|
1710
|
-
FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
|
1711
|
-
FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
|
1712
|
-
FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
|
2077
|
+
FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;
|
2078
|
+
FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;
|
2079
|
+
FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;
|
1713
2080
|
U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
|
1714
2081
|
const seqDef* const sequences = seqStorePtr->sequencesStart;
|
1715
2082
|
const BYTE* const ofCodeTable = seqStorePtr->ofCode;
|
@@ -1720,15 +2087,17 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1720
2087
|
BYTE* op = ostart;
|
1721
2088
|
size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
|
1722
2089
|
BYTE* seqHead;
|
2090
|
+
BYTE* lastNCount = NULL;
|
1723
2091
|
|
1724
2092
|
ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
|
1725
2093
|
|
1726
2094
|
/* Compress literals */
|
1727
2095
|
{ const BYTE* const literals = seqStorePtr->litStart;
|
1728
2096
|
size_t const litSize = seqStorePtr->lit - literals;
|
2097
|
+
int const disableLiteralCompression = (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);
|
1729
2098
|
size_t const cSize = ZSTD_compressLiterals(
|
1730
|
-
prevEntropy, nextEntropy,
|
1731
|
-
cctxParams->cParams.strategy,
|
2099
|
+
&prevEntropy->huf, &nextEntropy->huf,
|
2100
|
+
cctxParams->cParams.strategy, disableLiteralCompression,
|
1732
2101
|
op, dstCapacity,
|
1733
2102
|
literals, litSize,
|
1734
2103
|
workspace, bmi2);
|
@@ -1747,13 +2116,9 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1747
2116
|
else
|
1748
2117
|
op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
|
1749
2118
|
if (nbSeq==0) {
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
|
1754
|
-
memcpy(nextEntropy->matchlengthCTable, prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable));
|
1755
|
-
nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
|
1756
|
-
return op - ostart;
|
2119
|
+
/* Copy the old tables over as if we repeated them */
|
2120
|
+
memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));
|
2121
|
+
return op - ostart;
|
1757
2122
|
}
|
1758
2123
|
|
1759
2124
|
/* seqHead : flags for FSE encoding type */
|
@@ -1763,43 +2128,53 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1763
2128
|
ZSTD_seqToCodes(seqStorePtr);
|
1764
2129
|
/* build CTable for Literal Lengths */
|
1765
2130
|
{ U32 max = MaxLL;
|
1766
|
-
size_t const mostFrequent =
|
2131
|
+
size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, workspace); /* can't fail */
|
1767
2132
|
DEBUGLOG(5, "Building LL table");
|
1768
|
-
nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
|
1769
|
-
LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode, mostFrequent, nbSeq, LL_defaultNormLog, ZSTD_defaultAllowed);
|
2133
|
+
nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode;
|
2134
|
+
LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode, count, max, mostFrequent, nbSeq, LLFSELog, prevEntropy->fse.litlengthCTable, LL_defaultNorm, LL_defaultNormLog, ZSTD_defaultAllowed, strategy);
|
2135
|
+
assert(set_basic < set_compressed && set_rle < set_compressed);
|
2136
|
+
assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
1770
2137
|
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
|
1771
|
-
|
1772
|
-
|
1773
|
-
|
2138
|
+
count, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
|
2139
|
+
prevEntropy->fse.litlengthCTable, sizeof(prevEntropy->fse.litlengthCTable),
|
2140
|
+
workspace, HUF_WORKSPACE_SIZE);
|
1774
2141
|
if (ZSTD_isError(countSize)) return countSize;
|
2142
|
+
if (LLtype == set_compressed)
|
2143
|
+
lastNCount = op;
|
1775
2144
|
op += countSize;
|
1776
2145
|
} }
|
1777
2146
|
/* build CTable for Offsets */
|
1778
2147
|
{ U32 max = MaxOff;
|
1779
|
-
size_t const mostFrequent =
|
2148
|
+
size_t const mostFrequent = HIST_countFast_wksp(count, &max, ofCodeTable, nbSeq, workspace); /* can't fail */
|
1780
2149
|
/* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
|
1781
2150
|
ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
|
1782
2151
|
DEBUGLOG(5, "Building OF table");
|
1783
|
-
nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
|
1784
|
-
Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode, mostFrequent, nbSeq, OF_defaultNormLog, defaultPolicy);
|
2152
|
+
nextEntropy->fse.offcode_repeatMode = prevEntropy->fse.offcode_repeatMode;
|
2153
|
+
Offtype = ZSTD_selectEncodingType(&nextEntropy->fse.offcode_repeatMode, count, max, mostFrequent, nbSeq, OffFSELog, prevEntropy->fse.offcodeCTable, OF_defaultNorm, OF_defaultNormLog, defaultPolicy, strategy);
|
2154
|
+
assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
1785
2155
|
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
2156
|
+
count, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
|
2157
|
+
prevEntropy->fse.offcodeCTable, sizeof(prevEntropy->fse.offcodeCTable),
|
2158
|
+
workspace, HUF_WORKSPACE_SIZE);
|
1789
2159
|
if (ZSTD_isError(countSize)) return countSize;
|
2160
|
+
if (Offtype == set_compressed)
|
2161
|
+
lastNCount = op;
|
1790
2162
|
op += countSize;
|
1791
2163
|
} }
|
1792
2164
|
/* build CTable for MatchLengths */
|
1793
2165
|
{ U32 max = MaxML;
|
1794
|
-
size_t const mostFrequent =
|
2166
|
+
size_t const mostFrequent = HIST_countFast_wksp(count, &max, mlCodeTable, nbSeq, workspace); /* can't fail */
|
1795
2167
|
DEBUGLOG(5, "Building ML table");
|
1796
|
-
nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
|
1797
|
-
MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode, mostFrequent, nbSeq, ML_defaultNormLog, ZSTD_defaultAllowed);
|
2168
|
+
nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode;
|
2169
|
+
MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode, count, max, mostFrequent, nbSeq, MLFSELog, prevEntropy->fse.matchlengthCTable, ML_defaultNorm, ML_defaultNormLog, ZSTD_defaultAllowed, strategy);
|
2170
|
+
assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
1798
2171
|
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
2172
|
+
count, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
|
2173
|
+
prevEntropy->fse.matchlengthCTable, sizeof(prevEntropy->fse.matchlengthCTable),
|
2174
|
+
workspace, HUF_WORKSPACE_SIZE);
|
1802
2175
|
if (ZSTD_isError(countSize)) return countSize;
|
2176
|
+
if (MLtype == set_compressed)
|
2177
|
+
lastNCount = op;
|
1803
2178
|
op += countSize;
|
1804
2179
|
} }
|
1805
2180
|
|
@@ -1814,21 +2189,37 @@ MEM_STATIC size_t ZSTD_compressSequences_internal(seqStore_t* seqStorePtr,
|
|
1814
2189
|
longOffsets, bmi2);
|
1815
2190
|
if (ZSTD_isError(bitstreamSize)) return bitstreamSize;
|
1816
2191
|
op += bitstreamSize;
|
2192
|
+
/* zstd versions <= 1.3.4 mistakenly report corruption when
|
2193
|
+
* FSE_readNCount() recieves a buffer < 4 bytes.
|
2194
|
+
* Fixed by https://github.com/facebook/zstd/pull/1146.
|
2195
|
+
* This can happen when the last set_compressed table present is 2
|
2196
|
+
* bytes and the bitstream is only one byte.
|
2197
|
+
* In this exceedingly rare case, we will simply emit an uncompressed
|
2198
|
+
* block, since it isn't worth optimizing.
|
2199
|
+
*/
|
2200
|
+
if (lastNCount && (op - lastNCount) < 4) {
|
2201
|
+
/* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */
|
2202
|
+
assert(op - lastNCount == 3);
|
2203
|
+
DEBUGLOG(5, "Avoiding bug in zstd decoder in versions <= 1.3.4 by "
|
2204
|
+
"emitting an uncompressed block.");
|
2205
|
+
return 0;
|
2206
|
+
}
|
1817
2207
|
}
|
1818
2208
|
|
1819
2209
|
return op - ostart;
|
1820
2210
|
}
|
1821
2211
|
|
1822
2212
|
MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
|
1823
|
-
|
2213
|
+
const ZSTD_entropyCTables_t* prevEntropy,
|
1824
2214
|
ZSTD_entropyCTables_t* nextEntropy,
|
1825
|
-
|
2215
|
+
const ZSTD_CCtx_params* cctxParams,
|
1826
2216
|
void* dst, size_t dstCapacity,
|
1827
2217
|
size_t srcSize, U32* workspace, int bmi2)
|
1828
2218
|
{
|
1829
2219
|
size_t const cSize = ZSTD_compressSequences_internal(
|
1830
2220
|
seqStorePtr, prevEntropy, nextEntropy, cctxParams, dst, dstCapacity,
|
1831
2221
|
workspace, bmi2);
|
2222
|
+
if (cSize == 0) return 0;
|
1832
2223
|
/* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.
|
1833
2224
|
* Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.
|
1834
2225
|
*/
|
@@ -1837,7 +2228,7 @@ MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
|
|
1837
2228
|
if (ZSTD_isError(cSize)) return cSize;
|
1838
2229
|
|
1839
2230
|
/* Check compressibility */
|
1840
|
-
{ size_t const maxCSize = srcSize - ZSTD_minGain(srcSize
|
2231
|
+
{ size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);
|
1841
2232
|
if (cSize >= maxCSize) return 0; /* block not compressed */
|
1842
2233
|
}
|
1843
2234
|
|
@@ -1845,8 +2236,8 @@ MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
|
|
1845
2236
|
* block. After the first block, the offcode table might not have large
|
1846
2237
|
* enough codes to represent the offsets in the data.
|
1847
2238
|
*/
|
1848
|
-
if (nextEntropy->offcode_repeatMode == FSE_repeat_valid)
|
1849
|
-
nextEntropy->offcode_repeatMode = FSE_repeat_check;
|
2239
|
+
if (nextEntropy->fse.offcode_repeatMode == FSE_repeat_valid)
|
2240
|
+
nextEntropy->fse.offcode_repeatMode = FSE_repeat_check;
|
1850
2241
|
|
1851
2242
|
return cSize;
|
1852
2243
|
}
|
@@ -1854,23 +2245,45 @@ MEM_STATIC size_t ZSTD_compressSequences(seqStore_t* seqStorePtr,
|
|
1854
2245
|
/* ZSTD_selectBlockCompressor() :
|
1855
2246
|
* Not static, but internal use only (used by long distance matcher)
|
1856
2247
|
* assumption : strat is a valid strategy */
|
1857
|
-
ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat,
|
2248
|
+
ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode)
|
1858
2249
|
{
|
1859
|
-
static const ZSTD_blockCompressor blockCompressor[
|
2250
|
+
static const ZSTD_blockCompressor blockCompressor[3][(unsigned)ZSTD_btultra+1] = {
|
1860
2251
|
{ ZSTD_compressBlock_fast /* default for 0 */,
|
1861
|
-
ZSTD_compressBlock_fast,
|
1862
|
-
|
1863
|
-
|
2252
|
+
ZSTD_compressBlock_fast,
|
2253
|
+
ZSTD_compressBlock_doubleFast,
|
2254
|
+
ZSTD_compressBlock_greedy,
|
2255
|
+
ZSTD_compressBlock_lazy,
|
2256
|
+
ZSTD_compressBlock_lazy2,
|
2257
|
+
ZSTD_compressBlock_btlazy2,
|
2258
|
+
ZSTD_compressBlock_btopt,
|
2259
|
+
ZSTD_compressBlock_btultra },
|
1864
2260
|
{ ZSTD_compressBlock_fast_extDict /* default for 0 */,
|
1865
|
-
ZSTD_compressBlock_fast_extDict,
|
1866
|
-
|
1867
|
-
|
2261
|
+
ZSTD_compressBlock_fast_extDict,
|
2262
|
+
ZSTD_compressBlock_doubleFast_extDict,
|
2263
|
+
ZSTD_compressBlock_greedy_extDict,
|
2264
|
+
ZSTD_compressBlock_lazy_extDict,
|
2265
|
+
ZSTD_compressBlock_lazy2_extDict,
|
2266
|
+
ZSTD_compressBlock_btlazy2_extDict,
|
2267
|
+
ZSTD_compressBlock_btopt_extDict,
|
2268
|
+
ZSTD_compressBlock_btultra_extDict },
|
2269
|
+
{ ZSTD_compressBlock_fast_dictMatchState /* default for 0 */,
|
2270
|
+
ZSTD_compressBlock_fast_dictMatchState,
|
2271
|
+
ZSTD_compressBlock_doubleFast_dictMatchState,
|
2272
|
+
ZSTD_compressBlock_greedy_dictMatchState,
|
2273
|
+
ZSTD_compressBlock_lazy_dictMatchState,
|
2274
|
+
ZSTD_compressBlock_lazy2_dictMatchState,
|
2275
|
+
ZSTD_compressBlock_btlazy2_dictMatchState,
|
2276
|
+
ZSTD_compressBlock_btopt_dictMatchState,
|
2277
|
+
ZSTD_compressBlock_btultra_dictMatchState }
|
1868
2278
|
};
|
2279
|
+
ZSTD_blockCompressor selectedCompressor;
|
1869
2280
|
ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);
|
1870
2281
|
|
1871
2282
|
assert((U32)strat >= (U32)ZSTD_fast);
|
1872
2283
|
assert((U32)strat <= (U32)ZSTD_btultra);
|
1873
|
-
|
2284
|
+
selectedCompressor = blockCompressor[(int)dictMode][(U32)strat];
|
2285
|
+
assert(selectedCompressor != NULL);
|
2286
|
+
return selectedCompressor;
|
1874
2287
|
}
|
1875
2288
|
|
1876
2289
|
static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
|
@@ -1880,7 +2293,7 @@ static void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,
|
|
1880
2293
|
seqStorePtr->lit += lastLLSize;
|
1881
2294
|
}
|
1882
2295
|
|
1883
|
-
|
2296
|
+
void ZSTD_resetSeqStore(seqStore_t* ssPtr)
|
1884
2297
|
{
|
1885
2298
|
ssPtr->lit = ssPtr->litStart;
|
1886
2299
|
ssPtr->sequences = ssPtr->sequencesStart;
|
@@ -1892,24 +2305,32 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
|
1892
2305
|
const void* src, size_t srcSize)
|
1893
2306
|
{
|
1894
2307
|
ZSTD_matchState_t* const ms = &zc->blockState.matchState;
|
1895
|
-
DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%
|
1896
|
-
|
2308
|
+
DEBUGLOG(5, "ZSTD_compressBlock_internal (dstCapacity=%zu, dictLimit=%u, nextToUpdate=%u)",
|
2309
|
+
dstCapacity, ms->window.dictLimit, ms->nextToUpdate);
|
2310
|
+
|
1897
2311
|
if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {
|
1898
2312
|
ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.searchLength);
|
1899
2313
|
return 0; /* don't even attempt compression below a certain srcSize */
|
1900
2314
|
}
|
1901
2315
|
ZSTD_resetSeqStore(&(zc->seqStore));
|
2316
|
+
ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy; /* required for optimal parser to read stats from dictionary */
|
2317
|
+
|
2318
|
+
/* a gap between an attached dict and the current window is not safe,
|
2319
|
+
* they must remain adjacent, and when that stops being the case, the dict
|
2320
|
+
* must be unset */
|
2321
|
+
assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit);
|
1902
2322
|
|
1903
2323
|
/* limited update after a very long match */
|
1904
2324
|
{ const BYTE* const base = ms->window.base;
|
1905
2325
|
const BYTE* const istart = (const BYTE*)src;
|
1906
2326
|
const U32 current = (U32)(istart-base);
|
2327
|
+
if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1)); /* ensure no overflow */
|
1907
2328
|
if (current > ms->nextToUpdate + 384)
|
1908
2329
|
ms->nextToUpdate = current - MIN(192, (U32)(current - ms->nextToUpdate - 384));
|
1909
2330
|
}
|
1910
2331
|
|
1911
2332
|
/* select and store sequences */
|
1912
|
-
{
|
2333
|
+
{ ZSTD_dictMode_e const dictMode = ZSTD_matchState_dictMode(ms);
|
1913
2334
|
size_t lastLLSize;
|
1914
2335
|
{ int i;
|
1915
2336
|
for (i = 0; i < ZSTD_REP_NUM; ++i)
|
@@ -1923,7 +2344,7 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
|
1923
2344
|
ms, &zc->seqStore,
|
1924
2345
|
zc->blockState.nextCBlock->rep,
|
1925
2346
|
&zc->appliedParams.cParams,
|
1926
|
-
src, srcSize
|
2347
|
+
src, srcSize);
|
1927
2348
|
assert(zc->externSeqStore.pos <= zc->externSeqStore.size);
|
1928
2349
|
} else if (zc->appliedParams.ldmParams.enableLdm) {
|
1929
2350
|
rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0};
|
@@ -1940,10 +2361,10 @@ static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,
|
|
1940
2361
|
ms, &zc->seqStore,
|
1941
2362
|
zc->blockState.nextCBlock->rep,
|
1942
2363
|
&zc->appliedParams.cParams,
|
1943
|
-
src, srcSize
|
2364
|
+
src, srcSize);
|
1944
2365
|
assert(ldmSeqStore.pos == ldmSeqStore.size);
|
1945
2366
|
} else { /* not long range mode */
|
1946
|
-
ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy,
|
2367
|
+
ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, dictMode);
|
1947
2368
|
lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, &zc->appliedParams.cParams, src, srcSize);
|
1948
2369
|
}
|
1949
2370
|
{ const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;
|
@@ -2010,8 +2431,9 @@ static size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,
|
|
2010
2431
|
if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;
|
2011
2432
|
else ms->nextToUpdate -= correction;
|
2012
2433
|
ms->loadedDictEnd = 0;
|
2434
|
+
ms->dictMatchState = NULL;
|
2013
2435
|
}
|
2014
|
-
ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd);
|
2436
|
+
ZSTD_window_enforceMaxDist(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);
|
2015
2437
|
if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;
|
2016
2438
|
|
2017
2439
|
{ size_t cSize = ZSTD_compressBlock_internal(cctx,
|
@@ -2060,6 +2482,7 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
|
2060
2482
|
BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
|
2061
2483
|
size_t pos=0;
|
2062
2484
|
|
2485
|
+
assert(!(params.fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));
|
2063
2486
|
if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
|
2064
2487
|
DEBUGLOG(4, "ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u",
|
2065
2488
|
!params.fParams.noDictIDFlag, dictID, dictIDSizeCode);
|
@@ -2153,7 +2576,9 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
2153
2576
|
if (ZSTD_isError(cSize)) return cSize;
|
2154
2577
|
cctx->consumedSrcSize += srcSize;
|
2155
2578
|
cctx->producedCSize += (cSize + fhSize);
|
2156
|
-
|
2579
|
+
assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
|
2580
|
+
if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */
|
2581
|
+
ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
|
2157
2582
|
if (cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne) {
|
2158
2583
|
DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize >= %u",
|
2159
2584
|
(U32)cctx->pledgedSrcSizePlusOne-1, (U32)cctx->consumedSrcSize);
|
@@ -2190,7 +2615,10 @@ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const
|
|
2190
2615
|
/*! ZSTD_loadDictionaryContent() :
|
2191
2616
|
* @return : 0, or an error code
|
2192
2617
|
*/
|
2193
|
-
static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
|
2618
|
+
static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,
|
2619
|
+
ZSTD_CCtx_params const* params,
|
2620
|
+
const void* src, size_t srcSize,
|
2621
|
+
ZSTD_dictTableLoadMethod_e dtlm)
|
2194
2622
|
{
|
2195
2623
|
const BYTE* const ip = (const BYTE*) src;
|
2196
2624
|
const BYTE* const iend = ip + srcSize;
|
@@ -2204,10 +2632,10 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms, ZSTD_CCtx_params
|
|
2204
2632
|
switch(params->cParams.strategy)
|
2205
2633
|
{
|
2206
2634
|
case ZSTD_fast:
|
2207
|
-
ZSTD_fillHashTable(ms, cParams, iend);
|
2635
|
+
ZSTD_fillHashTable(ms, cParams, iend, dtlm);
|
2208
2636
|
break;
|
2209
2637
|
case ZSTD_dfast:
|
2210
|
-
ZSTD_fillDoubleHashTable(ms, cParams, iend);
|
2638
|
+
ZSTD_fillDoubleHashTable(ms, cParams, iend, dtlm);
|
2211
2639
|
break;
|
2212
2640
|
|
2213
2641
|
case ZSTD_greedy:
|
@@ -2256,7 +2684,12 @@ static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSym
|
|
2256
2684
|
* assumptions : magic number supposed already checked
|
2257
2685
|
* dictSize supposed > 8
|
2258
2686
|
*/
|
2259
|
-
static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
2687
|
+
static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,
|
2688
|
+
ZSTD_matchState_t* ms,
|
2689
|
+
ZSTD_CCtx_params const* params,
|
2690
|
+
const void* dict, size_t dictSize,
|
2691
|
+
ZSTD_dictTableLoadMethod_e dtlm,
|
2692
|
+
void* workspace)
|
2260
2693
|
{
|
2261
2694
|
const BYTE* dictPtr = (const BYTE*)dict;
|
2262
2695
|
const BYTE* const dictEnd = dictPtr + dictSize;
|
@@ -2265,13 +2698,15 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matc
|
|
2265
2698
|
size_t dictID;
|
2266
2699
|
|
2267
2700
|
ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));
|
2701
|
+
assert(dictSize > 8);
|
2702
|
+
assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);
|
2268
2703
|
|
2269
2704
|
dictPtr += 4; /* skip magic number */
|
2270
2705
|
dictID = params->fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr);
|
2271
2706
|
dictPtr += 4;
|
2272
2707
|
|
2273
2708
|
{ unsigned maxSymbolValue = 255;
|
2274
|
-
size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.
|
2709
|
+
size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr);
|
2275
2710
|
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
2276
2711
|
if (maxSymbolValue < 255) return ERROR(dictionary_corrupted);
|
2277
2712
|
dictPtr += hufHeaderSize;
|
@@ -2282,7 +2717,8 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matc
|
|
2282
2717
|
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
2283
2718
|
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
2284
2719
|
/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
|
2285
|
-
|
2720
|
+
/* fill all offset symbols to avoid garbage at end of table */
|
2721
|
+
CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.offcodeCTable, offcodeNCount, MaxOff, offcodeLog, workspace, HUF_WORKSPACE_SIZE),
|
2286
2722
|
dictionary_corrupted);
|
2287
2723
|
dictPtr += offcodeHeaderSize;
|
2288
2724
|
}
|
@@ -2294,7 +2730,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matc
|
|
2294
2730
|
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
2295
2731
|
/* Every match length code must have non-zero probability */
|
2296
2732
|
CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
|
2297
|
-
CHECK_E( FSE_buildCTable_wksp(bs->entropy.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE),
|
2733
|
+
CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, workspace, HUF_WORKSPACE_SIZE),
|
2298
2734
|
dictionary_corrupted);
|
2299
2735
|
dictPtr += matchlengthHeaderSize;
|
2300
2736
|
}
|
@@ -2306,7 +2742,7 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matc
|
|
2306
2742
|
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
2307
2743
|
/* Every literal length code must have non-zero probability */
|
2308
2744
|
CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
|
2309
|
-
CHECK_E( FSE_buildCTable_wksp(bs->entropy.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE),
|
2745
|
+
CHECK_E( FSE_buildCTable_wksp(bs->entropy.fse.litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, workspace, HUF_WORKSPACE_SIZE),
|
2310
2746
|
dictionary_corrupted);
|
2311
2747
|
dictPtr += litlengthHeaderSize;
|
2312
2748
|
}
|
@@ -2332,22 +2768,25 @@ static size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs, ZSTD_matc
|
|
2332
2768
|
if (bs->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
|
2333
2769
|
} }
|
2334
2770
|
|
2335
|
-
bs->entropy.
|
2336
|
-
bs->entropy.offcode_repeatMode = FSE_repeat_valid;
|
2337
|
-
bs->entropy.matchlength_repeatMode = FSE_repeat_valid;
|
2338
|
-
bs->entropy.litlength_repeatMode = FSE_repeat_valid;
|
2339
|
-
CHECK_F(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize));
|
2771
|
+
bs->entropy.huf.repeatMode = HUF_repeat_valid;
|
2772
|
+
bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;
|
2773
|
+
bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;
|
2774
|
+
bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;
|
2775
|
+
CHECK_F(ZSTD_loadDictionaryContent(ms, params, dictPtr, dictContentSize, dtlm));
|
2340
2776
|
return dictID;
|
2341
2777
|
}
|
2342
2778
|
}
|
2343
2779
|
|
2344
2780
|
/** ZSTD_compress_insertDictionary() :
|
2345
2781
|
* @return : dictID, or an error code */
|
2346
|
-
static size_t
|
2347
|
-
|
2348
|
-
|
2349
|
-
|
2350
|
-
|
2782
|
+
static size_t
|
2783
|
+
ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,
|
2784
|
+
ZSTD_matchState_t* ms,
|
2785
|
+
const ZSTD_CCtx_params* params,
|
2786
|
+
const void* dict, size_t dictSize,
|
2787
|
+
ZSTD_dictContentType_e dictContentType,
|
2788
|
+
ZSTD_dictTableLoadMethod_e dtlm,
|
2789
|
+
void* workspace)
|
2351
2790
|
{
|
2352
2791
|
DEBUGLOG(4, "ZSTD_compress_insertDictionary (dictSize=%u)", (U32)dictSize);
|
2353
2792
|
if ((dict==NULL) || (dictSize<=8)) return 0;
|
@@ -2356,12 +2795,12 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, ZS
|
|
2356
2795
|
|
2357
2796
|
/* dict restricted modes */
|
2358
2797
|
if (dictContentType == ZSTD_dct_rawContent)
|
2359
|
-
return ZSTD_loadDictionaryContent(ms, params, dict, dictSize);
|
2798
|
+
return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
|
2360
2799
|
|
2361
2800
|
if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {
|
2362
2801
|
if (dictContentType == ZSTD_dct_auto) {
|
2363
2802
|
DEBUGLOG(4, "raw content dictionary detected");
|
2364
|
-
return ZSTD_loadDictionaryContent(ms, params, dict, dictSize);
|
2803
|
+
return ZSTD_loadDictionaryContent(ms, params, dict, dictSize, dtlm);
|
2365
2804
|
}
|
2366
2805
|
if (dictContentType == ZSTD_dct_fullDict)
|
2367
2806
|
return ERROR(dictionary_wrong);
|
@@ -2369,7 +2808,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, ZS
|
|
2369
2808
|
}
|
2370
2809
|
|
2371
2810
|
/* dict as full zstd dictionary */
|
2372
|
-
return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, workspace);
|
2811
|
+
return ZSTD_loadZstdDictionary(bs, ms, params, dict, dictSize, dtlm, workspace);
|
2373
2812
|
}
|
2374
2813
|
|
2375
2814
|
/*! ZSTD_compressBegin_internal() :
|
@@ -2377,6 +2816,7 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs, ZS
|
|
2377
2816
|
size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
2378
2817
|
const void* dict, size_t dictSize,
|
2379
2818
|
ZSTD_dictContentType_e dictContentType,
|
2819
|
+
ZSTD_dictTableLoadMethod_e dtlm,
|
2380
2820
|
const ZSTD_CDict* cdict,
|
2381
2821
|
ZSTD_CCtx_params params, U64 pledgedSrcSize,
|
2382
2822
|
ZSTD_buffered_policy_e zbuff)
|
@@ -2387,9 +2827,7 @@ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
|
2387
2827
|
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
|
2388
2828
|
|
2389
2829
|
if (cdict && cdict->dictContentSize>0) {
|
2390
|
-
cctx
|
2391
|
-
return ZSTD_resetCCtx_usingCDict(cctx, cdict, params.cParams.windowLog,
|
2392
|
-
params.fParams, pledgedSrcSize, zbuff);
|
2830
|
+
return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff);
|
2393
2831
|
}
|
2394
2832
|
|
2395
2833
|
CHECK_F( ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,
|
@@ -2397,7 +2835,7 @@ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
|
2397
2835
|
{
|
2398
2836
|
size_t const dictID = ZSTD_compress_insertDictionary(
|
2399
2837
|
cctx->blockState.prevCBlock, &cctx->blockState.matchState,
|
2400
|
-
¶ms, dict, dictSize, dictContentType, cctx->entropyWorkspace);
|
2838
|
+
¶ms, dict, dictSize, dictContentType, dtlm, cctx->entropyWorkspace);
|
2401
2839
|
if (ZSTD_isError(dictID)) return dictID;
|
2402
2840
|
assert(dictID <= (size_t)(U32)-1);
|
2403
2841
|
cctx->dictID = (U32)dictID;
|
@@ -2408,6 +2846,7 @@ size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
|
2408
2846
|
size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
|
2409
2847
|
const void* dict, size_t dictSize,
|
2410
2848
|
ZSTD_dictContentType_e dictContentType,
|
2849
|
+
ZSTD_dictTableLoadMethod_e dtlm,
|
2411
2850
|
const ZSTD_CDict* cdict,
|
2412
2851
|
ZSTD_CCtx_params params,
|
2413
2852
|
unsigned long long pledgedSrcSize)
|
@@ -2416,7 +2855,7 @@ size_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,
|
|
2416
2855
|
/* compression parameters verification and optimization */
|
2417
2856
|
CHECK_F( ZSTD_checkCParams(params.cParams) );
|
2418
2857
|
return ZSTD_compressBegin_internal(cctx,
|
2419
|
-
dict, dictSize, dictContentType,
|
2858
|
+
dict, dictSize, dictContentType, dtlm,
|
2420
2859
|
cdict,
|
2421
2860
|
params, pledgedSrcSize,
|
2422
2861
|
ZSTDb_not_buffered);
|
@@ -2431,7 +2870,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
|
|
2431
2870
|
ZSTD_CCtx_params const cctxParams =
|
2432
2871
|
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
2433
2872
|
return ZSTD_compressBegin_advanced_internal(cctx,
|
2434
|
-
dict, dictSize, ZSTD_dct_auto,
|
2873
|
+
dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast,
|
2435
2874
|
NULL /*cdict*/,
|
2436
2875
|
cctxParams, pledgedSrcSize);
|
2437
2876
|
}
|
@@ -2442,7 +2881,7 @@ size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t di
|
|
2442
2881
|
ZSTD_CCtx_params const cctxParams =
|
2443
2882
|
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
2444
2883
|
DEBUGLOG(4, "ZSTD_compressBegin_usingDict (dictSize=%u)", (U32)dictSize);
|
2445
|
-
return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, NULL,
|
2884
|
+
return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
|
2446
2885
|
cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);
|
2447
2886
|
}
|
2448
2887
|
|
@@ -2505,7 +2944,9 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
|
|
2505
2944
|
if (ZSTD_isError(cSize)) return cSize;
|
2506
2945
|
endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
|
2507
2946
|
if (ZSTD_isError(endResult)) return endResult;
|
2508
|
-
|
2947
|
+
assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));
|
2948
|
+
if (cctx->pledgedSrcSizePlusOne != 0) { /* control src size */
|
2949
|
+
ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);
|
2509
2950
|
DEBUGLOG(4, "end of frame : controlling src size");
|
2510
2951
|
if (cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1) {
|
2511
2952
|
DEBUGLOG(4, "error : pledgedSrcSize = %u, while realSrcSize = %u",
|
@@ -2517,22 +2958,22 @@ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
|
|
2517
2958
|
|
2518
2959
|
|
2519
2960
|
static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
|
2520
|
-
|
2521
|
-
|
2522
|
-
|
2523
|
-
|
2961
|
+
void* dst, size_t dstCapacity,
|
2962
|
+
const void* src, size_t srcSize,
|
2963
|
+
const void* dict,size_t dictSize,
|
2964
|
+
ZSTD_parameters params)
|
2524
2965
|
{
|
2525
2966
|
ZSTD_CCtx_params const cctxParams =
|
2526
2967
|
ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
2527
2968
|
DEBUGLOG(4, "ZSTD_compress_internal");
|
2528
2969
|
return ZSTD_compress_advanced_internal(cctx,
|
2529
|
-
|
2530
|
-
|
2531
|
-
|
2532
|
-
|
2970
|
+
dst, dstCapacity,
|
2971
|
+
src, srcSize,
|
2972
|
+
dict, dictSize,
|
2973
|
+
cctxParams);
|
2533
2974
|
}
|
2534
2975
|
|
2535
|
-
size_t ZSTD_compress_advanced (ZSTD_CCtx*
|
2976
|
+
size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
|
2536
2977
|
void* dst, size_t dstCapacity,
|
2537
2978
|
const void* src, size_t srcSize,
|
2538
2979
|
const void* dict,size_t dictSize,
|
@@ -2540,7 +2981,11 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
|
2540
2981
|
{
|
2541
2982
|
DEBUGLOG(4, "ZSTD_compress_advanced");
|
2542
2983
|
CHECK_F(ZSTD_checkCParams(params.cParams));
|
2543
|
-
return ZSTD_compress_internal(
|
2984
|
+
return ZSTD_compress_internal(cctx,
|
2985
|
+
dst, dstCapacity,
|
2986
|
+
src, srcSize,
|
2987
|
+
dict, dictSize,
|
2988
|
+
params);
|
2544
2989
|
}
|
2545
2990
|
|
2546
2991
|
/* Internal */
|
@@ -2551,37 +2996,44 @@ size_t ZSTD_compress_advanced_internal(
|
|
2551
2996
|
const void* dict,size_t dictSize,
|
2552
2997
|
ZSTD_CCtx_params params)
|
2553
2998
|
{
|
2554
|
-
DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)",
|
2555
|
-
|
2556
|
-
|
2557
|
-
|
2999
|
+
DEBUGLOG(4, "ZSTD_compress_advanced_internal (srcSize:%u)", (U32)srcSize);
|
3000
|
+
CHECK_F( ZSTD_compressBegin_internal(cctx,
|
3001
|
+
dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,
|
3002
|
+
params, srcSize, ZSTDb_not_buffered) );
|
2558
3003
|
return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
|
2559
3004
|
}
|
2560
3005
|
|
2561
|
-
size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
|
2562
|
-
|
3006
|
+
size_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,
|
3007
|
+
void* dst, size_t dstCapacity,
|
3008
|
+
const void* src, size_t srcSize,
|
3009
|
+
const void* dict, size_t dictSize,
|
3010
|
+
int compressionLevel)
|
2563
3011
|
{
|
2564
|
-
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize
|
3012
|
+
ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize + (!srcSize), dict ? dictSize : 0);
|
2565
3013
|
ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(cctx->requestedParams, params);
|
2566
3014
|
assert(params.fParams.contentSizeFlag == 1);
|
2567
|
-
ZSTD_CCtxParam_setParameter(&cctxParams, ZSTD_p_compressLiterals, compressionLevel>=0);
|
2568
3015
|
return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, cctxParams);
|
2569
3016
|
}
|
2570
3017
|
|
2571
|
-
size_t ZSTD_compressCCtx
|
3018
|
+
size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
|
3019
|
+
void* dst, size_t dstCapacity,
|
3020
|
+
const void* src, size_t srcSize,
|
3021
|
+
int compressionLevel)
|
2572
3022
|
{
|
2573
3023
|
DEBUGLOG(4, "ZSTD_compressCCtx (srcSize=%u)", (U32)srcSize);
|
3024
|
+
assert(cctx != NULL);
|
2574
3025
|
return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
|
2575
3026
|
}
|
2576
3027
|
|
2577
|
-
size_t ZSTD_compress(void* dst, size_t dstCapacity,
|
3028
|
+
size_t ZSTD_compress(void* dst, size_t dstCapacity,
|
3029
|
+
const void* src, size_t srcSize,
|
3030
|
+
int compressionLevel)
|
2578
3031
|
{
|
2579
3032
|
size_t result;
|
2580
3033
|
ZSTD_CCtx ctxBody;
|
2581
|
-
|
2582
|
-
ctxBody.customMem = ZSTD_defaultCMem;
|
3034
|
+
ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem);
|
2583
3035
|
result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
|
2584
|
-
|
3036
|
+
ZSTD_freeCCtxContent(&ctxBody); /* can't free ctxBody itself, as it's on stack; free only heap content */
|
2585
3037
|
return result;
|
2586
3038
|
}
|
2587
3039
|
|
@@ -2619,7 +3071,7 @@ static size_t ZSTD_initCDict_internal(
|
|
2619
3071
|
ZSTD_dictContentType_e dictContentType,
|
2620
3072
|
ZSTD_compressionParameters cParams)
|
2621
3073
|
{
|
2622
|
-
DEBUGLOG(3, "ZSTD_initCDict_internal
|
3074
|
+
DEBUGLOG(3, "ZSTD_initCDict_internal (dictContentType:%u)", (U32)dictContentType);
|
2623
3075
|
assert(!ZSTD_checkCParams(cParams));
|
2624
3076
|
cdict->cParams = cParams;
|
2625
3077
|
if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {
|
@@ -2654,7 +3106,7 @@ static size_t ZSTD_initCDict_internal(
|
|
2654
3106
|
{ size_t const dictID = ZSTD_compress_insertDictionary(
|
2655
3107
|
&cdict->cBlockState, &cdict->matchState, ¶ms,
|
2656
3108
|
cdict->dictContent, cdict->dictContentSize,
|
2657
|
-
dictContentType, cdict->workspace);
|
3109
|
+
dictContentType, ZSTD_dtlm_full, cdict->workspace);
|
2658
3110
|
if (ZSTD_isError(dictID)) return dictID;
|
2659
3111
|
assert(dictID <= (size_t)(U32)-1);
|
2660
3112
|
cdict->dictID = (U32)dictID;
|
@@ -2799,7 +3251,7 @@ size_t ZSTD_compressBegin_usingCDict_advanced(
|
|
2799
3251
|
}
|
2800
3252
|
params.fParams = fParams;
|
2801
3253
|
return ZSTD_compressBegin_internal(cctx,
|
2802
|
-
NULL, 0, ZSTD_dct_auto,
|
3254
|
+
NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast,
|
2803
3255
|
cdict,
|
2804
3256
|
params, pledgedSrcSize,
|
2805
3257
|
ZSTDb_not_buffered);
|
@@ -2813,7 +3265,7 @@ size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
|
|
2813
3265
|
{
|
2814
3266
|
ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
|
2815
3267
|
DEBUGLOG(4, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u", !fParams.noDictIDFlag);
|
2816
|
-
return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams,
|
3268
|
+
return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN);
|
2817
3269
|
}
|
2818
3270
|
|
2819
3271
|
size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
|
@@ -2882,14 +3334,13 @@ static size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,
|
|
2882
3334
|
const ZSTD_CDict* const cdict,
|
2883
3335
|
ZSTD_CCtx_params const params, unsigned long long const pledgedSrcSize)
|
2884
3336
|
{
|
2885
|
-
DEBUGLOG(4, "ZSTD_resetCStream_internal
|
2886
|
-
params.disableLiteralCompression);
|
3337
|
+
DEBUGLOG(4, "ZSTD_resetCStream_internal");
|
2887
3338
|
/* params are supposed to be fully validated at this point */
|
2888
3339
|
assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
|
2889
3340
|
assert(!((dict) && (cdict))); /* either dict or cdict, not both */
|
2890
3341
|
|
2891
3342
|
CHECK_F( ZSTD_compressBegin_internal(cctx,
|
2892
|
-
dict, dictSize, dictContentType,
|
3343
|
+
dict, dictSize, dictContentType, ZSTD_dtlm_fast,
|
2893
3344
|
cdict,
|
2894
3345
|
params, pledgedSrcSize,
|
2895
3346
|
ZSTDb_buffered) );
|
@@ -3073,7 +3524,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
3073
3524
|
ip = iend;
|
3074
3525
|
op += cSize;
|
3075
3526
|
zcs->frameEnded = 1;
|
3076
|
-
|
3527
|
+
ZSTD_CCtx_reset(zcs);
|
3077
3528
|
someMoreWork = 0; break;
|
3078
3529
|
}
|
3079
3530
|
/* complete loading into inBuffer */
|
@@ -3126,7 +3577,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
3126
3577
|
if (zcs->frameEnded) {
|
3127
3578
|
DEBUGLOG(5, "Frame completed directly in outBuffer");
|
3128
3579
|
someMoreWork = 0;
|
3129
|
-
|
3580
|
+
ZSTD_CCtx_reset(zcs);
|
3130
3581
|
}
|
3131
3582
|
break;
|
3132
3583
|
}
|
@@ -3154,7 +3605,7 @@ size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
3154
3605
|
if (zcs->frameEnded) {
|
3155
3606
|
DEBUGLOG(5, "Frame completed on flush");
|
3156
3607
|
someMoreWork = 0;
|
3157
|
-
|
3608
|
+
ZSTD_CCtx_reset(zcs);
|
3158
3609
|
break;
|
3159
3610
|
}
|
3160
3611
|
zcs->streamStage = zcss_load;
|
@@ -3207,19 +3658,16 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|
3207
3658
|
params.cParams = ZSTD_getCParamsFromCCtxParams(
|
3208
3659
|
&cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);
|
3209
3660
|
|
3661
|
+
|
3210
3662
|
#ifdef ZSTD_MULTITHREAD
|
3211
3663
|
if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {
|
3212
3664
|
params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */
|
3213
3665
|
}
|
3214
3666
|
if (params.nbWorkers > 0) {
|
3215
3667
|
/* mt context creation */
|
3216
|
-
if (cctx->mtctx == NULL
|
3668
|
+
if (cctx->mtctx == NULL) {
|
3217
3669
|
DEBUGLOG(4, "ZSTD_compress_generic: creating new mtctx for nbWorkers=%u",
|
3218
3670
|
params.nbWorkers);
|
3219
|
-
if (cctx->mtctx != NULL)
|
3220
|
-
DEBUGLOG(4, "ZSTD_compress_generic: previous nbWorkers was %u",
|
3221
|
-
ZSTDMT_getNbWorkers(cctx->mtctx));
|
3222
|
-
ZSTDMT_freeCCtx(cctx->mtctx);
|
3223
3671
|
cctx->mtctx = ZSTDMT_createCCtx_advanced(params.nbWorkers, cctx->customMem);
|
3224
3672
|
if (cctx->mtctx == NULL) return ERROR(memory_allocation);
|
3225
3673
|
}
|
@@ -3251,7 +3699,7 @@ size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|
3251
3699
|
{ size_t const flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);
|
3252
3700
|
if ( ZSTD_isError(flushMin)
|
3253
3701
|
|| (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */
|
3254
|
-
|
3702
|
+
ZSTD_CCtx_reset(cctx);
|
3255
3703
|
}
|
3256
3704
|
return flushMin;
|
3257
3705
|
} }
|
@@ -3313,77 +3761,77 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
3313
3761
|
{ /* "default" - guarantees a monotonically increasing memory budget */
|
3314
3762
|
/* W, C, H, S, L, TL, strat */
|
3315
3763
|
{ 19, 12, 13, 1, 6, 1, ZSTD_fast }, /* base for negative levels */
|
3316
|
-
{ 19, 13, 14, 1, 7,
|
3317
|
-
{ 19, 15, 16, 1, 6,
|
3318
|
-
{ 20, 16, 17, 1, 5,
|
3319
|
-
{ 20,
|
3320
|
-
{ 20,
|
3321
|
-
{ 21,
|
3322
|
-
{ 21, 18, 19, 3, 5,
|
3323
|
-
{ 21,
|
3324
|
-
{ 21, 19, 20,
|
3325
|
-
{ 21,
|
3326
|
-
{
|
3764
|
+
{ 19, 13, 14, 1, 7, 0, ZSTD_fast }, /* level 1 */
|
3765
|
+
{ 19, 15, 16, 1, 6, 0, ZSTD_fast }, /* level 2 */
|
3766
|
+
{ 20, 16, 17, 1, 5, 1, ZSTD_dfast }, /* level 3 */
|
3767
|
+
{ 20, 18, 18, 1, 5, 1, ZSTD_dfast }, /* level 4 */
|
3768
|
+
{ 20, 18, 18, 2, 5, 2, ZSTD_greedy }, /* level 5 */
|
3769
|
+
{ 21, 18, 19, 2, 5, 4, ZSTD_lazy }, /* level 6 */
|
3770
|
+
{ 21, 18, 19, 3, 5, 8, ZSTD_lazy2 }, /* level 7 */
|
3771
|
+
{ 21, 19, 19, 3, 5, 16, ZSTD_lazy2 }, /* level 8 */
|
3772
|
+
{ 21, 19, 20, 4, 5, 16, ZSTD_lazy2 }, /* level 9 */
|
3773
|
+
{ 21, 20, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */
|
3774
|
+
{ 21, 21, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */
|
3327
3775
|
{ 22, 20, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 12 */
|
3328
3776
|
{ 22, 21, 22, 4, 5, 32, ZSTD_btlazy2 }, /* level 13 */
|
3329
3777
|
{ 22, 21, 22, 5, 5, 32, ZSTD_btlazy2 }, /* level 14 */
|
3330
3778
|
{ 22, 22, 22, 6, 5, 32, ZSTD_btlazy2 }, /* level 15 */
|
3331
3779
|
{ 22, 21, 22, 4, 5, 48, ZSTD_btopt }, /* level 16 */
|
3332
|
-
{ 23, 22, 22, 4, 4,
|
3333
|
-
{ 23,
|
3334
|
-
{ 23,
|
3335
|
-
{ 25, 25, 23, 7, 3,
|
3336
|
-
{ 26, 26, 24, 7, 3,
|
3337
|
-
{ 27, 27, 25, 9, 3,
|
3780
|
+
{ 23, 22, 22, 4, 4, 64, ZSTD_btopt }, /* level 17 */
|
3781
|
+
{ 23, 23, 22, 6, 3,256, ZSTD_btopt }, /* level 18 */
|
3782
|
+
{ 23, 24, 22, 7, 3,256, ZSTD_btultra }, /* level 19 */
|
3783
|
+
{ 25, 25, 23, 7, 3,256, ZSTD_btultra }, /* level 20 */
|
3784
|
+
{ 26, 26, 24, 7, 3,512, ZSTD_btultra }, /* level 21 */
|
3785
|
+
{ 27, 27, 25, 9, 3,999, ZSTD_btultra }, /* level 22 */
|
3338
3786
|
},
|
3339
3787
|
{ /* for srcSize <= 256 KB */
|
3340
3788
|
/* W, C, H, S, L, T, strat */
|
3341
3789
|
{ 18, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
|
3342
|
-
{ 18, 13, 14, 1, 6,
|
3343
|
-
{ 18, 14,
|
3344
|
-
{ 18, 16,
|
3345
|
-
{ 18,
|
3346
|
-
{ 18,
|
3347
|
-
{ 18,
|
3348
|
-
{ 18,
|
3349
|
-
{ 18,
|
3350
|
-
{ 18,
|
3351
|
-
{ 18,
|
3352
|
-
{ 18, 18,
|
3353
|
-
{ 18,
|
3354
|
-
{ 18, 19,
|
3355
|
-
{ 18, 18,
|
3356
|
-
{ 18, 18,
|
3357
|
-
{ 18, 19,
|
3358
|
-
{ 18, 19,
|
3359
|
-
{ 18, 19,
|
3360
|
-
{ 18, 19,
|
3361
|
-
{ 18, 19,
|
3362
|
-
{ 18, 19,
|
3363
|
-
{ 18, 19,
|
3790
|
+
{ 18, 13, 14, 1, 6, 0, ZSTD_fast }, /* level 1 */
|
3791
|
+
{ 18, 14, 14, 1, 5, 1, ZSTD_dfast }, /* level 2 */
|
3792
|
+
{ 18, 16, 16, 1, 4, 1, ZSTD_dfast }, /* level 3 */
|
3793
|
+
{ 18, 16, 17, 2, 5, 2, ZSTD_greedy }, /* level 4.*/
|
3794
|
+
{ 18, 18, 18, 3, 5, 2, ZSTD_greedy }, /* level 5.*/
|
3795
|
+
{ 18, 18, 19, 3, 5, 4, ZSTD_lazy }, /* level 6.*/
|
3796
|
+
{ 18, 18, 19, 4, 4, 4, ZSTD_lazy }, /* level 7 */
|
3797
|
+
{ 18, 18, 19, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
|
3798
|
+
{ 18, 18, 19, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
|
3799
|
+
{ 18, 18, 19, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
|
3800
|
+
{ 18, 18, 19, 5, 4, 16, ZSTD_btlazy2 }, /* level 11.*/
|
3801
|
+
{ 18, 19, 19, 6, 4, 16, ZSTD_btlazy2 }, /* level 12.*/
|
3802
|
+
{ 18, 19, 19, 8, 4, 16, ZSTD_btlazy2 }, /* level 13 */
|
3803
|
+
{ 18, 18, 19, 4, 4, 24, ZSTD_btopt }, /* level 14.*/
|
3804
|
+
{ 18, 18, 19, 4, 3, 24, ZSTD_btopt }, /* level 15.*/
|
3805
|
+
{ 18, 19, 19, 6, 3, 64, ZSTD_btopt }, /* level 16.*/
|
3806
|
+
{ 18, 19, 19, 8, 3,128, ZSTD_btopt }, /* level 17.*/
|
3807
|
+
{ 18, 19, 19, 10, 3,256, ZSTD_btopt }, /* level 18.*/
|
3808
|
+
{ 18, 19, 19, 10, 3,256, ZSTD_btultra }, /* level 19.*/
|
3809
|
+
{ 18, 19, 19, 11, 3,512, ZSTD_btultra }, /* level 20.*/
|
3810
|
+
{ 18, 19, 19, 12, 3,512, ZSTD_btultra }, /* level 21.*/
|
3811
|
+
{ 18, 19, 19, 13, 3,999, ZSTD_btultra }, /* level 22.*/
|
3364
3812
|
},
|
3365
3813
|
{ /* for srcSize <= 128 KB */
|
3366
3814
|
/* W, C, H, S, L, T, strat */
|
3367
|
-
{ 17, 12, 12, 1, 5, 1, ZSTD_fast }, /*
|
3368
|
-
{ 17, 12, 13, 1, 6,
|
3369
|
-
{ 17, 13,
|
3370
|
-
{ 17,
|
3371
|
-
{ 17,
|
3372
|
-
{ 17,
|
3373
|
-
{ 17,
|
3374
|
-
{ 17,
|
3815
|
+
{ 17, 12, 12, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
|
3816
|
+
{ 17, 12, 13, 1, 6, 0, ZSTD_fast }, /* level 1 */
|
3817
|
+
{ 17, 13, 15, 1, 5, 0, ZSTD_fast }, /* level 2 */
|
3818
|
+
{ 17, 15, 16, 2, 5, 1, ZSTD_dfast }, /* level 3 */
|
3819
|
+
{ 17, 17, 17, 2, 4, 1, ZSTD_dfast }, /* level 4 */
|
3820
|
+
{ 17, 16, 17, 3, 4, 2, ZSTD_greedy }, /* level 5 */
|
3821
|
+
{ 17, 17, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */
|
3822
|
+
{ 17, 17, 17, 3, 4, 8, ZSTD_lazy2 }, /* level 7 */
|
3375
3823
|
{ 17, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
|
3376
3824
|
{ 17, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
|
3377
3825
|
{ 17, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
|
3378
3826
|
{ 17, 17, 17, 7, 4, 8, ZSTD_lazy2 }, /* level 11 */
|
3379
|
-
{ 17,
|
3380
|
-
{ 17, 18, 17,
|
3381
|
-
{ 17,
|
3382
|
-
{ 17,
|
3383
|
-
{ 17, 18, 17, 7, 3,
|
3384
|
-
{ 17, 18, 17, 7, 3,
|
3385
|
-
{ 17, 18, 17,
|
3386
|
-
{ 17, 18, 17, 8, 3,256,
|
3827
|
+
{ 17, 18, 17, 6, 4, 16, ZSTD_btlazy2 }, /* level 12 */
|
3828
|
+
{ 17, 18, 17, 8, 4, 16, ZSTD_btlazy2 }, /* level 13.*/
|
3829
|
+
{ 17, 18, 17, 4, 4, 32, ZSTD_btopt }, /* level 14.*/
|
3830
|
+
{ 17, 18, 17, 6, 3, 64, ZSTD_btopt }, /* level 15.*/
|
3831
|
+
{ 17, 18, 17, 7, 3,128, ZSTD_btopt }, /* level 16.*/
|
3832
|
+
{ 17, 18, 17, 7, 3,256, ZSTD_btopt }, /* level 17.*/
|
3833
|
+
{ 17, 18, 17, 8, 3,256, ZSTD_btopt }, /* level 18.*/
|
3834
|
+
{ 17, 18, 17, 8, 3,256, ZSTD_btultra }, /* level 19.*/
|
3387
3835
|
{ 17, 18, 17, 9, 3,256, ZSTD_btultra }, /* level 20.*/
|
3388
3836
|
{ 17, 18, 17, 10, 3,256, ZSTD_btultra }, /* level 21.*/
|
3389
3837
|
{ 17, 18, 17, 11, 3,512, ZSTD_btultra }, /* level 22.*/
|
@@ -3391,28 +3839,28 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
|
|
3391
3839
|
{ /* for srcSize <= 16 KB */
|
3392
3840
|
/* W, C, H, S, L, T, strat */
|
3393
3841
|
{ 14, 12, 13, 1, 5, 1, ZSTD_fast }, /* base for negative levels */
|
3394
|
-
{ 14, 14,
|
3395
|
-
{ 14, 14,
|
3396
|
-
{ 14, 14, 14,
|
3397
|
-
{ 14, 14, 14, 4, 4,
|
3398
|
-
{ 14, 14, 14, 3, 4,
|
3399
|
-
{ 14, 14, 14, 4, 4,
|
3400
|
-
{ 14, 14, 14,
|
3401
|
-
{ 14, 14, 14,
|
3402
|
-
{ 14, 15, 14,
|
3403
|
-
{ 14, 15, 14,
|
3404
|
-
{ 14, 15, 14,
|
3842
|
+
{ 14, 14, 15, 1, 5, 0, ZSTD_fast }, /* level 1 */
|
3843
|
+
{ 14, 14, 15, 1, 4, 0, ZSTD_fast }, /* level 2 */
|
3844
|
+
{ 14, 14, 14, 2, 4, 1, ZSTD_dfast }, /* level 3.*/
|
3845
|
+
{ 14, 14, 14, 4, 4, 2, ZSTD_greedy }, /* level 4.*/
|
3846
|
+
{ 14, 14, 14, 3, 4, 4, ZSTD_lazy }, /* level 5.*/
|
3847
|
+
{ 14, 14, 14, 4, 4, 8, ZSTD_lazy2 }, /* level 6 */
|
3848
|
+
{ 14, 14, 14, 6, 4, 8, ZSTD_lazy2 }, /* level 7 */
|
3849
|
+
{ 14, 14, 14, 8, 4, 8, ZSTD_lazy2 }, /* level 8.*/
|
3850
|
+
{ 14, 15, 14, 5, 4, 8, ZSTD_btlazy2 }, /* level 9.*/
|
3851
|
+
{ 14, 15, 14, 9, 4, 8, ZSTD_btlazy2 }, /* level 10.*/
|
3852
|
+
{ 14, 15, 14, 3, 4, 12, ZSTD_btopt }, /* level 11.*/
|
3405
3853
|
{ 14, 15, 14, 6, 3, 16, ZSTD_btopt }, /* level 12.*/
|
3406
3854
|
{ 14, 15, 14, 6, 3, 24, ZSTD_btopt }, /* level 13.*/
|
3407
3855
|
{ 14, 15, 15, 6, 3, 48, ZSTD_btopt }, /* level 14.*/
|
3408
3856
|
{ 14, 15, 15, 6, 3, 64, ZSTD_btopt }, /* level 15.*/
|
3409
3857
|
{ 14, 15, 15, 6, 3, 96, ZSTD_btopt }, /* level 16.*/
|
3410
3858
|
{ 14, 15, 15, 6, 3,128, ZSTD_btopt }, /* level 17.*/
|
3411
|
-
{ 14, 15, 15,
|
3412
|
-
{ 14, 15, 15,
|
3859
|
+
{ 14, 15, 15, 8, 3,256, ZSTD_btopt }, /* level 18.*/
|
3860
|
+
{ 14, 15, 15, 6, 3,256, ZSTD_btultra }, /* level 19.*/
|
3413
3861
|
{ 14, 15, 15, 8, 3,256, ZSTD_btultra }, /* level 20.*/
|
3414
3862
|
{ 14, 15, 15, 9, 3,256, ZSTD_btultra }, /* level 21.*/
|
3415
|
-
{ 14, 15, 15, 10, 3,
|
3863
|
+
{ 14, 15, 15, 10, 3,512, ZSTD_btultra }, /* level 22.*/
|
3416
3864
|
},
|
3417
3865
|
};
|
3418
3866
|
|