extzstd 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +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
|
}
|