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