zstd-ruby 1.4.9.0 → 1.5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +8 -0
- data/README.md +1 -1
- data/ext/zstdruby/libzstd/BUCK +5 -7
- data/ext/zstdruby/libzstd/Makefile +42 -13
- data/ext/zstdruby/libzstd/README.md +8 -4
- data/ext/zstdruby/libzstd/common/bitstream.h +1 -1
- data/ext/zstdruby/libzstd/common/compiler.h +1 -1
- data/ext/zstdruby/libzstd/common/cpu.h +1 -1
- data/ext/zstdruby/libzstd/common/debug.c +1 -1
- data/ext/zstdruby/libzstd/common/debug.h +1 -1
- data/ext/zstdruby/libzstd/common/entropy_common.c +1 -1
- data/ext/zstdruby/libzstd/common/error_private.c +1 -1
- data/ext/zstdruby/libzstd/common/error_private.h +3 -3
- data/ext/zstdruby/libzstd/common/fse.h +2 -2
- data/ext/zstdruby/libzstd/common/fse_decompress.c +25 -15
- data/ext/zstdruby/libzstd/common/huf.h +3 -2
- data/ext/zstdruby/libzstd/common/mem.h +3 -5
- data/ext/zstdruby/libzstd/common/pool.c +1 -1
- data/ext/zstdruby/libzstd/common/pool.h +1 -1
- data/ext/zstdruby/libzstd/common/xxhash.c +2 -4
- data/ext/zstdruby/libzstd/common/xxhash.h +1 -1
- data/ext/zstdruby/libzstd/common/zstd_common.c +1 -1
- data/ext/zstdruby/libzstd/common/zstd_deps.h +1 -1
- data/ext/zstdruby/libzstd/common/zstd_internal.h +21 -9
- data/ext/zstdruby/libzstd/common/zstd_trace.h +7 -5
- data/ext/zstdruby/libzstd/compress/fse_compress.c +1 -1
- data/ext/zstdruby/libzstd/compress/hist.c +1 -1
- data/ext/zstdruby/libzstd/compress/hist.h +1 -1
- data/ext/zstdruby/libzstd/compress/huf_compress.c +51 -28
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +1373 -275
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +164 -21
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +14 -6
- data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +5 -282
- data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +147 -46
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +3 -3
- data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +4 -4
- data/ext/zstdruby/libzstd/compress/zstd_fast.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_lazy.c +914 -142
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +39 -1
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +51 -15
- data/ext/zstdruby/libzstd/compress/zstd_ldm.h +2 -1
- data/ext/zstdruby/libzstd/compress/zstd_ldm_geartab.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +15 -6
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +5 -5
- data/ext/zstdruby/libzstd/decompress/huf_decompress.c +44 -43
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +1 -1
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +1 -1
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +3 -4
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +44 -36
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +1 -1
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +1 -2
- data/ext/zstdruby/libzstd/deprecated/zbuff.h +1 -1
- data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +1 -1
- data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -1
- data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -1
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +7 -6
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +6 -5
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +7 -6
- data/ext/zstdruby/libzstd/dictBuilder/zdict.c +8 -7
- data/ext/zstdruby/libzstd/dll/example/Makefile +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v01.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v02.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v03.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v04.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v05.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v06.h +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +1 -1
- data/ext/zstdruby/libzstd/legacy/zstd_v07.h +1 -1
- data/ext/zstdruby/libzstd/{dictBuilder/zdict.h → zdict.h} +148 -2
- data/ext/zstdruby/libzstd/zstd.h +165 -83
- data/ext/zstdruby/libzstd/{common/zstd_errors.h → zstd_errors.h} +1 -1
- data/lib/zstd-ruby/version.rb +1 -1
- metadata +5 -5
- data/ext/zstdruby/libzstd/common/zstd_trace.c +0 -42
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c)
|
2
|
+
* Copyright (c) Yann Collet, Facebook, Inc.
|
3
3
|
* All rights reserved.
|
4
4
|
*
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
@@ -19,7 +19,6 @@
|
|
19
19
|
* Dependencies
|
20
20
|
***************************************/
|
21
21
|
#include "../common/zstd_internal.h"
|
22
|
-
#include "../common/zstd_trace.h" /* ZSTD_TraceCtx */
|
23
22
|
#include "zstd_cwksp.h"
|
24
23
|
#ifdef ZSTD_MULTITHREAD
|
25
24
|
# include "zstdmt_compress.h"
|
@@ -82,6 +81,53 @@ typedef struct {
|
|
82
81
|
ZSTD_fseCTables_t fse;
|
83
82
|
} ZSTD_entropyCTables_t;
|
84
83
|
|
84
|
+
/***********************************************
|
85
|
+
* Entropy buffer statistics structs and funcs *
|
86
|
+
***********************************************/
|
87
|
+
/** ZSTD_hufCTablesMetadata_t :
|
88
|
+
* Stores Literals Block Type for a super-block in hType, and
|
89
|
+
* huffman tree description in hufDesBuffer.
|
90
|
+
* hufDesSize refers to the size of huffman tree description in bytes.
|
91
|
+
* This metadata is populated in ZSTD_buildBlockEntropyStats_literals() */
|
92
|
+
typedef struct {
|
93
|
+
symbolEncodingType_e hType;
|
94
|
+
BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
|
95
|
+
size_t hufDesSize;
|
96
|
+
} ZSTD_hufCTablesMetadata_t;
|
97
|
+
|
98
|
+
/** ZSTD_fseCTablesMetadata_t :
|
99
|
+
* Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and
|
100
|
+
* fse tables in fseTablesBuffer.
|
101
|
+
* fseTablesSize refers to the size of fse tables in bytes.
|
102
|
+
* This metadata is populated in ZSTD_buildBlockEntropyStats_sequences() */
|
103
|
+
typedef struct {
|
104
|
+
symbolEncodingType_e llType;
|
105
|
+
symbolEncodingType_e ofType;
|
106
|
+
symbolEncodingType_e mlType;
|
107
|
+
BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
|
108
|
+
size_t fseTablesSize;
|
109
|
+
size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */
|
110
|
+
} ZSTD_fseCTablesMetadata_t;
|
111
|
+
|
112
|
+
typedef struct {
|
113
|
+
ZSTD_hufCTablesMetadata_t hufMetadata;
|
114
|
+
ZSTD_fseCTablesMetadata_t fseMetadata;
|
115
|
+
} ZSTD_entropyCTablesMetadata_t;
|
116
|
+
|
117
|
+
/** ZSTD_buildBlockEntropyStats() :
|
118
|
+
* Builds entropy for the block.
|
119
|
+
* @return : 0 on success or error code */
|
120
|
+
size_t ZSTD_buildBlockEntropyStats(seqStore_t* seqStorePtr,
|
121
|
+
const ZSTD_entropyCTables_t* prevEntropy,
|
122
|
+
ZSTD_entropyCTables_t* nextEntropy,
|
123
|
+
const ZSTD_CCtx_params* cctxParams,
|
124
|
+
ZSTD_entropyCTablesMetadata_t* entropyMetadata,
|
125
|
+
void* workspace, size_t wkspSize);
|
126
|
+
|
127
|
+
/*********************************
|
128
|
+
* Compression internals structs *
|
129
|
+
*********************************/
|
130
|
+
|
85
131
|
typedef struct {
|
86
132
|
U32 off; /* Offset code (offset + ZSTD_REP_MOVE) for the match */
|
87
133
|
U32 len; /* Raw length of match */
|
@@ -142,14 +188,21 @@ typedef struct {
|
|
142
188
|
} ZSTD_compressedBlockState_t;
|
143
189
|
|
144
190
|
typedef struct {
|
145
|
-
BYTE const* nextSrc;
|
146
|
-
BYTE const* base;
|
147
|
-
BYTE const* dictBase;
|
148
|
-
U32 dictLimit;
|
149
|
-
U32 lowLimit;
|
191
|
+
BYTE const* nextSrc; /* next block here to continue on current prefix */
|
192
|
+
BYTE const* base; /* All regular indexes relative to this position */
|
193
|
+
BYTE const* dictBase; /* extDict indexes relative to this position */
|
194
|
+
U32 dictLimit; /* below that point, need extDict */
|
195
|
+
U32 lowLimit; /* below that point, no more valid data */
|
196
|
+
U32 nbOverflowCorrections; /* Number of times overflow correction has run since
|
197
|
+
* ZSTD_window_init(). Useful for debugging coredumps
|
198
|
+
* and for ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY.
|
199
|
+
*/
|
150
200
|
} ZSTD_window_t;
|
151
201
|
|
152
202
|
typedef struct ZSTD_matchState_t ZSTD_matchState_t;
|
203
|
+
|
204
|
+
#define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */
|
205
|
+
|
153
206
|
struct ZSTD_matchState_t {
|
154
207
|
ZSTD_window_t window; /* State for window round buffer management */
|
155
208
|
U32 loadedDictEnd; /* index of end of dictionary, within context's referential.
|
@@ -161,9 +214,17 @@ struct ZSTD_matchState_t {
|
|
161
214
|
*/
|
162
215
|
U32 nextToUpdate; /* index from which to continue table update */
|
163
216
|
U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */
|
217
|
+
|
218
|
+
U32 rowHashLog; /* For row-based matchfinder: Hashlog based on nb of rows in the hashTable.*/
|
219
|
+
U16* tagTable; /* For row-based matchFinder: A row-based table containing the hashes and head index. */
|
220
|
+
U32 hashCache[ZSTD_ROW_HASH_CACHE_SIZE]; /* For row-based matchFinder: a cache of hashes to improve speed */
|
221
|
+
|
164
222
|
U32* hashTable;
|
165
223
|
U32* hashTable3;
|
166
224
|
U32* chainTable;
|
225
|
+
|
226
|
+
U32 forceNonContiguous; /* Non-zero if we should force non-contiguous load for the next window update. */
|
227
|
+
|
167
228
|
int dedicatedDictSearch; /* Indicates whether this matchState is using the
|
168
229
|
* dedicated dictionary search structure.
|
169
230
|
*/
|
@@ -256,6 +317,15 @@ struct ZSTD_CCtx_params_s {
|
|
256
317
|
ZSTD_sequenceFormat_e blockDelimiters;
|
257
318
|
int validateSequences;
|
258
319
|
|
320
|
+
/* Block splitting */
|
321
|
+
int splitBlocks;
|
322
|
+
|
323
|
+
/* Param for deciding whether to use row-based matchfinder */
|
324
|
+
ZSTD_useRowMatchFinderMode_e useRowMatchFinder;
|
325
|
+
|
326
|
+
/* Always load a dictionary in ext-dict mode (not prefix mode)? */
|
327
|
+
int deterministicRefPrefix;
|
328
|
+
|
259
329
|
/* Internal use, for createCCtxParams() and freeCCtxParams() only */
|
260
330
|
ZSTD_customMem customMem;
|
261
331
|
}; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
|
@@ -279,6 +349,7 @@ struct ZSTD_CCtx_s {
|
|
279
349
|
int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */
|
280
350
|
ZSTD_CCtx_params requestedParams;
|
281
351
|
ZSTD_CCtx_params appliedParams;
|
352
|
+
ZSTD_CCtx_params simpleApiParams; /* Param storage used by the simple API - not sticky. Must only be used in top-level simple API functions for storage. */
|
282
353
|
U32 dictID;
|
283
354
|
size_t dictContentSize;
|
284
355
|
|
@@ -371,7 +442,7 @@ typedef enum {
|
|
371
442
|
typedef size_t (*ZSTD_blockCompressor) (
|
372
443
|
ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
373
444
|
void const* src, size_t srcSize);
|
374
|
-
ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode);
|
445
|
+
ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_useRowMatchFinderMode_e rowMatchfinderMode, ZSTD_dictMode_e dictMode);
|
375
446
|
|
376
447
|
|
377
448
|
MEM_STATIC U32 ZSTD_LLcode(U32 litLength)
|
@@ -548,8 +619,8 @@ void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* litera
|
|
548
619
|
|
549
620
|
/* literal Length */
|
550
621
|
if (litLength>0xFFFF) {
|
551
|
-
assert(seqStorePtr->
|
552
|
-
seqStorePtr->
|
622
|
+
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
|
623
|
+
seqStorePtr->longLengthType = ZSTD_llt_literalLength;
|
553
624
|
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
554
625
|
}
|
555
626
|
seqStorePtr->sequences[0].litLength = (U16)litLength;
|
@@ -559,8 +630,8 @@ void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* litera
|
|
559
630
|
|
560
631
|
/* match Length */
|
561
632
|
if (mlBase>0xFFFF) {
|
562
|
-
assert(seqStorePtr->
|
563
|
-
seqStorePtr->
|
633
|
+
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
|
634
|
+
seqStorePtr->longLengthType = ZSTD_llt_matchLength;
|
564
635
|
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
565
636
|
}
|
566
637
|
seqStorePtr->sequences[0].matchLength = (U16)mlBase;
|
@@ -811,6 +882,13 @@ MEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window)
|
|
811
882
|
window->dictLimit = end;
|
812
883
|
}
|
813
884
|
|
885
|
+
MEM_STATIC U32 ZSTD_window_isEmpty(ZSTD_window_t const window)
|
886
|
+
{
|
887
|
+
return window.dictLimit == 1 &&
|
888
|
+
window.lowLimit == 1 &&
|
889
|
+
(window.nextSrc - window.base) == 1;
|
890
|
+
}
|
891
|
+
|
814
892
|
/**
|
815
893
|
* ZSTD_window_hasExtDict():
|
816
894
|
* Returns non-zero if the window has a non-empty extDict.
|
@@ -834,15 +912,69 @@ MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)
|
|
834
912
|
ZSTD_noDict;
|
835
913
|
}
|
836
914
|
|
915
|
+
/* Defining this macro to non-zero tells zstd to run the overflow correction
|
916
|
+
* code much more frequently. This is very inefficient, and should only be
|
917
|
+
* used for tests and fuzzers.
|
918
|
+
*/
|
919
|
+
#ifndef ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY
|
920
|
+
# ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
921
|
+
# define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 1
|
922
|
+
# else
|
923
|
+
# define ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY 0
|
924
|
+
# endif
|
925
|
+
#endif
|
926
|
+
|
927
|
+
/**
|
928
|
+
* ZSTD_window_canOverflowCorrect():
|
929
|
+
* Returns non-zero if the indices are large enough for overflow correction
|
930
|
+
* to work correctly without impacting compression ratio.
|
931
|
+
*/
|
932
|
+
MEM_STATIC U32 ZSTD_window_canOverflowCorrect(ZSTD_window_t const window,
|
933
|
+
U32 cycleLog,
|
934
|
+
U32 maxDist,
|
935
|
+
U32 loadedDictEnd,
|
936
|
+
void const* src)
|
937
|
+
{
|
938
|
+
U32 const cycleSize = 1u << cycleLog;
|
939
|
+
U32 const curr = (U32)((BYTE const*)src - window.base);
|
940
|
+
U32 const minIndexToOverflowCorrect = cycleSize + MAX(maxDist, cycleSize);
|
941
|
+
|
942
|
+
/* Adjust the min index to backoff the overflow correction frequency,
|
943
|
+
* so we don't waste too much CPU in overflow correction. If this
|
944
|
+
* computation overflows we don't really care, we just need to make
|
945
|
+
* sure it is at least minIndexToOverflowCorrect.
|
946
|
+
*/
|
947
|
+
U32 const adjustment = window.nbOverflowCorrections + 1;
|
948
|
+
U32 const adjustedIndex = MAX(minIndexToOverflowCorrect * adjustment,
|
949
|
+
minIndexToOverflowCorrect);
|
950
|
+
U32 const indexLargeEnough = curr > adjustedIndex;
|
951
|
+
|
952
|
+
/* Only overflow correct early if the dictionary is invalidated already,
|
953
|
+
* so we don't hurt compression ratio.
|
954
|
+
*/
|
955
|
+
U32 const dictionaryInvalidated = curr > maxDist + loadedDictEnd;
|
956
|
+
|
957
|
+
return indexLargeEnough && dictionaryInvalidated;
|
958
|
+
}
|
959
|
+
|
837
960
|
/**
|
838
961
|
* ZSTD_window_needOverflowCorrection():
|
839
962
|
* Returns non-zero if the indices are getting too large and need overflow
|
840
963
|
* protection.
|
841
964
|
*/
|
842
965
|
MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
|
966
|
+
U32 cycleLog,
|
967
|
+
U32 maxDist,
|
968
|
+
U32 loadedDictEnd,
|
969
|
+
void const* src,
|
843
970
|
void const* srcEnd)
|
844
971
|
{
|
845
972
|
U32 const curr = (U32)((BYTE const*)srcEnd - window.base);
|
973
|
+
if (ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) {
|
974
|
+
if (ZSTD_window_canOverflowCorrect(window, cycleLog, maxDist, loadedDictEnd, src)) {
|
975
|
+
return 1;
|
976
|
+
}
|
977
|
+
}
|
846
978
|
return curr > ZSTD_CURRENT_MAX;
|
847
979
|
}
|
848
980
|
|
@@ -854,7 +986,6 @@ MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
|
|
854
986
|
*
|
855
987
|
* The least significant cycleLog bits of the indices must remain the same,
|
856
988
|
* which may be 0. Every index up to maxDist in the past must be valid.
|
857
|
-
* NOTE: (maxDist & cycleMask) must be zero.
|
858
989
|
*/
|
859
990
|
MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
|
860
991
|
U32 maxDist, void const* src)
|
@@ -878,17 +1009,25 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
|
|
878
1009
|
* 3. (cctx->lowLimit + 1<<windowLog) < 1<<32:
|
879
1010
|
* windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.
|
880
1011
|
*/
|
881
|
-
U32 const
|
1012
|
+
U32 const cycleSize = 1u << cycleLog;
|
1013
|
+
U32 const cycleMask = cycleSize - 1;
|
882
1014
|
U32 const curr = (U32)((BYTE const*)src - window->base);
|
883
1015
|
U32 const currentCycle0 = curr & cycleMask;
|
884
1016
|
/* Exclude zero so that newCurrent - maxDist >= 1. */
|
885
|
-
U32 const currentCycle1 = currentCycle0 == 0 ?
|
886
|
-
U32 const newCurrent = currentCycle1 + maxDist;
|
1017
|
+
U32 const currentCycle1 = currentCycle0 == 0 ? cycleSize : currentCycle0;
|
1018
|
+
U32 const newCurrent = currentCycle1 + MAX(maxDist, cycleSize);
|
887
1019
|
U32 const correction = curr - newCurrent;
|
888
|
-
|
1020
|
+
/* maxDist must be a power of two so that:
|
1021
|
+
* (newCurrent & cycleMask) == (curr & cycleMask)
|
1022
|
+
* This is required to not corrupt the chains / binary tree.
|
1023
|
+
*/
|
1024
|
+
assert((maxDist & (maxDist - 1)) == 0);
|
1025
|
+
assert((curr & cycleMask) == (newCurrent & cycleMask));
|
889
1026
|
assert(curr > newCurrent);
|
890
|
-
|
891
|
-
|
1027
|
+
if (!ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY) {
|
1028
|
+
/* Loose bound, should be around 1<<29 (see above) */
|
1029
|
+
assert(correction > 1<<28);
|
1030
|
+
}
|
892
1031
|
|
893
1032
|
window->base += correction;
|
894
1033
|
window->dictBase += correction;
|
@@ -904,6 +1043,8 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
|
|
904
1043
|
assert(window->lowLimit <= newCurrent);
|
905
1044
|
assert(window->dictLimit <= newCurrent);
|
906
1045
|
|
1046
|
+
++window->nbOverflowCorrections;
|
1047
|
+
|
907
1048
|
DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction,
|
908
1049
|
window->lowLimit);
|
909
1050
|
return correction;
|
@@ -1013,6 +1154,7 @@ MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
|
|
1013
1154
|
window->dictLimit = 1; /* start from 1, so that 1st position is valid */
|
1014
1155
|
window->lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
|
1015
1156
|
window->nextSrc = window->base + 1; /* see issue #1241 */
|
1157
|
+
window->nbOverflowCorrections = 0;
|
1016
1158
|
}
|
1017
1159
|
|
1018
1160
|
/**
|
@@ -1023,7 +1165,8 @@ MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
|
|
1023
1165
|
* Returns non-zero if the segment is contiguous.
|
1024
1166
|
*/
|
1025
1167
|
MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
|
1026
|
-
void const* src, size_t srcSize
|
1168
|
+
void const* src, size_t srcSize,
|
1169
|
+
int forceNonContiguous)
|
1027
1170
|
{
|
1028
1171
|
BYTE const* const ip = (BYTE const*)src;
|
1029
1172
|
U32 contiguous = 1;
|
@@ -1033,7 +1176,7 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
|
|
1033
1176
|
assert(window->base != NULL);
|
1034
1177
|
assert(window->dictBase != NULL);
|
1035
1178
|
/* Check if blocks follow each other */
|
1036
|
-
if (src != window->nextSrc) {
|
1179
|
+
if (src != window->nextSrc || forceNonContiguous) {
|
1037
1180
|
/* not contiguous */
|
1038
1181
|
size_t const distanceFromBase = (size_t)(window->nextSrc - window->base);
|
1039
1182
|
DEBUGLOG(5, "Non contiguous blocks, new segment starts at %u", window->dictLimit);
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c)
|
2
|
+
* Copyright (c) Yann Collet, Facebook, Inc.
|
3
3
|
* All rights reserved.
|
4
4
|
*
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
@@ -117,7 +117,7 @@ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
|
|
117
117
|
}
|
118
118
|
}
|
119
119
|
|
120
|
-
if ((cLitSize==0)
|
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
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c)
|
2
|
+
* Copyright (c) Yann Collet, Facebook, Inc.
|
3
3
|
* All rights reserved.
|
4
4
|
*
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
@@ -85,6 +85,8 @@ static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t
|
|
85
85
|
{
|
86
86
|
unsigned cost = 0;
|
87
87
|
unsigned s;
|
88
|
+
|
89
|
+
assert(total > 0);
|
88
90
|
for (s = 0; s <= max; ++s) {
|
89
91
|
unsigned norm = (unsigned)((256 * count[s]) / total);
|
90
92
|
if (count[s] != 0 && norm == 0)
|
@@ -232,6 +234,11 @@ ZSTD_selectEncodingType(
|
|
232
234
|
return set_compressed;
|
233
235
|
}
|
234
236
|
|
237
|
+
typedef struct {
|
238
|
+
S16 norm[MaxSeq + 1];
|
239
|
+
U32 wksp[FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(MaxSeq, MaxFSELog)];
|
240
|
+
} ZSTD_BuildCTableWksp;
|
241
|
+
|
235
242
|
size_t
|
236
243
|
ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
237
244
|
FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
|
@@ -258,7 +265,7 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
|
258
265
|
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize), ""); /* note : could be pre-calculated */
|
259
266
|
return 0;
|
260
267
|
case set_compressed: {
|
261
|
-
|
268
|
+
ZSTD_BuildCTableWksp* wksp = (ZSTD_BuildCTableWksp*)entropyWorkspace;
|
262
269
|
size_t nbSeq_1 = nbSeq;
|
263
270
|
const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
|
264
271
|
if (count[codeTable[nbSeq-1]] > 1) {
|
@@ -266,11 +273,12 @@ ZSTD_buildCTable(void* dst, size_t dstCapacity,
|
|
266
273
|
nbSeq_1--;
|
267
274
|
}
|
268
275
|
assert(nbSeq_1 > 1);
|
269
|
-
assert(entropyWorkspaceSize >=
|
270
|
-
|
271
|
-
|
276
|
+
assert(entropyWorkspaceSize >= sizeof(ZSTD_BuildCTableWksp));
|
277
|
+
(void)entropyWorkspaceSize;
|
278
|
+
FORWARD_IF_ERROR(FSE_normalizeCount(wksp->norm, tableLog, count, nbSeq_1, max, ZSTD_useLowProbCount(nbSeq_1)), "");
|
279
|
+
{ size_t const NCountSize = FSE_writeNCount(op, oend - op, wksp->norm, max, tableLog); /* overflow protected */
|
272
280
|
FORWARD_IF_ERROR(NCountSize, "FSE_writeNCount failed");
|
273
|
-
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog,
|
281
|
+
FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, wksp->norm, max, tableLog, wksp->wksp, sizeof(wksp->wksp)), "");
|
274
282
|
return NCountSize;
|
275
283
|
}
|
276
284
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*
|
2
|
-
* Copyright (c)
|
2
|
+
* Copyright (c) Yann Collet, Facebook, Inc.
|
3
3
|
* All rights reserved.
|
4
4
|
*
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
@@ -15,288 +15,10 @@
|
|
15
15
|
|
16
16
|
#include "../common/zstd_internal.h" /* ZSTD_getSequenceLength */
|
17
17
|
#include "hist.h" /* HIST_countFast_wksp */
|
18
|
-
#include "zstd_compress_internal.h"
|
18
|
+
#include "zstd_compress_internal.h" /* ZSTD_[huf|fse|entropy]CTablesMetadata_t */
|
19
19
|
#include "zstd_compress_sequences.h"
|
20
20
|
#include "zstd_compress_literals.h"
|
21
21
|
|
22
|
-
/*-*************************************
|
23
|
-
* Superblock entropy buffer structs
|
24
|
-
***************************************/
|
25
|
-
/** ZSTD_hufCTablesMetadata_t :
|
26
|
-
* Stores Literals Block Type for a super-block in hType, and
|
27
|
-
* huffman tree description in hufDesBuffer.
|
28
|
-
* hufDesSize refers to the size of huffman tree description in bytes.
|
29
|
-
* This metadata is populated in ZSTD_buildSuperBlockEntropy_literal() */
|
30
|
-
typedef struct {
|
31
|
-
symbolEncodingType_e hType;
|
32
|
-
BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
|
33
|
-
size_t hufDesSize;
|
34
|
-
} ZSTD_hufCTablesMetadata_t;
|
35
|
-
|
36
|
-
/** ZSTD_fseCTablesMetadata_t :
|
37
|
-
* Stores symbol compression modes for a super-block in {ll, ol, ml}Type, and
|
38
|
-
* fse tables in fseTablesBuffer.
|
39
|
-
* fseTablesSize refers to the size of fse tables in bytes.
|
40
|
-
* This metadata is populated in ZSTD_buildSuperBlockEntropy_sequences() */
|
41
|
-
typedef struct {
|
42
|
-
symbolEncodingType_e llType;
|
43
|
-
symbolEncodingType_e ofType;
|
44
|
-
symbolEncodingType_e mlType;
|
45
|
-
BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
|
46
|
-
size_t fseTablesSize;
|
47
|
-
size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_compressSubBlock_sequences() */
|
48
|
-
} ZSTD_fseCTablesMetadata_t;
|
49
|
-
|
50
|
-
typedef struct {
|
51
|
-
ZSTD_hufCTablesMetadata_t hufMetadata;
|
52
|
-
ZSTD_fseCTablesMetadata_t fseMetadata;
|
53
|
-
} ZSTD_entropyCTablesMetadata_t;
|
54
|
-
|
55
|
-
|
56
|
-
/** ZSTD_buildSuperBlockEntropy_literal() :
|
57
|
-
* Builds entropy for the super-block literals.
|
58
|
-
* Stores literals block type (raw, rle, compressed, repeat) and
|
59
|
-
* huffman description table to hufMetadata.
|
60
|
-
* @return : size of huffman description table or error code */
|
61
|
-
static size_t ZSTD_buildSuperBlockEntropy_literal(void* const src, size_t srcSize,
|
62
|
-
const ZSTD_hufCTables_t* prevHuf,
|
63
|
-
ZSTD_hufCTables_t* nextHuf,
|
64
|
-
ZSTD_hufCTablesMetadata_t* hufMetadata,
|
65
|
-
const int disableLiteralsCompression,
|
66
|
-
void* workspace, size_t wkspSize)
|
67
|
-
{
|
68
|
-
BYTE* const wkspStart = (BYTE*)workspace;
|
69
|
-
BYTE* const wkspEnd = wkspStart + wkspSize;
|
70
|
-
BYTE* const countWkspStart = wkspStart;
|
71
|
-
unsigned* const countWksp = (unsigned*)workspace;
|
72
|
-
const size_t countWkspSize = (HUF_SYMBOLVALUE_MAX + 1) * sizeof(unsigned);
|
73
|
-
BYTE* const nodeWksp = countWkspStart + countWkspSize;
|
74
|
-
const size_t nodeWkspSize = wkspEnd-nodeWksp;
|
75
|
-
unsigned maxSymbolValue = 255;
|
76
|
-
unsigned huffLog = HUF_TABLELOG_DEFAULT;
|
77
|
-
HUF_repeat repeat = prevHuf->repeatMode;
|
78
|
-
|
79
|
-
DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_literal (srcSize=%zu)", srcSize);
|
80
|
-
|
81
|
-
/* Prepare nextEntropy assuming reusing the existing table */
|
82
|
-
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
83
|
-
|
84
|
-
if (disableLiteralsCompression) {
|
85
|
-
DEBUGLOG(5, "set_basic - disabled");
|
86
|
-
hufMetadata->hType = set_basic;
|
87
|
-
return 0;
|
88
|
-
}
|
89
|
-
|
90
|
-
/* small ? don't even attempt compression (speed opt) */
|
91
|
-
# define COMPRESS_LITERALS_SIZE_MIN 63
|
92
|
-
{ size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
|
93
|
-
if (srcSize <= minLitSize) {
|
94
|
-
DEBUGLOG(5, "set_basic - too small");
|
95
|
-
hufMetadata->hType = set_basic;
|
96
|
-
return 0;
|
97
|
-
}
|
98
|
-
}
|
99
|
-
|
100
|
-
/* Scan input and build symbol stats */
|
101
|
-
{ size_t const largest = HIST_count_wksp (countWksp, &maxSymbolValue, (const BYTE*)src, srcSize, workspace, wkspSize);
|
102
|
-
FORWARD_IF_ERROR(largest, "HIST_count_wksp failed");
|
103
|
-
if (largest == srcSize) {
|
104
|
-
DEBUGLOG(5, "set_rle");
|
105
|
-
hufMetadata->hType = set_rle;
|
106
|
-
return 0;
|
107
|
-
}
|
108
|
-
if (largest <= (srcSize >> 7)+4) {
|
109
|
-
DEBUGLOG(5, "set_basic - no gain");
|
110
|
-
hufMetadata->hType = set_basic;
|
111
|
-
return 0;
|
112
|
-
}
|
113
|
-
}
|
114
|
-
|
115
|
-
/* Validate the previous Huffman table */
|
116
|
-
if (repeat == HUF_repeat_check && !HUF_validateCTable((HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue)) {
|
117
|
-
repeat = HUF_repeat_none;
|
118
|
-
}
|
119
|
-
|
120
|
-
/* Build Huffman Tree */
|
121
|
-
ZSTD_memset(nextHuf->CTable, 0, sizeof(nextHuf->CTable));
|
122
|
-
huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
|
123
|
-
{ size_t const maxBits = HUF_buildCTable_wksp((HUF_CElt*)nextHuf->CTable, countWksp,
|
124
|
-
maxSymbolValue, huffLog,
|
125
|
-
nodeWksp, nodeWkspSize);
|
126
|
-
FORWARD_IF_ERROR(maxBits, "HUF_buildCTable_wksp");
|
127
|
-
huffLog = (U32)maxBits;
|
128
|
-
{ /* Build and write the CTable */
|
129
|
-
size_t const newCSize = HUF_estimateCompressedSize(
|
130
|
-
(HUF_CElt*)nextHuf->CTable, countWksp, maxSymbolValue);
|
131
|
-
size_t const hSize = HUF_writeCTable(
|
132
|
-
hufMetadata->hufDesBuffer, sizeof(hufMetadata->hufDesBuffer),
|
133
|
-
(HUF_CElt*)nextHuf->CTable, maxSymbolValue, huffLog);
|
134
|
-
/* Check against repeating the previous CTable */
|
135
|
-
if (repeat != HUF_repeat_none) {
|
136
|
-
size_t const oldCSize = HUF_estimateCompressedSize(
|
137
|
-
(HUF_CElt const*)prevHuf->CTable, countWksp, maxSymbolValue);
|
138
|
-
if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize)) {
|
139
|
-
DEBUGLOG(5, "set_repeat - smaller");
|
140
|
-
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
141
|
-
hufMetadata->hType = set_repeat;
|
142
|
-
return 0;
|
143
|
-
}
|
144
|
-
}
|
145
|
-
if (newCSize + hSize >= srcSize) {
|
146
|
-
DEBUGLOG(5, "set_basic - no gains");
|
147
|
-
ZSTD_memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
|
148
|
-
hufMetadata->hType = set_basic;
|
149
|
-
return 0;
|
150
|
-
}
|
151
|
-
DEBUGLOG(5, "set_compressed (hSize=%u)", (U32)hSize);
|
152
|
-
hufMetadata->hType = set_compressed;
|
153
|
-
nextHuf->repeatMode = HUF_repeat_check;
|
154
|
-
return hSize;
|
155
|
-
}
|
156
|
-
}
|
157
|
-
}
|
158
|
-
|
159
|
-
/** ZSTD_buildSuperBlockEntropy_sequences() :
|
160
|
-
* Builds entropy for the super-block sequences.
|
161
|
-
* Stores symbol compression modes and fse table to fseMetadata.
|
162
|
-
* @return : size of fse tables or error code */
|
163
|
-
static size_t ZSTD_buildSuperBlockEntropy_sequences(seqStore_t* seqStorePtr,
|
164
|
-
const ZSTD_fseCTables_t* prevEntropy,
|
165
|
-
ZSTD_fseCTables_t* nextEntropy,
|
166
|
-
const ZSTD_CCtx_params* cctxParams,
|
167
|
-
ZSTD_fseCTablesMetadata_t* fseMetadata,
|
168
|
-
void* workspace, size_t wkspSize)
|
169
|
-
{
|
170
|
-
BYTE* const wkspStart = (BYTE*)workspace;
|
171
|
-
BYTE* const wkspEnd = wkspStart + wkspSize;
|
172
|
-
BYTE* const countWkspStart = wkspStart;
|
173
|
-
unsigned* const countWksp = (unsigned*)workspace;
|
174
|
-
const size_t countWkspSize = (MaxSeq + 1) * sizeof(unsigned);
|
175
|
-
BYTE* const cTableWksp = countWkspStart + countWkspSize;
|
176
|
-
const size_t cTableWkspSize = wkspEnd-cTableWksp;
|
177
|
-
ZSTD_strategy const strategy = cctxParams->cParams.strategy;
|
178
|
-
FSE_CTable* CTable_LitLength = nextEntropy->litlengthCTable;
|
179
|
-
FSE_CTable* CTable_OffsetBits = nextEntropy->offcodeCTable;
|
180
|
-
FSE_CTable* CTable_MatchLength = nextEntropy->matchlengthCTable;
|
181
|
-
const BYTE* const ofCodeTable = seqStorePtr->ofCode;
|
182
|
-
const BYTE* const llCodeTable = seqStorePtr->llCode;
|
183
|
-
const BYTE* const mlCodeTable = seqStorePtr->mlCode;
|
184
|
-
size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
|
185
|
-
BYTE* const ostart = fseMetadata->fseTablesBuffer;
|
186
|
-
BYTE* const oend = ostart + sizeof(fseMetadata->fseTablesBuffer);
|
187
|
-
BYTE* op = ostart;
|
188
|
-
|
189
|
-
assert(cTableWkspSize >= (1 << MaxFSELog) * sizeof(FSE_FUNCTION_TYPE));
|
190
|
-
DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy_sequences (nbSeq=%zu)", nbSeq);
|
191
|
-
ZSTD_memset(workspace, 0, wkspSize);
|
192
|
-
|
193
|
-
fseMetadata->lastCountSize = 0;
|
194
|
-
/* convert length/distances into codes */
|
195
|
-
ZSTD_seqToCodes(seqStorePtr);
|
196
|
-
/* build CTable for Literal Lengths */
|
197
|
-
{ U32 LLtype;
|
198
|
-
unsigned max = MaxLL;
|
199
|
-
size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, llCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
|
200
|
-
DEBUGLOG(5, "Building LL table");
|
201
|
-
nextEntropy->litlength_repeatMode = prevEntropy->litlength_repeatMode;
|
202
|
-
LLtype = ZSTD_selectEncodingType(&nextEntropy->litlength_repeatMode,
|
203
|
-
countWksp, max, mostFrequent, nbSeq,
|
204
|
-
LLFSELog, prevEntropy->litlengthCTable,
|
205
|
-
LL_defaultNorm, LL_defaultNormLog,
|
206
|
-
ZSTD_defaultAllowed, strategy);
|
207
|
-
assert(set_basic < set_compressed && set_rle < set_compressed);
|
208
|
-
assert(!(LLtype < set_compressed && nextEntropy->litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
209
|
-
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,
|
210
|
-
countWksp, max, llCodeTable, nbSeq, LL_defaultNorm, LL_defaultNormLog, MaxLL,
|
211
|
-
prevEntropy->litlengthCTable, sizeof(prevEntropy->litlengthCTable),
|
212
|
-
cTableWksp, cTableWkspSize);
|
213
|
-
FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for LitLens failed");
|
214
|
-
if (LLtype == set_compressed)
|
215
|
-
fseMetadata->lastCountSize = countSize;
|
216
|
-
op += countSize;
|
217
|
-
fseMetadata->llType = (symbolEncodingType_e) LLtype;
|
218
|
-
} }
|
219
|
-
/* build CTable for Offsets */
|
220
|
-
{ U32 Offtype;
|
221
|
-
unsigned max = MaxOff;
|
222
|
-
size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, ofCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
|
223
|
-
/* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */
|
224
|
-
ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;
|
225
|
-
DEBUGLOG(5, "Building OF table");
|
226
|
-
nextEntropy->offcode_repeatMode = prevEntropy->offcode_repeatMode;
|
227
|
-
Offtype = ZSTD_selectEncodingType(&nextEntropy->offcode_repeatMode,
|
228
|
-
countWksp, max, mostFrequent, nbSeq,
|
229
|
-
OffFSELog, prevEntropy->offcodeCTable,
|
230
|
-
OF_defaultNorm, OF_defaultNormLog,
|
231
|
-
defaultPolicy, strategy);
|
232
|
-
assert(!(Offtype < set_compressed && nextEntropy->offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
233
|
-
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,
|
234
|
-
countWksp, max, ofCodeTable, nbSeq, OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
|
235
|
-
prevEntropy->offcodeCTable, sizeof(prevEntropy->offcodeCTable),
|
236
|
-
cTableWksp, cTableWkspSize);
|
237
|
-
FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for Offsets failed");
|
238
|
-
if (Offtype == set_compressed)
|
239
|
-
fseMetadata->lastCountSize = countSize;
|
240
|
-
op += countSize;
|
241
|
-
fseMetadata->ofType = (symbolEncodingType_e) Offtype;
|
242
|
-
} }
|
243
|
-
/* build CTable for MatchLengths */
|
244
|
-
{ U32 MLtype;
|
245
|
-
unsigned max = MaxML;
|
246
|
-
size_t const mostFrequent = HIST_countFast_wksp(countWksp, &max, mlCodeTable, nbSeq, workspace, wkspSize); /* can't fail */
|
247
|
-
DEBUGLOG(5, "Building ML table (remaining space : %i)", (int)(oend-op));
|
248
|
-
nextEntropy->matchlength_repeatMode = prevEntropy->matchlength_repeatMode;
|
249
|
-
MLtype = ZSTD_selectEncodingType(&nextEntropy->matchlength_repeatMode,
|
250
|
-
countWksp, max, mostFrequent, nbSeq,
|
251
|
-
MLFSELog, prevEntropy->matchlengthCTable,
|
252
|
-
ML_defaultNorm, ML_defaultNormLog,
|
253
|
-
ZSTD_defaultAllowed, strategy);
|
254
|
-
assert(!(MLtype < set_compressed && nextEntropy->matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */
|
255
|
-
{ size_t const countSize = ZSTD_buildCTable(op, oend - op, CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,
|
256
|
-
countWksp, max, mlCodeTable, nbSeq, ML_defaultNorm, ML_defaultNormLog, MaxML,
|
257
|
-
prevEntropy->matchlengthCTable, sizeof(prevEntropy->matchlengthCTable),
|
258
|
-
cTableWksp, cTableWkspSize);
|
259
|
-
FORWARD_IF_ERROR(countSize, "ZSTD_buildCTable for MatchLengths failed");
|
260
|
-
if (MLtype == set_compressed)
|
261
|
-
fseMetadata->lastCountSize = countSize;
|
262
|
-
op += countSize;
|
263
|
-
fseMetadata->mlType = (symbolEncodingType_e) MLtype;
|
264
|
-
} }
|
265
|
-
assert((size_t) (op-ostart) <= sizeof(fseMetadata->fseTablesBuffer));
|
266
|
-
return op-ostart;
|
267
|
-
}
|
268
|
-
|
269
|
-
|
270
|
-
/** ZSTD_buildSuperBlockEntropy() :
|
271
|
-
* Builds entropy for the super-block.
|
272
|
-
* @return : 0 on success or error code */
|
273
|
-
static size_t
|
274
|
-
ZSTD_buildSuperBlockEntropy(seqStore_t* seqStorePtr,
|
275
|
-
const ZSTD_entropyCTables_t* prevEntropy,
|
276
|
-
ZSTD_entropyCTables_t* nextEntropy,
|
277
|
-
const ZSTD_CCtx_params* cctxParams,
|
278
|
-
ZSTD_entropyCTablesMetadata_t* entropyMetadata,
|
279
|
-
void* workspace, size_t wkspSize)
|
280
|
-
{
|
281
|
-
size_t const litSize = seqStorePtr->lit - seqStorePtr->litStart;
|
282
|
-
DEBUGLOG(5, "ZSTD_buildSuperBlockEntropy");
|
283
|
-
entropyMetadata->hufMetadata.hufDesSize =
|
284
|
-
ZSTD_buildSuperBlockEntropy_literal(seqStorePtr->litStart, litSize,
|
285
|
-
&prevEntropy->huf, &nextEntropy->huf,
|
286
|
-
&entropyMetadata->hufMetadata,
|
287
|
-
ZSTD_disableLiteralsCompression(cctxParams),
|
288
|
-
workspace, wkspSize);
|
289
|
-
FORWARD_IF_ERROR(entropyMetadata->hufMetadata.hufDesSize, "ZSTD_buildSuperBlockEntropy_literal failed");
|
290
|
-
entropyMetadata->fseMetadata.fseTablesSize =
|
291
|
-
ZSTD_buildSuperBlockEntropy_sequences(seqStorePtr,
|
292
|
-
&prevEntropy->fse, &nextEntropy->fse,
|
293
|
-
cctxParams,
|
294
|
-
&entropyMetadata->fseMetadata,
|
295
|
-
workspace, wkspSize);
|
296
|
-
FORWARD_IF_ERROR(entropyMetadata->fseMetadata.fseTablesSize, "ZSTD_buildSuperBlockEntropy_sequences failed");
|
297
|
-
return 0;
|
298
|
-
}
|
299
|
-
|
300
22
|
/** ZSTD_compressSubBlock_literal() :
|
301
23
|
* Compresses literals section for a sub-block.
|
302
24
|
* When we have to write the Huffman table we will sometimes choose a header
|
@@ -643,8 +365,9 @@ static size_t ZSTD_estimateSubBlockSize_sequences(const BYTE* ofCodeTable,
|
|
643
365
|
void* workspace, size_t wkspSize,
|
644
366
|
int writeEntropy)
|
645
367
|
{
|
646
|
-
size_t sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
|
368
|
+
size_t const sequencesSectionHeaderSize = 3; /* Use hard coded size of 3 bytes */
|
647
369
|
size_t cSeqSizeEstimate = 0;
|
370
|
+
if (nbSeq == 0) return sequencesSectionHeaderSize;
|
648
371
|
cSeqSizeEstimate += ZSTD_estimateSubBlockSize_symbolType(fseMetadata->ofType, ofCodeTable, MaxOff,
|
649
372
|
nbSeq, fseTables->offcodeCTable, NULL,
|
650
373
|
OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,
|
@@ -830,7 +553,7 @@ size_t ZSTD_compressSuperBlock(ZSTD_CCtx* zc,
|
|
830
553
|
unsigned lastBlock) {
|
831
554
|
ZSTD_entropyCTablesMetadata_t entropyMetadata;
|
832
555
|
|
833
|
-
FORWARD_IF_ERROR(
|
556
|
+
FORWARD_IF_ERROR(ZSTD_buildBlockEntropyStats(&zc->seqStore,
|
834
557
|
&zc->blockState.prevCBlock->entropy,
|
835
558
|
&zc->blockState.nextCBlock->entropy,
|
836
559
|
&zc->appliedParams,
|