extzstd 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +28 -14
- data/contrib/zstd/CHANGELOG +114 -56
- data/contrib/zstd/CONTRIBUTING.md +14 -0
- data/contrib/zstd/Makefile +37 -31
- data/contrib/zstd/README.md +6 -0
- data/contrib/zstd/appveyor.yml +4 -1
- data/contrib/zstd/lib/Makefile +231 -134
- data/contrib/zstd/lib/README.md +28 -0
- data/contrib/zstd/lib/common/bitstream.h +24 -15
- data/contrib/zstd/lib/common/compiler.h +116 -3
- data/contrib/zstd/lib/common/cpu.h +0 -2
- data/contrib/zstd/lib/common/debug.h +11 -18
- data/contrib/zstd/lib/common/entropy_common.c +188 -42
- data/contrib/zstd/lib/common/error_private.c +1 -0
- data/contrib/zstd/lib/common/error_private.h +1 -1
- data/contrib/zstd/lib/common/fse.h +38 -11
- data/contrib/zstd/lib/common/fse_decompress.c +123 -16
- data/contrib/zstd/lib/common/huf.h +26 -5
- data/contrib/zstd/lib/common/mem.h +66 -93
- data/contrib/zstd/lib/common/pool.c +22 -16
- data/contrib/zstd/lib/common/pool.h +1 -1
- data/contrib/zstd/lib/common/threading.c +6 -5
- data/contrib/zstd/lib/common/xxhash.c +18 -56
- data/contrib/zstd/lib/common/xxhash.h +1 -1
- data/contrib/zstd/lib/common/zstd_common.c +9 -9
- data/contrib/zstd/lib/common/zstd_deps.h +111 -0
- data/contrib/zstd/lib/common/zstd_errors.h +1 -0
- data/contrib/zstd/lib/common/zstd_internal.h +89 -58
- data/contrib/zstd/lib/compress/fse_compress.c +30 -23
- data/contrib/zstd/lib/compress/hist.c +26 -28
- data/contrib/zstd/lib/compress/hist.h +1 -1
- data/contrib/zstd/lib/compress/huf_compress.c +210 -95
- data/contrib/zstd/lib/compress/zstd_compress.c +1339 -409
- data/contrib/zstd/lib/compress/zstd_compress_internal.h +119 -41
- data/contrib/zstd/lib/compress/zstd_compress_literals.c +4 -4
- data/contrib/zstd/lib/compress/zstd_compress_sequences.c +17 -3
- data/contrib/zstd/lib/compress/zstd_compress_superblock.c +23 -19
- data/contrib/zstd/lib/compress/zstd_cwksp.h +60 -24
- data/contrib/zstd/lib/compress/zstd_double_fast.c +22 -22
- data/contrib/zstd/lib/compress/zstd_fast.c +19 -19
- data/contrib/zstd/lib/compress/zstd_lazy.c +351 -77
- data/contrib/zstd/lib/compress/zstd_lazy.h +20 -0
- data/contrib/zstd/lib/compress/zstd_ldm.c +59 -18
- data/contrib/zstd/lib/compress/zstd_ldm.h +6 -0
- data/contrib/zstd/lib/compress/zstd_opt.c +190 -45
- data/contrib/zstd/lib/compress/zstdmt_compress.c +74 -406
- data/contrib/zstd/lib/compress/zstdmt_compress.h +26 -108
- data/contrib/zstd/lib/decompress/huf_decompress.c +302 -200
- data/contrib/zstd/lib/decompress/zstd_ddict.c +8 -8
- data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
- data/contrib/zstd/lib/decompress/zstd_decompress.c +125 -80
- data/contrib/zstd/lib/decompress/zstd_decompress_block.c +145 -37
- data/contrib/zstd/lib/decompress/zstd_decompress_block.h +5 -2
- data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +11 -10
- data/contrib/zstd/lib/dictBuilder/cover.c +29 -20
- data/contrib/zstd/lib/dictBuilder/cover.h +1 -1
- data/contrib/zstd/lib/dictBuilder/fastcover.c +20 -19
- data/contrib/zstd/lib/dictBuilder/zdict.c +15 -16
- data/contrib/zstd/lib/dictBuilder/zdict.h +1 -1
- data/contrib/zstd/lib/legacy/zstd_v01.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v02.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v03.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v04.c +6 -2
- data/contrib/zstd/lib/legacy/zstd_v05.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v06.c +5 -1
- data/contrib/zstd/lib/legacy/zstd_v07.c +5 -1
- data/contrib/zstd/lib/libzstd.pc.in +3 -3
- data/contrib/zstd/lib/zstd.h +348 -47
- data/ext/extzstd.c +6 -0
- data/ext/extzstd.h +6 -0
- data/gemstub.rb +3 -21
- data/lib/extzstd.rb +0 -2
- data/lib/extzstd/version.rb +6 -1
- data/test/test_basic.rb +0 -5
- metadata +5 -4
@@ -28,7 +28,6 @@
|
|
28
28
|
extern "C" {
|
29
29
|
#endif
|
30
30
|
|
31
|
-
|
32
31
|
/*-*************************************
|
33
32
|
* Constants
|
34
33
|
***************************************/
|
@@ -64,7 +63,7 @@ typedef struct {
|
|
64
63
|
} ZSTD_localDict;
|
65
64
|
|
66
65
|
typedef struct {
|
67
|
-
|
66
|
+
HUF_CElt CTable[HUF_CTABLE_SIZE_U32(255)];
|
68
67
|
HUF_repeat repeatMode;
|
69
68
|
} ZSTD_hufCTables_t;
|
70
69
|
|
@@ -83,10 +82,27 @@ typedef struct {
|
|
83
82
|
} ZSTD_entropyCTables_t;
|
84
83
|
|
85
84
|
typedef struct {
|
86
|
-
U32 off;
|
87
|
-
U32 len;
|
85
|
+
U32 off; /* Offset code (offset + ZSTD_REP_MOVE) for the match */
|
86
|
+
U32 len; /* Raw length of match */
|
88
87
|
} ZSTD_match_t;
|
89
88
|
|
89
|
+
typedef struct {
|
90
|
+
U32 offset; /* Offset of sequence */
|
91
|
+
U32 litLength; /* Length of literals prior to match */
|
92
|
+
U32 matchLength; /* Raw length of match */
|
93
|
+
} rawSeq;
|
94
|
+
|
95
|
+
typedef struct {
|
96
|
+
rawSeq* seq; /* The start of the sequences */
|
97
|
+
size_t pos; /* The index in seq where reading stopped. pos <= size. */
|
98
|
+
size_t posInSequence; /* The position within the sequence at seq[pos] where reading
|
99
|
+
stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */
|
100
|
+
size_t size; /* The number of sequences. <= capacity. */
|
101
|
+
size_t capacity; /* The capacity starting from `seq` pointer */
|
102
|
+
} rawSeqStore_t;
|
103
|
+
|
104
|
+
UNUSED_ATTR static const rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0};
|
105
|
+
|
90
106
|
typedef struct {
|
91
107
|
int price;
|
92
108
|
U32 off;
|
@@ -147,9 +163,13 @@ struct ZSTD_matchState_t {
|
|
147
163
|
U32* hashTable;
|
148
164
|
U32* hashTable3;
|
149
165
|
U32* chainTable;
|
166
|
+
int dedicatedDictSearch; /* Indicates whether this matchState is using the
|
167
|
+
* dedicated dictionary search structure.
|
168
|
+
*/
|
150
169
|
optState_t opt; /* optimal parser state */
|
151
170
|
const ZSTD_matchState_t* dictMatchState;
|
152
171
|
ZSTD_compressionParameters cParams;
|
172
|
+
const rawSeqStore_t* ldmSeqStore;
|
153
173
|
};
|
154
174
|
|
155
175
|
typedef struct {
|
@@ -181,19 +201,6 @@ typedef struct {
|
|
181
201
|
U32 windowLog; /* Window log for the LDM */
|
182
202
|
} ldmParams_t;
|
183
203
|
|
184
|
-
typedef struct {
|
185
|
-
U32 offset;
|
186
|
-
U32 litLength;
|
187
|
-
U32 matchLength;
|
188
|
-
} rawSeq;
|
189
|
-
|
190
|
-
typedef struct {
|
191
|
-
rawSeq* seq; /* The start of the sequences */
|
192
|
-
size_t pos; /* The position where reading stopped. <= size. */
|
193
|
-
size_t size; /* The number of sequences. <= capacity. */
|
194
|
-
size_t capacity; /* The capacity starting from `seq` pointer */
|
195
|
-
} rawSeqStore_t;
|
196
|
-
|
197
204
|
typedef struct {
|
198
205
|
int collectSequences;
|
199
206
|
ZSTD_Sequence* seqStart;
|
@@ -228,10 +235,34 @@ struct ZSTD_CCtx_params_s {
|
|
228
235
|
/* Long distance matching parameters */
|
229
236
|
ldmParams_t ldmParams;
|
230
237
|
|
238
|
+
/* Dedicated dict search algorithm trigger */
|
239
|
+
int enableDedicatedDictSearch;
|
240
|
+
|
241
|
+
/* Input/output buffer modes */
|
242
|
+
ZSTD_bufferMode_e inBufferMode;
|
243
|
+
ZSTD_bufferMode_e outBufferMode;
|
244
|
+
|
245
|
+
/* Sequence compression API */
|
246
|
+
ZSTD_sequenceFormat_e blockDelimiters;
|
247
|
+
int validateSequences;
|
248
|
+
|
231
249
|
/* Internal use, for createCCtxParams() and freeCCtxParams() only */
|
232
250
|
ZSTD_customMem customMem;
|
233
251
|
}; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
|
234
252
|
|
253
|
+
#define COMPRESS_SEQUENCES_WORKSPACE_SIZE (sizeof(unsigned) * (MaxSeq + 2))
|
254
|
+
#define ENTROPY_WORKSPACE_SIZE (HUF_WORKSPACE_SIZE + COMPRESS_SEQUENCES_WORKSPACE_SIZE)
|
255
|
+
|
256
|
+
/**
|
257
|
+
* Indicates whether this compression proceeds directly from user-provided
|
258
|
+
* source buffer to user-provided destination buffer (ZSTDb_not_buffered), or
|
259
|
+
* whether the context needs to buffer the input/output (ZSTDb_buffered).
|
260
|
+
*/
|
261
|
+
typedef enum {
|
262
|
+
ZSTDb_not_buffered,
|
263
|
+
ZSTDb_buffered
|
264
|
+
} ZSTD_buffered_policy_e;
|
265
|
+
|
235
266
|
struct ZSTD_CCtx_s {
|
236
267
|
ZSTD_compressionStage_e stage;
|
237
268
|
int cParamsChanged; /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */
|
@@ -247,6 +278,7 @@ struct ZSTD_CCtx_s {
|
|
247
278
|
unsigned long long producedCSize;
|
248
279
|
XXH64_state_t xxhState;
|
249
280
|
ZSTD_customMem customMem;
|
281
|
+
ZSTD_threadPool* pool;
|
250
282
|
size_t staticSize;
|
251
283
|
SeqCollector seqCollector;
|
252
284
|
int isFirstBlock;
|
@@ -258,7 +290,10 @@ struct ZSTD_CCtx_s {
|
|
258
290
|
size_t maxNbLdmSequences;
|
259
291
|
rawSeqStore_t externSeqStore; /* Mutable reference to external sequences */
|
260
292
|
ZSTD_blockState_t blockState;
|
261
|
-
U32* entropyWorkspace; /* entropy workspace of
|
293
|
+
U32* entropyWorkspace; /* entropy workspace of ENTROPY_WORKSPACE_SIZE bytes */
|
294
|
+
|
295
|
+
/* Wether we are streaming or not */
|
296
|
+
ZSTD_buffered_policy_e bufferedPolicy;
|
262
297
|
|
263
298
|
/* streaming */
|
264
299
|
char* inBuff;
|
@@ -273,6 +308,10 @@ struct ZSTD_CCtx_s {
|
|
273
308
|
ZSTD_cStreamStage streamStage;
|
274
309
|
U32 frameEnded;
|
275
310
|
|
311
|
+
/* Stable in/out buffer verification */
|
312
|
+
ZSTD_inBuffer expectedInBuffer;
|
313
|
+
size_t expectedOutBufferSize;
|
314
|
+
|
276
315
|
/* Dictionary */
|
277
316
|
ZSTD_localDict localDict;
|
278
317
|
const ZSTD_CDict* cdict;
|
@@ -286,8 +325,32 @@ struct ZSTD_CCtx_s {
|
|
286
325
|
|
287
326
|
typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e;
|
288
327
|
|
289
|
-
typedef enum {
|
290
|
-
|
328
|
+
typedef enum {
|
329
|
+
ZSTD_noDict = 0,
|
330
|
+
ZSTD_extDict = 1,
|
331
|
+
ZSTD_dictMatchState = 2,
|
332
|
+
ZSTD_dedicatedDictSearch = 3
|
333
|
+
} ZSTD_dictMode_e;
|
334
|
+
|
335
|
+
typedef enum {
|
336
|
+
ZSTD_cpm_noAttachDict = 0, /* Compression with ZSTD_noDict or ZSTD_extDict.
|
337
|
+
* In this mode we use both the srcSize and the dictSize
|
338
|
+
* when selecting and adjusting parameters.
|
339
|
+
*/
|
340
|
+
ZSTD_cpm_attachDict = 1, /* Compression with ZSTD_dictMatchState or ZSTD_dedicatedDictSearch.
|
341
|
+
* In this mode we only take the srcSize into account when selecting
|
342
|
+
* and adjusting parameters.
|
343
|
+
*/
|
344
|
+
ZSTD_cpm_createCDict = 2, /* Creating a CDict.
|
345
|
+
* In this mode we take both the source size and the dictionary size
|
346
|
+
* into account when selecting and adjusting the parameters.
|
347
|
+
*/
|
348
|
+
ZSTD_cpm_unknown = 3, /* ZSTD_getCParams, ZSTD_getParams, ZSTD_adjustParams.
|
349
|
+
* We don't know what these parameters are for. We default to the legacy
|
350
|
+
* behavior of taking both the source size and the dict size into account
|
351
|
+
* when selecting and adjusting parameters.
|
352
|
+
*/
|
353
|
+
} ZSTD_cParamMode_e;
|
291
354
|
|
292
355
|
typedef size_t (*ZSTD_blockCompressor) (
|
293
356
|
ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
@@ -345,7 +408,7 @@ MEM_STATIC repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 con
|
|
345
408
|
newReps.rep[1] = rep[0];
|
346
409
|
newReps.rep[0] = currentOffset;
|
347
410
|
} else { /* repCode == 0 */
|
348
|
-
|
411
|
+
ZSTD_memcpy(&newReps, rep, sizeof(newReps));
|
349
412
|
}
|
350
413
|
}
|
351
414
|
return newReps;
|
@@ -372,7 +435,7 @@ MEM_STATIC size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const voi
|
|
372
435
|
RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity,
|
373
436
|
dstSize_tooSmall, "dst buf too small for uncompressed block");
|
374
437
|
MEM_writeLE24(dst, cBlockHeader24);
|
375
|
-
|
438
|
+
ZSTD_memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
|
376
439
|
return ZSTD_blockHeaderSize + srcSize;
|
377
440
|
}
|
378
441
|
|
@@ -498,8 +561,12 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
|
|
498
561
|
if (MEM_isLittleEndian()) {
|
499
562
|
if (MEM_64bits()) {
|
500
563
|
# if defined(_MSC_VER) && defined(_WIN64)
|
501
|
-
|
502
|
-
|
564
|
+
# if STATIC_BMI2
|
565
|
+
return _tzcnt_u64(val) >> 3;
|
566
|
+
# else
|
567
|
+
unsigned long r = 0;
|
568
|
+
return _BitScanForward64( &r, (U64)val ) ? (unsigned)(r >> 3) : 0;
|
569
|
+
# endif
|
503
570
|
# elif defined(__GNUC__) && (__GNUC__ >= 4)
|
504
571
|
return (__builtin_ctzll((U64)val) >> 3);
|
505
572
|
# else
|
@@ -530,8 +597,12 @@ static unsigned ZSTD_NbCommonBytes (size_t val)
|
|
530
597
|
} else { /* Big Endian CPU */
|
531
598
|
if (MEM_64bits()) {
|
532
599
|
# if defined(_MSC_VER) && defined(_WIN64)
|
533
|
-
|
534
|
-
|
600
|
+
# if STATIC_BMI2
|
601
|
+
return _lzcnt_u64(val) >> 3;
|
602
|
+
# else
|
603
|
+
unsigned long r = 0;
|
604
|
+
return _BitScanReverse64(&r, (U64)val) ? (unsigned)(r >> 3) : 0;
|
605
|
+
# endif
|
535
606
|
# elif defined(__GNUC__) && (__GNUC__ >= 4)
|
536
607
|
return (__builtin_clzll(val) >> 3);
|
537
608
|
# else
|
@@ -626,7 +697,8 @@ static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
|
|
626
697
|
static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
|
627
698
|
static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
|
628
699
|
|
629
|
-
MEM_STATIC
|
700
|
+
MEM_STATIC FORCE_INLINE_ATTR
|
701
|
+
size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
|
630
702
|
{
|
631
703
|
switch(mls)
|
632
704
|
{
|
@@ -742,7 +814,7 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
|
|
742
814
|
return ZSTD_window_hasExtDict(ms->window) ?
|
743
815
|
ZSTD_extDict :
|
744
816
|
ms->dictMatchState != NULL ?
|
745
|
-
ZSTD_dictMatchState :
|
817
|
+
(ms->dictMatchState->dedicatedDictSearch ? ZSTD_dedicatedDictSearch : ZSTD_dictMatchState) :
|
746
818
|
ZSTD_noDict;
|
747
819
|
}
|
748
820
|
|
@@ -754,8 +826,8 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
|
|
754
826
|
MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
|
755
827
|
void const* srcEnd)
|
756
828
|
{
|
757
|
-
U32 const
|
758
|
-
return
|
829
|
+
U32 const curr = (U32)((BYTE const*)srcEnd - window.base);
|
830
|
+
return curr > ZSTD_CURRENT_MAX;
|
759
831
|
}
|
760
832
|
|
761
833
|
/**
|
@@ -791,14 +863,14 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
|
|
791
863
|
* windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.
|
792
864
|
*/
|
793
865
|
U32 const cycleMask = (1U << cycleLog) - 1;
|
794
|
-
U32 const
|
795
|
-
U32 const currentCycle0 =
|
866
|
+
U32 const curr = (U32)((BYTE const*)src - window->base);
|
867
|
+
U32 const currentCycle0 = curr & cycleMask;
|
796
868
|
/* Exclude zero so that newCurrent - maxDist >= 1. */
|
797
869
|
U32 const currentCycle1 = currentCycle0 == 0 ? (1U << cycleLog) : currentCycle0;
|
798
870
|
U32 const newCurrent = currentCycle1 + maxDist;
|
799
|
-
U32 const correction =
|
871
|
+
U32 const correction = curr - newCurrent;
|
800
872
|
assert((maxDist & cycleMask) == 0);
|
801
|
-
assert(
|
873
|
+
assert(curr > newCurrent);
|
802
874
|
/* Loose bound, should be around 1<<29 (see above) */
|
803
875
|
assert(correction > 1<<28);
|
804
876
|
|
@@ -919,7 +991,7 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window,
|
|
919
991
|
}
|
920
992
|
|
921
993
|
MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
|
922
|
-
|
994
|
+
ZSTD_memset(window, 0, sizeof(*window));
|
923
995
|
window->base = (BYTE const*)"";
|
924
996
|
window->dictBase = (BYTE const*)"";
|
925
997
|
window->dictLimit = 1; /* start from 1, so that 1st position is valid */
|
@@ -973,12 +1045,16 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
|
|
973
1045
|
/**
|
974
1046
|
* Returns the lowest allowed match index. It may either be in the ext-dict or the prefix.
|
975
1047
|
*/
|
976
|
-
MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32
|
1048
|
+
MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
|
977
1049
|
{
|
978
1050
|
U32 const maxDistance = 1U << windowLog;
|
979
1051
|
U32 const lowestValid = ms->window.lowLimit;
|
980
|
-
U32 const withinWindow = (
|
1052
|
+
U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
|
981
1053
|
U32 const isDictionary = (ms->loadedDictEnd != 0);
|
1054
|
+
/* When using a dictionary the entire dictionary is valid if a single byte of the dictionary
|
1055
|
+
* is within the window. We invalidate the dictionary (and set loadedDictEnd to 0) when it isn't
|
1056
|
+
* valid for the entire block. So this check is sufficient to find the lowest valid match index.
|
1057
|
+
*/
|
982
1058
|
U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
|
983
1059
|
return matchLowest;
|
984
1060
|
}
|
@@ -986,12 +1062,15 @@ MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current
|
|
986
1062
|
/**
|
987
1063
|
* Returns the lowest allowed match index in the prefix.
|
988
1064
|
*/
|
989
|
-
MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32
|
1065
|
+
MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 curr, unsigned windowLog)
|
990
1066
|
{
|
991
1067
|
U32 const maxDistance = 1U << windowLog;
|
992
1068
|
U32 const lowestValid = ms->window.dictLimit;
|
993
|
-
U32 const withinWindow = (
|
1069
|
+
U32 const withinWindow = (curr - lowestValid > maxDistance) ? curr - maxDistance : lowestValid;
|
994
1070
|
U32 const isDictionary = (ms->loadedDictEnd != 0);
|
1071
|
+
/* When computing the lowest prefix index we need to take the dictionary into account to handle
|
1072
|
+
* the edge case where the dictionary and the source are contiguous in memory.
|
1073
|
+
*/
|
995
1074
|
U32 const matchLowest = isDictionary ? lowestValid : withinWindow;
|
996
1075
|
return matchLowest;
|
997
1076
|
}
|
@@ -1045,7 +1124,6 @@ MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max)
|
|
1045
1124
|
* assumptions : magic number supposed already checked
|
1046
1125
|
* and dictSize >= 8 */
|
1047
1126
|
size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
|
1048
|
-
short* offcodeNCount, unsigned* offcodeMaxValue,
|
1049
1127
|
const void* const dict, size_t dictSize);
|
1050
1128
|
|
1051
1129
|
void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
|
@@ -1061,7 +1139,7 @@ void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
|
|
1061
1139
|
* Note: srcSizeHint == 0 means 0!
|
1062
1140
|
*/
|
1063
1141
|
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
|
1064
|
-
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize);
|
1142
|
+
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_cParamMode_e mode);
|
1065
1143
|
|
1066
1144
|
/*! ZSTD_initCStream_internal() :
|
1067
1145
|
* Private use only. Init streaming operation.
|
@@ -35,7 +35,7 @@ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src,
|
|
35
35
|
assert(0);
|
36
36
|
}
|
37
37
|
|
38
|
-
|
38
|
+
ZSTD_memcpy(ostart + flSize, src, srcSize);
|
39
39
|
DEBUGLOG(5, "Raw literals: %u -> %u", (U32)srcSize, (U32)(srcSize + flSize));
|
40
40
|
return srcSize + flSize;
|
41
41
|
}
|
@@ -86,7 +86,7 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
|
|
86
86
|
disableLiteralCompression, (U32)srcSize);
|
87
87
|
|
88
88
|
/* Prepare nextEntropy assuming reusing the existing table */
|
89
|
-
|
89
|
+
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
90
90
|
|
91
91
|
if (disableLiteralCompression)
|
92
92
|
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
@@ -118,11 +118,11 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
|
|
118
118
|
}
|
119
119
|
|
120
120
|
if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
|
121
|
-
|
121
|
+
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
122
122
|
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
123
123
|
}
|
124
124
|
if (cLitSize==1) {
|
125
|
-
|
125
|
+
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
126
126
|
return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
|
127
127
|
}
|
128
128
|
|
@@ -50,6 +50,19 @@ static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
|
|
50
50
|
return maxSymbolValue;
|
51
51
|
}
|
52
52
|
|
53
|
+
/**
|
54
|
+
* Returns true if we should use ncount=-1 else we should
|
55
|
+
* use ncount=1 for low probability symbols instead.
|
56
|
+
*/
|
57
|
+
static unsigned ZSTD_useLowProbCount(size_t const nbSeq)
|
58
|
+
{
|
59
|
+
/* Heuristic: This should cover most blocks <= 16K and
|
60
|
+
* start to fade out after 16K to about 32K depending on
|
61
|
+
* comprssibility.
|
62
|
+
*/
|
63
|
+
return nbSeq >= 2048;
|
64
|
+
}
|
65
|
+
|
53
66
|
/**
|
54
67
|
* Returns the cost in bytes of encoding the normalized count header.
|
55
68
|
* Returns an error if any of the helper functions return an error.
|
@@ -60,7 +73,7 @@ static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
|
|
60
73
|
BYTE wksp[FSE_NCOUNTBOUND];
|
61
74
|
S16 norm[MaxSeq + 1];
|
62
75
|
const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
|
63
|
-
FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max), "");
|
76
|
+
FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max, ZSTD_useLowProbCount(nbSeq)), "");
|
64
77
|
return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
|
65
78
|
}
|
66
79
|
|
@@ -239,7 +252,7 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
|
239
252
|
*op = codeTable[0];
|
240
253
|
return 1;
|
241
254
|
case set_repeat:
|
242
|
-
|
255
|
+
ZSTD_memcpy(nextCTable, prevCTable, prevCTableSize);
|
243
256
|
return 0;
|
244
257
|
case set_basic:
|
245
258
|
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */
|
@@ -253,7 +266,8 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
|
253
266
|
nbSeq_1--;
|
254
267
|
}
|
255
268
|
assert(nbSeq_1 > 1);
|
256
|
-
|
269
|
+
assert(entropyWorkspaceSize >= FSE_BUILD_CTABLE_WORKSPACE_SIZE(MaxSeq, MaxFSELog));
|
270
|
+
FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "");
|
257
271
|
{ size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
|
258
272
|
FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
|
259
273
|
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize), "");
|
@@ -29,7 +29,7 @@
|
|
29
29
|
* This metadata is populated in ZSTD_buildSuperBlockEntropy_literal() */
|
30
30
|
typedef struct {
|
31
31
|
symbolEncodingType_e hType;
|
32
|
-
BYTE hufDesBuffer[
|
32
|
+
BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
|
33
33
|
size_t hufDesSize;
|
34
34
|
} ZSTD_hufCTablesMetadata_t;
|
35
35
|
|
@@ -42,7 +42,7 @@ typedef struct {
|
|
42
42
|
symbolEncodingType_e llType;
|
43
43
|
symbolEncodingType_e ofType;
|
44
44
|
symbolEncodingType_e mlType;
|
45
|
-
BYTE fseTablesBuffer[
|
45
|
+
BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
|
46
46
|
size_t fseTablesSize;
|
47
47
|
size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_compressSubBlock_sequences() */
|
48
48
|
} ZSTD_fseCTablesMetadata_t;
|
@@ -79,7 +79,7 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz
|
|
79
79
|
DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_literal (srcSize=%zu)", srcSize);
|
80
80
|
|
81
81
|
/* Prepare nextEntropy assuming reusing the existing table */
|
82
|
-
|
82
|
+
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
83
83
|
|
84
84
|
if (disableLiteralsCompression) {
|
85
85
|
DEBUGLOG(5, "set_basic - disabled");
|
@@ -118,7 +118,7 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz
|
|
118
118
|
}
|
119
119
|
|
120
120
|
/* Build Huffman Tree */
|
121
|
-
|
121
|
+
ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
|
122
122
|
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
|
123
123
|
{ size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp,
|
124
124
|
maxSymbolValue, huffLog,
|
@@ -137,14 +137,14 @@ static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSiz
|
|
137
137
|
(HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
|
138
138
|
if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
|
139
139
|
DEBUGLOG(5, "set_repeat - smaller");
|
140
|
-
|
140
|
+
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
141
141
|
hufMetadata->hType = set_repeat;
|
142
142
|
return 0;
|
143
143
|
}
|
144
144
|
}
|
145
145
|
if (newCSize + hSize >= srcSize) {
|
146
146
|
DEBUGLOG(5, "set_basic - no gains");
|
147
|
-
|
147
|
+
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
148
148
|
hufMetadata->hType = set_basic;
|
149
149
|
return 0;
|
150
150
|
}
|
@@ -188,7 +188,7 @@ static size_t ZSTD_buildSuperBlockEntropy_sequences(seqStore_t* seqStorePtr,
|
|
188
188
|
|
189
189
|
assert(cTableWkspSize >= (1 << MaxFSELog) * sizeof(FSE_FUNCTION_TYPE));
|
190
190
|
DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_sequences (nbSeq=%zu)", nbSeq);
|
191
|
-
|
191
|
+
ZSTD_memset(workspace, 0, wkspSize);
|
192
192
|
|
193
193
|
fseMetadata->lastCountSize = 0;
|
194
194
|
/* convert length/distances into codes */
|
@@ -348,7 +348,7 @@ static size_t ZSTD_compressSubBlock_literal(const HUF_CElt* hufTable,
|
|
348
348
|
assert(hufMetadata->hType == set_compressed || hufMetadata->hType == set_repeat);
|
349
349
|
|
350
350
|
if (writeEntropy && hufMetadata->hType == set_compressed) {
|
351
|
-
|
351
|
+
ZSTD_memcpy(op, hufMetadata->hufDesBuffer, hufMetadata->hufDesSize);
|
352
352
|
op += hufMetadata->hufDesSize;
|
353
353
|
cLitSize += hufMetadata->hufDesSize;
|
354
354
|
DEBUGLOG(5, "ZSTD_compressSubBlock_literal (hSize=%zu)", hufMetadata->hufDesSize);
|
@@ -474,7 +474,7 @@ static size_t ZSTD_compressSubBlock_sequences(const ZSTD_fseCTables_t* fseTables
|
|
474
474
|
const U32 MLtype = fseMetadata->mlType;
|
475
475
|
DEBUGLOG(5, "ZSTD_compressSubBlock_sequences (fseTablesSize=%zu)", fseMetadata->fseTablesSize);
|
476
476
|
*seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
|
477
|
-
|
477
|
+
ZSTD_memcpy(op, fseMetadata->fseTablesBuffer, fseMetadata->fseTablesSize);
|
478
478
|
op += fseMetadata->fseTablesSize;
|
479
479
|
} else {
|
480
480
|
const U32 repeat = set_repeat;
|
@@ -603,7 +603,7 @@ static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type,
|
|
603
603
|
const BYTE* codeTable, unsigned maxCode,
|
604
604
|
size_t nbSeq, const FSE_CTable* fseCTable,
|
605
605
|
const U32* additionalBits,
|
606
|
-
short const* defaultNorm, U32 defaultNormLog,
|
606
|
+
short const* defaultNorm, U32 defaultNormLog, U32 defaultMax,
|
607
607
|
void* workspace, size_t wkspSize)
|
608
608
|
{
|
609
609
|
unsigned* const countWksp = (unsigned*)workspace;
|
@@ -615,7 +615,11 @@ static size_t ZSTD_estimateSubBlockSize_symbolType(symbolEncodingType_e type,
|
|
615
615
|
|
616
616
|
HIST_countFast_wksp(countWksp, &max, codeTable, nbSeq, workspace, wkspSize); /* can't fail */
|
617
617
|
if (type == set_basic) {
|
618
|
-
|
618
|
+
/* We selected this encoding type, so it must be valid. */
|
619
|
+
assert(max <= defaultMax);
|
620
|
+
cSymbolTypeSizeEstimateInBits = max <= defaultMax
|
621
|
+
? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, countWksp, max)
|
622
|
+
: ERROR(GENERIC);
|
619
623
|
} else if (type == set_rle) {
|
620
624
|
cSymbolTypeSizeEstimateInBits = 0;
|
621
625
|
} else if (type == set_compressed || type == set_repeat) {
|
@@ -643,15 +647,15 @@ static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable,
|
|
643
647
|
size_t cSeqSizeEstimate = 0;
|
644
648
|
cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff,
|
645
649
|
nbSeq, fseTables->offcodeCTable, NULL,
|
646
|
-
OF_defaultNorm, OF_defaultNormLog,
|
650
|
+
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
|
647
651
|
workspace, wkspSize);
|
648
652
|
cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->llType, llCodeTable, MaxLL,
|
649
653
|
nbSeq, fseTables->litlengthCTable, LL_bits,
|
650
|
-
LL_defaultNorm, LL_defaultNormLog,
|
654
|
+
LL_defaultNorm, LL_defaultNormLog, MaxLL,
|
651
655
|
workspace, wkspSize);
|
652
656
|
cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->mlType, mlCodeTable, MaxML,
|
653
657
|
nbSeq, fseTables->matchlengthCTable, ML_bits,
|
654
|
-
ML_defaultNorm, ML_defaultNormLog,
|
658
|
+
ML_defaultNorm, ML_defaultNormLog, MaxML,
|
655
659
|
workspace, wkspSize);
|
656
660
|
if (writeEntropy) cSeqSizeEstimate += fseMetadata->fseTablesSize;
|
657
661
|
return cSeqSizeEstimate + sequencesSectionHeaderSize;
|
@@ -790,7 +794,7 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
|
|
790
794
|
} while (!lastSequence);
|
791
795
|
if (writeLitEntropy) {
|
792
796
|
DEBUGLOG(5, "ZSTD_compressSubBlock_multi has literal entropy tables unwritten");
|
793
|
-
|
797
|
+
ZSTD_memcpy(&nextCBlock->entropy.huf, &prevCBlock->entropy.huf, sizeof(prevCBlock->entropy.huf));
|
794
798
|
}
|
795
799
|
if (writeSeqEntropy && ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) {
|
796
800
|
/* If we haven't written our entropy tables, then we've violated our contract and
|
@@ -809,11 +813,11 @@ static size_t ZSTD_compressSubBlock_multi(const seqStore_t* seqStorePtr,
|
|
809
813
|
if (sp < send) {
|
810
814
|
seqDef const* seq;
|
811
815
|
repcodes_t rep;
|
812
|
-
|
816
|
+
ZSTD_memcpy(&rep, prevCBlock->rep, sizeof(rep));
|
813
817
|
for (seq = sstart; seq < sp; ++seq) {
|
814
818
|
rep = ZSTD_updateRep(rep.rep, seq->offset - 1, ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0);
|
815
819
|
}
|
816
|
-
|
820
|
+
ZSTD_memcpy(nextCBlock->rep, &rep, sizeof(rep));
|
817
821
|
}
|
818
822
|
}
|
819
823
|
DEBUGLOG(5, "ZSTD_compressSubBlock_multi compressed");
|
@@ -831,7 +835,7 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
|
|
831
835
|
&zc->blockState.nextCBlock->entropy,
|
832
836
|
&zc->appliedParams,
|
833
837
|
&entropyMetadata,
|
834
|
-
zc->entropyWorkspace,
|
838
|
+
zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */), "");
|
835
839
|
|
836
840
|
return ZSTD_compressSubBlock_multi(&zc->seqStore,
|
837
841
|
zc->blockState.prevCBlock,
|
@@ -841,5 +845,5 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
|
|
841
845
|
dst, dstCapacity,
|
842
846
|
src, srcSize,
|
843
847
|
zc->bmi2, lastBlock,
|
844
|
-
zc->entropyWorkspace,
|
848
|
+
zc->entropyWorkspace, ENTROPY_WORKSPACE_SIZE /* statically allocated in resetCCtx */);
|
845
849
|
}
|