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