multi_compress 0.3.1 → 0.3.3
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/CHANGELOG.md +15 -3
- data/GET_STARTED.md +3 -3
- data/README.md +75 -66
- data/THIRD_PARTY_NOTICES.md +24 -0
- data/ext/multi_compress/brotli_dec_static_init.c +3 -0
- data/ext/multi_compress/brotli_enc_static_init.c +3 -0
- data/ext/multi_compress/extconf.rb +22 -1
- data/ext/multi_compress/multi_compress.c +152 -72
- data/ext/multi_compress/vendor/.vendored +2 -2
- data/ext/multi_compress/vendor/brotli/LICENSE +19 -0
- data/ext/multi_compress/vendor/brotli/c/common/constants.c +7 -7
- data/ext/multi_compress/vendor/brotli/c/common/constants.h +2 -5
- data/ext/multi_compress/vendor/brotli/c/common/context.c +2 -2
- data/ext/multi_compress/vendor/brotli/c/common/context.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/dictionary.c +4 -5856
- data/ext/multi_compress/vendor/brotli/c/common/dictionary.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/dictionary_inc.h +5847 -0
- data/ext/multi_compress/vendor/brotli/c/common/platform.c +0 -4
- data/ext/multi_compress/vendor/brotli/c/common/platform.h +182 -43
- data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary.c +3 -7
- data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary_internal.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/common/static_init.h +56 -0
- data/ext/multi_compress/vendor/brotli/c/common/transform.c +6 -4
- data/ext/multi_compress/vendor/brotli/c/common/transform.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/version.h +3 -3
- data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.c +2 -3
- data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/dec/decode.c +128 -39
- data/ext/multi_compress/vendor/brotli/c/dec/huffman.c +2 -5
- data/ext/multi_compress/vendor/brotli/c/dec/huffman.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/dec/prefix.c +67 -0
- data/ext/multi_compress/vendor/brotli/c/dec/prefix.h +18 -708
- data/ext/multi_compress/vendor/brotli/c/dec/prefix_inc.h +707 -0
- data/ext/multi_compress/vendor/brotli/c/dec/state.c +18 -15
- data/ext/multi_compress/vendor/brotli/c/dec/state.h +2 -6
- data/ext/multi_compress/vendor/brotli/c/dec/static_init.c +53 -0
- data/ext/multi_compress/vendor/brotli/c/dec/static_init.h +30 -0
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references.c +32 -8
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references.h +1 -5
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.c +15 -15
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.h +1 -5
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.c +28 -4
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.h +8 -40
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost_inc.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.c +9 -12
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.h +0 -3
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter_inc.h +14 -8
- data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.c +10 -9
- data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.h +0 -6
- data/ext/multi_compress/vendor/brotli/c/enc/cluster.c +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/cluster.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/command.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/command.h +8 -10
- data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.c +3 -5
- data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.h +1 -4
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.c +3 -13
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.c +5 -15
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.c +127 -1830
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.h +23 -3
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash_inc.h +1829 -0
- data/ext/multi_compress/vendor/brotli/c/enc/encode.c +77 -52
- data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.c +9 -7
- data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.h +2 -4
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.c +3 -6
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.h +2 -4
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode_static.h +18 -12
- data/ext/multi_compress/vendor/brotli/c/enc/fast_log.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/fast_log.h +2 -3
- data/ext/multi_compress/vendor/brotli/c/enc/find_match_length.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/hash.h +38 -31
- data/ext/multi_compress/vendor/brotli/c/enc/hash_base.h +38 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +11 -1
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_inc.h +24 -7
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h +304 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_inc.h +30 -11
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_simd_inc.h +278 -0
- data/ext/multi_compress/vendor/brotli/c/enc/histogram.c +1 -0
- data/ext/multi_compress/vendor/brotli/c/enc/histogram.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.c +4 -6
- data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/matching_tag_mask.h +69 -0
- data/ext/multi_compress/vendor/brotli/c/enc/memory.c +0 -5
- data/ext/multi_compress/vendor/brotli/c/enc/memory.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/enc/metablock.c +7 -9
- data/ext/multi_compress/vendor/brotli/c/enc/metablock.h +3 -3
- data/ext/multi_compress/vendor/brotli/c/enc/metablock_inc.h +4 -4
- data/ext/multi_compress/vendor/brotli/c/enc/params.h +0 -1
- data/ext/multi_compress/vendor/brotli/c/enc/prefix.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/quality.h +17 -10
- data/ext/multi_compress/vendor/brotli/c/enc/ringbuffer.h +1 -4
- data/ext/multi_compress/vendor/brotli/c/enc/state.h +2 -2
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict.c +5 -11
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict.h +1 -3
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.c +224 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.h +20 -5837
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut_inc.h +5830 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init.c +59 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init.h +30 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init_lazy.cc +26 -0
- data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/write_bits.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/include/brotli/decode.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/include/brotli/encode.h +5 -1
- data/ext/multi_compress/vendor/brotli/c/include/brotli/port.h +4 -7
- data/ext/multi_compress/vendor/brotli/c/include/brotli/types.h +2 -2
- data/ext/multi_compress/vendor/lz4/LICENSE +12 -0
- data/ext/multi_compress/vendor/zstd/COPYING +339 -0
- data/ext/multi_compress/vendor/zstd/LICENSE +30 -0
- data/ext/multi_compress/vendor/zstd/lib/Makefile +67 -35
- data/ext/multi_compress/vendor/zstd/lib/README.md +33 -2
- data/ext/multi_compress/vendor/zstd/lib/common/allocations.h +55 -0
- data/ext/multi_compress/vendor/zstd/lib/common/bits.h +205 -0
- data/ext/multi_compress/vendor/zstd/lib/common/bitstream.h +84 -108
- data/ext/multi_compress/vendor/zstd/lib/common/compiler.h +170 -41
- data/ext/multi_compress/vendor/zstd/lib/common/cpu.h +37 -1
- data/ext/multi_compress/vendor/zstd/lib/common/debug.c +7 -1
- data/ext/multi_compress/vendor/zstd/lib/common/debug.h +21 -21
- data/ext/multi_compress/vendor/zstd/lib/common/entropy_common.c +12 -40
- data/ext/multi_compress/vendor/zstd/lib/common/error_private.c +10 -2
- data/ext/multi_compress/vendor/zstd/lib/common/error_private.h +46 -47
- data/ext/multi_compress/vendor/zstd/lib/common/fse.h +8 -100
- data/ext/multi_compress/vendor/zstd/lib/common/fse_decompress.c +28 -116
- data/ext/multi_compress/vendor/zstd/lib/common/huf.h +79 -166
- data/ext/multi_compress/vendor/zstd/lib/common/mem.h +46 -66
- data/ext/multi_compress/vendor/zstd/lib/common/pool.c +27 -11
- data/ext/multi_compress/vendor/zstd/lib/common/pool.h +8 -11
- data/ext/multi_compress/vendor/zstd/lib/common/portability_macros.h +45 -11
- data/ext/multi_compress/vendor/zstd/lib/common/threading.c +74 -14
- data/ext/multi_compress/vendor/zstd/lib/common/threading.h +5 -18
- data/ext/multi_compress/vendor/zstd/lib/common/xxhash.c +5 -11
- data/ext/multi_compress/vendor/zstd/lib/common/xxhash.h +2411 -1003
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_common.c +1 -36
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_deps.h +13 -1
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_internal.h +13 -182
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_trace.h +6 -13
- data/ext/multi_compress/vendor/zstd/lib/compress/clevels.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/fse_compress.c +15 -131
- data/ext/multi_compress/vendor/zstd/lib/compress/hist.c +11 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/hist.h +8 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/huf_compress.c +283 -189
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress.c +2419 -903
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_internal.h +423 -245
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.c +116 -40
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.h +16 -8
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.c +10 -10
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.h +8 -7
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.c +254 -139
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_cwksp.h +184 -95
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.c +163 -81
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.h +18 -14
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.c +507 -197
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.h +7 -14
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.c +579 -484
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.h +133 -65
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.c +61 -40
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.h +7 -15
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm_geartab.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.c +352 -218
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.h +37 -21
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.c +238 -0
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.h +33 -0
- data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.c +239 -175
- data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.h +5 -16
- data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress.c +543 -488
- data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress_amd64.S +78 -61
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.c +4 -4
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress.c +295 -115
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.c +430 -293
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.h +7 -2
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_internal.h +11 -7
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_common.c +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_compress.c +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_decompress.c +3 -1
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.c +95 -46
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.h +3 -9
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/divsufsort.h +0 -10
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/fastcover.c +4 -4
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/zdict.c +25 -97
- data/ext/multi_compress/vendor/zstd/lib/dll/example/Makefile +1 -1
- data/ext/multi_compress/vendor/zstd/lib/dll/example/README.md +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_legacy.h +38 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.c +19 -50
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.c +27 -80
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.c +28 -83
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.c +25 -74
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.c +31 -76
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.c +44 -88
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.c +33 -84
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/libzstd.mk +65 -33
- data/ext/multi_compress/vendor/zstd/lib/libzstd.pc.in +5 -5
- data/ext/multi_compress/vendor/zstd/lib/module.modulemap +13 -3
- data/ext/multi_compress/vendor/zstd/lib/zdict.h +65 -36
- data/ext/multi_compress/vendor/zstd/lib/zstd.h +890 -267
- data/ext/multi_compress/vendor/zstd/lib/zstd_errors.h +28 -16
- data/lib/multi_compress/version.rb +1 -1
- metadata +29 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -23,10 +23,8 @@
|
|
|
23
23
|
#ifdef ZSTD_MULTITHREAD
|
|
24
24
|
# include "zstdmt_compress.h"
|
|
25
25
|
#endif
|
|
26
|
-
|
|
27
|
-
#
|
|
28
|
-
extern "C" {
|
|
29
|
-
#endif
|
|
26
|
+
#include "../common/bits.h" /* ZSTD_highbit32, ZSTD_NbCommonBytes */
|
|
27
|
+
#include "zstd_preSplit.h" /* ZSTD_SLIPBLOCK_WORKSPACESIZE */
|
|
30
28
|
|
|
31
29
|
/*-*************************************
|
|
32
30
|
* Constants
|
|
@@ -38,7 +36,7 @@ extern "C" {
|
|
|
38
36
|
It's not a big deal though : candidate will just be sorted again.
|
|
39
37
|
Additionally, candidate position 1 will be lost.
|
|
40
38
|
But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss.
|
|
41
|
-
The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table
|
|
39
|
+
The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table reuse with a different strategy.
|
|
42
40
|
This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */
|
|
43
41
|
|
|
44
42
|
|
|
@@ -81,6 +79,70 @@ typedef struct {
|
|
|
81
79
|
ZSTD_fseCTables_t fse;
|
|
82
80
|
} ZSTD_entropyCTables_t;
|
|
83
81
|
|
|
82
|
+
/***********************************************
|
|
83
|
+
* Sequences *
|
|
84
|
+
***********************************************/
|
|
85
|
+
typedef struct SeqDef_s {
|
|
86
|
+
U32 offBase; /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */
|
|
87
|
+
U16 litLength;
|
|
88
|
+
U16 mlBase; /* mlBase == matchLength - MINMATCH */
|
|
89
|
+
} SeqDef;
|
|
90
|
+
|
|
91
|
+
/* Controls whether seqStore has a single "long" litLength or matchLength. See SeqStore_t. */
|
|
92
|
+
typedef enum {
|
|
93
|
+
ZSTD_llt_none = 0, /* no longLengthType */
|
|
94
|
+
ZSTD_llt_literalLength = 1, /* represents a long literal */
|
|
95
|
+
ZSTD_llt_matchLength = 2 /* represents a long match */
|
|
96
|
+
} ZSTD_longLengthType_e;
|
|
97
|
+
|
|
98
|
+
typedef struct {
|
|
99
|
+
SeqDef* sequencesStart;
|
|
100
|
+
SeqDef* sequences; /* ptr to end of sequences */
|
|
101
|
+
BYTE* litStart;
|
|
102
|
+
BYTE* lit; /* ptr to end of literals */
|
|
103
|
+
BYTE* llCode;
|
|
104
|
+
BYTE* mlCode;
|
|
105
|
+
BYTE* ofCode;
|
|
106
|
+
size_t maxNbSeq;
|
|
107
|
+
size_t maxNbLit;
|
|
108
|
+
|
|
109
|
+
/* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength
|
|
110
|
+
* in the seqStore that has a value larger than U16 (if it exists). To do so, we increment
|
|
111
|
+
* the existing value of the litLength or matchLength by 0x10000.
|
|
112
|
+
*/
|
|
113
|
+
ZSTD_longLengthType_e longLengthType;
|
|
114
|
+
U32 longLengthPos; /* Index of the sequence to apply long length modification to */
|
|
115
|
+
} SeqStore_t;
|
|
116
|
+
|
|
117
|
+
typedef struct {
|
|
118
|
+
U32 litLength;
|
|
119
|
+
U32 matchLength;
|
|
120
|
+
} ZSTD_SequenceLength;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Returns the ZSTD_SequenceLength for the given sequences. It handles the decoding of long sequences
|
|
124
|
+
* indicated by longLengthPos and longLengthType, and adds MINMATCH back to matchLength.
|
|
125
|
+
*/
|
|
126
|
+
MEM_STATIC ZSTD_SequenceLength ZSTD_getSequenceLength(SeqStore_t const* seqStore, SeqDef const* seq)
|
|
127
|
+
{
|
|
128
|
+
ZSTD_SequenceLength seqLen;
|
|
129
|
+
seqLen.litLength = seq->litLength;
|
|
130
|
+
seqLen.matchLength = seq->mlBase + MINMATCH;
|
|
131
|
+
if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
|
|
132
|
+
if (seqStore->longLengthType == ZSTD_llt_literalLength) {
|
|
133
|
+
seqLen.litLength += 0x10000;
|
|
134
|
+
}
|
|
135
|
+
if (seqStore->longLengthType == ZSTD_llt_matchLength) {
|
|
136
|
+
seqLen.matchLength += 0x10000;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return seqLen;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const SeqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */
|
|
143
|
+
int ZSTD_seqToCodes(const SeqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
|
|
144
|
+
|
|
145
|
+
|
|
84
146
|
/***********************************************
|
|
85
147
|
* Entropy buffer statistics structs and funcs *
|
|
86
148
|
***********************************************/
|
|
@@ -90,7 +152,7 @@ typedef struct {
|
|
|
90
152
|
* hufDesSize refers to the size of huffman tree description in bytes.
|
|
91
153
|
* This metadata is populated in ZSTD_buildBlockEntropyStats_literals() */
|
|
92
154
|
typedef struct {
|
|
93
|
-
|
|
155
|
+
SymbolEncodingType_e hType;
|
|
94
156
|
BYTE hufDesBuffer[ZSTD_MAX_HUF_HEADER_SIZE];
|
|
95
157
|
size_t hufDesSize;
|
|
96
158
|
} ZSTD_hufCTablesMetadata_t;
|
|
@@ -101,9 +163,9 @@ typedef struct {
|
|
|
101
163
|
* fseTablesSize refers to the size of fse tables in bytes.
|
|
102
164
|
* This metadata is populated in ZSTD_buildBlockEntropyStats_sequences() */
|
|
103
165
|
typedef struct {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
166
|
+
SymbolEncodingType_e llType;
|
|
167
|
+
SymbolEncodingType_e ofType;
|
|
168
|
+
SymbolEncodingType_e mlType;
|
|
107
169
|
BYTE fseTablesBuffer[ZSTD_MAX_FSE_HEADERS_SIZE];
|
|
108
170
|
size_t fseTablesSize;
|
|
109
171
|
size_t lastCountSize; /* This is to account for bug in 1.3.4. More detail in ZSTD_entropyCompressSeqStore_internal() */
|
|
@@ -117,12 +179,13 @@ typedef struct {
|
|
|
117
179
|
/** ZSTD_buildBlockEntropyStats() :
|
|
118
180
|
* Builds entropy for the block.
|
|
119
181
|
* @return : 0 on success or error code */
|
|
120
|
-
size_t ZSTD_buildBlockEntropyStats(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
182
|
+
size_t ZSTD_buildBlockEntropyStats(
|
|
183
|
+
const SeqStore_t* seqStorePtr,
|
|
184
|
+
const ZSTD_entropyCTables_t* prevEntropy,
|
|
185
|
+
ZSTD_entropyCTables_t* nextEntropy,
|
|
186
|
+
const ZSTD_CCtx_params* cctxParams,
|
|
187
|
+
ZSTD_entropyCTablesMetadata_t* entropyMetadata,
|
|
188
|
+
void* workspace, size_t wkspSize);
|
|
126
189
|
|
|
127
190
|
/*********************************
|
|
128
191
|
* Compression internals structs *
|
|
@@ -146,28 +209,29 @@ typedef struct {
|
|
|
146
209
|
stopped. posInSequence <= seq[pos].litLength + seq[pos].matchLength */
|
|
147
210
|
size_t size; /* The number of sequences. <= capacity. */
|
|
148
211
|
size_t capacity; /* The capacity starting from `seq` pointer */
|
|
149
|
-
}
|
|
212
|
+
} RawSeqStore_t;
|
|
150
213
|
|
|
151
|
-
UNUSED_ATTR static const
|
|
214
|
+
UNUSED_ATTR static const RawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0, 0};
|
|
152
215
|
|
|
153
216
|
typedef struct {
|
|
154
|
-
int price;
|
|
155
|
-
U32 off;
|
|
156
|
-
U32 mlen;
|
|
157
|
-
U32 litlen;
|
|
158
|
-
U32 rep[ZSTD_REP_NUM];
|
|
217
|
+
int price; /* price from beginning of segment to this position */
|
|
218
|
+
U32 off; /* offset of previous match */
|
|
219
|
+
U32 mlen; /* length of previous match */
|
|
220
|
+
U32 litlen; /* nb of literals since previous match */
|
|
221
|
+
U32 rep[ZSTD_REP_NUM]; /* offset history after previous match */
|
|
159
222
|
} ZSTD_optimal_t;
|
|
160
223
|
|
|
161
224
|
typedef enum { zop_dynamic=0, zop_predef } ZSTD_OptPrice_e;
|
|
162
225
|
|
|
226
|
+
#define ZSTD_OPT_SIZE (ZSTD_OPT_NUM+3)
|
|
163
227
|
typedef struct {
|
|
164
228
|
/* All tables are allocated inside cctx->workspace by ZSTD_resetCCtx_internal() */
|
|
165
229
|
unsigned* litFreq; /* table of literals statistics, of size 256 */
|
|
166
230
|
unsigned* litLengthFreq; /* table of litLength statistics, of size (MaxLL+1) */
|
|
167
231
|
unsigned* matchLengthFreq; /* table of matchLength statistics, of size (MaxML+1) */
|
|
168
232
|
unsigned* offCodeFreq; /* table of offCode statistics, of size (MaxOff+1) */
|
|
169
|
-
ZSTD_match_t* matchTable; /* list of found matches, of size
|
|
170
|
-
ZSTD_optimal_t* priceTable; /* All positions tracked by optimal parser, of size
|
|
233
|
+
ZSTD_match_t* matchTable; /* list of found matches, of size ZSTD_OPT_SIZE */
|
|
234
|
+
ZSTD_optimal_t* priceTable; /* All positions tracked by optimal parser, of size ZSTD_OPT_SIZE */
|
|
171
235
|
|
|
172
236
|
U32 litSum; /* nb of literals */
|
|
173
237
|
U32 litLengthSum; /* nb of litLength codes */
|
|
@@ -179,7 +243,7 @@ typedef struct {
|
|
|
179
243
|
U32 offCodeSumBasePrice; /* to compare to log2(offreq) */
|
|
180
244
|
ZSTD_OptPrice_e priceType; /* prices can be determined dynamically, or follow a pre-defined cost structure */
|
|
181
245
|
const ZSTD_entropyCTables_t* symbolCosts; /* pre-calculated dictionary statistics */
|
|
182
|
-
|
|
246
|
+
ZSTD_ParamSwitch_e literalCompressionMode;
|
|
183
247
|
} optState_t;
|
|
184
248
|
|
|
185
249
|
typedef struct {
|
|
@@ -201,11 +265,11 @@ typedef struct {
|
|
|
201
265
|
|
|
202
266
|
#define ZSTD_WINDOW_START_INDEX 2
|
|
203
267
|
|
|
204
|
-
typedef struct
|
|
268
|
+
typedef struct ZSTD_MatchState_t ZSTD_MatchState_t;
|
|
205
269
|
|
|
206
270
|
#define ZSTD_ROW_HASH_CACHE_SIZE 8 /* Size of prefetching hash cache for row-based matchfinder */
|
|
207
271
|
|
|
208
|
-
struct
|
|
272
|
+
struct ZSTD_MatchState_t {
|
|
209
273
|
ZSTD_window_t window; /* State for window round buffer management */
|
|
210
274
|
U32 loadedDictEnd; /* index of end of dictionary, within context's referential.
|
|
211
275
|
* When loadedDictEnd != 0, a dictionary is in use, and still valid.
|
|
@@ -218,28 +282,42 @@ struct ZSTD_matchState_t {
|
|
|
218
282
|
U32 hashLog3; /* dispatch table for matches of len==3 : larger == faster, more memory */
|
|
219
283
|
|
|
220
284
|
U32 rowHashLog; /* For row-based matchfinder: Hashlog based on nb of rows in the hashTable.*/
|
|
221
|
-
|
|
285
|
+
BYTE* tagTable; /* For row-based matchFinder: A row-based table containing the hashes and head index. */
|
|
222
286
|
U32 hashCache[ZSTD_ROW_HASH_CACHE_SIZE]; /* For row-based matchFinder: a cache of hashes to improve speed */
|
|
287
|
+
U64 hashSalt; /* For row-based matchFinder: salts the hash for reuse of tag table */
|
|
288
|
+
U32 hashSaltEntropy; /* For row-based matchFinder: collects entropy for salt generation */
|
|
223
289
|
|
|
224
290
|
U32* hashTable;
|
|
225
291
|
U32* hashTable3;
|
|
226
292
|
U32* chainTable;
|
|
227
293
|
|
|
228
|
-
|
|
294
|
+
int forceNonContiguous; /* Non-zero if we should force non-contiguous load for the next window update. */
|
|
229
295
|
|
|
230
296
|
int dedicatedDictSearch; /* Indicates whether this matchState is using the
|
|
231
297
|
* dedicated dictionary search structure.
|
|
232
298
|
*/
|
|
233
299
|
optState_t opt; /* optimal parser state */
|
|
234
|
-
const
|
|
300
|
+
const ZSTD_MatchState_t* dictMatchState;
|
|
235
301
|
ZSTD_compressionParameters cParams;
|
|
236
|
-
const
|
|
302
|
+
const RawSeqStore_t* ldmSeqStore;
|
|
303
|
+
|
|
304
|
+
/* Controls prefetching in some dictMatchState matchfinders.
|
|
305
|
+
* This behavior is controlled from the cctx ms.
|
|
306
|
+
* This parameter has no effect in the cdict ms. */
|
|
307
|
+
int prefetchCDictTables;
|
|
308
|
+
|
|
309
|
+
/* When == 0, lazy match finders insert every position.
|
|
310
|
+
* When != 0, lazy match finders only insert positions they search.
|
|
311
|
+
* This allows them to skip much faster over incompressible data,
|
|
312
|
+
* at a small cost to compression ratio.
|
|
313
|
+
*/
|
|
314
|
+
int lazySkipping;
|
|
237
315
|
};
|
|
238
316
|
|
|
239
317
|
typedef struct {
|
|
240
318
|
ZSTD_compressedBlockState_t* prevCBlock;
|
|
241
319
|
ZSTD_compressedBlockState_t* nextCBlock;
|
|
242
|
-
|
|
320
|
+
ZSTD_MatchState_t matchState;
|
|
243
321
|
} ZSTD_blockState_t;
|
|
244
322
|
|
|
245
323
|
typedef struct {
|
|
@@ -266,7 +344,7 @@ typedef struct {
|
|
|
266
344
|
} ldmState_t;
|
|
267
345
|
|
|
268
346
|
typedef struct {
|
|
269
|
-
|
|
347
|
+
ZSTD_ParamSwitch_e enableLdm; /* ZSTD_ps_enable to enable LDM. ZSTD_ps_auto by default */
|
|
270
348
|
U32 hashLog; /* Log size of hashTable */
|
|
271
349
|
U32 bucketSizeLog; /* Log bucket size for collision resolution, at most 8 */
|
|
272
350
|
U32 minMatchLength; /* Minimum match length */
|
|
@@ -297,7 +375,7 @@ struct ZSTD_CCtx_params_s {
|
|
|
297
375
|
* There is no guarantee that hint is close to actual source size */
|
|
298
376
|
|
|
299
377
|
ZSTD_dictAttachPref_e attachDictPref;
|
|
300
|
-
|
|
378
|
+
ZSTD_ParamSwitch_e literalCompressionMode;
|
|
301
379
|
|
|
302
380
|
/* Multithreading: used to pass parameters to mtctx */
|
|
303
381
|
int nbWorkers;
|
|
@@ -316,24 +394,54 @@ struct ZSTD_CCtx_params_s {
|
|
|
316
394
|
ZSTD_bufferMode_e outBufferMode;
|
|
317
395
|
|
|
318
396
|
/* Sequence compression API */
|
|
319
|
-
|
|
397
|
+
ZSTD_SequenceFormat_e blockDelimiters;
|
|
320
398
|
int validateSequences;
|
|
321
399
|
|
|
322
|
-
/* Block splitting
|
|
323
|
-
|
|
400
|
+
/* Block splitting
|
|
401
|
+
* @postBlockSplitter executes split analysis after sequences are produced,
|
|
402
|
+
* it's more accurate but consumes more resources.
|
|
403
|
+
* @preBlockSplitter_level splits before knowing sequences,
|
|
404
|
+
* it's more approximative but also cheaper.
|
|
405
|
+
* Valid @preBlockSplitter_level values range from 0 to 6 (included).
|
|
406
|
+
* 0 means auto, 1 means do not split,
|
|
407
|
+
* then levels are sorted in increasing cpu budget, from 2 (fastest) to 6 (slowest).
|
|
408
|
+
* Highest @preBlockSplitter_level combines well with @postBlockSplitter.
|
|
409
|
+
*/
|
|
410
|
+
ZSTD_ParamSwitch_e postBlockSplitter;
|
|
411
|
+
int preBlockSplitter_level;
|
|
412
|
+
|
|
413
|
+
/* Adjust the max block size*/
|
|
414
|
+
size_t maxBlockSize;
|
|
324
415
|
|
|
325
416
|
/* Param for deciding whether to use row-based matchfinder */
|
|
326
|
-
|
|
417
|
+
ZSTD_ParamSwitch_e useRowMatchFinder;
|
|
327
418
|
|
|
328
419
|
/* Always load a dictionary in ext-dict mode (not prefix mode)? */
|
|
329
420
|
int deterministicRefPrefix;
|
|
330
421
|
|
|
331
422
|
/* Internal use, for createCCtxParams() and freeCCtxParams() only */
|
|
332
423
|
ZSTD_customMem customMem;
|
|
424
|
+
|
|
425
|
+
/* Controls prefetching in some dictMatchState matchfinders */
|
|
426
|
+
ZSTD_ParamSwitch_e prefetchCDictTables;
|
|
427
|
+
|
|
428
|
+
/* Controls whether zstd will fall back to an internal matchfinder
|
|
429
|
+
* if the external matchfinder returns an error code. */
|
|
430
|
+
int enableMatchFinderFallback;
|
|
431
|
+
|
|
432
|
+
/* Parameters for the external sequence producer API.
|
|
433
|
+
* Users set these parameters through ZSTD_registerSequenceProducer().
|
|
434
|
+
* It is not possible to set these parameters individually through the public API. */
|
|
435
|
+
void* extSeqProdState;
|
|
436
|
+
ZSTD_sequenceProducer_F extSeqProdFunc;
|
|
437
|
+
|
|
438
|
+
/* Controls repcode search in external sequence parsing */
|
|
439
|
+
ZSTD_ParamSwitch_e searchForExternalRepcodes;
|
|
333
440
|
}; /* typedef'd to ZSTD_CCtx_params within "zstd.h" */
|
|
334
441
|
|
|
335
442
|
#define COMPRESS_SEQUENCES_WORKSPACE_SIZE (sizeof(unsigned) * (MaxSeq + 2))
|
|
336
443
|
#define ENTROPY_WORKSPACE_SIZE (HUF_WORKSPACE_SIZE + COMPRESS_SEQUENCES_WORKSPACE_SIZE)
|
|
444
|
+
#define TMP_WORKSPACE_SIZE (MAX(ENTROPY_WORKSPACE_SIZE, ZSTD_SLIPBLOCK_WORKSPACESIZE))
|
|
337
445
|
|
|
338
446
|
/**
|
|
339
447
|
* Indicates whether this compression proceeds directly from user-provided
|
|
@@ -351,11 +459,11 @@ typedef enum {
|
|
|
351
459
|
*/
|
|
352
460
|
#define ZSTD_MAX_NB_BLOCK_SPLITS 196
|
|
353
461
|
typedef struct {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
462
|
+
SeqStore_t fullSeqStoreChunk;
|
|
463
|
+
SeqStore_t firstHalfSeqStore;
|
|
464
|
+
SeqStore_t secondHalfSeqStore;
|
|
465
|
+
SeqStore_t currSeqStore;
|
|
466
|
+
SeqStore_t nextSeqStore;
|
|
359
467
|
|
|
360
468
|
U32 partitions[ZSTD_MAX_NB_BLOCK_SPLITS];
|
|
361
469
|
ZSTD_entropyCTablesMetadata_t entropyMetadata;
|
|
@@ -372,7 +480,7 @@ struct ZSTD_CCtx_s {
|
|
|
372
480
|
size_t dictContentSize;
|
|
373
481
|
|
|
374
482
|
ZSTD_cwksp workspace; /* manages buffer for dynamic allocations */
|
|
375
|
-
size_t
|
|
483
|
+
size_t blockSizeMax;
|
|
376
484
|
unsigned long long pledgedSrcSizePlusOne; /* this way, 0 (default) == unknown */
|
|
377
485
|
unsigned long long consumedSrcSize;
|
|
378
486
|
unsigned long long producedCSize;
|
|
@@ -384,13 +492,14 @@ struct ZSTD_CCtx_s {
|
|
|
384
492
|
int isFirstBlock;
|
|
385
493
|
int initialized;
|
|
386
494
|
|
|
387
|
-
|
|
495
|
+
SeqStore_t seqStore; /* sequences storage ptrs */
|
|
388
496
|
ldmState_t ldmState; /* long distance matching state */
|
|
389
497
|
rawSeq* ldmSequences; /* Storage for the ldm output sequences */
|
|
390
498
|
size_t maxNbLdmSequences;
|
|
391
|
-
|
|
499
|
+
RawSeqStore_t externSeqStore; /* Mutable reference to external sequences */
|
|
392
500
|
ZSTD_blockState_t blockState;
|
|
393
|
-
|
|
501
|
+
void* tmpWorkspace; /* used as substitute of stack space - must be aligned for S64 type */
|
|
502
|
+
size_t tmpWkspSize;
|
|
394
503
|
|
|
395
504
|
/* Whether we are streaming or not */
|
|
396
505
|
ZSTD_buffered_policy_e bufferedPolicy;
|
|
@@ -410,6 +519,7 @@ struct ZSTD_CCtx_s {
|
|
|
410
519
|
|
|
411
520
|
/* Stable in/out buffer verification */
|
|
412
521
|
ZSTD_inBuffer expectedInBuffer;
|
|
522
|
+
size_t stableIn_notConsumed; /* nb bytes within stable input buffer that are said to be consumed but are not */
|
|
413
523
|
size_t expectedOutBufferSize;
|
|
414
524
|
|
|
415
525
|
/* Dictionary */
|
|
@@ -429,9 +539,14 @@ struct ZSTD_CCtx_s {
|
|
|
429
539
|
|
|
430
540
|
/* Workspace for block splitter */
|
|
431
541
|
ZSTD_blockSplitCtx blockSplitCtx;
|
|
542
|
+
|
|
543
|
+
/* Buffer for output from external sequence producer */
|
|
544
|
+
ZSTD_Sequence* extSeqBuf;
|
|
545
|
+
size_t extSeqBufCapacity;
|
|
432
546
|
};
|
|
433
547
|
|
|
434
548
|
typedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e;
|
|
549
|
+
typedef enum { ZSTD_tfp_forCCtx, ZSTD_tfp_forCDict } ZSTD_tableFillPurpose_e;
|
|
435
550
|
|
|
436
551
|
typedef enum {
|
|
437
552
|
ZSTD_noDict = 0,
|
|
@@ -453,17 +568,17 @@ typedef enum {
|
|
|
453
568
|
* In this mode we take both the source size and the dictionary size
|
|
454
569
|
* into account when selecting and adjusting the parameters.
|
|
455
570
|
*/
|
|
456
|
-
ZSTD_cpm_unknown = 3
|
|
571
|
+
ZSTD_cpm_unknown = 3 /* ZSTD_getCParams, ZSTD_getParams, ZSTD_adjustParams.
|
|
457
572
|
* We don't know what these parameters are for. We default to the legacy
|
|
458
573
|
* behavior of taking both the source size and the dict size into account
|
|
459
574
|
* when selecting and adjusting parameters.
|
|
460
575
|
*/
|
|
461
|
-
}
|
|
576
|
+
} ZSTD_CParamMode_e;
|
|
462
577
|
|
|
463
|
-
typedef size_t (*
|
|
464
|
-
|
|
578
|
+
typedef size_t (*ZSTD_BlockCompressor_f) (
|
|
579
|
+
ZSTD_MatchState_t* bs, SeqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],
|
|
465
580
|
void const* src, size_t srcSize);
|
|
466
|
-
|
|
581
|
+
ZSTD_BlockCompressor_f ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_ParamSwitch_e rowMatchfinderMode, ZSTD_dictMode_e dictMode);
|
|
467
582
|
|
|
468
583
|
|
|
469
584
|
MEM_STATIC U32 ZSTD_LLcode(U32 litLength)
|
|
@@ -509,12 +624,33 @@ MEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)
|
|
|
509
624
|
return 1;
|
|
510
625
|
}
|
|
511
626
|
|
|
627
|
+
/* ZSTD_selectAddr:
|
|
628
|
+
* @return index >= lowLimit ? candidate : backup,
|
|
629
|
+
* tries to force branchless codegen. */
|
|
630
|
+
MEM_STATIC const BYTE*
|
|
631
|
+
ZSTD_selectAddr(U32 index, U32 lowLimit, const BYTE* candidate, const BYTE* backup)
|
|
632
|
+
{
|
|
633
|
+
#if defined(__GNUC__) && defined(__x86_64__)
|
|
634
|
+
__asm__ (
|
|
635
|
+
"cmp %1, %2\n"
|
|
636
|
+
"cmova %3, %0\n"
|
|
637
|
+
: "+r"(candidate)
|
|
638
|
+
: "r"(index), "r"(lowLimit), "r"(backup)
|
|
639
|
+
);
|
|
640
|
+
return candidate;
|
|
641
|
+
#else
|
|
642
|
+
return index >= lowLimit ? candidate : backup;
|
|
643
|
+
#endif
|
|
644
|
+
}
|
|
645
|
+
|
|
512
646
|
/* ZSTD_noCompressBlock() :
|
|
513
647
|
* Writes uncompressed block to dst buffer from given src.
|
|
514
648
|
* Returns the size of the block */
|
|
515
|
-
MEM_STATIC size_t
|
|
649
|
+
MEM_STATIC size_t
|
|
650
|
+
ZSTD_noCompressBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)
|
|
516
651
|
{
|
|
517
652
|
U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);
|
|
653
|
+
DEBUGLOG(5, "ZSTD_noCompressBlock (srcSize=%zu, dstCapacity=%zu)", srcSize, dstCapacity);
|
|
518
654
|
RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity,
|
|
519
655
|
dstSize_tooSmall, "dst buf too small for uncompressed block");
|
|
520
656
|
MEM_writeLE24(dst, cBlockHeader24);
|
|
@@ -522,7 +658,8 @@ MEM_STATIC size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const voi
|
|
|
522
658
|
return ZSTD_blockHeaderSize + srcSize;
|
|
523
659
|
}
|
|
524
660
|
|
|
525
|
-
MEM_STATIC size_t
|
|
661
|
+
MEM_STATIC size_t
|
|
662
|
+
ZSTD_rleCompressBlock(void* dst, size_t dstCapacity, BYTE src, size_t srcSize, U32 lastBlock)
|
|
526
663
|
{
|
|
527
664
|
BYTE* const op = (BYTE*)dst;
|
|
528
665
|
U32 const cBlockHeader = lastBlock + (((U32)bt_rle)<<1) + (U32)(srcSize << 3);
|
|
@@ -541,7 +678,7 @@ MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
|
|
|
541
678
|
{
|
|
542
679
|
U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6;
|
|
543
680
|
ZSTD_STATIC_ASSERT(ZSTD_btultra == 8);
|
|
544
|
-
assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
|
|
681
|
+
assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, (int)strat));
|
|
545
682
|
return (srcSize >> minlog) + 2;
|
|
546
683
|
}
|
|
547
684
|
|
|
@@ -577,29 +714,68 @@ ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE con
|
|
|
577
714
|
while (ip < iend) *op++ = *ip++;
|
|
578
715
|
}
|
|
579
716
|
|
|
580
|
-
|
|
581
|
-
#define
|
|
582
|
-
#define
|
|
583
|
-
#define
|
|
584
|
-
#define
|
|
585
|
-
#define
|
|
586
|
-
#define
|
|
587
|
-
#define
|
|
588
|
-
#define
|
|
589
|
-
#define
|
|
590
|
-
|
|
591
|
-
|
|
717
|
+
|
|
718
|
+
#define REPCODE1_TO_OFFBASE REPCODE_TO_OFFBASE(1)
|
|
719
|
+
#define REPCODE2_TO_OFFBASE REPCODE_TO_OFFBASE(2)
|
|
720
|
+
#define REPCODE3_TO_OFFBASE REPCODE_TO_OFFBASE(3)
|
|
721
|
+
#define REPCODE_TO_OFFBASE(r) (assert((r)>=1), assert((r)<=ZSTD_REP_NUM), (r)) /* accepts IDs 1,2,3 */
|
|
722
|
+
#define OFFSET_TO_OFFBASE(o) (assert((o)>0), o + ZSTD_REP_NUM)
|
|
723
|
+
#define OFFBASE_IS_OFFSET(o) ((o) > ZSTD_REP_NUM)
|
|
724
|
+
#define OFFBASE_IS_REPCODE(o) ( 1 <= (o) && (o) <= ZSTD_REP_NUM)
|
|
725
|
+
#define OFFBASE_TO_OFFSET(o) (assert(OFFBASE_IS_OFFSET(o)), (o) - ZSTD_REP_NUM)
|
|
726
|
+
#define OFFBASE_TO_REPCODE(o) (assert(OFFBASE_IS_REPCODE(o)), (o)) /* returns ID 1,2,3 */
|
|
727
|
+
|
|
728
|
+
/*! ZSTD_storeSeqOnly() :
|
|
729
|
+
* Store a sequence (litlen, litPtr, offBase and matchLength) into SeqStore_t.
|
|
730
|
+
* Literals themselves are not copied, but @litPtr is updated.
|
|
731
|
+
* @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE().
|
|
732
|
+
* @matchLength : must be >= MINMATCH
|
|
733
|
+
*/
|
|
734
|
+
HINT_INLINE UNUSED_ATTR void
|
|
735
|
+
ZSTD_storeSeqOnly(SeqStore_t* seqStorePtr,
|
|
736
|
+
size_t litLength,
|
|
737
|
+
U32 offBase,
|
|
738
|
+
size_t matchLength)
|
|
739
|
+
{
|
|
740
|
+
assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq);
|
|
741
|
+
|
|
742
|
+
/* literal Length */
|
|
743
|
+
assert(litLength <= ZSTD_BLOCKSIZE_MAX);
|
|
744
|
+
if (UNLIKELY(litLength>0xFFFF)) {
|
|
745
|
+
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
|
|
746
|
+
seqStorePtr->longLengthType = ZSTD_llt_literalLength;
|
|
747
|
+
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
|
748
|
+
}
|
|
749
|
+
seqStorePtr->sequences[0].litLength = (U16)litLength;
|
|
750
|
+
|
|
751
|
+
/* match offset */
|
|
752
|
+
seqStorePtr->sequences[0].offBase = offBase;
|
|
753
|
+
|
|
754
|
+
/* match Length */
|
|
755
|
+
assert(matchLength <= ZSTD_BLOCKSIZE_MAX);
|
|
756
|
+
assert(matchLength >= MINMATCH);
|
|
757
|
+
{ size_t const mlBase = matchLength - MINMATCH;
|
|
758
|
+
if (UNLIKELY(mlBase>0xFFFF)) {
|
|
759
|
+
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
|
|
760
|
+
seqStorePtr->longLengthType = ZSTD_llt_matchLength;
|
|
761
|
+
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
|
762
|
+
}
|
|
763
|
+
seqStorePtr->sequences[0].mlBase = (U16)mlBase;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
seqStorePtr->sequences++;
|
|
767
|
+
}
|
|
592
768
|
|
|
593
769
|
/*! ZSTD_storeSeq() :
|
|
594
|
-
* Store a sequence (litlen, litPtr,
|
|
595
|
-
* @
|
|
770
|
+
* Store a sequence (litlen, litPtr, offBase and matchLength) into SeqStore_t.
|
|
771
|
+
* @offBase : Users should employ macros REPCODE_TO_OFFBASE() and OFFSET_TO_OFFBASE().
|
|
596
772
|
* @matchLength : must be >= MINMATCH
|
|
597
|
-
* Allowed to
|
|
773
|
+
* Allowed to over-read literals up to litLimit.
|
|
598
774
|
*/
|
|
599
775
|
HINT_INLINE UNUSED_ATTR void
|
|
600
|
-
ZSTD_storeSeq(
|
|
776
|
+
ZSTD_storeSeq(SeqStore_t* seqStorePtr,
|
|
601
777
|
size_t litLength, const BYTE* literals, const BYTE* litLimit,
|
|
602
|
-
U32
|
|
778
|
+
U32 offBase,
|
|
603
779
|
size_t matchLength)
|
|
604
780
|
{
|
|
605
781
|
BYTE const* const litLimit_w = litLimit - WILDCOPY_OVERLENGTH;
|
|
@@ -608,8 +784,8 @@ ZSTD_storeSeq(seqStore_t* seqStorePtr,
|
|
|
608
784
|
static const BYTE* g_start = NULL;
|
|
609
785
|
if (g_start==NULL) g_start = (const BYTE*)literals; /* note : index only works for compression within a single segment */
|
|
610
786
|
{ U32 const pos = (U32)((const BYTE*)literals - g_start);
|
|
611
|
-
DEBUGLOG(6, "Cpos%7u :%3u literals, match%4u bytes at
|
|
612
|
-
pos, (U32)litLength, (U32)matchLength, (U32)
|
|
787
|
+
DEBUGLOG(6, "Cpos%7u :%3u literals, match%4u bytes at offBase%7u",
|
|
788
|
+
pos, (U32)litLength, (U32)matchLength, (U32)offBase);
|
|
613
789
|
}
|
|
614
790
|
#endif
|
|
615
791
|
assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq);
|
|
@@ -619,9 +795,9 @@ ZSTD_storeSeq(seqStore_t* seqStorePtr,
|
|
|
619
795
|
assert(literals + litLength <= litLimit);
|
|
620
796
|
if (litEnd <= litLimit_w) {
|
|
621
797
|
/* Common case we can use wildcopy.
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
798
|
+
* First copy 16 bytes, because literals are likely short.
|
|
799
|
+
*/
|
|
800
|
+
ZSTD_STATIC_ASSERT(WILDCOPY_OVERLENGTH >= 16);
|
|
625
801
|
ZSTD_copy16(seqStorePtr->lit, literals);
|
|
626
802
|
if (litLength > 16) {
|
|
627
803
|
ZSTD_wildcopy(seqStorePtr->lit+16, literals+16, (ptrdiff_t)litLength-16, ZSTD_no_overlap);
|
|
@@ -631,44 +807,22 @@ ZSTD_storeSeq(seqStore_t* seqStorePtr,
|
|
|
631
807
|
}
|
|
632
808
|
seqStorePtr->lit += litLength;
|
|
633
809
|
|
|
634
|
-
|
|
635
|
-
if (litLength>0xFFFF) {
|
|
636
|
-
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
|
|
637
|
-
seqStorePtr->longLengthType = ZSTD_llt_literalLength;
|
|
638
|
-
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
|
639
|
-
}
|
|
640
|
-
seqStorePtr->sequences[0].litLength = (U16)litLength;
|
|
641
|
-
|
|
642
|
-
/* match offset */
|
|
643
|
-
seqStorePtr->sequences[0].offBase = STORED_TO_OFFBASE(offBase_minus1);
|
|
644
|
-
|
|
645
|
-
/* match Length */
|
|
646
|
-
assert(matchLength >= MINMATCH);
|
|
647
|
-
{ size_t const mlBase = matchLength - MINMATCH;
|
|
648
|
-
if (mlBase>0xFFFF) {
|
|
649
|
-
assert(seqStorePtr->longLengthType == ZSTD_llt_none); /* there can only be a single long length */
|
|
650
|
-
seqStorePtr->longLengthType = ZSTD_llt_matchLength;
|
|
651
|
-
seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
|
|
652
|
-
}
|
|
653
|
-
seqStorePtr->sequences[0].mlBase = (U16)mlBase;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
seqStorePtr->sequences++;
|
|
810
|
+
ZSTD_storeSeqOnly(seqStorePtr, litLength, offBase, matchLength);
|
|
657
811
|
}
|
|
658
812
|
|
|
659
813
|
/* ZSTD_updateRep() :
|
|
660
814
|
* updates in-place @rep (array of repeat offsets)
|
|
661
|
-
* @
|
|
815
|
+
* @offBase : sum-type, using numeric representation of ZSTD_storeSeq()
|
|
662
816
|
*/
|
|
663
817
|
MEM_STATIC void
|
|
664
|
-
ZSTD_updateRep(U32 rep[ZSTD_REP_NUM], U32 const
|
|
818
|
+
ZSTD_updateRep(U32 rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0)
|
|
665
819
|
{
|
|
666
|
-
if (
|
|
820
|
+
if (OFFBASE_IS_OFFSET(offBase)) { /* full offset */
|
|
667
821
|
rep[2] = rep[1];
|
|
668
822
|
rep[1] = rep[0];
|
|
669
|
-
rep[0] =
|
|
823
|
+
rep[0] = OFFBASE_TO_OFFSET(offBase);
|
|
670
824
|
} else { /* repcode */
|
|
671
|
-
U32 const repCode =
|
|
825
|
+
U32 const repCode = OFFBASE_TO_REPCODE(offBase) - 1 + ll0;
|
|
672
826
|
if (repCode > 0) { /* note : if repCode==0, no change */
|
|
673
827
|
U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];
|
|
674
828
|
rep[2] = (repCode >= 2) ? rep[1] : rep[2];
|
|
@@ -682,14 +836,14 @@ ZSTD_updateRep(U32 rep[ZSTD_REP_NUM], U32 const offBase_minus1, U32 const ll0)
|
|
|
682
836
|
|
|
683
837
|
typedef struct repcodes_s {
|
|
684
838
|
U32 rep[3];
|
|
685
|
-
}
|
|
839
|
+
} Repcodes_t;
|
|
686
840
|
|
|
687
|
-
MEM_STATIC
|
|
688
|
-
ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const
|
|
841
|
+
MEM_STATIC Repcodes_t
|
|
842
|
+
ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const offBase, U32 const ll0)
|
|
689
843
|
{
|
|
690
|
-
|
|
844
|
+
Repcodes_t newReps;
|
|
691
845
|
ZSTD_memcpy(&newReps, rep, sizeof(newReps));
|
|
692
|
-
ZSTD_updateRep(newReps.rep,
|
|
846
|
+
ZSTD_updateRep(newReps.rep, offBase, ll0);
|
|
693
847
|
return newReps;
|
|
694
848
|
}
|
|
695
849
|
|
|
@@ -697,103 +851,6 @@ ZSTD_newRep(U32 const rep[ZSTD_REP_NUM], U32 const offBase_minus1, U32 const ll0
|
|
|
697
851
|
/*-*************************************
|
|
698
852
|
* Match length counter
|
|
699
853
|
***************************************/
|
|
700
|
-
static unsigned ZSTD_NbCommonBytes (size_t val)
|
|
701
|
-
{
|
|
702
|
-
if (MEM_isLittleEndian()) {
|
|
703
|
-
if (MEM_64bits()) {
|
|
704
|
-
# if defined(_MSC_VER) && defined(_WIN64)
|
|
705
|
-
# if STATIC_BMI2
|
|
706
|
-
return _tzcnt_u64(val) >> 3;
|
|
707
|
-
# else
|
|
708
|
-
if (val != 0) {
|
|
709
|
-
unsigned long r;
|
|
710
|
-
_BitScanForward64(&r, (U64)val);
|
|
711
|
-
return (unsigned)(r >> 3);
|
|
712
|
-
} else {
|
|
713
|
-
/* Should not reach this code path */
|
|
714
|
-
__assume(0);
|
|
715
|
-
}
|
|
716
|
-
# endif
|
|
717
|
-
# elif defined(__GNUC__) && (__GNUC__ >= 4)
|
|
718
|
-
return (__builtin_ctzll((U64)val) >> 3);
|
|
719
|
-
# else
|
|
720
|
-
static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,
|
|
721
|
-
0, 3, 1, 3, 1, 4, 2, 7,
|
|
722
|
-
0, 2, 3, 6, 1, 5, 3, 5,
|
|
723
|
-
1, 3, 4, 4, 2, 5, 6, 7,
|
|
724
|
-
7, 0, 1, 2, 3, 3, 4, 6,
|
|
725
|
-
2, 6, 5, 5, 3, 4, 5, 6,
|
|
726
|
-
7, 1, 2, 4, 6, 4, 4, 5,
|
|
727
|
-
7, 2, 6, 5, 7, 6, 7, 7 };
|
|
728
|
-
return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
|
|
729
|
-
# endif
|
|
730
|
-
} else { /* 32 bits */
|
|
731
|
-
# if defined(_MSC_VER)
|
|
732
|
-
if (val != 0) {
|
|
733
|
-
unsigned long r;
|
|
734
|
-
_BitScanForward(&r, (U32)val);
|
|
735
|
-
return (unsigned)(r >> 3);
|
|
736
|
-
} else {
|
|
737
|
-
/* Should not reach this code path */
|
|
738
|
-
__assume(0);
|
|
739
|
-
}
|
|
740
|
-
# elif defined(__GNUC__) && (__GNUC__ >= 3)
|
|
741
|
-
return (__builtin_ctz((U32)val) >> 3);
|
|
742
|
-
# else
|
|
743
|
-
static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,
|
|
744
|
-
3, 2, 2, 1, 3, 2, 0, 1,
|
|
745
|
-
3, 3, 1, 2, 2, 2, 2, 0,
|
|
746
|
-
3, 1, 2, 0, 1, 0, 1, 1 };
|
|
747
|
-
return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
|
|
748
|
-
# endif
|
|
749
|
-
}
|
|
750
|
-
} else { /* Big Endian CPU */
|
|
751
|
-
if (MEM_64bits()) {
|
|
752
|
-
# if defined(_MSC_VER) && defined(_WIN64)
|
|
753
|
-
# if STATIC_BMI2
|
|
754
|
-
return _lzcnt_u64(val) >> 3;
|
|
755
|
-
# else
|
|
756
|
-
if (val != 0) {
|
|
757
|
-
unsigned long r;
|
|
758
|
-
_BitScanReverse64(&r, (U64)val);
|
|
759
|
-
return (unsigned)(r >> 3);
|
|
760
|
-
} else {
|
|
761
|
-
/* Should not reach this code path */
|
|
762
|
-
__assume(0);
|
|
763
|
-
}
|
|
764
|
-
# endif
|
|
765
|
-
# elif defined(__GNUC__) && (__GNUC__ >= 4)
|
|
766
|
-
return (__builtin_clzll(val) >> 3);
|
|
767
|
-
# else
|
|
768
|
-
unsigned r;
|
|
769
|
-
const unsigned n32 = sizeof(size_t)*4; /* calculate this way due to compiler complaining in 32-bits mode */
|
|
770
|
-
if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
|
|
771
|
-
if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
|
|
772
|
-
r += (!val);
|
|
773
|
-
return r;
|
|
774
|
-
# endif
|
|
775
|
-
} else { /* 32 bits */
|
|
776
|
-
# if defined(_MSC_VER)
|
|
777
|
-
if (val != 0) {
|
|
778
|
-
unsigned long r;
|
|
779
|
-
_BitScanReverse(&r, (unsigned long)val);
|
|
780
|
-
return (unsigned)(r >> 3);
|
|
781
|
-
} else {
|
|
782
|
-
/* Should not reach this code path */
|
|
783
|
-
__assume(0);
|
|
784
|
-
}
|
|
785
|
-
# elif defined(__GNUC__) && (__GNUC__ >= 3)
|
|
786
|
-
return (__builtin_clz((U32)val) >> 3);
|
|
787
|
-
# else
|
|
788
|
-
unsigned r;
|
|
789
|
-
if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
|
|
790
|
-
r += (!val);
|
|
791
|
-
return r;
|
|
792
|
-
# endif
|
|
793
|
-
} }
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
|
|
797
854
|
MEM_STATIC size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)
|
|
798
855
|
{
|
|
799
856
|
const BYTE* const pStart = pIn;
|
|
@@ -827,8 +884,8 @@ ZSTD_count_2segments(const BYTE* ip, const BYTE* match,
|
|
|
827
884
|
size_t const matchLength = ZSTD_count(ip, match, vEnd);
|
|
828
885
|
if (match + matchLength != mEnd) return matchLength;
|
|
829
886
|
DEBUGLOG(7, "ZSTD_count_2segments: found a 2-parts match (current length==%zu)", matchLength);
|
|
830
|
-
DEBUGLOG(7, "distance from match beginning to end dictionary = %
|
|
831
|
-
DEBUGLOG(7, "distance from current pos to end buffer = %
|
|
887
|
+
DEBUGLOG(7, "distance from match beginning to end dictionary = %i", (int)(mEnd - match));
|
|
888
|
+
DEBUGLOG(7, "distance from current pos to end buffer = %i", (int)(iEnd - ip));
|
|
832
889
|
DEBUGLOG(7, "next byte : ip==%02X, istart==%02X", ip[matchLength], *iStart);
|
|
833
890
|
DEBUGLOG(7, "final match length = %zu", matchLength + ZSTD_count(ip+matchLength, iStart, iEnd));
|
|
834
891
|
return matchLength + ZSTD_count(ip+matchLength, iStart, iEnd);
|
|
@@ -839,32 +896,43 @@ ZSTD_count_2segments(const BYTE* ip, const BYTE* match,
|
|
|
839
896
|
* Hashes
|
|
840
897
|
***************************************/
|
|
841
898
|
static const U32 prime3bytes = 506832829U;
|
|
842
|
-
static U32 ZSTD_hash3(U32 u, U32 h) { return ((u << (32-24)) * prime3bytes) >> (32-h) ; }
|
|
843
|
-
MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); } /* only in zstd_opt.h */
|
|
899
|
+
static U32 ZSTD_hash3(U32 u, U32 h, U32 s) { assert(h <= 32); return (((u << (32-24)) * prime3bytes) ^ s) >> (32-h) ; }
|
|
900
|
+
MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h, 0); } /* only in zstd_opt.h */
|
|
901
|
+
MEM_STATIC size_t ZSTD_hash3PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash3(MEM_readLE32(ptr), h, s); }
|
|
844
902
|
|
|
845
903
|
static const U32 prime4bytes = 2654435761U;
|
|
846
|
-
static U32 ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
|
|
847
|
-
static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(
|
|
904
|
+
static U32 ZSTD_hash4(U32 u, U32 h, U32 s) { assert(h <= 32); return ((u * prime4bytes) ^ s) >> (32-h) ; }
|
|
905
|
+
static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_readLE32(ptr), h, 0); }
|
|
906
|
+
static size_t ZSTD_hash4PtrS(const void* ptr, U32 h, U32 s) { return ZSTD_hash4(MEM_readLE32(ptr), h, s); }
|
|
848
907
|
|
|
849
908
|
static const U64 prime5bytes = 889523592379ULL;
|
|
850
|
-
static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u << (64-40)) * prime5bytes) >> (64-h)) ; }
|
|
851
|
-
static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); }
|
|
909
|
+
static size_t ZSTD_hash5(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-40)) * prime5bytes) ^ s) >> (64-h)) ; }
|
|
910
|
+
static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h, 0); }
|
|
911
|
+
static size_t ZSTD_hash5PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash5(MEM_readLE64(p), h, s); }
|
|
852
912
|
|
|
853
913
|
static const U64 prime6bytes = 227718039650203ULL;
|
|
854
|
-
static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u << (64-48)) * prime6bytes) >> (64-h)) ; }
|
|
855
|
-
static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); }
|
|
914
|
+
static size_t ZSTD_hash6(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-48)) * prime6bytes) ^ s) >> (64-h)) ; }
|
|
915
|
+
static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h, 0); }
|
|
916
|
+
static size_t ZSTD_hash6PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash6(MEM_readLE64(p), h, s); }
|
|
856
917
|
|
|
857
918
|
static const U64 prime7bytes = 58295818150454627ULL;
|
|
858
|
-
static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u << (64-56)) * prime7bytes) >> (64-h)) ; }
|
|
859
|
-
static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }
|
|
919
|
+
static size_t ZSTD_hash7(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u << (64-56)) * prime7bytes) ^ s) >> (64-h)) ; }
|
|
920
|
+
static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h, 0); }
|
|
921
|
+
static size_t ZSTD_hash7PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash7(MEM_readLE64(p), h, s); }
|
|
860
922
|
|
|
861
923
|
static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
|
|
862
|
-
static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
|
|
863
|
-
static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
|
|
924
|
+
static size_t ZSTD_hash8(U64 u, U32 h, U64 s) { assert(h <= 64); return (size_t)((((u) * prime8bytes) ^ s) >> (64-h)) ; }
|
|
925
|
+
static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h, 0); }
|
|
926
|
+
static size_t ZSTD_hash8PtrS(const void* p, U32 h, U64 s) { return ZSTD_hash8(MEM_readLE64(p), h, s); }
|
|
927
|
+
|
|
864
928
|
|
|
865
929
|
MEM_STATIC FORCE_INLINE_ATTR
|
|
866
930
|
size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
|
|
867
931
|
{
|
|
932
|
+
/* Although some of these hashes do support hBits up to 64, some do not.
|
|
933
|
+
* To be on the safe side, always avoid hBits > 32. */
|
|
934
|
+
assert(hBits <= 32);
|
|
935
|
+
|
|
868
936
|
switch(mls)
|
|
869
937
|
{
|
|
870
938
|
default:
|
|
@@ -876,6 +944,24 @@ size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
|
|
|
876
944
|
}
|
|
877
945
|
}
|
|
878
946
|
|
|
947
|
+
MEM_STATIC FORCE_INLINE_ATTR
|
|
948
|
+
size_t ZSTD_hashPtrSalted(const void* p, U32 hBits, U32 mls, const U64 hashSalt) {
|
|
949
|
+
/* Although some of these hashes do support hBits up to 64, some do not.
|
|
950
|
+
* To be on the safe side, always avoid hBits > 32. */
|
|
951
|
+
assert(hBits <= 32);
|
|
952
|
+
|
|
953
|
+
switch(mls)
|
|
954
|
+
{
|
|
955
|
+
default:
|
|
956
|
+
case 4: return ZSTD_hash4PtrS(p, hBits, (U32)hashSalt);
|
|
957
|
+
case 5: return ZSTD_hash5PtrS(p, hBits, hashSalt);
|
|
958
|
+
case 6: return ZSTD_hash6PtrS(p, hBits, hashSalt);
|
|
959
|
+
case 7: return ZSTD_hash7PtrS(p, hBits, hashSalt);
|
|
960
|
+
case 8: return ZSTD_hash8PtrS(p, hBits, hashSalt);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
|
|
879
965
|
/** ZSTD_ipow() :
|
|
880
966
|
* Return base^exponent.
|
|
881
967
|
*/
|
|
@@ -937,11 +1023,12 @@ MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64
|
|
|
937
1023
|
/*-*************************************
|
|
938
1024
|
* Round buffer management
|
|
939
1025
|
***************************************/
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
1026
|
+
/* Max @current value allowed:
|
|
1027
|
+
* In 32-bit mode: we want to avoid crossing the 2 GB limit,
|
|
1028
|
+
* reducing risks of side effects in case of signed operations on indexes.
|
|
1029
|
+
* In 64-bit mode: we want to ensure that adding the maximum job size (512 MB)
|
|
1030
|
+
* doesn't overflow U32 index capacity (4 GB) */
|
|
1031
|
+
#define ZSTD_CURRENT_MAX (MEM_64bits() ? 3500U MB : 2000U MB)
|
|
945
1032
|
/* Maximum chunk size before overflow correction needs to be called again */
|
|
946
1033
|
#define ZSTD_CHUNKSIZE_MAX \
|
|
947
1034
|
( ((U32)-1) /* Maximum ending current index */ \
|
|
@@ -981,7 +1068,7 @@ MEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window)
|
|
|
981
1068
|
* Inspects the provided matchState and figures out what dictMode should be
|
|
982
1069
|
* passed to the compressor.
|
|
983
1070
|
*/
|
|
984
|
-
MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const
|
|
1071
|
+
MEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_MatchState_t *ms)
|
|
985
1072
|
{
|
|
986
1073
|
return ZSTD_window_hasExtDict(ms->window) ?
|
|
987
1074
|
ZSTD_extDict :
|
|
@@ -1067,7 +1154,9 @@ MEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,
|
|
|
1067
1154
|
* The least significant cycleLog bits of the indices must remain the same,
|
|
1068
1155
|
* which may be 0. Every index up to maxDist in the past must be valid.
|
|
1069
1156
|
*/
|
|
1070
|
-
MEM_STATIC
|
|
1157
|
+
MEM_STATIC
|
|
1158
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
1159
|
+
U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
|
|
1071
1160
|
U32 maxDist, void const* src)
|
|
1072
1161
|
{
|
|
1073
1162
|
/* preemptive overflow correction:
|
|
@@ -1168,7 +1257,7 @@ ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
|
|
|
1168
1257
|
const void* blockEnd,
|
|
1169
1258
|
U32 maxDist,
|
|
1170
1259
|
U32* loadedDictEndPtr,
|
|
1171
|
-
const
|
|
1260
|
+
const ZSTD_MatchState_t** dictMatchStatePtr)
|
|
1172
1261
|
{
|
|
1173
1262
|
U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
|
|
1174
1263
|
U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
|
|
@@ -1213,7 +1302,7 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window,
|
|
|
1213
1302
|
const void* blockEnd,
|
|
1214
1303
|
U32 maxDist,
|
|
1215
1304
|
U32* loadedDictEndPtr,
|
|
1216
|
-
const
|
|
1305
|
+
const ZSTD_MatchState_t** dictMatchStatePtr)
|
|
1217
1306
|
{
|
|
1218
1307
|
assert(loadedDictEndPtr != NULL);
|
|
1219
1308
|
assert(dictMatchStatePtr != NULL);
|
|
@@ -1223,10 +1312,15 @@ ZSTD_checkDictValidity(const ZSTD_window_t* window,
|
|
|
1223
1312
|
(unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
|
|
1224
1313
|
assert(blockEndIdx >= loadedDictEnd);
|
|
1225
1314
|
|
|
1226
|
-
if (blockEndIdx > loadedDictEnd + maxDist) {
|
|
1315
|
+
if (blockEndIdx > loadedDictEnd + maxDist || loadedDictEnd != window->dictLimit) {
|
|
1227
1316
|
/* On reaching window size, dictionaries are invalidated.
|
|
1228
1317
|
* For simplification, if window size is reached anywhere within next block,
|
|
1229
1318
|
* the dictionary is invalidated for the full block.
|
|
1319
|
+
*
|
|
1320
|
+
* We also have to invalidate the dictionary if ZSTD_window_update() has detected
|
|
1321
|
+
* non-contiguous segments, which means that loadedDictEnd != window->dictLimit.
|
|
1322
|
+
* loadedDictEnd may be 0, if forceWindow is true, but in that case we never use
|
|
1323
|
+
* dictMatchState, so setting it to NULL is not a problem.
|
|
1230
1324
|
*/
|
|
1231
1325
|
DEBUGLOG(6, "invalidating dictionary for current block (distance > windowSize)");
|
|
1232
1326
|
*loadedDictEndPtr = 0;
|
|
@@ -1255,9 +1349,11 @@ MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
|
|
|
1255
1349
|
* forget about the extDict. Handles overlap of the prefix and extDict.
|
|
1256
1350
|
* Returns non-zero if the segment is contiguous.
|
|
1257
1351
|
*/
|
|
1258
|
-
MEM_STATIC
|
|
1259
|
-
|
|
1260
|
-
|
|
1352
|
+
MEM_STATIC
|
|
1353
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
1354
|
+
U32 ZSTD_window_update(ZSTD_window_t* window,
|
|
1355
|
+
const void* src, size_t srcSize,
|
|
1356
|
+
int forceNonContiguous)
|
|
1261
1357
|
{
|
|
1262
1358
|
BYTE const* const ip = (BYTE const*)src;
|
|
1263
1359
|
U32 contiguous = 1;
|
|
@@ -1284,8 +1380,9 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
|
|
|
1284
1380
|
/* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
|
|
1285
1381
|
if ( (ip+srcSize > window->dictBase + window->lowLimit)
|
|
1286
1382
|
& (ip < window->dictBase + window->dictLimit)) {
|
|
1287
|
-
|
|
1288
|
-
U32 const lowLimitMax = (highInputIdx > (
|
|
1383
|
+
size_t const highInputIdx = (size_t)((ip + srcSize) - window->dictBase);
|
|
1384
|
+
U32 const lowLimitMax = (highInputIdx > (size_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx;
|
|
1385
|
+
assert(highInputIdx < UINT_MAX);
|
|
1289
1386
|
window->lowLimit = lowLimitMax;
|
|
1290
1387
|
DEBUGLOG(5, "Overlapping extDict and input : new lowLimit = %u", window->lowLimit);
|
|
1291
1388
|
}
|
|
@@ -1295,7 +1392,7 @@ MEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,
|
|
|
1295
1392
|
/**
|
|
1296
1393
|
* Returns the lowest allowed match index. It may either be in the ext-dict or the prefix.
|
|
1297
1394
|
*/
|
|
1298
|
-
MEM_STATIC U32 ZSTD_getLowestMatchIndex(const
|
|
1395
|
+
MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_MatchState_t* ms, U32 curr, unsigned windowLog)
|
|
1299
1396
|
{
|
|
1300
1397
|
U32 const maxDistance = 1U << windowLog;
|
|
1301
1398
|
U32 const lowestValid = ms->window.lowLimit;
|
|
@@ -1312,7 +1409,7 @@ MEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 curr, u
|
|
|
1312
1409
|
/**
|
|
1313
1410
|
* Returns the lowest allowed match index in the prefix.
|
|
1314
1411
|
*/
|
|
1315
|
-
MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const
|
|
1412
|
+
MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_MatchState_t* ms, U32 curr, unsigned windowLog)
|
|
1316
1413
|
{
|
|
1317
1414
|
U32 const maxDistance = 1U << windowLog;
|
|
1318
1415
|
U32 const lowestValid = ms->window.dictLimit;
|
|
@@ -1325,6 +1422,13 @@ MEM_STATIC U32 ZSTD_getLowestPrefixIndex(const ZSTD_matchState_t* ms, U32 curr,
|
|
|
1325
1422
|
return matchLowest;
|
|
1326
1423
|
}
|
|
1327
1424
|
|
|
1425
|
+
/* index_safety_check:
|
|
1426
|
+
* intentional underflow : ensure repIndex isn't overlapping dict + prefix
|
|
1427
|
+
* @return 1 if values are not overlapping,
|
|
1428
|
+
* 0 otherwise */
|
|
1429
|
+
MEM_STATIC int ZSTD_index_overlap_check(const U32 prefixLowestIndex, const U32 repIndex) {
|
|
1430
|
+
return ((U32)((prefixLowestIndex-1) - repIndex) >= 3);
|
|
1431
|
+
}
|
|
1328
1432
|
|
|
1329
1433
|
|
|
1330
1434
|
/* debug functions */
|
|
@@ -1358,10 +1462,42 @@ MEM_STATIC void ZSTD_debugTable(const U32* table, U32 max)
|
|
|
1358
1462
|
|
|
1359
1463
|
#endif
|
|
1360
1464
|
|
|
1465
|
+
/* Short Cache */
|
|
1466
|
+
|
|
1467
|
+
/* Normally, zstd matchfinders follow this flow:
|
|
1468
|
+
* 1. Compute hash at ip
|
|
1469
|
+
* 2. Load index from hashTable[hash]
|
|
1470
|
+
* 3. Check if *ip == *(base + index)
|
|
1471
|
+
* In dictionary compression, loading *(base + index) is often an L2 or even L3 miss.
|
|
1472
|
+
*
|
|
1473
|
+
* Short cache is an optimization which allows us to avoid step 3 most of the time
|
|
1474
|
+
* when the data doesn't actually match. With short cache, the flow becomes:
|
|
1475
|
+
* 1. Compute (hash, currentTag) at ip. currentTag is an 8-bit independent hash at ip.
|
|
1476
|
+
* 2. Load (index, matchTag) from hashTable[hash]. See ZSTD_writeTaggedIndex to understand how this works.
|
|
1477
|
+
* 3. Only if currentTag == matchTag, check *ip == *(base + index). Otherwise, continue.
|
|
1478
|
+
*
|
|
1479
|
+
* Currently, short cache is only implemented in CDict hashtables. Thus, its use is limited to
|
|
1480
|
+
* dictMatchState matchfinders.
|
|
1481
|
+
*/
|
|
1482
|
+
#define ZSTD_SHORT_CACHE_TAG_BITS 8
|
|
1483
|
+
#define ZSTD_SHORT_CACHE_TAG_MASK ((1u << ZSTD_SHORT_CACHE_TAG_BITS) - 1)
|
|
1484
|
+
|
|
1485
|
+
/* Helper function for ZSTD_fillHashTable and ZSTD_fillDoubleHashTable.
|
|
1486
|
+
* Unpacks hashAndTag into (hash, tag), then packs (index, tag) into hashTable[hash]. */
|
|
1487
|
+
MEM_STATIC void ZSTD_writeTaggedIndex(U32* const hashTable, size_t hashAndTag, U32 index) {
|
|
1488
|
+
size_t const hash = hashAndTag >> ZSTD_SHORT_CACHE_TAG_BITS;
|
|
1489
|
+
U32 const tag = (U32)(hashAndTag & ZSTD_SHORT_CACHE_TAG_MASK);
|
|
1490
|
+
assert(index >> (32 - ZSTD_SHORT_CACHE_TAG_BITS) == 0);
|
|
1491
|
+
hashTable[hash] = (index << ZSTD_SHORT_CACHE_TAG_BITS) | tag;
|
|
1492
|
+
}
|
|
1361
1493
|
|
|
1362
|
-
|
|
1494
|
+
/* Helper function for short cache matchfinders.
|
|
1495
|
+
* Unpacks tag1 and tag2 from lower bits of packedTag1 and packedTag2, then checks if the tags match. */
|
|
1496
|
+
MEM_STATIC int ZSTD_comparePackedTags(size_t packedTag1, size_t packedTag2) {
|
|
1497
|
+
U32 const tag1 = packedTag1 & ZSTD_SHORT_CACHE_TAG_MASK;
|
|
1498
|
+
U32 const tag2 = packedTag2 & ZSTD_SHORT_CACHE_TAG_MASK;
|
|
1499
|
+
return tag1 == tag2;
|
|
1363
1500
|
}
|
|
1364
|
-
#endif
|
|
1365
1501
|
|
|
1366
1502
|
/* ===============================================================
|
|
1367
1503
|
* Shared internal declarations
|
|
@@ -1378,6 +1514,25 @@ size_t ZSTD_loadCEntropy(ZSTD_compressedBlockState_t* bs, void* workspace,
|
|
|
1378
1514
|
|
|
1379
1515
|
void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
|
|
1380
1516
|
|
|
1517
|
+
typedef struct {
|
|
1518
|
+
U32 idx; /* Index in array of ZSTD_Sequence */
|
|
1519
|
+
U32 posInSequence; /* Position within sequence at idx */
|
|
1520
|
+
size_t posInSrc; /* Number of bytes given by sequences provided so far */
|
|
1521
|
+
} ZSTD_SequencePosition;
|
|
1522
|
+
|
|
1523
|
+
/* for benchmark */
|
|
1524
|
+
size_t ZSTD_convertBlockSequences(ZSTD_CCtx* cctx,
|
|
1525
|
+
const ZSTD_Sequence* const inSeqs, size_t nbSequences,
|
|
1526
|
+
int const repcodeResolution);
|
|
1527
|
+
|
|
1528
|
+
typedef struct {
|
|
1529
|
+
size_t nbSequences;
|
|
1530
|
+
size_t blockSize;
|
|
1531
|
+
size_t litSize;
|
|
1532
|
+
} BlockSummary;
|
|
1533
|
+
|
|
1534
|
+
BlockSummary ZSTD_get1BlockSummary(const ZSTD_Sequence* seqs, size_t nbSeqs);
|
|
1535
|
+
|
|
1381
1536
|
/* ==============================================================
|
|
1382
1537
|
* Private declarations
|
|
1383
1538
|
* These prototypes shall only be called from within lib/compress
|
|
@@ -1389,7 +1544,7 @@ void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs);
|
|
|
1389
1544
|
* Note: srcSizeHint == 0 means 0!
|
|
1390
1545
|
*/
|
|
1391
1546
|
ZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(
|
|
1392
|
-
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize,
|
|
1547
|
+
const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize, ZSTD_CParamMode_e mode);
|
|
1393
1548
|
|
|
1394
1549
|
/*! ZSTD_initCStream_internal() :
|
|
1395
1550
|
* Private use only. Init streaming operation.
|
|
@@ -1401,7 +1556,7 @@ size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
|
|
|
1401
1556
|
const ZSTD_CDict* cdict,
|
|
1402
1557
|
const ZSTD_CCtx_params* params, unsigned long long pledgedSrcSize);
|
|
1403
1558
|
|
|
1404
|
-
void ZSTD_resetSeqStore(
|
|
1559
|
+
void ZSTD_resetSeqStore(SeqStore_t* ssPtr);
|
|
1405
1560
|
|
|
1406
1561
|
/*! ZSTD_getCParamsFromCDict() :
|
|
1407
1562
|
* as the name implies */
|
|
@@ -1440,11 +1595,10 @@ size_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity);
|
|
|
1440
1595
|
* This cannot be used when long range matching is enabled.
|
|
1441
1596
|
* Zstd will use these sequences, and pass the literals to a secondary block
|
|
1442
1597
|
* compressor.
|
|
1443
|
-
* @return : An error code on failure.
|
|
1444
1598
|
* NOTE: seqs are not verified! Invalid sequences can cause out-of-bounds memory
|
|
1445
1599
|
* access and data corruption.
|
|
1446
1600
|
*/
|
|
1447
|
-
|
|
1601
|
+
void ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq);
|
|
1448
1602
|
|
|
1449
1603
|
/** ZSTD_cycleLog() :
|
|
1450
1604
|
* condition for correct operation : hashLog > 1 */
|
|
@@ -1455,4 +1609,28 @@ U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat);
|
|
|
1455
1609
|
*/
|
|
1456
1610
|
void ZSTD_CCtx_trace(ZSTD_CCtx* cctx, size_t extraCSize);
|
|
1457
1611
|
|
|
1612
|
+
/* Returns 1 if an external sequence producer is registered, otherwise returns 0. */
|
|
1613
|
+
MEM_STATIC int ZSTD_hasExtSeqProd(const ZSTD_CCtx_params* params) {
|
|
1614
|
+
return params->extSeqProdFunc != NULL;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
/* ===============================================================
|
|
1618
|
+
* Deprecated definitions that are still used internally to avoid
|
|
1619
|
+
* deprecation warnings. These functions are exactly equivalent to
|
|
1620
|
+
* their public variants, but avoid the deprecation warnings.
|
|
1621
|
+
* =============================================================== */
|
|
1622
|
+
|
|
1623
|
+
size_t ZSTD_compressBegin_usingCDict_deprecated(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
|
|
1624
|
+
|
|
1625
|
+
size_t ZSTD_compressContinue_public(ZSTD_CCtx* cctx,
|
|
1626
|
+
void* dst, size_t dstCapacity,
|
|
1627
|
+
const void* src, size_t srcSize);
|
|
1628
|
+
|
|
1629
|
+
size_t ZSTD_compressEnd_public(ZSTD_CCtx* cctx,
|
|
1630
|
+
void* dst, size_t dstCapacity,
|
|
1631
|
+
const void* src, size_t srcSize);
|
|
1632
|
+
|
|
1633
|
+
size_t ZSTD_compressBlock_deprecated(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
|
|
1634
|
+
|
|
1635
|
+
|
|
1458
1636
|
#endif /* ZSTD_COMPRESS_H */
|