/src/duckdb/third_party/brotli/enc/brotli_hash.h
Line | Count | Source |
1 | | /* Copyright 2010 Google Inc. All Rights Reserved. |
2 | | |
3 | | Distributed under MIT license. |
4 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
5 | | */ |
6 | | |
7 | | /* A (forgetful) hash table to the data seen by the compressor, to |
8 | | help create backward references to previous data. */ |
9 | | |
10 | | #ifndef BROTLI_ENC_HASH_H_ |
11 | | #define BROTLI_ENC_HASH_H_ |
12 | | |
13 | | #include <stdlib.h> /* exit */ |
14 | | #include <string.h> /* memcmp, memset */ |
15 | | |
16 | | #include <brotli/types.h> |
17 | | |
18 | | #include "../common/brotli_constants.h" |
19 | | #include "../common/dictionary.h" |
20 | | #include "../common/brotli_platform.h" |
21 | | #include "compound_dictionary.h" |
22 | | #include "encoder_dict.h" |
23 | | #include "fast_log.h" |
24 | | #include "find_match_length.h" |
25 | | #include "memory.h" |
26 | | #include "quality.h" |
27 | | #include "static_dict.h" |
28 | | |
29 | | namespace duckdb_brotli { |
30 | | |
31 | | typedef struct { |
32 | | /** |
33 | | * Dynamically allocated areas; regular hasher uses one or two allocations; |
34 | | * "composite" hasher uses up to 4 allocations. |
35 | | */ |
36 | | void* extra[4]; |
37 | | |
38 | | /** |
39 | | * False before the fisrt invocation of HasherSetup (where "extra" memory) |
40 | | * is allocated. |
41 | | */ |
42 | | BROTLI_BOOL is_setup_; |
43 | | |
44 | | size_t dict_num_lookups; |
45 | | size_t dict_num_matches; |
46 | | |
47 | | BrotliHasherParams params; |
48 | | |
49 | | /** |
50 | | * False if hasher needs to be "prepared" before use (before the first |
51 | | * invocation of HasherSetup or after HasherReset). "preparation" is hasher |
52 | | * data initialization (using input ringbuffer). |
53 | | */ |
54 | | BROTLI_BOOL is_prepared_; |
55 | | } HasherCommon; |
56 | | |
57 | 0 | #define score_t size_t |
58 | | |
59 | | static const uint32_t kCutoffTransformsCount = 10; |
60 | | /* 0, 12, 27, 23, 42, 63, 56, 48, 59, 64 */ |
61 | | /* 0+0, 4+8, 8+19, 12+11, 16+26, 20+43, 24+32, 28+20, 32+27, 36+28 */ |
62 | | static const uint64_t kCutoffTransforms = |
63 | | BROTLI_MAKE_UINT64_T(0x071B520A, 0xDA2D3200); |
64 | | |
65 | | typedef struct HasherSearchResult { |
66 | | size_t len; |
67 | | size_t distance; |
68 | | score_t score; |
69 | | int len_code_delta; /* == len_code - len */ |
70 | | } HasherSearchResult; |
71 | | |
72 | | /* kHashMul32 multiplier has these properties: |
73 | | * The multiplier must be odd. Otherwise we may lose the highest bit. |
74 | | * No long streaks of ones or zeros. |
75 | | * There is no effort to ensure that it is a prime, the oddity is enough |
76 | | for this use. |
77 | | * The number has been tuned heuristically against compression benchmarks. */ |
78 | | static const uint32_t kHashMul32 = 0x1E35A7BD; |
79 | | static const uint64_t kHashMul64 = |
80 | | BROTLI_MAKE_UINT64_T(0x1FE35A7Bu, 0xD3579BD3u); |
81 | | |
82 | 0 | static BROTLI_INLINE uint32_t Hash14(const uint8_t* data) { |
83 | 0 | uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; |
84 | | /* The higher bits contain more mixture from the multiplication, |
85 | | so we take our results from there. */ |
86 | 0 | return h >> (32 - 14); |
87 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::Hash14(unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::Hash14(unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::Hash14(unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::Hash14(unsigned char const*) |
88 | | |
89 | | static BROTLI_INLINE void PrepareDistanceCache( |
90 | 0 | int* BROTLI_RESTRICT distance_cache, const int num_distances) { |
91 | 0 | if (num_distances > 4) { |
92 | 0 | int last_distance = distance_cache[0]; |
93 | 0 | distance_cache[4] = last_distance - 1; |
94 | 0 | distance_cache[5] = last_distance + 1; |
95 | 0 | distance_cache[6] = last_distance - 2; |
96 | 0 | distance_cache[7] = last_distance + 2; |
97 | 0 | distance_cache[8] = last_distance - 3; |
98 | 0 | distance_cache[9] = last_distance + 3; |
99 | 0 | if (num_distances > 10) { |
100 | 0 | int next_last_distance = distance_cache[1]; |
101 | 0 | distance_cache[10] = next_last_distance - 1; |
102 | 0 | distance_cache[11] = next_last_distance + 1; |
103 | 0 | distance_cache[12] = next_last_distance - 2; |
104 | 0 | distance_cache[13] = next_last_distance + 2; |
105 | 0 | distance_cache[14] = next_last_distance - 3; |
106 | 0 | distance_cache[15] = next_last_distance + 3; |
107 | 0 | } |
108 | 0 | } |
109 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCache(int*, int) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCache(int*, int) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCache(int*, int) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCache(int*, int) |
110 | | |
111 | 0 | #define BROTLI_LITERAL_BYTE_SCORE 135 |
112 | 0 | #define BROTLI_DISTANCE_BIT_PENALTY 30 |
113 | | /* Score must be positive after applying maximal penalty. */ |
114 | 0 | #define BROTLI_SCORE_BASE (BROTLI_DISTANCE_BIT_PENALTY * 8 * sizeof(size_t)) |
115 | | |
116 | | /* Usually, we always choose the longest backward reference. This function |
117 | | allows for the exception of that rule. |
118 | | |
119 | | If we choose a backward reference that is further away, it will |
120 | | usually be coded with more bits. We approximate this by assuming |
121 | | log2(distance). If the distance can be expressed in terms of the |
122 | | last four distances, we use some heuristic constants to estimate |
123 | | the bits cost. For the first up to four literals we use the bit |
124 | | cost of the literals from the literal cost model, after that we |
125 | | use the average bit cost of the cost model. |
126 | | |
127 | | This function is used to sometimes discard a longer backward reference |
128 | | when it is not much longer and the bit cost for encoding it is more |
129 | | than the saved literals. |
130 | | |
131 | | backward_reference_offset MUST be positive. */ |
132 | | static BROTLI_INLINE score_t BackwardReferenceScore( |
133 | 0 | size_t copy_length, size_t backward_reference_offset) { |
134 | 0 | return BROTLI_SCORE_BASE + BROTLI_LITERAL_BYTE_SCORE * (score_t)copy_length - |
135 | 0 | BROTLI_DISTANCE_BIT_PENALTY * Log2FloorNonZero(backward_reference_offset); |
136 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::BackwardReferenceScore(unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::BackwardReferenceScore(unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::BackwardReferenceScore(unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::BackwardReferenceScore(unsigned long, unsigned long) |
137 | | |
138 | | static BROTLI_INLINE score_t BackwardReferenceScoreUsingLastDistance( |
139 | 0 | size_t copy_length) { |
140 | 0 | return BROTLI_LITERAL_BYTE_SCORE * (score_t)copy_length + |
141 | 0 | BROTLI_SCORE_BASE + 15; |
142 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::BackwardReferenceScoreUsingLastDistance(unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::BackwardReferenceScoreUsingLastDistance(unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::BackwardReferenceScoreUsingLastDistance(unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::BackwardReferenceScoreUsingLastDistance(unsigned long) |
143 | | |
144 | | static BROTLI_INLINE score_t BackwardReferencePenaltyUsingLastDistance( |
145 | 0 | size_t distance_short_code) { |
146 | 0 | return (score_t)39 + ((0x1CA10 >> (distance_short_code & 0xE)) & 0xE); |
147 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::BackwardReferencePenaltyUsingLastDistance(unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::BackwardReferencePenaltyUsingLastDistance(unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::BackwardReferencePenaltyUsingLastDistance(unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::BackwardReferencePenaltyUsingLastDistance(unsigned long) |
148 | | |
149 | | static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem( |
150 | | const BrotliEncoderDictionary* dictionary, size_t len, size_t word_idx, |
151 | | const uint8_t* data, size_t max_length, size_t max_backward, |
152 | 0 | size_t max_distance, HasherSearchResult* out) { |
153 | 0 | size_t offset; |
154 | 0 | size_t matchlen; |
155 | 0 | size_t backward; |
156 | 0 | score_t score; |
157 | 0 | offset = dictionary->words->offsets_by_length[len] + len * word_idx; |
158 | 0 | if (len > max_length) { |
159 | 0 | return BROTLI_FALSE; |
160 | 0 | } |
161 | | |
162 | 0 | matchlen = |
163 | 0 | FindMatchLengthWithLimit(data, &dictionary->words->data[offset], len); |
164 | 0 | if (matchlen + dictionary->cutoffTransformsCount <= len || matchlen == 0) { |
165 | 0 | return BROTLI_FALSE; |
166 | 0 | } |
167 | 0 | { |
168 | 0 | size_t cut = len - matchlen; |
169 | 0 | size_t transform_id = (cut << 2) + |
170 | 0 | (size_t)((dictionary->cutoffTransforms >> (cut * 6)) & 0x3F); |
171 | 0 | backward = max_backward + 1 + word_idx + |
172 | 0 | (transform_id << dictionary->words->size_bits_by_length[len]); |
173 | 0 | } |
174 | 0 | if (backward > max_distance) { |
175 | 0 | return BROTLI_FALSE; |
176 | 0 | } |
177 | 0 | score = BackwardReferenceScore(matchlen, backward); |
178 | 0 | if (score < out->score) { |
179 | 0 | return BROTLI_FALSE; |
180 | 0 | } |
181 | 0 | out->len = matchlen; |
182 | 0 | out->len_code_delta = (int)len - (int)matchlen; |
183 | 0 | out->distance = backward; |
184 | 0 | out->score = score; |
185 | 0 | return BROTLI_TRUE; |
186 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::TestStaticDictionaryItem(duckdb_brotli::BrotliEncoderDictionary const*, unsigned long, unsigned long, unsigned char const*, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::TestStaticDictionaryItem(duckdb_brotli::BrotliEncoderDictionary const*, unsigned long, unsigned long, unsigned char const*, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::TestStaticDictionaryItem(duckdb_brotli::BrotliEncoderDictionary const*, unsigned long, unsigned long, unsigned char const*, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::TestStaticDictionaryItem(duckdb_brotli::BrotliEncoderDictionary const*, unsigned long, unsigned long, unsigned char const*, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
187 | | |
188 | | static BROTLI_INLINE void SearchInStaticDictionary( |
189 | | const BrotliEncoderDictionary* dictionary, |
190 | | HasherCommon* common, const uint8_t* data, size_t max_length, |
191 | | size_t max_backward, size_t max_distance, |
192 | 0 | HasherSearchResult* out, BROTLI_BOOL shallow) { |
193 | 0 | size_t key; |
194 | 0 | size_t i; |
195 | 0 | if (common->dict_num_matches < (common->dict_num_lookups >> 7)) { |
196 | 0 | return; |
197 | 0 | } |
198 | 0 | key = Hash14(data) << 1; |
199 | 0 | for (i = 0; i < (shallow ? 1u : 2u); ++i, ++key) { |
200 | 0 | common->dict_num_lookups++; |
201 | 0 | if (dictionary->hash_table_lengths[key] != 0) { |
202 | 0 | BROTLI_BOOL item_matches = TestStaticDictionaryItem( |
203 | 0 | dictionary, dictionary->hash_table_lengths[key], |
204 | 0 | dictionary->hash_table_words[key], data, |
205 | 0 | max_length, max_backward, max_distance, out); |
206 | 0 | if (item_matches) { |
207 | 0 | common->dict_num_matches++; |
208 | 0 | } |
209 | 0 | } |
210 | 0 | } |
211 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::SearchInStaticDictionary(duckdb_brotli::BrotliEncoderDictionary const*, duckdb_brotli::HasherCommon*, unsigned char const*, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*, int) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::SearchInStaticDictionary(duckdb_brotli::BrotliEncoderDictionary const*, duckdb_brotli::HasherCommon*, unsigned char const*, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*, int) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::SearchInStaticDictionary(duckdb_brotli::BrotliEncoderDictionary const*, duckdb_brotli::HasherCommon*, unsigned char const*, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*, int) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::SearchInStaticDictionary(duckdb_brotli::BrotliEncoderDictionary const*, duckdb_brotli::HasherCommon*, unsigned char const*, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*, int) |
212 | | |
213 | | typedef struct BackwardMatch { |
214 | | uint32_t distance; |
215 | | uint32_t length_and_code; |
216 | | } BackwardMatch; |
217 | | |
218 | | static BROTLI_INLINE void InitBackwardMatch(BackwardMatch* self, |
219 | 0 | size_t dist, size_t len) { |
220 | 0 | self->distance = (uint32_t)dist; |
221 | 0 | self->length_and_code = (uint32_t)(len << 5); |
222 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitBackwardMatch(duckdb_brotli::BackwardMatch*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitBackwardMatch(duckdb_brotli::BackwardMatch*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitBackwardMatch(duckdb_brotli::BackwardMatch*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitBackwardMatch(duckdb_brotli::BackwardMatch*, unsigned long, unsigned long) |
223 | | |
224 | | static BROTLI_INLINE void InitDictionaryBackwardMatch(BackwardMatch* self, |
225 | 0 | size_t dist, size_t len, size_t len_code) { |
226 | 0 | self->distance = (uint32_t)dist; |
227 | 0 | self->length_and_code = |
228 | 0 | (uint32_t)((len << 5) | (len == len_code ? 0 : len_code)); |
229 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitDictionaryBackwardMatch(duckdb_brotli::BackwardMatch*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitDictionaryBackwardMatch(duckdb_brotli::BackwardMatch*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitDictionaryBackwardMatch(duckdb_brotli::BackwardMatch*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitDictionaryBackwardMatch(duckdb_brotli::BackwardMatch*, unsigned long, unsigned long, unsigned long) |
230 | | |
231 | 0 | static BROTLI_INLINE size_t BackwardMatchLength(const BackwardMatch* self) { |
232 | 0 | return self->length_and_code >> 5; |
233 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::BackwardMatchLength(duckdb_brotli::BackwardMatch const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::BackwardMatchLength(duckdb_brotli::BackwardMatch const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::BackwardMatchLength(duckdb_brotli::BackwardMatch const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::BackwardMatchLength(duckdb_brotli::BackwardMatch const*) |
234 | | |
235 | 0 | static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) { |
236 | 0 | size_t code = self->length_and_code & 31; |
237 | 0 | return code ? code : BackwardMatchLength(self); |
238 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::BackwardMatchLengthCode(duckdb_brotli::BackwardMatch const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::BackwardMatchLengthCode(duckdb_brotli::BackwardMatch const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::BackwardMatchLengthCode(duckdb_brotli::BackwardMatch const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::BackwardMatchLengthCode(duckdb_brotli::BackwardMatch const*) |
239 | | |
240 | 0 | #define EXPAND_CAT(a, b) CAT(a, b) |
241 | 0 | #define CAT(a, b) a ## b |
242 | 0 | #define FN(X) EXPAND_CAT(X, HASHER()) |
243 | | |
244 | | #define HASHER() H10 |
245 | 0 | #define BUCKET_BITS 17 |
246 | 0 | #define MAX_TREE_SEARCH_DEPTH 64 |
247 | 0 | #define MAX_TREE_COMP_LENGTH 128 |
248 | | /* NOLINT(build/header_guard) */ |
249 | | /* Copyright 2016 Google Inc. All Rights Reserved. |
250 | | |
251 | | Distributed under MIT license. |
252 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
253 | | */ |
254 | | |
255 | | /* template parameters: FN, BUCKET_BITS, MAX_TREE_COMP_LENGTH, |
256 | | MAX_TREE_SEARCH_DEPTH */ |
257 | | |
258 | | /* A (forgetful) hash table where each hash bucket contains a binary tree of |
259 | | sequences whose first 4 bytes share the same hash code. |
260 | | Each sequence is MAX_TREE_COMP_LENGTH long and is identified by its starting |
261 | | position in the input data. The binary tree is sorted by the lexicographic |
262 | | order of the sequences, and it is also a max-heap with respect to the |
263 | | starting positions. */ |
264 | | |
265 | | #define HashToBinaryTree HASHER() |
266 | | |
267 | 0 | #define BUCKET_SIZE (1 << BUCKET_BITS) |
268 | | |
269 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH10() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH10() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH10() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH10() |
270 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { |
271 | 0 | return MAX_TREE_COMP_LENGTH; |
272 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH10() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH10() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH10() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH10() |
273 | | |
274 | 0 | static uint32_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) { |
275 | 0 | uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; |
276 | | /* The higher bits contain more mixture from the multiplication, |
277 | | so we take our results from there. */ |
278 | 0 | return h >> (32 - BUCKET_BITS); |
279 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashBytesH10(unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashBytesH10(unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashBytesH10(unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashBytesH10(unsigned char const*) |
280 | | |
281 | | typedef struct HashToBinaryTree { |
282 | | /* The window size minus 1 */ |
283 | | size_t window_mask_; |
284 | | |
285 | | /* Hash table that maps the 4-byte hashes of the sequence to the last |
286 | | position where this hash was found, which is the root of the binary |
287 | | tree of sequences that share this hash bucket. */ |
288 | | uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */ |
289 | | |
290 | | /* A position used to mark a non-existent sequence, i.e. a tree is empty if |
291 | | its root is at invalid_pos_ and a node is a leaf if both its children |
292 | | are at invalid_pos_. */ |
293 | | uint32_t invalid_pos_; |
294 | | |
295 | | /* --- Dynamic size members --- */ |
296 | | |
297 | | /* The union of the binary trees of each hash bucket. The root of the tree |
298 | | corresponding to a hash is a sequence starting at buckets_[hash] and |
299 | | the left and right children of a sequence starting at pos are |
300 | | forest_[2 * pos] and forest_[2 * pos + 1]. */ |
301 | | uint32_t* forest_; /* uint32_t[2 * num_nodes] */ |
302 | | } HashToBinaryTree; |
303 | | |
304 | | static void FN(Initialize)( |
305 | | HasherCommon* common, HashToBinaryTree* BROTLI_RESTRICT self, |
306 | 0 | const BrotliEncoderParams* params) { |
307 | 0 | self->buckets_ = (uint32_t*)common->extra[0]; |
308 | 0 | self->forest_ = (uint32_t*)common->extra[1]; |
309 | |
|
310 | 0 | self->window_mask_ = (1u << params->lgwin) - 1u; |
311 | 0 | self->invalid_pos_ = (uint32_t)(0 - self->window_mask_); |
312 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH10(duckdb_brotli::HasherCommon*, duckdb_brotli::H10*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH10(duckdb_brotli::HasherCommon*, duckdb_brotli::H10*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH10(duckdb_brotli::HasherCommon*, duckdb_brotli::H10*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH10(duckdb_brotli::HasherCommon*, duckdb_brotli::H10*, BrotliEncoderParams const*) |
313 | | |
314 | | static void FN(Prepare) |
315 | | (HashToBinaryTree* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
316 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
317 | 0 | uint32_t invalid_pos = self->invalid_pos_; |
318 | 0 | uint32_t i; |
319 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
320 | 0 | BROTLI_UNUSED(data); |
321 | 0 | BROTLI_UNUSED(one_shot); |
322 | 0 | BROTLI_UNUSED(input_size); |
323 | 0 | for (i = 0; i < BUCKET_SIZE; i++) { |
324 | 0 | buckets[i] = invalid_pos; |
325 | 0 | } |
326 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH10(duckdb_brotli::H10*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH10(duckdb_brotli::H10*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH10(duckdb_brotli::H10*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH10(duckdb_brotli::H10*, int, unsigned long, unsigned char const*) |
327 | | |
328 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
329 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
330 | 0 | size_t input_size, size_t* alloc_size) { |
331 | 0 | size_t num_nodes = (size_t)1 << params->lgwin; |
332 | 0 | if (one_shot && input_size < num_nodes) { |
333 | 0 | num_nodes = input_size; |
334 | 0 | } |
335 | 0 | alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE; |
336 | 0 | alloc_size[1] = 2 * sizeof(uint32_t) * num_nodes; |
337 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH10(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH10(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH10(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH10(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
338 | | |
339 | | static BROTLI_INLINE size_t FN(LeftChildIndex)( |
340 | | HashToBinaryTree* BROTLI_RESTRICT self, |
341 | 0 | const size_t pos) { |
342 | 0 | return 2 * (pos & self->window_mask_); |
343 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::LeftChildIndexH10(duckdb_brotli::H10*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::LeftChildIndexH10(duckdb_brotli::H10*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::LeftChildIndexH10(duckdb_brotli::H10*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::LeftChildIndexH10(duckdb_brotli::H10*, unsigned long) |
344 | | |
345 | | static BROTLI_INLINE size_t FN(RightChildIndex)( |
346 | | HashToBinaryTree* BROTLI_RESTRICT self, |
347 | 0 | const size_t pos) { |
348 | 0 | return 2 * (pos & self->window_mask_) + 1; |
349 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::RightChildIndexH10(duckdb_brotli::H10*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::RightChildIndexH10(duckdb_brotli::H10*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::RightChildIndexH10(duckdb_brotli::H10*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::RightChildIndexH10(duckdb_brotli::H10*, unsigned long) |
350 | | |
351 | | /* Stores the hash of the next 4 bytes and in a single tree-traversal, the |
352 | | hash bucket's binary tree is searched for matches and is re-rooted at the |
353 | | current position. |
354 | | |
355 | | If less than MAX_TREE_COMP_LENGTH data is available, the hash bucket of the |
356 | | current position is searched for matches, but the state of the hash table |
357 | | is not changed, since we can not know the final sorting order of the |
358 | | current (incomplete) sequence. |
359 | | |
360 | | This function must be called with increasing cur_ix positions. */ |
361 | | static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)( |
362 | | HashToBinaryTree* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, |
363 | | const size_t cur_ix, const size_t ring_buffer_mask, const size_t max_length, |
364 | | const size_t max_backward, size_t* const BROTLI_RESTRICT best_len, |
365 | 0 | BackwardMatch* BROTLI_RESTRICT matches) { |
366 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
367 | 0 | const size_t max_comp_len = |
368 | 0 | BROTLI_MIN(size_t, max_length, MAX_TREE_COMP_LENGTH); |
369 | 0 | const BROTLI_BOOL should_reroot_tree = |
370 | 0 | TO_BROTLI_BOOL(max_length >= MAX_TREE_COMP_LENGTH); |
371 | 0 | const uint32_t key = FN(HashBytes)(&data[cur_ix_masked]); |
372 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
373 | 0 | uint32_t* BROTLI_RESTRICT forest = self->forest_; |
374 | 0 | size_t prev_ix = buckets[key]; |
375 | | /* The forest index of the rightmost node of the left subtree of the new |
376 | | root, updated as we traverse and re-root the tree of the hash bucket. */ |
377 | 0 | size_t node_left = FN(LeftChildIndex)(self, cur_ix); |
378 | | /* The forest index of the leftmost node of the right subtree of the new |
379 | | root, updated as we traverse and re-root the tree of the hash bucket. */ |
380 | 0 | size_t node_right = FN(RightChildIndex)(self, cur_ix); |
381 | | /* The match length of the rightmost node of the left subtree of the new |
382 | | root, updated as we traverse and re-root the tree of the hash bucket. */ |
383 | 0 | size_t best_len_left = 0; |
384 | | /* The match length of the leftmost node of the right subtree of the new |
385 | | root, updated as we traverse and re-root the tree of the hash bucket. */ |
386 | 0 | size_t best_len_right = 0; |
387 | 0 | size_t depth_remaining; |
388 | 0 | if (should_reroot_tree) { |
389 | 0 | buckets[key] = (uint32_t)cur_ix; |
390 | 0 | } |
391 | 0 | for (depth_remaining = MAX_TREE_SEARCH_DEPTH; ; --depth_remaining) { |
392 | 0 | const size_t backward = cur_ix - prev_ix; |
393 | 0 | const size_t prev_ix_masked = prev_ix & ring_buffer_mask; |
394 | 0 | if (backward == 0 || backward > max_backward || depth_remaining == 0) { |
395 | 0 | if (should_reroot_tree) { |
396 | 0 | forest[node_left] = self->invalid_pos_; |
397 | 0 | forest[node_right] = self->invalid_pos_; |
398 | 0 | } |
399 | 0 | break; |
400 | 0 | } |
401 | 0 | { |
402 | 0 | const size_t cur_len = BROTLI_MIN(size_t, best_len_left, best_len_right); |
403 | 0 | size_t len; |
404 | 0 | BROTLI_DCHECK(cur_len <= MAX_TREE_COMP_LENGTH); |
405 | 0 | len = cur_len + |
406 | 0 | FindMatchLengthWithLimit(&data[cur_ix_masked + cur_len], |
407 | 0 | &data[prev_ix_masked + cur_len], |
408 | 0 | max_length - cur_len); |
409 | 0 | BROTLI_DCHECK( |
410 | 0 | 0 == memcmp(&data[cur_ix_masked], &data[prev_ix_masked], len)); |
411 | 0 | if (matches && len > *best_len) { |
412 | 0 | *best_len = len; |
413 | 0 | InitBackwardMatch(matches++, backward, len); |
414 | 0 | } |
415 | 0 | if (len >= max_comp_len) { |
416 | 0 | if (should_reroot_tree) { |
417 | 0 | forest[node_left] = forest[FN(LeftChildIndex)(self, prev_ix)]; |
418 | 0 | forest[node_right] = forest[FN(RightChildIndex)(self, prev_ix)]; |
419 | 0 | } |
420 | 0 | break; |
421 | 0 | } |
422 | 0 | if (data[cur_ix_masked + len] > data[prev_ix_masked + len]) { |
423 | 0 | best_len_left = len; |
424 | 0 | if (should_reroot_tree) { |
425 | 0 | forest[node_left] = (uint32_t)prev_ix; |
426 | 0 | } |
427 | 0 | node_left = FN(RightChildIndex)(self, prev_ix); |
428 | 0 | prev_ix = forest[node_left]; |
429 | 0 | } else { |
430 | 0 | best_len_right = len; |
431 | 0 | if (should_reroot_tree) { |
432 | 0 | forest[node_right] = (uint32_t)prev_ix; |
433 | 0 | } |
434 | 0 | node_right = FN(LeftChildIndex)(self, prev_ix); |
435 | 0 | prev_ix = forest[node_right]; |
436 | 0 | } |
437 | 0 | } |
438 | 0 | } |
439 | 0 | return matches; |
440 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreAndFindMatchesH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long*, duckdb_brotli::BackwardMatch*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreAndFindMatchesH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long*, duckdb_brotli::BackwardMatch*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreAndFindMatchesH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long*, duckdb_brotli::BackwardMatch*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreAndFindMatchesH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long*, duckdb_brotli::BackwardMatch*) |
441 | | |
442 | | /* Finds all backward matches of &data[cur_ix & ring_buffer_mask] up to the |
443 | | length of max_length and stores the position cur_ix in the hash table. |
444 | | |
445 | | Sets *num_matches to the number of matches found, and stores the found |
446 | | matches in matches[0] to matches[*num_matches - 1]. The matches will be |
447 | | sorted by strictly increasing length and (non-strictly) increasing |
448 | | distance. */ |
449 | | static BROTLI_INLINE size_t FN(FindAllMatches)( |
450 | | HashToBinaryTree* BROTLI_RESTRICT self, |
451 | | const BrotliEncoderDictionary* dictionary, |
452 | | const uint8_t* BROTLI_RESTRICT data, |
453 | | const size_t ring_buffer_mask, const size_t cur_ix, |
454 | | const size_t max_length, const size_t max_backward, |
455 | | const size_t dictionary_distance, const BrotliEncoderParams* params, |
456 | 0 | BackwardMatch* matches) { |
457 | 0 | BackwardMatch* const orig_matches = matches; |
458 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
459 | 0 | size_t best_len = 1; |
460 | 0 | const size_t short_match_max_backward = |
461 | 0 | params->quality != HQ_ZOPFLIFICATION_QUALITY ? 16 : 64; |
462 | 0 | size_t stop = cur_ix - short_match_max_backward; |
463 | 0 | uint32_t dict_matches[BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN + 1]; |
464 | 0 | size_t i; |
465 | 0 | if (cur_ix < short_match_max_backward) { stop = 0; } |
466 | 0 | for (i = cur_ix - 1; i > stop && best_len <= 2; --i) { |
467 | 0 | size_t prev_ix = i; |
468 | 0 | const size_t backward = cur_ix - prev_ix; |
469 | 0 | if (BROTLI_PREDICT_FALSE(backward > max_backward)) { |
470 | 0 | break; |
471 | 0 | } |
472 | 0 | prev_ix &= ring_buffer_mask; |
473 | 0 | if (data[cur_ix_masked] != data[prev_ix] || |
474 | 0 | data[cur_ix_masked + 1] != data[prev_ix + 1]) { |
475 | 0 | continue; |
476 | 0 | } |
477 | 0 | { |
478 | 0 | const size_t len = |
479 | 0 | FindMatchLengthWithLimit(&data[prev_ix], &data[cur_ix_masked], |
480 | 0 | max_length); |
481 | 0 | if (len > best_len) { |
482 | 0 | best_len = len; |
483 | 0 | InitBackwardMatch(matches++, backward, len); |
484 | 0 | } |
485 | 0 | } |
486 | 0 | } |
487 | 0 | if (best_len < max_length) { |
488 | 0 | matches = FN(StoreAndFindMatches)(self, data, cur_ix, |
489 | 0 | ring_buffer_mask, max_length, max_backward, &best_len, matches); |
490 | 0 | } |
491 | 0 | for (i = 0; i <= BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN; ++i) { |
492 | 0 | dict_matches[i] = kInvalidMatch; |
493 | 0 | } |
494 | 0 | { |
495 | 0 | size_t minlen = BROTLI_MAX(size_t, 4, best_len + 1); |
496 | 0 | if (BrotliFindAllStaticDictionaryMatches(dictionary, |
497 | 0 | &data[cur_ix_masked], minlen, max_length, &dict_matches[0])) { |
498 | 0 | size_t maxlen = BROTLI_MIN( |
499 | 0 | size_t, BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN, max_length); |
500 | 0 | size_t l; |
501 | 0 | for (l = minlen; l <= maxlen; ++l) { |
502 | 0 | uint32_t dict_id = dict_matches[l]; |
503 | 0 | if (dict_id < kInvalidMatch) { |
504 | 0 | size_t distance = dictionary_distance + (dict_id >> 5) + 1; |
505 | 0 | if (distance <= params->dist.max_distance) { |
506 | 0 | InitDictionaryBackwardMatch(matches++, distance, l, dict_id & 31); |
507 | 0 | } |
508 | 0 | } |
509 | 0 | } |
510 | 0 | } |
511 | 0 | } |
512 | 0 | return (size_t)(matches - orig_matches); |
513 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindAllMatchesH10(duckdb_brotli::H10*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, BrotliEncoderParams const*, duckdb_brotli::BackwardMatch*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindAllMatchesH10(duckdb_brotli::H10*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, BrotliEncoderParams const*, duckdb_brotli::BackwardMatch*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindAllMatchesH10(duckdb_brotli::H10*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, BrotliEncoderParams const*, duckdb_brotli::BackwardMatch*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindAllMatchesH10(duckdb_brotli::H10*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, BrotliEncoderParams const*, duckdb_brotli::BackwardMatch*) |
514 | | |
515 | | /* Stores the hash of the next 4 bytes and re-roots the binary tree at the |
516 | | current sequence, without returning any matches. |
517 | | REQUIRES: ix + MAX_TREE_COMP_LENGTH <= end-of-current-block */ |
518 | | static BROTLI_INLINE void FN(Store)(HashToBinaryTree* BROTLI_RESTRICT self, |
519 | | const uint8_t* BROTLI_RESTRICT data, |
520 | 0 | const size_t mask, const size_t ix) { |
521 | | /* Maximum distance is window size - 16, see section 9.1. of the spec. */ |
522 | 0 | const size_t max_backward = self->window_mask_ - BROTLI_WINDOW_GAP + 1; |
523 | 0 | FN(StoreAndFindMatches)(self, data, ix, mask, MAX_TREE_COMP_LENGTH, |
524 | 0 | max_backward, NULL, NULL); |
525 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long) |
526 | | |
527 | | static BROTLI_INLINE void FN(StoreRange)(HashToBinaryTree* BROTLI_RESTRICT self, |
528 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
529 | 0 | const size_t ix_start, const size_t ix_end) { |
530 | 0 | size_t i = ix_start; |
531 | 0 | size_t j = ix_start; |
532 | 0 | if (ix_start + 63 <= ix_end) { |
533 | 0 | i = ix_end - 63; |
534 | 0 | } |
535 | 0 | if (ix_start + 512 <= i) { |
536 | 0 | for (; j < i; j += 8) { |
537 | 0 | FN(Store)(self, data, mask, j); |
538 | 0 | } |
539 | 0 | } |
540 | 0 | for (; i < ix_end; ++i) { |
541 | 0 | FN(Store)(self, data, mask, i); |
542 | 0 | } |
543 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH10(duckdb_brotli::H10*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
544 | | |
545 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
546 | | HashToBinaryTree* BROTLI_RESTRICT self, |
547 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
548 | 0 | size_t ringbuffer_mask) { |
549 | 0 | if (num_bytes >= FN(HashTypeLength)() - 1 && |
550 | 0 | position >= MAX_TREE_COMP_LENGTH) { |
551 | | /* Store the last `MAX_TREE_COMP_LENGTH - 1` positions in the hasher. |
552 | | These could not be calculated before, since they require knowledge |
553 | | of both the previous and the current block. */ |
554 | 0 | const size_t i_start = position - MAX_TREE_COMP_LENGTH + 1; |
555 | 0 | const size_t i_end = BROTLI_MIN(size_t, position, i_start + num_bytes); |
556 | 0 | size_t i; |
557 | 0 | for (i = i_start; i < i_end; ++i) { |
558 | | /* Maximum distance is window size - 16, see section 9.1. of the spec. |
559 | | Furthermore, we have to make sure that we don't look further back |
560 | | from the start of the next block than the window size, otherwise we |
561 | | could access already overwritten areas of the ring-buffer. */ |
562 | 0 | const size_t max_backward = |
563 | 0 | self->window_mask_ - BROTLI_MAX(size_t, |
564 | 0 | BROTLI_WINDOW_GAP - 1, |
565 | 0 | position - i); |
566 | | /* We know that i + MAX_TREE_COMP_LENGTH <= position + num_bytes, i.e. the |
567 | | end of the current block and that we have at least |
568 | | MAX_TREE_COMP_LENGTH tail in the ring-buffer. */ |
569 | 0 | FN(StoreAndFindMatches)(self, ringbuffer, i, ringbuffer_mask, |
570 | 0 | MAX_TREE_COMP_LENGTH, max_backward, NULL, NULL); |
571 | 0 | } |
572 | 0 | } |
573 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH10(duckdb_brotli::H10*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH10(duckdb_brotli::H10*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH10(duckdb_brotli::H10*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH10(duckdb_brotli::H10*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
574 | | |
575 | | #undef BUCKET_SIZE |
576 | | |
577 | | #undef HashToBinaryTree |
578 | | #undef MAX_TREE_SEARCH_DEPTH |
579 | | #undef MAX_TREE_COMP_LENGTH |
580 | | #undef BUCKET_BITS |
581 | | #undef HASHER |
582 | | /* MAX_NUM_MATCHES == 64 + MAX_TREE_SEARCH_DEPTH */ |
583 | 0 | #define MAX_NUM_MATCHES_H10 128 |
584 | | |
585 | | /* For BUCKET_SWEEP_BITS == 0, enabling the dictionary lookup makes compression |
586 | | a little faster (0.5% - 1%) and it compresses 0.15% better on small text |
587 | | and HTML inputs. */ |
588 | | |
589 | | #define HASHER() H2 |
590 | 0 | #define BUCKET_BITS 16 |
591 | 0 | #define BUCKET_SWEEP_BITS 0 |
592 | 0 | #define HASH_LEN 5 |
593 | 0 | #define USE_DICTIONARY 1 |
594 | | /* NOLINT(build/header_guard) */ |
595 | | /* Copyright 2010 Google Inc. All Rights Reserved. |
596 | | |
597 | | Distributed under MIT license. |
598 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
599 | | */ |
600 | | |
601 | | /* template parameters: FN, BUCKET_BITS, BUCKET_SWEEP_BITS, HASH_LEN, |
602 | | USE_DICTIONARY |
603 | | */ |
604 | | |
605 | | #define HashLongestMatchQuickly HASHER() |
606 | | |
607 | 0 | #define BUCKET_SIZE (1 << BUCKET_BITS) |
608 | 0 | #define BUCKET_MASK (BUCKET_SIZE - 1) |
609 | 0 | #define BUCKET_SWEEP (1 << BUCKET_SWEEP_BITS) |
610 | 0 | #define BUCKET_SWEEP_MASK ((BUCKET_SWEEP - 1) << 3) |
611 | | |
612 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH2() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH2() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH2() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH2() |
613 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH2() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH2() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH2() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH2() |
614 | | |
615 | | /* HashBytes is the function that chooses the bucket to place |
616 | | the address in. The HashLongestMatch and HashLongestMatchQuickly |
617 | | classes have separate, different implementations of hashing. */ |
618 | 0 | static uint32_t FN(HashBytes)(const uint8_t* data) { |
619 | 0 | const uint64_t h = ((BROTLI_UNALIGNED_LOAD64LE(data) << (64 - 8 * HASH_LEN)) * |
620 | 0 | kHashMul64); |
621 | | /* The higher bits contain more mixture from the multiplication, |
622 | | so we take our results from there. */ |
623 | 0 | return (uint32_t)(h >> (64 - BUCKET_BITS)); |
624 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashBytesH2(unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashBytesH2(unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashBytesH2(unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashBytesH2(unsigned char const*) |
625 | | |
626 | | /* A (forgetful) hash table to the data seen by the compressor, to |
627 | | help create backward references to previous data. |
628 | | |
629 | | This is a hash map of fixed size (BUCKET_SIZE). */ |
630 | | typedef struct HashLongestMatchQuickly { |
631 | | /* Shortcuts. */ |
632 | | HasherCommon* common; |
633 | | |
634 | | /* --- Dynamic size members --- */ |
635 | | |
636 | | uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */ |
637 | | } HashLongestMatchQuickly; |
638 | | |
639 | | static void FN(Initialize)( |
640 | | HasherCommon* common, HashLongestMatchQuickly* BROTLI_RESTRICT self, |
641 | 0 | const BrotliEncoderParams* params) { |
642 | 0 | self->common = common; |
643 | |
|
644 | 0 | BROTLI_UNUSED(params); |
645 | 0 | self->buckets_ = (uint32_t*)common->extra[0]; |
646 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH2(duckdb_brotli::HasherCommon*, duckdb_brotli::H2*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH2(duckdb_brotli::HasherCommon*, duckdb_brotli::H2*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH2(duckdb_brotli::HasherCommon*, duckdb_brotli::H2*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH2(duckdb_brotli::HasherCommon*, duckdb_brotli::H2*, BrotliEncoderParams const*) |
647 | | |
648 | | static void FN(Prepare)( |
649 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
650 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
651 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
652 | | /* Partial preparation is 100 times slower (per socket). */ |
653 | 0 | size_t partial_prepare_threshold = BUCKET_SIZE >> 5; |
654 | 0 | if (one_shot && input_size <= partial_prepare_threshold) { |
655 | 0 | size_t i; |
656 | 0 | for (i = 0; i < input_size; ++i) { |
657 | 0 | const uint32_t key = FN(HashBytes)(&data[i]); |
658 | 0 | if (BUCKET_SWEEP == 1) { |
659 | 0 | buckets[key] = 0; |
660 | 0 | } else { |
661 | 0 | uint32_t j; |
662 | 0 | for (j = 0; j < BUCKET_SWEEP; ++j) { |
663 | 0 | buckets[(key + (j << 3)) & BUCKET_MASK] = 0; |
664 | 0 | } |
665 | 0 | } |
666 | 0 | } |
667 | 0 | } else { |
668 | | /* It is not strictly necessary to fill this buffer here, but |
669 | | not filling will make the results of the compression stochastic |
670 | | (but correct). This is because random data would cause the |
671 | | system to find accidentally good backward references here and there. */ |
672 | 0 | memset(buckets, 0, sizeof(uint32_t) * BUCKET_SIZE); |
673 | 0 | } |
674 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH2(duckdb_brotli::H2*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH2(duckdb_brotli::H2*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH2(duckdb_brotli::H2*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH2(duckdb_brotli::H2*, int, unsigned long, unsigned char const*) |
675 | | |
676 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
677 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
678 | 0 | size_t input_size, size_t* alloc_size) { |
679 | 0 | BROTLI_UNUSED(params); |
680 | 0 | BROTLI_UNUSED(one_shot); |
681 | 0 | BROTLI_UNUSED(input_size); |
682 | 0 | alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE; |
683 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH2(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH2(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH2(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH2(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
684 | | |
685 | | /* Look at 5 bytes at &data[ix & mask]. |
686 | | Compute a hash from these, and store the value somewhere within |
687 | | [ix .. ix+3]. */ |
688 | | static BROTLI_INLINE void FN(Store)( |
689 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
690 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
691 | 0 | const uint32_t key = FN(HashBytes)(&data[ix & mask]); |
692 | 0 | if (BUCKET_SWEEP == 1) { |
693 | 0 | self->buckets_[key] = (uint32_t)ix; |
694 | 0 | } else { |
695 | | /* Wiggle the value with the bucket sweep range. */ |
696 | 0 | const uint32_t off = ix & BUCKET_SWEEP_MASK; |
697 | 0 | self->buckets_[(key + off) & BUCKET_MASK] = (uint32_t)ix; |
698 | 0 | } |
699 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH2(duckdb_brotli::H2*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH2(duckdb_brotli::H2*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH2(duckdb_brotli::H2*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH2(duckdb_brotli::H2*, unsigned char const*, unsigned long, unsigned long) |
700 | | |
701 | | static BROTLI_INLINE void FN(StoreRange)( |
702 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
703 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
704 | 0 | const size_t ix_start, const size_t ix_end) { |
705 | 0 | size_t i; |
706 | 0 | for (i = ix_start; i < ix_end; ++i) { |
707 | 0 | FN(Store)(self, data, mask, i); |
708 | 0 | } |
709 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH2(duckdb_brotli::H2*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH2(duckdb_brotli::H2*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH2(duckdb_brotli::H2*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH2(duckdb_brotli::H2*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
710 | | |
711 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
712 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
713 | | size_t num_bytes, size_t position, |
714 | 0 | const uint8_t* ringbuffer, size_t ringbuffer_mask) { |
715 | 0 | if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { |
716 | | /* Prepare the hashes for three last bytes of the last write. |
717 | | These could not be calculated before, since they require knowledge |
718 | | of both the previous and the current block. */ |
719 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); |
720 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); |
721 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); |
722 | 0 | } |
723 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH2(duckdb_brotli::H2*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH2(duckdb_brotli::H2*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH2(duckdb_brotli::H2*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH2(duckdb_brotli::H2*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
724 | | |
725 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
726 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
727 | 0 | int* BROTLI_RESTRICT distance_cache) { |
728 | 0 | BROTLI_UNUSED(self); |
729 | 0 | BROTLI_UNUSED(distance_cache); |
730 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH2(duckdb_brotli::H2*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH2(duckdb_brotli::H2*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH2(duckdb_brotli::H2*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH2(duckdb_brotli::H2*, int*) |
731 | | |
732 | | /* Find a longest backward match of &data[cur_ix & ring_buffer_mask] |
733 | | up to the length of max_length and stores the position cur_ix in the |
734 | | hash table. |
735 | | |
736 | | Does not look for matches longer than max_length. |
737 | | Does not look for matches further away than max_backward. |
738 | | Writes the best match into |out|. |
739 | | |out|->score is updated only if a better match is found. */ |
740 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
741 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
742 | | const BrotliEncoderDictionary* dictionary, |
743 | | const uint8_t* BROTLI_RESTRICT data, |
744 | | const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, |
745 | | const size_t cur_ix, const size_t max_length, const size_t max_backward, |
746 | | const size_t dictionary_distance, const size_t max_distance, |
747 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
748 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
749 | 0 | const size_t best_len_in = out->len; |
750 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
751 | 0 | int compare_char = data[cur_ix_masked + best_len_in]; |
752 | 0 | size_t key = FN(HashBytes)(&data[cur_ix_masked]); |
753 | 0 | size_t key_out; |
754 | 0 | score_t min_score = out->score; |
755 | 0 | score_t best_score = out->score; |
756 | 0 | size_t best_len = best_len_in; |
757 | 0 | size_t cached_backward = (size_t)distance_cache[0]; |
758 | 0 | size_t prev_ix = cur_ix - cached_backward; |
759 | 0 | out->len_code_delta = 0; |
760 | 0 | if (prev_ix < cur_ix) { |
761 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
762 | 0 | if (compare_char == data[prev_ix + best_len]) { |
763 | 0 | const size_t len = FindMatchLengthWithLimit( |
764 | 0 | &data[prev_ix], &data[cur_ix_masked], max_length); |
765 | 0 | if (len >= 4) { |
766 | 0 | const score_t score = BackwardReferenceScoreUsingLastDistance(len); |
767 | 0 | if (best_score < score) { |
768 | 0 | out->len = len; |
769 | 0 | out->distance = cached_backward; |
770 | 0 | out->score = score; |
771 | 0 | if (BUCKET_SWEEP == 1) { |
772 | 0 | buckets[key] = (uint32_t)cur_ix; |
773 | 0 | return; |
774 | 0 | } else { |
775 | 0 | best_len = len; |
776 | 0 | best_score = score; |
777 | 0 | compare_char = data[cur_ix_masked + len]; |
778 | 0 | } |
779 | 0 | } |
780 | 0 | } |
781 | 0 | } |
782 | 0 | } |
783 | 0 | if (BUCKET_SWEEP == 1) { |
784 | 0 | size_t backward; |
785 | 0 | size_t len; |
786 | | /* Only one to look for, don't bother to prepare for a loop. */ |
787 | 0 | prev_ix = buckets[key]; |
788 | 0 | buckets[key] = (uint32_t)cur_ix; |
789 | 0 | backward = cur_ix - prev_ix; |
790 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
791 | 0 | if (compare_char != data[prev_ix + best_len_in]) { |
792 | 0 | return; |
793 | 0 | } |
794 | 0 | if (BROTLI_PREDICT_FALSE(backward == 0 || backward > max_backward)) { |
795 | 0 | return; |
796 | 0 | } |
797 | 0 | len = FindMatchLengthWithLimit(&data[prev_ix], |
798 | 0 | &data[cur_ix_masked], |
799 | 0 | max_length); |
800 | 0 | if (len >= 4) { |
801 | 0 | const score_t score = BackwardReferenceScore(len, backward); |
802 | 0 | if (best_score < score) { |
803 | 0 | out->len = len; |
804 | 0 | out->distance = backward; |
805 | 0 | out->score = score; |
806 | 0 | return; |
807 | 0 | } |
808 | 0 | } |
809 | 0 | } else { |
810 | 0 | size_t keys[BUCKET_SWEEP]; |
811 | 0 | size_t i; |
812 | 0 | for (i = 0; i < BUCKET_SWEEP; ++i) { |
813 | 0 | keys[i] = (key + (i << 3)) & BUCKET_MASK; |
814 | 0 | } |
815 | 0 | key_out = keys[(cur_ix & BUCKET_SWEEP_MASK) >> 3]; |
816 | 0 | for (i = 0; i < BUCKET_SWEEP; ++i) { |
817 | 0 | size_t len; |
818 | 0 | size_t backward; |
819 | 0 | prev_ix = buckets[keys[i]]; |
820 | 0 | backward = cur_ix - prev_ix; |
821 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
822 | 0 | if (compare_char != data[prev_ix + best_len]) { |
823 | 0 | continue; |
824 | 0 | } |
825 | 0 | if (BROTLI_PREDICT_FALSE(backward == 0 || backward > max_backward)) { |
826 | 0 | continue; |
827 | 0 | } |
828 | 0 | len = FindMatchLengthWithLimit(&data[prev_ix], |
829 | 0 | &data[cur_ix_masked], |
830 | 0 | max_length); |
831 | 0 | if (len >= 4) { |
832 | 0 | const score_t score = BackwardReferenceScore(len, backward); |
833 | 0 | if (best_score < score) { |
834 | 0 | best_len = len; |
835 | 0 | out->len = len; |
836 | 0 | compare_char = data[cur_ix_masked + len]; |
837 | 0 | best_score = score; |
838 | 0 | out->score = score; |
839 | 0 | out->distance = backward; |
840 | 0 | } |
841 | 0 | } |
842 | 0 | } |
843 | 0 | } |
844 | 0 | if (USE_DICTIONARY && min_score == out->score) { |
845 | 0 | SearchInStaticDictionary(dictionary, |
846 | 0 | self->common, &data[cur_ix_masked], max_length, dictionary_distance, |
847 | 0 | max_distance, out, BROTLI_TRUE); |
848 | 0 | } |
849 | 0 | if (BUCKET_SWEEP != 1) { |
850 | 0 | buckets[key_out] = (uint32_t)cur_ix; |
851 | 0 | } |
852 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH2(duckdb_brotli::H2*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH2(duckdb_brotli::H2*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH2(duckdb_brotli::H2*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH2(duckdb_brotli::H2*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
853 | | |
854 | | #undef BUCKET_SWEEP_MASK |
855 | | #undef BUCKET_SWEEP |
856 | | #undef BUCKET_MASK |
857 | | #undef BUCKET_SIZE |
858 | | |
859 | | #undef HashLongestMatchQuickly |
860 | | #undef BUCKET_SWEEP_BITS |
861 | | #undef USE_DICTIONARY |
862 | | #undef HASHER |
863 | | |
864 | | #define HASHER() H3 |
865 | 0 | #define BUCKET_SWEEP_BITS 1 |
866 | 0 | #define USE_DICTIONARY 0 |
867 | | /* NOLINT(build/header_guard) */ |
868 | | /* Copyright 2010 Google Inc. All Rights Reserved. |
869 | | |
870 | | Distributed under MIT license. |
871 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
872 | | */ |
873 | | |
874 | | /* template parameters: FN, BUCKET_BITS, BUCKET_SWEEP_BITS, HASH_LEN, |
875 | | USE_DICTIONARY |
876 | | */ |
877 | | |
878 | | #define HashLongestMatchQuickly HASHER() |
879 | | |
880 | 0 | #define BUCKET_SIZE (1 << BUCKET_BITS) |
881 | 0 | #define BUCKET_MASK (BUCKET_SIZE - 1) |
882 | 0 | #define BUCKET_SWEEP (1 << BUCKET_SWEEP_BITS) |
883 | 0 | #define BUCKET_SWEEP_MASK ((BUCKET_SWEEP - 1) << 3) |
884 | | |
885 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH3() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH3() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH3() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH3() |
886 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH3() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH3() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH3() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH3() |
887 | | |
888 | | /* HashBytes is the function that chooses the bucket to place |
889 | | the address in. The HashLongestMatch and HashLongestMatchQuickly |
890 | | classes have separate, different implementations of hashing. */ |
891 | 0 | static uint32_t FN(HashBytes)(const uint8_t* data) { |
892 | 0 | const uint64_t h = ((BROTLI_UNALIGNED_LOAD64LE(data) << (64 - 8 * HASH_LEN)) * |
893 | 0 | kHashMul64); |
894 | | /* The higher bits contain more mixture from the multiplication, |
895 | | so we take our results from there. */ |
896 | 0 | return (uint32_t)(h >> (64 - BUCKET_BITS)); |
897 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashBytesH3(unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashBytesH3(unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashBytesH3(unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashBytesH3(unsigned char const*) |
898 | | |
899 | | /* A (forgetful) hash table to the data seen by the compressor, to |
900 | | help create backward references to previous data. |
901 | | |
902 | | This is a hash map of fixed size (BUCKET_SIZE). */ |
903 | | typedef struct HashLongestMatchQuickly { |
904 | | /* Shortcuts. */ |
905 | | HasherCommon* common; |
906 | | |
907 | | /* --- Dynamic size members --- */ |
908 | | |
909 | | uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */ |
910 | | } HashLongestMatchQuickly; |
911 | | |
912 | | static void FN(Initialize)( |
913 | | HasherCommon* common, HashLongestMatchQuickly* BROTLI_RESTRICT self, |
914 | 0 | const BrotliEncoderParams* params) { |
915 | 0 | self->common = common; |
916 | |
|
917 | 0 | BROTLI_UNUSED(params); |
918 | 0 | self->buckets_ = (uint32_t*)common->extra[0]; |
919 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH3(duckdb_brotli::HasherCommon*, duckdb_brotli::H3*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH3(duckdb_brotli::HasherCommon*, duckdb_brotli::H3*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH3(duckdb_brotli::HasherCommon*, duckdb_brotli::H3*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH3(duckdb_brotli::HasherCommon*, duckdb_brotli::H3*, BrotliEncoderParams const*) |
920 | | |
921 | | static void FN(Prepare)( |
922 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
923 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
924 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
925 | | /* Partial preparation is 100 times slower (per socket). */ |
926 | 0 | size_t partial_prepare_threshold = BUCKET_SIZE >> 5; |
927 | 0 | if (one_shot && input_size <= partial_prepare_threshold) { |
928 | 0 | size_t i; |
929 | 0 | for (i = 0; i < input_size; ++i) { |
930 | 0 | const uint32_t key = FN(HashBytes)(&data[i]); |
931 | 0 | if (BUCKET_SWEEP == 1) { |
932 | 0 | buckets[key] = 0; |
933 | 0 | } else { |
934 | 0 | uint32_t j; |
935 | 0 | for (j = 0; j < BUCKET_SWEEP; ++j) { |
936 | 0 | buckets[(key + (j << 3)) & BUCKET_MASK] = 0; |
937 | 0 | } |
938 | 0 | } |
939 | 0 | } |
940 | 0 | } else { |
941 | | /* It is not strictly necessary to fill this buffer here, but |
942 | | not filling will make the results of the compression stochastic |
943 | | (but correct). This is because random data would cause the |
944 | | system to find accidentally good backward references here and there. */ |
945 | 0 | memset(buckets, 0, sizeof(uint32_t) * BUCKET_SIZE); |
946 | 0 | } |
947 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH3(duckdb_brotli::H3*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH3(duckdb_brotli::H3*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH3(duckdb_brotli::H3*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH3(duckdb_brotli::H3*, int, unsigned long, unsigned char const*) |
948 | | |
949 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
950 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
951 | 0 | size_t input_size, size_t* alloc_size) { |
952 | 0 | BROTLI_UNUSED(params); |
953 | 0 | BROTLI_UNUSED(one_shot); |
954 | 0 | BROTLI_UNUSED(input_size); |
955 | 0 | alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE; |
956 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH3(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH3(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH3(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH3(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
957 | | |
958 | | /* Look at 5 bytes at &data[ix & mask]. |
959 | | Compute a hash from these, and store the value somewhere within |
960 | | [ix .. ix+3]. */ |
961 | | static BROTLI_INLINE void FN(Store)( |
962 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
963 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
964 | 0 | const uint32_t key = FN(HashBytes)(&data[ix & mask]); |
965 | 0 | if (BUCKET_SWEEP == 1) { |
966 | 0 | self->buckets_[key] = (uint32_t)ix; |
967 | 0 | } else { |
968 | | /* Wiggle the value with the bucket sweep range. */ |
969 | 0 | const uint32_t off = ix & BUCKET_SWEEP_MASK; |
970 | 0 | self->buckets_[(key + off) & BUCKET_MASK] = (uint32_t)ix; |
971 | 0 | } |
972 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH3(duckdb_brotli::H3*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH3(duckdb_brotli::H3*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH3(duckdb_brotli::H3*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH3(duckdb_brotli::H3*, unsigned char const*, unsigned long, unsigned long) |
973 | | |
974 | | static BROTLI_INLINE void FN(StoreRange)( |
975 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
976 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
977 | 0 | const size_t ix_start, const size_t ix_end) { |
978 | 0 | size_t i; |
979 | 0 | for (i = ix_start; i < ix_end; ++i) { |
980 | 0 | FN(Store)(self, data, mask, i); |
981 | 0 | } |
982 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH3(duckdb_brotli::H3*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH3(duckdb_brotli::H3*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH3(duckdb_brotli::H3*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH3(duckdb_brotli::H3*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
983 | | |
984 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
985 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
986 | | size_t num_bytes, size_t position, |
987 | 0 | const uint8_t* ringbuffer, size_t ringbuffer_mask) { |
988 | 0 | if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { |
989 | | /* Prepare the hashes for three last bytes of the last write. |
990 | | These could not be calculated before, since they require knowledge |
991 | | of both the previous and the current block. */ |
992 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); |
993 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); |
994 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); |
995 | 0 | } |
996 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH3(duckdb_brotli::H3*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH3(duckdb_brotli::H3*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH3(duckdb_brotli::H3*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH3(duckdb_brotli::H3*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
997 | | |
998 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
999 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
1000 | 0 | int* BROTLI_RESTRICT distance_cache) { |
1001 | 0 | BROTLI_UNUSED(self); |
1002 | 0 | BROTLI_UNUSED(distance_cache); |
1003 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH3(duckdb_brotli::H3*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH3(duckdb_brotli::H3*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH3(duckdb_brotli::H3*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH3(duckdb_brotli::H3*, int*) |
1004 | | |
1005 | | /* Find a longest backward match of &data[cur_ix & ring_buffer_mask] |
1006 | | up to the length of max_length and stores the position cur_ix in the |
1007 | | hash table. |
1008 | | |
1009 | | Does not look for matches longer than max_length. |
1010 | | Does not look for matches further away than max_backward. |
1011 | | Writes the best match into |out|. |
1012 | | |out|->score is updated only if a better match is found. */ |
1013 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
1014 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
1015 | | const BrotliEncoderDictionary* dictionary, |
1016 | | const uint8_t* BROTLI_RESTRICT data, |
1017 | | const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, |
1018 | | const size_t cur_ix, const size_t max_length, const size_t max_backward, |
1019 | | const size_t dictionary_distance, const size_t max_distance, |
1020 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
1021 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
1022 | 0 | const size_t best_len_in = out->len; |
1023 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
1024 | 0 | int compare_char = data[cur_ix_masked + best_len_in]; |
1025 | 0 | size_t key = FN(HashBytes)(&data[cur_ix_masked]); |
1026 | 0 | size_t key_out; |
1027 | 0 | score_t min_score = out->score; |
1028 | 0 | score_t best_score = out->score; |
1029 | 0 | size_t best_len = best_len_in; |
1030 | 0 | size_t cached_backward = (size_t)distance_cache[0]; |
1031 | 0 | size_t prev_ix = cur_ix - cached_backward; |
1032 | 0 | out->len_code_delta = 0; |
1033 | 0 | if (prev_ix < cur_ix) { |
1034 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
1035 | 0 | if (compare_char == data[prev_ix + best_len]) { |
1036 | 0 | const size_t len = FindMatchLengthWithLimit( |
1037 | 0 | &data[prev_ix], &data[cur_ix_masked], max_length); |
1038 | 0 | if (len >= 4) { |
1039 | 0 | const score_t score = BackwardReferenceScoreUsingLastDistance(len); |
1040 | 0 | if (best_score < score) { |
1041 | 0 | out->len = len; |
1042 | 0 | out->distance = cached_backward; |
1043 | 0 | out->score = score; |
1044 | 0 | if (BUCKET_SWEEP == 1) { |
1045 | 0 | buckets[key] = (uint32_t)cur_ix; |
1046 | 0 | return; |
1047 | 0 | } else { |
1048 | 0 | best_len = len; |
1049 | 0 | best_score = score; |
1050 | 0 | compare_char = data[cur_ix_masked + len]; |
1051 | 0 | } |
1052 | 0 | } |
1053 | 0 | } |
1054 | 0 | } |
1055 | 0 | } |
1056 | 0 | if (BUCKET_SWEEP == 1) { |
1057 | 0 | size_t backward; |
1058 | 0 | size_t len; |
1059 | | /* Only one to look for, don't bother to prepare for a loop. */ |
1060 | 0 | prev_ix = buckets[key]; |
1061 | 0 | buckets[key] = (uint32_t)cur_ix; |
1062 | 0 | backward = cur_ix - prev_ix; |
1063 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
1064 | 0 | if (compare_char != data[prev_ix + best_len_in]) { |
1065 | 0 | return; |
1066 | 0 | } |
1067 | 0 | if (BROTLI_PREDICT_FALSE(backward == 0 || backward > max_backward)) { |
1068 | 0 | return; |
1069 | 0 | } |
1070 | 0 | len = FindMatchLengthWithLimit(&data[prev_ix], |
1071 | 0 | &data[cur_ix_masked], |
1072 | 0 | max_length); |
1073 | 0 | if (len >= 4) { |
1074 | 0 | const score_t score = BackwardReferenceScore(len, backward); |
1075 | 0 | if (best_score < score) { |
1076 | 0 | out->len = len; |
1077 | 0 | out->distance = backward; |
1078 | 0 | out->score = score; |
1079 | 0 | return; |
1080 | 0 | } |
1081 | 0 | } |
1082 | 0 | } else { |
1083 | 0 | size_t keys[BUCKET_SWEEP]; |
1084 | 0 | size_t i; |
1085 | 0 | for (i = 0; i < BUCKET_SWEEP; ++i) { |
1086 | 0 | keys[i] = (key + (i << 3)) & BUCKET_MASK; |
1087 | 0 | } |
1088 | 0 | key_out = keys[(cur_ix & BUCKET_SWEEP_MASK) >> 3]; |
1089 | 0 | for (i = 0; i < BUCKET_SWEEP; ++i) { |
1090 | 0 | size_t len; |
1091 | 0 | size_t backward; |
1092 | 0 | prev_ix = buckets[keys[i]]; |
1093 | 0 | backward = cur_ix - prev_ix; |
1094 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
1095 | 0 | if (compare_char != data[prev_ix + best_len]) { |
1096 | 0 | continue; |
1097 | 0 | } |
1098 | 0 | if (BROTLI_PREDICT_FALSE(backward == 0 || backward > max_backward)) { |
1099 | 0 | continue; |
1100 | 0 | } |
1101 | 0 | len = FindMatchLengthWithLimit(&data[prev_ix], |
1102 | 0 | &data[cur_ix_masked], |
1103 | 0 | max_length); |
1104 | 0 | if (len >= 4) { |
1105 | 0 | const score_t score = BackwardReferenceScore(len, backward); |
1106 | 0 | if (best_score < score) { |
1107 | 0 | best_len = len; |
1108 | 0 | out->len = len; |
1109 | 0 | compare_char = data[cur_ix_masked + len]; |
1110 | 0 | best_score = score; |
1111 | 0 | out->score = score; |
1112 | 0 | out->distance = backward; |
1113 | 0 | } |
1114 | 0 | } |
1115 | 0 | } |
1116 | 0 | } |
1117 | 0 | if (USE_DICTIONARY && min_score == out->score) { |
1118 | 0 | SearchInStaticDictionary(dictionary, |
1119 | 0 | self->common, &data[cur_ix_masked], max_length, dictionary_distance, |
1120 | 0 | max_distance, out, BROTLI_TRUE); |
1121 | 0 | } |
1122 | 0 | if (BUCKET_SWEEP != 1) { |
1123 | 0 | buckets[key_out] = (uint32_t)cur_ix; |
1124 | 0 | } |
1125 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH3(duckdb_brotli::H3*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH3(duckdb_brotli::H3*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH3(duckdb_brotli::H3*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH3(duckdb_brotli::H3*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
1126 | | |
1127 | | #undef BUCKET_SWEEP_MASK |
1128 | | #undef BUCKET_SWEEP |
1129 | | #undef BUCKET_MASK |
1130 | | #undef BUCKET_SIZE |
1131 | | |
1132 | | #undef HashLongestMatchQuickly |
1133 | | #undef USE_DICTIONARY |
1134 | | #undef BUCKET_SWEEP_BITS |
1135 | | #undef BUCKET_BITS |
1136 | | #undef HASHER |
1137 | | |
1138 | | #define HASHER() H4 |
1139 | 0 | #define BUCKET_BITS 17 |
1140 | 0 | #define BUCKET_SWEEP_BITS 2 |
1141 | 0 | #define USE_DICTIONARY 1 |
1142 | | /* NOLINT(build/header_guard) */ |
1143 | | /* Copyright 2010 Google Inc. All Rights Reserved. |
1144 | | |
1145 | | Distributed under MIT license. |
1146 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
1147 | | */ |
1148 | | |
1149 | | /* template parameters: FN, BUCKET_BITS, BUCKET_SWEEP_BITS, HASH_LEN, |
1150 | | USE_DICTIONARY |
1151 | | */ |
1152 | | |
1153 | | #define HashLongestMatchQuickly HASHER() |
1154 | | |
1155 | 0 | #define BUCKET_SIZE (1 << BUCKET_BITS) |
1156 | 0 | #define BUCKET_MASK (BUCKET_SIZE - 1) |
1157 | 0 | #define BUCKET_SWEEP (1 << BUCKET_SWEEP_BITS) |
1158 | 0 | #define BUCKET_SWEEP_MASK ((BUCKET_SWEEP - 1) << 3) |
1159 | | |
1160 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH4() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH4() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH4() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH4() |
1161 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH4() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH4() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH4() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH4() |
1162 | | |
1163 | | /* HashBytes is the function that chooses the bucket to place |
1164 | | the address in. The HashLongestMatch and HashLongestMatchQuickly |
1165 | | classes have separate, different implementations of hashing. */ |
1166 | 0 | static uint32_t FN(HashBytes)(const uint8_t* data) { |
1167 | 0 | const uint64_t h = ((BROTLI_UNALIGNED_LOAD64LE(data) << (64 - 8 * HASH_LEN)) * |
1168 | 0 | kHashMul64); |
1169 | | /* The higher bits contain more mixture from the multiplication, |
1170 | | so we take our results from there. */ |
1171 | 0 | return (uint32_t)(h >> (64 - BUCKET_BITS)); |
1172 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashBytesH4(unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashBytesH4(unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashBytesH4(unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashBytesH4(unsigned char const*) |
1173 | | |
1174 | | /* A (forgetful) hash table to the data seen by the compressor, to |
1175 | | help create backward references to previous data. |
1176 | | |
1177 | | This is a hash map of fixed size (BUCKET_SIZE). */ |
1178 | | typedef struct HashLongestMatchQuickly { |
1179 | | /* Shortcuts. */ |
1180 | | HasherCommon* common; |
1181 | | |
1182 | | /* --- Dynamic size members --- */ |
1183 | | |
1184 | | uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */ |
1185 | | } HashLongestMatchQuickly; |
1186 | | |
1187 | | static void FN(Initialize)( |
1188 | | HasherCommon* common, HashLongestMatchQuickly* BROTLI_RESTRICT self, |
1189 | 0 | const BrotliEncoderParams* params) { |
1190 | 0 | self->common = common; |
1191 | |
|
1192 | 0 | BROTLI_UNUSED(params); |
1193 | 0 | self->buckets_ = (uint32_t*)common->extra[0]; |
1194 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH4(duckdb_brotli::HasherCommon*, duckdb_brotli::H4*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH4(duckdb_brotli::HasherCommon*, duckdb_brotli::H4*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH4(duckdb_brotli::HasherCommon*, duckdb_brotli::H4*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH4(duckdb_brotli::HasherCommon*, duckdb_brotli::H4*, BrotliEncoderParams const*) |
1195 | | |
1196 | | static void FN(Prepare)( |
1197 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
1198 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
1199 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
1200 | | /* Partial preparation is 100 times slower (per socket). */ |
1201 | 0 | size_t partial_prepare_threshold = BUCKET_SIZE >> 5; |
1202 | 0 | if (one_shot && input_size <= partial_prepare_threshold) { |
1203 | 0 | size_t i; |
1204 | 0 | for (i = 0; i < input_size; ++i) { |
1205 | 0 | const uint32_t key = FN(HashBytes)(&data[i]); |
1206 | 0 | if (BUCKET_SWEEP == 1) { |
1207 | 0 | buckets[key] = 0; |
1208 | 0 | } else { |
1209 | 0 | uint32_t j; |
1210 | 0 | for (j = 0; j < BUCKET_SWEEP; ++j) { |
1211 | 0 | buckets[(key + (j << 3)) & BUCKET_MASK] = 0; |
1212 | 0 | } |
1213 | 0 | } |
1214 | 0 | } |
1215 | 0 | } else { |
1216 | | /* It is not strictly necessary to fill this buffer here, but |
1217 | | not filling will make the results of the compression stochastic |
1218 | | (but correct). This is because random data would cause the |
1219 | | system to find accidentally good backward references here and there. */ |
1220 | 0 | memset(buckets, 0, sizeof(uint32_t) * BUCKET_SIZE); |
1221 | 0 | } |
1222 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH4(duckdb_brotli::H4*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH4(duckdb_brotli::H4*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH4(duckdb_brotli::H4*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH4(duckdb_brotli::H4*, int, unsigned long, unsigned char const*) |
1223 | | |
1224 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
1225 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
1226 | 0 | size_t input_size, size_t* alloc_size) { |
1227 | 0 | BROTLI_UNUSED(params); |
1228 | 0 | BROTLI_UNUSED(one_shot); |
1229 | 0 | BROTLI_UNUSED(input_size); |
1230 | 0 | alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE; |
1231 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH4(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH4(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH4(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH4(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
1232 | | |
1233 | | /* Look at 5 bytes at &data[ix & mask]. |
1234 | | Compute a hash from these, and store the value somewhere within |
1235 | | [ix .. ix+3]. */ |
1236 | | static BROTLI_INLINE void FN(Store)( |
1237 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
1238 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
1239 | 0 | const uint32_t key = FN(HashBytes)(&data[ix & mask]); |
1240 | 0 | if (BUCKET_SWEEP == 1) { |
1241 | 0 | self->buckets_[key] = (uint32_t)ix; |
1242 | 0 | } else { |
1243 | | /* Wiggle the value with the bucket sweep range. */ |
1244 | 0 | const uint32_t off = ix & BUCKET_SWEEP_MASK; |
1245 | 0 | self->buckets_[(key + off) & BUCKET_MASK] = (uint32_t)ix; |
1246 | 0 | } |
1247 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH4(duckdb_brotli::H4*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH4(duckdb_brotli::H4*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH4(duckdb_brotli::H4*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH4(duckdb_brotli::H4*, unsigned char const*, unsigned long, unsigned long) |
1248 | | |
1249 | | static BROTLI_INLINE void FN(StoreRange)( |
1250 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
1251 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
1252 | 0 | const size_t ix_start, const size_t ix_end) { |
1253 | 0 | size_t i; |
1254 | 0 | for (i = ix_start; i < ix_end; ++i) { |
1255 | 0 | FN(Store)(self, data, mask, i); |
1256 | 0 | } |
1257 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH4(duckdb_brotli::H4*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH4(duckdb_brotli::H4*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH4(duckdb_brotli::H4*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH4(duckdb_brotli::H4*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
1258 | | |
1259 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
1260 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
1261 | | size_t num_bytes, size_t position, |
1262 | 0 | const uint8_t* ringbuffer, size_t ringbuffer_mask) { |
1263 | 0 | if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { |
1264 | | /* Prepare the hashes for three last bytes of the last write. |
1265 | | These could not be calculated before, since they require knowledge |
1266 | | of both the previous and the current block. */ |
1267 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); |
1268 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); |
1269 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); |
1270 | 0 | } |
1271 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH4(duckdb_brotli::H4*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH4(duckdb_brotli::H4*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH4(duckdb_brotli::H4*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH4(duckdb_brotli::H4*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
1272 | | |
1273 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
1274 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
1275 | 0 | int* BROTLI_RESTRICT distance_cache) { |
1276 | 0 | BROTLI_UNUSED(self); |
1277 | 0 | BROTLI_UNUSED(distance_cache); |
1278 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH4(duckdb_brotli::H4*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH4(duckdb_brotli::H4*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH4(duckdb_brotli::H4*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH4(duckdb_brotli::H4*, int*) |
1279 | | |
1280 | | /* Find a longest backward match of &data[cur_ix & ring_buffer_mask] |
1281 | | up to the length of max_length and stores the position cur_ix in the |
1282 | | hash table. |
1283 | | |
1284 | | Does not look for matches longer than max_length. |
1285 | | Does not look for matches further away than max_backward. |
1286 | | Writes the best match into |out|. |
1287 | | |out|->score is updated only if a better match is found. */ |
1288 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
1289 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
1290 | | const BrotliEncoderDictionary* dictionary, |
1291 | | const uint8_t* BROTLI_RESTRICT data, |
1292 | | const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, |
1293 | | const size_t cur_ix, const size_t max_length, const size_t max_backward, |
1294 | | const size_t dictionary_distance, const size_t max_distance, |
1295 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
1296 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
1297 | 0 | const size_t best_len_in = out->len; |
1298 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
1299 | 0 | int compare_char = data[cur_ix_masked + best_len_in]; |
1300 | 0 | size_t key = FN(HashBytes)(&data[cur_ix_masked]); |
1301 | 0 | size_t key_out; |
1302 | 0 | score_t min_score = out->score; |
1303 | 0 | score_t best_score = out->score; |
1304 | 0 | size_t best_len = best_len_in; |
1305 | 0 | size_t cached_backward = (size_t)distance_cache[0]; |
1306 | 0 | size_t prev_ix = cur_ix - cached_backward; |
1307 | 0 | out->len_code_delta = 0; |
1308 | 0 | if (prev_ix < cur_ix) { |
1309 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
1310 | 0 | if (compare_char == data[prev_ix + best_len]) { |
1311 | 0 | const size_t len = FindMatchLengthWithLimit( |
1312 | 0 | &data[prev_ix], &data[cur_ix_masked], max_length); |
1313 | 0 | if (len >= 4) { |
1314 | 0 | const score_t score = BackwardReferenceScoreUsingLastDistance(len); |
1315 | 0 | if (best_score < score) { |
1316 | 0 | out->len = len; |
1317 | 0 | out->distance = cached_backward; |
1318 | 0 | out->score = score; |
1319 | 0 | if (BUCKET_SWEEP == 1) { |
1320 | 0 | buckets[key] = (uint32_t)cur_ix; |
1321 | 0 | return; |
1322 | 0 | } else { |
1323 | 0 | best_len = len; |
1324 | 0 | best_score = score; |
1325 | 0 | compare_char = data[cur_ix_masked + len]; |
1326 | 0 | } |
1327 | 0 | } |
1328 | 0 | } |
1329 | 0 | } |
1330 | 0 | } |
1331 | 0 | if (BUCKET_SWEEP == 1) { |
1332 | 0 | size_t backward; |
1333 | 0 | size_t len; |
1334 | | /* Only one to look for, don't bother to prepare for a loop. */ |
1335 | 0 | prev_ix = buckets[key]; |
1336 | 0 | buckets[key] = (uint32_t)cur_ix; |
1337 | 0 | backward = cur_ix - prev_ix; |
1338 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
1339 | 0 | if (compare_char != data[prev_ix + best_len_in]) { |
1340 | 0 | return; |
1341 | 0 | } |
1342 | 0 | if (BROTLI_PREDICT_FALSE(backward == 0 || backward > max_backward)) { |
1343 | 0 | return; |
1344 | 0 | } |
1345 | 0 | len = FindMatchLengthWithLimit(&data[prev_ix], |
1346 | 0 | &data[cur_ix_masked], |
1347 | 0 | max_length); |
1348 | 0 | if (len >= 4) { |
1349 | 0 | const score_t score = BackwardReferenceScore(len, backward); |
1350 | 0 | if (best_score < score) { |
1351 | 0 | out->len = len; |
1352 | 0 | out->distance = backward; |
1353 | 0 | out->score = score; |
1354 | 0 | return; |
1355 | 0 | } |
1356 | 0 | } |
1357 | 0 | } else { |
1358 | 0 | size_t keys[BUCKET_SWEEP]; |
1359 | 0 | size_t i; |
1360 | 0 | for (i = 0; i < BUCKET_SWEEP; ++i) { |
1361 | 0 | keys[i] = (key + (i << 3)) & BUCKET_MASK; |
1362 | 0 | } |
1363 | 0 | key_out = keys[(cur_ix & BUCKET_SWEEP_MASK) >> 3]; |
1364 | 0 | for (i = 0; i < BUCKET_SWEEP; ++i) { |
1365 | 0 | size_t len; |
1366 | 0 | size_t backward; |
1367 | 0 | prev_ix = buckets[keys[i]]; |
1368 | 0 | backward = cur_ix - prev_ix; |
1369 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
1370 | 0 | if (compare_char != data[prev_ix + best_len]) { |
1371 | 0 | continue; |
1372 | 0 | } |
1373 | 0 | if (BROTLI_PREDICT_FALSE(backward == 0 || backward > max_backward)) { |
1374 | 0 | continue; |
1375 | 0 | } |
1376 | 0 | len = FindMatchLengthWithLimit(&data[prev_ix], |
1377 | 0 | &data[cur_ix_masked], |
1378 | 0 | max_length); |
1379 | 0 | if (len >= 4) { |
1380 | 0 | const score_t score = BackwardReferenceScore(len, backward); |
1381 | 0 | if (best_score < score) { |
1382 | 0 | best_len = len; |
1383 | 0 | out->len = len; |
1384 | 0 | compare_char = data[cur_ix_masked + len]; |
1385 | 0 | best_score = score; |
1386 | 0 | out->score = score; |
1387 | 0 | out->distance = backward; |
1388 | 0 | } |
1389 | 0 | } |
1390 | 0 | } |
1391 | 0 | } |
1392 | 0 | if (USE_DICTIONARY && min_score == out->score) { |
1393 | 0 | SearchInStaticDictionary(dictionary, |
1394 | 0 | self->common, &data[cur_ix_masked], max_length, dictionary_distance, |
1395 | 0 | max_distance, out, BROTLI_TRUE); |
1396 | 0 | } |
1397 | 0 | if (BUCKET_SWEEP != 1) { |
1398 | 0 | buckets[key_out] = (uint32_t)cur_ix; |
1399 | 0 | } |
1400 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH4(duckdb_brotli::H4*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH4(duckdb_brotli::H4*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH4(duckdb_brotli::H4*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH4(duckdb_brotli::H4*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
1401 | | |
1402 | | #undef BUCKET_SWEEP_MASK |
1403 | | #undef BUCKET_SWEEP |
1404 | | #undef BUCKET_MASK |
1405 | | #undef BUCKET_SIZE |
1406 | | |
1407 | | #undef HashLongestMatchQuickly |
1408 | | #undef USE_DICTIONARY |
1409 | | #undef HASH_LEN |
1410 | | #undef BUCKET_SWEEP_BITS |
1411 | | #undef BUCKET_BITS |
1412 | | #undef HASHER |
1413 | | |
1414 | | #define HASHER() H5 |
1415 | | /* NOLINT(build/header_guard) */ |
1416 | | /* Copyright 2010 Google Inc. All Rights Reserved. |
1417 | | |
1418 | | Distributed under MIT license. |
1419 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
1420 | | */ |
1421 | | |
1422 | | /* template parameters: FN */ |
1423 | | |
1424 | | /* A (forgetful) hash table to the data seen by the compressor, to |
1425 | | help create backward references to previous data. |
1426 | | |
1427 | | This is a hash map of fixed size (bucket_size_) to a ring buffer of |
1428 | | fixed size (block_size_). The ring buffer contains the last block_size_ |
1429 | | index positions of the given hash key in the compressed data. */ |
1430 | | |
1431 | | #define HashLongestMatch HASHER() |
1432 | | |
1433 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH5() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH5() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH5() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH5() |
1434 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH5() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH5() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH5() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH5() |
1435 | | |
1436 | | /* HashBytes is the function that chooses the bucket to place the address in. */ |
1437 | | static uint32_t FN(HashBytes)( |
1438 | 0 | const uint8_t* BROTLI_RESTRICT data, const int shift) { |
1439 | 0 | uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; |
1440 | | /* The higher bits contain more mixture from the multiplication, |
1441 | | so we take our results from there. */ |
1442 | 0 | return (uint32_t)(h >> shift); |
1443 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashBytesH5(unsigned char const*, int) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashBytesH5(unsigned char const*, int) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashBytesH5(unsigned char const*, int) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashBytesH5(unsigned char const*, int) |
1444 | | |
1445 | | typedef struct HashLongestMatch { |
1446 | | /* Number of hash buckets. */ |
1447 | | size_t bucket_size_; |
1448 | | /* Only block_size_ newest backward references are kept, |
1449 | | and the older are forgotten. */ |
1450 | | size_t block_size_; |
1451 | | /* Left-shift for computing hash bucket index from hash value. */ |
1452 | | int hash_shift_; |
1453 | | /* Mask for accessing entries in a block (in a ring-buffer manner). */ |
1454 | | uint32_t block_mask_; |
1455 | | |
1456 | | int block_bits_; |
1457 | | int num_last_distances_to_check_; |
1458 | | |
1459 | | /* Shortcuts. */ |
1460 | | HasherCommon* common_; |
1461 | | |
1462 | | /* --- Dynamic size members --- */ |
1463 | | |
1464 | | /* Number of entries in a particular bucket. */ |
1465 | | uint16_t* num_; /* uint16_t[bucket_size]; */ |
1466 | | |
1467 | | /* Buckets containing block_size_ of backward references. */ |
1468 | | uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */ |
1469 | | } HashLongestMatch; |
1470 | | |
1471 | | static void FN(Initialize)( |
1472 | | HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self, |
1473 | 0 | const BrotliEncoderParams* params) { |
1474 | 0 | self->common_ = common; |
1475 | |
|
1476 | 0 | BROTLI_UNUSED(params); |
1477 | 0 | self->hash_shift_ = 32 - common->params.bucket_bits; |
1478 | 0 | self->bucket_size_ = (size_t)1 << common->params.bucket_bits; |
1479 | 0 | self->block_size_ = (size_t)1 << common->params.block_bits; |
1480 | 0 | self->block_mask_ = (uint32_t)(self->block_size_ - 1); |
1481 | 0 | self->num_ = (uint16_t*)common->extra[0]; |
1482 | 0 | self->buckets_ = (uint32_t*)common->extra[1]; |
1483 | 0 | self->block_bits_ = common->params.block_bits; |
1484 | 0 | self->num_last_distances_to_check_ = |
1485 | 0 | common->params.num_last_distances_to_check; |
1486 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH5(duckdb_brotli::HasherCommon*, duckdb_brotli::H5*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH5(duckdb_brotli::HasherCommon*, duckdb_brotli::H5*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH5(duckdb_brotli::HasherCommon*, duckdb_brotli::H5*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH5(duckdb_brotli::HasherCommon*, duckdb_brotli::H5*, BrotliEncoderParams const*) |
1487 | | |
1488 | | static void FN(Prepare)( |
1489 | | HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
1490 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
1491 | 0 | uint16_t* BROTLI_RESTRICT num = self->num_; |
1492 | | /* Partial preparation is 100 times slower (per socket). */ |
1493 | 0 | size_t partial_prepare_threshold = self->bucket_size_ >> 6; |
1494 | 0 | if (one_shot && input_size <= partial_prepare_threshold) { |
1495 | 0 | size_t i; |
1496 | 0 | for (i = 0; i < input_size; ++i) { |
1497 | 0 | const uint32_t key = FN(HashBytes)(&data[i], self->hash_shift_); |
1498 | 0 | num[key] = 0; |
1499 | 0 | } |
1500 | 0 | } else { |
1501 | 0 | memset(num, 0, self->bucket_size_ * sizeof(num[0])); |
1502 | 0 | } |
1503 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH5(duckdb_brotli::H5*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH5(duckdb_brotli::H5*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH5(duckdb_brotli::H5*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH5(duckdb_brotli::H5*, int, unsigned long, unsigned char const*) |
1504 | | |
1505 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
1506 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
1507 | 0 | size_t input_size, size_t* alloc_size) { |
1508 | 0 | size_t bucket_size = (size_t)1 << params->hasher.bucket_bits; |
1509 | 0 | size_t block_size = (size_t)1 << params->hasher.block_bits; |
1510 | 0 | BROTLI_UNUSED(one_shot); |
1511 | 0 | BROTLI_UNUSED(input_size); |
1512 | 0 | alloc_size[0] = sizeof(uint16_t) * bucket_size; |
1513 | 0 | alloc_size[1] = sizeof(uint32_t) * bucket_size * block_size; |
1514 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH5(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH5(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH5(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH5(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
1515 | | |
1516 | | /* Look at 4 bytes at &data[ix & mask]. |
1517 | | Compute a hash from these, and store the value of ix at that position. */ |
1518 | | static BROTLI_INLINE void FN(Store)( |
1519 | | HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, |
1520 | 0 | const size_t mask, const size_t ix) { |
1521 | 0 | const uint32_t key = FN(HashBytes)(&data[ix & mask], self->hash_shift_); |
1522 | 0 | const size_t minor_ix = self->num_[key] & self->block_mask_; |
1523 | 0 | const size_t offset = minor_ix + (key << self->block_bits_); |
1524 | 0 | self->buckets_[offset] = (uint32_t)ix; |
1525 | 0 | ++self->num_[key]; |
1526 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH5(duckdb_brotli::H5*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH5(duckdb_brotli::H5*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH5(duckdb_brotli::H5*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH5(duckdb_brotli::H5*, unsigned char const*, unsigned long, unsigned long) |
1527 | | |
1528 | | static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self, |
1529 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
1530 | 0 | const size_t ix_start, const size_t ix_end) { |
1531 | 0 | size_t i; |
1532 | 0 | for (i = ix_start; i < ix_end; ++i) { |
1533 | 0 | FN(Store)(self, data, mask, i); |
1534 | 0 | } |
1535 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH5(duckdb_brotli::H5*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH5(duckdb_brotli::H5*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH5(duckdb_brotli::H5*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH5(duckdb_brotli::H5*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
1536 | | |
1537 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
1538 | | HashLongestMatch* BROTLI_RESTRICT self, |
1539 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
1540 | 0 | size_t ringbuffer_mask) { |
1541 | 0 | if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { |
1542 | | /* Prepare the hashes for three last bytes of the last write. |
1543 | | These could not be calculated before, since they require knowledge |
1544 | | of both the previous and the current block. */ |
1545 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); |
1546 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); |
1547 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); |
1548 | 0 | } |
1549 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH5(duckdb_brotli::H5*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH5(duckdb_brotli::H5*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH5(duckdb_brotli::H5*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH5(duckdb_brotli::H5*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
1550 | | |
1551 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
1552 | | HashLongestMatch* BROTLI_RESTRICT self, |
1553 | 0 | int* BROTLI_RESTRICT distance_cache) { |
1554 | 0 | PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_); |
1555 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH5(duckdb_brotli::H5*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH5(duckdb_brotli::H5*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH5(duckdb_brotli::H5*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH5(duckdb_brotli::H5*, int*) |
1556 | | |
1557 | | /* Find a longest backward match of &data[cur_ix] up to the length of |
1558 | | max_length and stores the position cur_ix in the hash table. |
1559 | | |
1560 | | REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache |
1561 | | values; if this method is invoked repeatedly with the same distance |
1562 | | cache values, it is enough to invoke FN(PrepareDistanceCache) once. |
1563 | | |
1564 | | Does not look for matches longer than max_length. |
1565 | | Does not look for matches further away than max_backward. |
1566 | | Writes the best match into |out|. |
1567 | | |out|->score is updated only if a better match is found. */ |
1568 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
1569 | | HashLongestMatch* BROTLI_RESTRICT self, |
1570 | | const BrotliEncoderDictionary* dictionary, |
1571 | | const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, |
1572 | | const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, |
1573 | | const size_t max_length, const size_t max_backward, |
1574 | | const size_t dictionary_distance, const size_t max_distance, |
1575 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
1576 | 0 | uint16_t* BROTLI_RESTRICT num = self->num_; |
1577 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
1578 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
1579 | | /* Don't accept a short copy from far away. */ |
1580 | 0 | score_t min_score = out->score; |
1581 | 0 | score_t best_score = out->score; |
1582 | 0 | size_t best_len = out->len; |
1583 | 0 | size_t i; |
1584 | 0 | out->len = 0; |
1585 | 0 | out->len_code_delta = 0; |
1586 | | /* Try last distance first. */ |
1587 | 0 | for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) { |
1588 | 0 | const size_t backward = (size_t)distance_cache[i]; |
1589 | 0 | size_t prev_ix = (size_t)(cur_ix - backward); |
1590 | 0 | if (prev_ix >= cur_ix) { |
1591 | 0 | continue; |
1592 | 0 | } |
1593 | 0 | if (BROTLI_PREDICT_FALSE(backward > max_backward)) { |
1594 | 0 | continue; |
1595 | 0 | } |
1596 | 0 | prev_ix &= ring_buffer_mask; |
1597 | |
|
1598 | 0 | if (cur_ix_masked + best_len > ring_buffer_mask || |
1599 | 0 | prev_ix + best_len > ring_buffer_mask || |
1600 | 0 | data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { |
1601 | 0 | continue; |
1602 | 0 | } |
1603 | 0 | { |
1604 | 0 | const size_t len = FindMatchLengthWithLimit(&data[prev_ix], |
1605 | 0 | &data[cur_ix_masked], |
1606 | 0 | max_length); |
1607 | 0 | if (len >= 3 || (len == 2 && i < 2)) { |
1608 | | /* Comparing for >= 2 does not change the semantics, but just saves for |
1609 | | a few unnecessary binary logarithms in backward reference score, |
1610 | | since we are not interested in such short matches. */ |
1611 | 0 | score_t score = BackwardReferenceScoreUsingLastDistance(len); |
1612 | 0 | if (best_score < score) { |
1613 | 0 | if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); |
1614 | 0 | if (best_score < score) { |
1615 | 0 | best_score = score; |
1616 | 0 | best_len = len; |
1617 | 0 | out->len = best_len; |
1618 | 0 | out->distance = backward; |
1619 | 0 | out->score = best_score; |
1620 | 0 | } |
1621 | 0 | } |
1622 | 0 | } |
1623 | 0 | } |
1624 | 0 | } |
1625 | 0 | { |
1626 | 0 | const uint32_t key = |
1627 | 0 | FN(HashBytes)(&data[cur_ix_masked], self->hash_shift_); |
1628 | 0 | uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_]; |
1629 | 0 | const size_t down = |
1630 | 0 | (num[key] > self->block_size_) ? (num[key] - self->block_size_) : 0u; |
1631 | 0 | for (i = num[key]; i > down;) { |
1632 | 0 | size_t prev_ix = bucket[--i & self->block_mask_]; |
1633 | 0 | const size_t backward = cur_ix - prev_ix; |
1634 | 0 | if (BROTLI_PREDICT_FALSE(backward > max_backward)) { |
1635 | 0 | break; |
1636 | 0 | } |
1637 | 0 | prev_ix &= ring_buffer_mask; |
1638 | 0 | if (cur_ix_masked + best_len > ring_buffer_mask || |
1639 | 0 | prev_ix + best_len > ring_buffer_mask || |
1640 | 0 | data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { |
1641 | 0 | continue; |
1642 | 0 | } |
1643 | 0 | { |
1644 | 0 | const size_t len = FindMatchLengthWithLimit(&data[prev_ix], |
1645 | 0 | &data[cur_ix_masked], |
1646 | 0 | max_length); |
1647 | 0 | if (len >= 4) { |
1648 | | /* Comparing for >= 3 does not change the semantics, but just saves |
1649 | | for a few unnecessary binary logarithms in backward reference |
1650 | | score, since we are not interested in such short matches. */ |
1651 | 0 | score_t score = BackwardReferenceScore(len, backward); |
1652 | 0 | if (best_score < score) { |
1653 | 0 | best_score = score; |
1654 | 0 | best_len = len; |
1655 | 0 | out->len = best_len; |
1656 | 0 | out->distance = backward; |
1657 | 0 | out->score = best_score; |
1658 | 0 | } |
1659 | 0 | } |
1660 | 0 | } |
1661 | 0 | } |
1662 | 0 | bucket[num[key] & self->block_mask_] = (uint32_t)cur_ix; |
1663 | 0 | ++num[key]; |
1664 | 0 | } |
1665 | 0 | if (min_score == out->score) { |
1666 | 0 | SearchInStaticDictionary(dictionary, |
1667 | 0 | self->common_, &data[cur_ix_masked], max_length, dictionary_distance, |
1668 | 0 | max_distance, out, BROTLI_FALSE); |
1669 | 0 | } |
1670 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH5(duckdb_brotli::H5*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH5(duckdb_brotli::H5*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH5(duckdb_brotli::H5*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH5(duckdb_brotli::H5*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
1671 | | |
1672 | | #undef HashLongestMatch |
1673 | | #undef HASHER |
1674 | | |
1675 | | #define HASHER() H6 |
1676 | | /* NOLINT(build/header_guard) */ |
1677 | | /* Copyright 2010 Google Inc. All Rights Reserved. |
1678 | | |
1679 | | Distributed under MIT license. |
1680 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
1681 | | */ |
1682 | | |
1683 | | /* template parameters: FN */ |
1684 | | |
1685 | | /* A (forgetful) hash table to the data seen by the compressor, to |
1686 | | help create backward references to previous data. |
1687 | | |
1688 | | This is a hash map of fixed size (bucket_size_) to a ring buffer of |
1689 | | fixed size (block_size_). The ring buffer contains the last block_size_ |
1690 | | index positions of the given hash key in the compressed data. */ |
1691 | | |
1692 | | #define HashLongestMatch HASHER() |
1693 | | |
1694 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH6() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH6() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH6() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH6() |
1695 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH6() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH6() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH6() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH6() |
1696 | | |
1697 | | /* HashBytes is the function that chooses the bucket to place the address in. */ |
1698 | | static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data, |
1699 | 0 | uint64_t hash_mul) { |
1700 | 0 | const uint64_t h = BROTLI_UNALIGNED_LOAD64LE(data) * hash_mul; |
1701 | | /* The higher bits contain more mixture from the multiplication, |
1702 | | so we take our results from there. */ |
1703 | 0 | return (size_t)(h >> (64 - 15)); |
1704 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashBytesH6(unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashBytesH6(unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashBytesH6(unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashBytesH6(unsigned char const*, unsigned long) |
1705 | | |
1706 | | typedef struct HashLongestMatch { |
1707 | | /* Number of hash buckets. */ |
1708 | | size_t bucket_size_; |
1709 | | /* Only block_size_ newest backward references are kept, |
1710 | | and the older are forgotten. */ |
1711 | | size_t block_size_; |
1712 | | /* Hash multiplier tuned to match length. */ |
1713 | | uint64_t hash_mul_; |
1714 | | /* Mask for accessing entries in a block (in a ring-buffer manner). */ |
1715 | | uint32_t block_mask_; |
1716 | | |
1717 | | int block_bits_; |
1718 | | int num_last_distances_to_check_; |
1719 | | |
1720 | | /* Shortcuts. */ |
1721 | | HasherCommon* common_; |
1722 | | |
1723 | | /* --- Dynamic size members --- */ |
1724 | | |
1725 | | /* Number of entries in a particular bucket. */ |
1726 | | uint16_t* num_; /* uint16_t[bucket_size]; */ |
1727 | | |
1728 | | /* Buckets containing block_size_ of backward references. */ |
1729 | | uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */ |
1730 | | } HashLongestMatch; |
1731 | | |
1732 | | static void FN(Initialize)( |
1733 | | HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self, |
1734 | 0 | const BrotliEncoderParams* params) { |
1735 | 0 | self->common_ = common; |
1736 | |
|
1737 | 0 | BROTLI_UNUSED(params); |
1738 | 0 | self->hash_mul_ = kHashMul64 << (64 - 5 * 8); |
1739 | 0 | BROTLI_DCHECK(common->params.bucket_bits == 15); |
1740 | 0 | self->bucket_size_ = (size_t)1 << common->params.bucket_bits; |
1741 | 0 | self->block_bits_ = common->params.block_bits; |
1742 | 0 | self->block_size_ = (size_t)1 << common->params.block_bits; |
1743 | 0 | self->block_mask_ = (uint32_t)(self->block_size_ - 1); |
1744 | 0 | self->num_last_distances_to_check_ = |
1745 | 0 | common->params.num_last_distances_to_check; |
1746 | 0 | self->num_ = (uint16_t*)common->extra[0]; |
1747 | 0 | self->buckets_ = (uint32_t*)common->extra[1]; |
1748 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH6(duckdb_brotli::HasherCommon*, duckdb_brotli::H6*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH6(duckdb_brotli::HasherCommon*, duckdb_brotli::H6*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH6(duckdb_brotli::HasherCommon*, duckdb_brotli::H6*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH6(duckdb_brotli::HasherCommon*, duckdb_brotli::H6*, BrotliEncoderParams const*) |
1749 | | |
1750 | | static void FN(Prepare)( |
1751 | | HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
1752 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
1753 | 0 | uint16_t* BROTLI_RESTRICT num = self->num_; |
1754 | | /* Partial preparation is 100 times slower (per socket). */ |
1755 | 0 | size_t partial_prepare_threshold = self->bucket_size_ >> 6; |
1756 | 0 | if (one_shot && input_size <= partial_prepare_threshold) { |
1757 | 0 | size_t i; |
1758 | 0 | for (i = 0; i < input_size; ++i) { |
1759 | 0 | const size_t key = FN(HashBytes)(&data[i], self->hash_mul_); |
1760 | 0 | num[key] = 0; |
1761 | 0 | } |
1762 | 0 | } else { |
1763 | 0 | memset(num, 0, self->bucket_size_ * sizeof(num[0])); |
1764 | 0 | } |
1765 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH6(duckdb_brotli::H6*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH6(duckdb_brotli::H6*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH6(duckdb_brotli::H6*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH6(duckdb_brotli::H6*, int, unsigned long, unsigned char const*) |
1766 | | |
1767 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
1768 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
1769 | 0 | size_t input_size, size_t* alloc_size) { |
1770 | 0 | size_t bucket_size = (size_t)1 << params->hasher.bucket_bits; |
1771 | 0 | size_t block_size = (size_t)1 << params->hasher.block_bits; |
1772 | 0 | BROTLI_UNUSED(one_shot); |
1773 | 0 | BROTLI_UNUSED(input_size); |
1774 | 0 | alloc_size[0] = sizeof(uint16_t) * bucket_size; |
1775 | 0 | alloc_size[1] = sizeof(uint32_t) * bucket_size * block_size; |
1776 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH6(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH6(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH6(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH6(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
1777 | | |
1778 | | /* Look at 4 bytes at &data[ix & mask]. |
1779 | | Compute a hash from these, and store the value of ix at that position. */ |
1780 | | static BROTLI_INLINE void FN(Store)( |
1781 | | HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, |
1782 | 0 | const size_t mask, const size_t ix) { |
1783 | 0 | uint16_t* BROTLI_RESTRICT num = self->num_; |
1784 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
1785 | 0 | const size_t key = FN(HashBytes)(&data[ix & mask], self->hash_mul_); |
1786 | 0 | const size_t minor_ix = num[key] & self->block_mask_; |
1787 | 0 | const size_t offset = minor_ix + (key << self->block_bits_); |
1788 | 0 | ++num[key]; |
1789 | 0 | buckets[offset] = (uint32_t)ix; |
1790 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH6(duckdb_brotli::H6*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH6(duckdb_brotli::H6*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH6(duckdb_brotli::H6*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH6(duckdb_brotli::H6*, unsigned char const*, unsigned long, unsigned long) |
1791 | | |
1792 | | static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self, |
1793 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
1794 | 0 | const size_t ix_start, const size_t ix_end) { |
1795 | 0 | size_t i; |
1796 | 0 | for (i = ix_start; i < ix_end; ++i) { |
1797 | 0 | FN(Store)(self, data, mask, i); |
1798 | 0 | } |
1799 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH6(duckdb_brotli::H6*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH6(duckdb_brotli::H6*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH6(duckdb_brotli::H6*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH6(duckdb_brotli::H6*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
1800 | | |
1801 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
1802 | | HashLongestMatch* BROTLI_RESTRICT self, |
1803 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
1804 | 0 | size_t ringbuffer_mask) { |
1805 | 0 | if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { |
1806 | | /* Prepare the hashes for three last bytes of the last write. |
1807 | | These could not be calculated before, since they require knowledge |
1808 | | of both the previous and the current block. */ |
1809 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); |
1810 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); |
1811 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); |
1812 | 0 | } |
1813 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH6(duckdb_brotli::H6*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH6(duckdb_brotli::H6*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH6(duckdb_brotli::H6*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH6(duckdb_brotli::H6*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
1814 | | |
1815 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
1816 | | HashLongestMatch* BROTLI_RESTRICT self, |
1817 | 0 | int* BROTLI_RESTRICT distance_cache) { |
1818 | 0 | PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_); |
1819 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH6(duckdb_brotli::H6*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH6(duckdb_brotli::H6*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH6(duckdb_brotli::H6*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH6(duckdb_brotli::H6*, int*) |
1820 | | |
1821 | | /* Find a longest backward match of &data[cur_ix] up to the length of |
1822 | | max_length and stores the position cur_ix in the hash table. |
1823 | | |
1824 | | REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache |
1825 | | values; if this method is invoked repeatedly with the same distance |
1826 | | cache values, it is enough to invoke FN(PrepareDistanceCache) once. |
1827 | | |
1828 | | Does not look for matches longer than max_length. |
1829 | | Does not look for matches further away than max_backward. |
1830 | | Writes the best match into |out|. |
1831 | | |out|->score is updated only if a better match is found. */ |
1832 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
1833 | | HashLongestMatch* BROTLI_RESTRICT self, |
1834 | | const BrotliEncoderDictionary* dictionary, |
1835 | | const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, |
1836 | | const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, |
1837 | | const size_t max_length, const size_t max_backward, |
1838 | | const size_t dictionary_distance, const size_t max_distance, |
1839 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
1840 | 0 | uint16_t* BROTLI_RESTRICT num = self->num_; |
1841 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
1842 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
1843 | | /* Don't accept a short copy from far away. */ |
1844 | 0 | score_t min_score = out->score; |
1845 | 0 | score_t best_score = out->score; |
1846 | 0 | size_t best_len = out->len; |
1847 | 0 | size_t i; |
1848 | 0 | out->len = 0; |
1849 | 0 | out->len_code_delta = 0; |
1850 | | /* Try last distance first. */ |
1851 | 0 | for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) { |
1852 | 0 | const size_t backward = (size_t)distance_cache[i]; |
1853 | 0 | size_t prev_ix = (size_t)(cur_ix - backward); |
1854 | 0 | if (prev_ix >= cur_ix) { |
1855 | 0 | continue; |
1856 | 0 | } |
1857 | 0 | if (BROTLI_PREDICT_FALSE(backward > max_backward)) { |
1858 | 0 | continue; |
1859 | 0 | } |
1860 | 0 | prev_ix &= ring_buffer_mask; |
1861 | |
|
1862 | 0 | if (cur_ix_masked + best_len > ring_buffer_mask || |
1863 | 0 | prev_ix + best_len > ring_buffer_mask || |
1864 | 0 | data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { |
1865 | 0 | continue; |
1866 | 0 | } |
1867 | 0 | { |
1868 | 0 | const size_t len = FindMatchLengthWithLimit(&data[prev_ix], |
1869 | 0 | &data[cur_ix_masked], |
1870 | 0 | max_length); |
1871 | 0 | if (len >= 3 || (len == 2 && i < 2)) { |
1872 | | /* Comparing for >= 2 does not change the semantics, but just saves for |
1873 | | a few unnecessary binary logarithms in backward reference score, |
1874 | | since we are not interested in such short matches. */ |
1875 | 0 | score_t score = BackwardReferenceScoreUsingLastDistance(len); |
1876 | 0 | if (best_score < score) { |
1877 | 0 | if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); |
1878 | 0 | if (best_score < score) { |
1879 | 0 | best_score = score; |
1880 | 0 | best_len = len; |
1881 | 0 | out->len = best_len; |
1882 | 0 | out->distance = backward; |
1883 | 0 | out->score = best_score; |
1884 | 0 | } |
1885 | 0 | } |
1886 | 0 | } |
1887 | 0 | } |
1888 | 0 | } |
1889 | 0 | { |
1890 | 0 | const size_t key = FN(HashBytes)(&data[cur_ix_masked], self->hash_mul_); |
1891 | 0 | uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_]; |
1892 | 0 | const size_t down = |
1893 | 0 | (num[key] > self->block_size_) ? |
1894 | 0 | (num[key] - self->block_size_) : 0u; |
1895 | 0 | const uint32_t first4 = BrotliUnalignedRead32(data + cur_ix_masked); |
1896 | 0 | const size_t max_length_m4 = max_length - 4; |
1897 | 0 | i = num[key]; |
1898 | 0 | for (; i > down;) { |
1899 | 0 | size_t prev_ix = bucket[--i & self->block_mask_]; |
1900 | 0 | uint32_t current4; |
1901 | 0 | const size_t backward = cur_ix - prev_ix; |
1902 | 0 | if (BROTLI_PREDICT_FALSE(backward > max_backward)) { |
1903 | 0 | break; |
1904 | 0 | } |
1905 | 0 | prev_ix &= ring_buffer_mask; |
1906 | 0 | if (cur_ix_masked + best_len > ring_buffer_mask || |
1907 | 0 | prev_ix + best_len > ring_buffer_mask || |
1908 | 0 | data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { |
1909 | 0 | continue; |
1910 | 0 | } |
1911 | 0 | current4 = BrotliUnalignedRead32(data + prev_ix); |
1912 | 0 | if (first4 != current4) continue; |
1913 | 0 | { |
1914 | 0 | const size_t len = FindMatchLengthWithLimit(&data[prev_ix + 4], |
1915 | 0 | &data[cur_ix_masked + 4], |
1916 | 0 | max_length_m4) + 4; |
1917 | 0 | const score_t score = BackwardReferenceScore(len, backward); |
1918 | 0 | if (best_score < score) { |
1919 | 0 | best_score = score; |
1920 | 0 | best_len = len; |
1921 | 0 | out->len = best_len; |
1922 | 0 | out->distance = backward; |
1923 | 0 | out->score = best_score; |
1924 | 0 | } |
1925 | 0 | } |
1926 | 0 | } |
1927 | 0 | bucket[num[key] & self->block_mask_] = (uint32_t)cur_ix; |
1928 | 0 | ++num[key]; |
1929 | 0 | } |
1930 | 0 | if (min_score == out->score) { |
1931 | 0 | SearchInStaticDictionary(dictionary, |
1932 | 0 | self->common_, &data[cur_ix_masked], max_length, dictionary_distance, |
1933 | 0 | max_distance, out, BROTLI_FALSE); |
1934 | 0 | } |
1935 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH6(duckdb_brotli::H6*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH6(duckdb_brotli::H6*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH6(duckdb_brotli::H6*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH6(duckdb_brotli::H6*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
1936 | | |
1937 | | #undef HashLongestMatch |
1938 | | #undef HASHER |
1939 | | |
1940 | 0 | #define BUCKET_BITS 15 |
1941 | | |
1942 | 0 | #define NUM_LAST_DISTANCES_TO_CHECK 4 |
1943 | 0 | #define NUM_BANKS 1 |
1944 | 0 | #define BANK_BITS 16 |
1945 | | #define HASHER() H40 |
1946 | | /* NOLINT(build/header_guard) */ |
1947 | | /* Copyright 2016 Google Inc. All Rights Reserved. |
1948 | | |
1949 | | Distributed under MIT license. |
1950 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
1951 | | */ |
1952 | | |
1953 | | /* template parameters: FN, BUCKET_BITS, NUM_BANKS, BANK_BITS, |
1954 | | NUM_LAST_DISTANCES_TO_CHECK */ |
1955 | | |
1956 | | /* A (forgetful) hash table to the data seen by the compressor, to |
1957 | | help create backward references to previous data. |
1958 | | |
1959 | | Hashes are stored in chains which are bucketed to groups. Group of chains |
1960 | | share a storage "bank". When more than "bank size" chain nodes are added, |
1961 | | oldest nodes are replaced; this way several chains may share a tail. */ |
1962 | | |
1963 | | #define HashForgetfulChain HASHER() |
1964 | | |
1965 | 0 | #define BANK_SIZE (1 << BANK_BITS) |
1966 | | |
1967 | | /* Number of hash buckets. */ |
1968 | 0 | #define BUCKET_SIZE (1 << BUCKET_BITS) |
1969 | | |
1970 | 0 | #define CAPPED_CHAINS 0 |
1971 | | |
1972 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH40() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH40() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH40() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH40() |
1973 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH40() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH40() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH40() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH40() |
1974 | | |
1975 | | /* HashBytes is the function that chooses the bucket to place the address in.*/ |
1976 | 0 | static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) { |
1977 | 0 | const uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; |
1978 | | /* The higher bits contain more mixture from the multiplication, |
1979 | | so we take our results from there. */ |
1980 | 0 | return h >> (32 - BUCKET_BITS); |
1981 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashBytesH40(unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashBytesH40(unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashBytesH40(unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashBytesH40(unsigned char const*) |
1982 | | |
1983 | | typedef struct FN(Slot) { |
1984 | | uint16_t delta; |
1985 | | uint16_t next; |
1986 | | } FN(Slot); |
1987 | | |
1988 | | typedef struct FN(Bank) { |
1989 | | FN(Slot) slots[BANK_SIZE]; |
1990 | | } FN(Bank); |
1991 | | |
1992 | | typedef struct HashForgetfulChain { |
1993 | | uint16_t free_slot_idx[NUM_BANKS]; /* Up to 1KiB. Move to dynamic? */ |
1994 | | size_t max_hops; |
1995 | | |
1996 | | /* Shortcuts. */ |
1997 | | void* extra[2]; |
1998 | | HasherCommon* common; |
1999 | | |
2000 | | /* --- Dynamic size members --- */ |
2001 | | |
2002 | | /* uint32_t addr[BUCKET_SIZE]; */ |
2003 | | |
2004 | | /* uint16_t head[BUCKET_SIZE]; */ |
2005 | | |
2006 | | /* Truncated hash used for quick rejection of "distance cache" candidates. */ |
2007 | | /* uint8_t tiny_hash[65536];*/ |
2008 | | |
2009 | | /* FN(Bank) banks[NUM_BANKS]; */ |
2010 | | } HashForgetfulChain; |
2011 | | |
2012 | 0 | static uint32_t* FN(Addr)(void* extra) { |
2013 | 0 | return (uint32_t*)extra; |
2014 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::AddrH40(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::AddrH40(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::AddrH40(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::AddrH40(void*) |
2015 | | |
2016 | 0 | static uint16_t* FN(Head)(void* extra) { |
2017 | 0 | return (uint16_t*)(&FN(Addr)(extra)[BUCKET_SIZE]); |
2018 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HeadH40(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HeadH40(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HeadH40(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HeadH40(void*) |
2019 | | |
2020 | 0 | static uint8_t* FN(TinyHash)(void* extra) { |
2021 | 0 | return (uint8_t*)(&FN(Head)(extra)[BUCKET_SIZE]); |
2022 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::TinyHashH40(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::TinyHashH40(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::TinyHashH40(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::TinyHashH40(void*) |
2023 | | |
2024 | 0 | static FN(Bank)* FN(Banks)(void* extra) { |
2025 | 0 | return (FN(Bank)*)(extra); |
2026 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::BanksH40(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::BanksH40(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::BanksH40(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::BanksH40(void*) |
2027 | | |
2028 | | static void FN(Initialize)( |
2029 | | HasherCommon* common, HashForgetfulChain* BROTLI_RESTRICT self, |
2030 | 0 | const BrotliEncoderParams* params) { |
2031 | 0 | self->common = common; |
2032 | 0 | self->extra[0] = common->extra[0]; |
2033 | 0 | self->extra[1] = common->extra[1]; |
2034 | |
|
2035 | 0 | self->max_hops = (params->quality > 6 ? 7u : 8u) << (params->quality - 4); |
2036 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH40(duckdb_brotli::HasherCommon*, duckdb_brotli::H40*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH40(duckdb_brotli::HasherCommon*, duckdb_brotli::H40*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH40(duckdb_brotli::HasherCommon*, duckdb_brotli::H40*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH40(duckdb_brotli::HasherCommon*, duckdb_brotli::H40*, BrotliEncoderParams const*) |
2037 | | |
2038 | | static void FN(Prepare)( |
2039 | | HashForgetfulChain* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
2040 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
2041 | 0 | uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); |
2042 | 0 | uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); |
2043 | 0 | uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra[0]); |
2044 | | /* Partial preparation is 100 times slower (per socket). */ |
2045 | 0 | size_t partial_prepare_threshold = BUCKET_SIZE >> 6; |
2046 | 0 | if (one_shot && input_size <= partial_prepare_threshold) { |
2047 | 0 | size_t i; |
2048 | 0 | for (i = 0; i < input_size; ++i) { |
2049 | 0 | size_t bucket = FN(HashBytes)(&data[i]); |
2050 | | /* See InitEmpty comment. */ |
2051 | 0 | addr[bucket] = 0xCCCCCCCC; |
2052 | 0 | head[bucket] = 0xCCCC; |
2053 | 0 | } |
2054 | 0 | } else { |
2055 | | /* Fill |addr| array with 0xCCCCCCCC value. Because of wrapping, position |
2056 | | processed by hasher never reaches 3GB + 64M; this makes all new chains |
2057 | | to be terminated after the first node. */ |
2058 | 0 | memset(addr, 0xCC, sizeof(uint32_t) * BUCKET_SIZE); |
2059 | 0 | memset(head, 0, sizeof(uint16_t) * BUCKET_SIZE); |
2060 | 0 | } |
2061 | 0 | memset(tiny_hash, 0, sizeof(uint8_t) * 65536); |
2062 | 0 | memset(self->free_slot_idx, 0, sizeof(self->free_slot_idx)); |
2063 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH40(duckdb_brotli::H40*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH40(duckdb_brotli::H40*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH40(duckdb_brotli::H40*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH40(duckdb_brotli::H40*, int, unsigned long, unsigned char const*) |
2064 | | |
2065 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
2066 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
2067 | 0 | size_t input_size, size_t* alloc_size) { |
2068 | 0 | BROTLI_UNUSED(params); |
2069 | 0 | BROTLI_UNUSED(one_shot); |
2070 | 0 | BROTLI_UNUSED(input_size); |
2071 | 0 | alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE + |
2072 | 0 | sizeof(uint16_t) * BUCKET_SIZE + sizeof(uint8_t) * 65536; |
2073 | 0 | alloc_size[1] = sizeof(FN(Bank)) * NUM_BANKS; |
2074 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH40(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH40(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH40(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH40(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
2075 | | |
2076 | | /* Look at 4 bytes at &data[ix & mask]. Compute a hash from these, and prepend |
2077 | | node to corresponding chain; also update tiny_hash for current position. */ |
2078 | | static BROTLI_INLINE void FN(Store)(HashForgetfulChain* BROTLI_RESTRICT self, |
2079 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
2080 | 0 | uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); |
2081 | 0 | uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); |
2082 | 0 | uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra[0]); |
2083 | 0 | FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra[1]); |
2084 | 0 | const size_t key = FN(HashBytes)(&data[ix & mask]); |
2085 | 0 | const size_t bank = key & (NUM_BANKS - 1); |
2086 | 0 | const size_t idx = self->free_slot_idx[bank]++ & (BANK_SIZE - 1); |
2087 | 0 | size_t delta = ix - addr[key]; |
2088 | 0 | tiny_hash[(uint16_t)ix] = (uint8_t)key; |
2089 | 0 | if (delta > 0xFFFF) delta = CAPPED_CHAINS ? 0 : 0xFFFF; |
2090 | 0 | banks[bank].slots[idx].delta = (uint16_t)delta; |
2091 | 0 | banks[bank].slots[idx].next = head[key]; |
2092 | 0 | addr[key] = (uint32_t)ix; |
2093 | 0 | head[key] = (uint16_t)idx; |
2094 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH40(duckdb_brotli::H40*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH40(duckdb_brotli::H40*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH40(duckdb_brotli::H40*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH40(duckdb_brotli::H40*, unsigned char const*, unsigned long, unsigned long) |
2095 | | |
2096 | | static BROTLI_INLINE void FN(StoreRange)( |
2097 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2098 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
2099 | 0 | const size_t ix_start, const size_t ix_end) { |
2100 | 0 | size_t i; |
2101 | 0 | for (i = ix_start; i < ix_end; ++i) { |
2102 | 0 | FN(Store)(self, data, mask, i); |
2103 | 0 | } |
2104 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH40(duckdb_brotli::H40*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH40(duckdb_brotli::H40*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH40(duckdb_brotli::H40*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH40(duckdb_brotli::H40*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
2105 | | |
2106 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
2107 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2108 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
2109 | 0 | size_t ring_buffer_mask) { |
2110 | 0 | if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { |
2111 | | /* Prepare the hashes for three last bytes of the last write. |
2112 | | These could not be calculated before, since they require knowledge |
2113 | | of both the previous and the current block. */ |
2114 | 0 | FN(Store)(self, ringbuffer, ring_buffer_mask, position - 3); |
2115 | 0 | FN(Store)(self, ringbuffer, ring_buffer_mask, position - 2); |
2116 | 0 | FN(Store)(self, ringbuffer, ring_buffer_mask, position - 1); |
2117 | 0 | } |
2118 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH40(duckdb_brotli::H40*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH40(duckdb_brotli::H40*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH40(duckdb_brotli::H40*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH40(duckdb_brotli::H40*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
2119 | | |
2120 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
2121 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2122 | 0 | int* BROTLI_RESTRICT distance_cache) { |
2123 | 0 | BROTLI_UNUSED(self); |
2124 | 0 | PrepareDistanceCache(distance_cache, NUM_LAST_DISTANCES_TO_CHECK); |
2125 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH40(duckdb_brotli::H40*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH40(duckdb_brotli::H40*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH40(duckdb_brotli::H40*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH40(duckdb_brotli::H40*, int*) |
2126 | | |
2127 | | /* Find a longest backward match of &data[cur_ix] up to the length of |
2128 | | max_length and stores the position cur_ix in the hash table. |
2129 | | |
2130 | | REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache |
2131 | | values; if this method is invoked repeatedly with the same distance |
2132 | | cache values, it is enough to invoke FN(PrepareDistanceCache) once. |
2133 | | |
2134 | | Does not look for matches longer than max_length. |
2135 | | Does not look for matches further away than max_backward. |
2136 | | Writes the best match into |out|. |
2137 | | |out|->score is updated only if a better match is found. */ |
2138 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
2139 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2140 | | const BrotliEncoderDictionary* dictionary, |
2141 | | const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, |
2142 | | const int* BROTLI_RESTRICT distance_cache, |
2143 | | const size_t cur_ix, const size_t max_length, const size_t max_backward, |
2144 | | const size_t dictionary_distance, const size_t max_distance, |
2145 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
2146 | 0 | uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); |
2147 | 0 | uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); |
2148 | 0 | uint8_t* BROTLI_RESTRICT tiny_hashes = FN(TinyHash)(self->extra[0]); |
2149 | 0 | FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra[1]); |
2150 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
2151 | | /* Don't accept a short copy from far away. */ |
2152 | 0 | score_t min_score = out->score; |
2153 | 0 | score_t best_score = out->score; |
2154 | 0 | size_t best_len = out->len; |
2155 | 0 | size_t i; |
2156 | 0 | const size_t key = FN(HashBytes)(&data[cur_ix_masked]); |
2157 | 0 | const uint8_t tiny_hash = (uint8_t)(key); |
2158 | 0 | out->len = 0; |
2159 | 0 | out->len_code_delta = 0; |
2160 | | /* Try last distance first. */ |
2161 | 0 | for (i = 0; i < NUM_LAST_DISTANCES_TO_CHECK; ++i) { |
2162 | 0 | const size_t backward = (size_t)distance_cache[i]; |
2163 | 0 | size_t prev_ix = (cur_ix - backward); |
2164 | | /* For distance code 0 we want to consider 2-byte matches. */ |
2165 | 0 | if (i > 0 && tiny_hashes[(uint16_t)prev_ix] != tiny_hash) continue; |
2166 | 0 | if (prev_ix >= cur_ix || backward > max_backward) { |
2167 | 0 | continue; |
2168 | 0 | } |
2169 | 0 | prev_ix &= ring_buffer_mask; |
2170 | 0 | { |
2171 | 0 | const size_t len = FindMatchLengthWithLimit(&data[prev_ix], |
2172 | 0 | &data[cur_ix_masked], |
2173 | 0 | max_length); |
2174 | 0 | if (len >= 2) { |
2175 | 0 | score_t score = BackwardReferenceScoreUsingLastDistance(len); |
2176 | 0 | if (best_score < score) { |
2177 | 0 | if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); |
2178 | 0 | if (best_score < score) { |
2179 | 0 | best_score = score; |
2180 | 0 | best_len = len; |
2181 | 0 | out->len = best_len; |
2182 | 0 | out->distance = backward; |
2183 | 0 | out->score = best_score; |
2184 | 0 | } |
2185 | 0 | } |
2186 | 0 | } |
2187 | 0 | } |
2188 | 0 | } |
2189 | 0 | { |
2190 | 0 | const size_t bank = key & (NUM_BANKS - 1); |
2191 | 0 | size_t backward = 0; |
2192 | 0 | size_t hops = self->max_hops; |
2193 | 0 | size_t delta = cur_ix - addr[key]; |
2194 | 0 | size_t slot = head[key]; |
2195 | 0 | while (hops--) { |
2196 | 0 | size_t prev_ix; |
2197 | 0 | size_t last = slot; |
2198 | 0 | backward += delta; |
2199 | 0 | if (backward > max_backward || (CAPPED_CHAINS && !delta)) break; |
2200 | 0 | prev_ix = (cur_ix - backward) & ring_buffer_mask; |
2201 | 0 | slot = banks[bank].slots[last].next; |
2202 | 0 | delta = banks[bank].slots[last].delta; |
2203 | 0 | if (cur_ix_masked + best_len > ring_buffer_mask || |
2204 | 0 | prev_ix + best_len > ring_buffer_mask || |
2205 | 0 | data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { |
2206 | 0 | continue; |
2207 | 0 | } |
2208 | 0 | { |
2209 | 0 | const size_t len = FindMatchLengthWithLimit(&data[prev_ix], |
2210 | 0 | &data[cur_ix_masked], |
2211 | 0 | max_length); |
2212 | 0 | if (len >= 4) { |
2213 | | /* Comparing for >= 3 does not change the semantics, but just saves |
2214 | | for a few unnecessary binary logarithms in backward reference |
2215 | | score, since we are not interested in such short matches. */ |
2216 | 0 | score_t score = BackwardReferenceScore(len, backward); |
2217 | 0 | if (best_score < score) { |
2218 | 0 | best_score = score; |
2219 | 0 | best_len = len; |
2220 | 0 | out->len = best_len; |
2221 | 0 | out->distance = backward; |
2222 | 0 | out->score = best_score; |
2223 | 0 | } |
2224 | 0 | } |
2225 | 0 | } |
2226 | 0 | } |
2227 | 0 | FN(Store)(self, data, ring_buffer_mask, cur_ix); |
2228 | 0 | } |
2229 | 0 | if (out->score == min_score) { |
2230 | 0 | SearchInStaticDictionary(dictionary, |
2231 | 0 | self->common, &data[cur_ix_masked], max_length, dictionary_distance, |
2232 | 0 | max_distance, out, BROTLI_FALSE); |
2233 | 0 | } |
2234 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH40(duckdb_brotli::H40*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH40(duckdb_brotli::H40*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH40(duckdb_brotli::H40*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH40(duckdb_brotli::H40*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
2235 | | |
2236 | | #undef BANK_SIZE |
2237 | | #undef BUCKET_SIZE |
2238 | | #undef CAPPED_CHAINS |
2239 | | |
2240 | | #undef HashForgetfulChain |
2241 | | #undef HASHER |
2242 | | #undef NUM_LAST_DISTANCES_TO_CHECK |
2243 | | |
2244 | 0 | #define NUM_LAST_DISTANCES_TO_CHECK 10 |
2245 | | #define HASHER() H41 |
2246 | | /* NOLINT(build/header_guard) */ |
2247 | | /* Copyright 2016 Google Inc. All Rights Reserved. |
2248 | | |
2249 | | Distributed under MIT license. |
2250 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
2251 | | */ |
2252 | | |
2253 | | /* template parameters: FN, BUCKET_BITS, NUM_BANKS, BANK_BITS, |
2254 | | NUM_LAST_DISTANCES_TO_CHECK */ |
2255 | | |
2256 | | /* A (forgetful) hash table to the data seen by the compressor, to |
2257 | | help create backward references to previous data. |
2258 | | |
2259 | | Hashes are stored in chains which are bucketed to groups. Group of chains |
2260 | | share a storage "bank". When more than "bank size" chain nodes are added, |
2261 | | oldest nodes are replaced; this way several chains may share a tail. */ |
2262 | | |
2263 | | #define HashForgetfulChain HASHER() |
2264 | | |
2265 | 0 | #define BANK_SIZE (1 << BANK_BITS) |
2266 | | |
2267 | | /* Number of hash buckets. */ |
2268 | 0 | #define BUCKET_SIZE (1 << BUCKET_BITS) |
2269 | | |
2270 | 0 | #define CAPPED_CHAINS 0 |
2271 | | |
2272 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH41() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH41() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH41() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH41() |
2273 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH41() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH41() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH41() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH41() |
2274 | | |
2275 | | /* HashBytes is the function that chooses the bucket to place the address in.*/ |
2276 | 0 | static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) { |
2277 | 0 | const uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; |
2278 | | /* The higher bits contain more mixture from the multiplication, |
2279 | | so we take our results from there. */ |
2280 | 0 | return h >> (32 - BUCKET_BITS); |
2281 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashBytesH41(unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashBytesH41(unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashBytesH41(unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashBytesH41(unsigned char const*) |
2282 | | |
2283 | | typedef struct FN(Slot) { |
2284 | | uint16_t delta; |
2285 | | uint16_t next; |
2286 | | } FN(Slot); |
2287 | | |
2288 | | typedef struct FN(Bank) { |
2289 | | FN(Slot) slots[BANK_SIZE]; |
2290 | | } FN(Bank); |
2291 | | |
2292 | | typedef struct HashForgetfulChain { |
2293 | | uint16_t free_slot_idx[NUM_BANKS]; /* Up to 1KiB. Move to dynamic? */ |
2294 | | size_t max_hops; |
2295 | | |
2296 | | /* Shortcuts. */ |
2297 | | void* extra[2]; |
2298 | | HasherCommon* common; |
2299 | | |
2300 | | /* --- Dynamic size members --- */ |
2301 | | |
2302 | | /* uint32_t addr[BUCKET_SIZE]; */ |
2303 | | |
2304 | | /* uint16_t head[BUCKET_SIZE]; */ |
2305 | | |
2306 | | /* Truncated hash used for quick rejection of "distance cache" candidates. */ |
2307 | | /* uint8_t tiny_hash[65536];*/ |
2308 | | |
2309 | | /* FN(Bank) banks[NUM_BANKS]; */ |
2310 | | } HashForgetfulChain; |
2311 | | |
2312 | 0 | static uint32_t* FN(Addr)(void* extra) { |
2313 | 0 | return (uint32_t*)extra; |
2314 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::AddrH41(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::AddrH41(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::AddrH41(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::AddrH41(void*) |
2315 | | |
2316 | 0 | static uint16_t* FN(Head)(void* extra) { |
2317 | 0 | return (uint16_t*)(&FN(Addr)(extra)[BUCKET_SIZE]); |
2318 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HeadH41(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HeadH41(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HeadH41(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HeadH41(void*) |
2319 | | |
2320 | 0 | static uint8_t* FN(TinyHash)(void* extra) { |
2321 | 0 | return (uint8_t*)(&FN(Head)(extra)[BUCKET_SIZE]); |
2322 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::TinyHashH41(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::TinyHashH41(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::TinyHashH41(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::TinyHashH41(void*) |
2323 | | |
2324 | 0 | static FN(Bank)* FN(Banks)(void* extra) { |
2325 | 0 | return (FN(Bank)*)(extra); |
2326 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::BanksH41(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::BanksH41(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::BanksH41(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::BanksH41(void*) |
2327 | | |
2328 | | static void FN(Initialize)( |
2329 | | HasherCommon* common, HashForgetfulChain* BROTLI_RESTRICT self, |
2330 | 0 | const BrotliEncoderParams* params) { |
2331 | 0 | self->common = common; |
2332 | 0 | self->extra[0] = common->extra[0]; |
2333 | 0 | self->extra[1] = common->extra[1]; |
2334 | |
|
2335 | 0 | self->max_hops = (params->quality > 6 ? 7u : 8u) << (params->quality - 4); |
2336 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH41(duckdb_brotli::HasherCommon*, duckdb_brotli::H41*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH41(duckdb_brotli::HasherCommon*, duckdb_brotli::H41*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH41(duckdb_brotli::HasherCommon*, duckdb_brotli::H41*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH41(duckdb_brotli::HasherCommon*, duckdb_brotli::H41*, BrotliEncoderParams const*) |
2337 | | |
2338 | | static void FN(Prepare)( |
2339 | | HashForgetfulChain* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
2340 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
2341 | 0 | uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); |
2342 | 0 | uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); |
2343 | 0 | uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra[0]); |
2344 | | /* Partial preparation is 100 times slower (per socket). */ |
2345 | 0 | size_t partial_prepare_threshold = BUCKET_SIZE >> 6; |
2346 | 0 | if (one_shot && input_size <= partial_prepare_threshold) { |
2347 | 0 | size_t i; |
2348 | 0 | for (i = 0; i < input_size; ++i) { |
2349 | 0 | size_t bucket = FN(HashBytes)(&data[i]); |
2350 | | /* See InitEmpty comment. */ |
2351 | 0 | addr[bucket] = 0xCCCCCCCC; |
2352 | 0 | head[bucket] = 0xCCCC; |
2353 | 0 | } |
2354 | 0 | } else { |
2355 | | /* Fill |addr| array with 0xCCCCCCCC value. Because of wrapping, position |
2356 | | processed by hasher never reaches 3GB + 64M; this makes all new chains |
2357 | | to be terminated after the first node. */ |
2358 | 0 | memset(addr, 0xCC, sizeof(uint32_t) * BUCKET_SIZE); |
2359 | 0 | memset(head, 0, sizeof(uint16_t) * BUCKET_SIZE); |
2360 | 0 | } |
2361 | 0 | memset(tiny_hash, 0, sizeof(uint8_t) * 65536); |
2362 | 0 | memset(self->free_slot_idx, 0, sizeof(self->free_slot_idx)); |
2363 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH41(duckdb_brotli::H41*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH41(duckdb_brotli::H41*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH41(duckdb_brotli::H41*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH41(duckdb_brotli::H41*, int, unsigned long, unsigned char const*) |
2364 | | |
2365 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
2366 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
2367 | 0 | size_t input_size, size_t* alloc_size) { |
2368 | 0 | BROTLI_UNUSED(params); |
2369 | 0 | BROTLI_UNUSED(one_shot); |
2370 | 0 | BROTLI_UNUSED(input_size); |
2371 | 0 | alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE + |
2372 | 0 | sizeof(uint16_t) * BUCKET_SIZE + sizeof(uint8_t) * 65536; |
2373 | 0 | alloc_size[1] = sizeof(FN(Bank)) * NUM_BANKS; |
2374 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH41(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH41(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH41(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH41(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
2375 | | |
2376 | | /* Look at 4 bytes at &data[ix & mask]. Compute a hash from these, and prepend |
2377 | | node to corresponding chain; also update tiny_hash for current position. */ |
2378 | | static BROTLI_INLINE void FN(Store)(HashForgetfulChain* BROTLI_RESTRICT self, |
2379 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
2380 | 0 | uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); |
2381 | 0 | uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); |
2382 | 0 | uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra[0]); |
2383 | 0 | FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra[1]); |
2384 | 0 | const size_t key = FN(HashBytes)(&data[ix & mask]); |
2385 | 0 | const size_t bank = key & (NUM_BANKS - 1); |
2386 | 0 | const size_t idx = self->free_slot_idx[bank]++ & (BANK_SIZE - 1); |
2387 | 0 | size_t delta = ix - addr[key]; |
2388 | 0 | tiny_hash[(uint16_t)ix] = (uint8_t)key; |
2389 | 0 | if (delta > 0xFFFF) delta = CAPPED_CHAINS ? 0 : 0xFFFF; |
2390 | 0 | banks[bank].slots[idx].delta = (uint16_t)delta; |
2391 | 0 | banks[bank].slots[idx].next = head[key]; |
2392 | 0 | addr[key] = (uint32_t)ix; |
2393 | 0 | head[key] = (uint16_t)idx; |
2394 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH41(duckdb_brotli::H41*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH41(duckdb_brotli::H41*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH41(duckdb_brotli::H41*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH41(duckdb_brotli::H41*, unsigned char const*, unsigned long, unsigned long) |
2395 | | |
2396 | | static BROTLI_INLINE void FN(StoreRange)( |
2397 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2398 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
2399 | 0 | const size_t ix_start, const size_t ix_end) { |
2400 | 0 | size_t i; |
2401 | 0 | for (i = ix_start; i < ix_end; ++i) { |
2402 | 0 | FN(Store)(self, data, mask, i); |
2403 | 0 | } |
2404 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH41(duckdb_brotli::H41*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH41(duckdb_brotli::H41*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH41(duckdb_brotli::H41*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH41(duckdb_brotli::H41*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
2405 | | |
2406 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
2407 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2408 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
2409 | 0 | size_t ring_buffer_mask) { |
2410 | 0 | if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { |
2411 | | /* Prepare the hashes for three last bytes of the last write. |
2412 | | These could not be calculated before, since they require knowledge |
2413 | | of both the previous and the current block. */ |
2414 | 0 | FN(Store)(self, ringbuffer, ring_buffer_mask, position - 3); |
2415 | 0 | FN(Store)(self, ringbuffer, ring_buffer_mask, position - 2); |
2416 | 0 | FN(Store)(self, ringbuffer, ring_buffer_mask, position - 1); |
2417 | 0 | } |
2418 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH41(duckdb_brotli::H41*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH41(duckdb_brotli::H41*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH41(duckdb_brotli::H41*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH41(duckdb_brotli::H41*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
2419 | | |
2420 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
2421 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2422 | 0 | int* BROTLI_RESTRICT distance_cache) { |
2423 | 0 | BROTLI_UNUSED(self); |
2424 | 0 | PrepareDistanceCache(distance_cache, NUM_LAST_DISTANCES_TO_CHECK); |
2425 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH41(duckdb_brotli::H41*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH41(duckdb_brotli::H41*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH41(duckdb_brotli::H41*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH41(duckdb_brotli::H41*, int*) |
2426 | | |
2427 | | /* Find a longest backward match of &data[cur_ix] up to the length of |
2428 | | max_length and stores the position cur_ix in the hash table. |
2429 | | |
2430 | | REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache |
2431 | | values; if this method is invoked repeatedly with the same distance |
2432 | | cache values, it is enough to invoke FN(PrepareDistanceCache) once. |
2433 | | |
2434 | | Does not look for matches longer than max_length. |
2435 | | Does not look for matches further away than max_backward. |
2436 | | Writes the best match into |out|. |
2437 | | |out|->score is updated only if a better match is found. */ |
2438 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
2439 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2440 | | const BrotliEncoderDictionary* dictionary, |
2441 | | const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, |
2442 | | const int* BROTLI_RESTRICT distance_cache, |
2443 | | const size_t cur_ix, const size_t max_length, const size_t max_backward, |
2444 | | const size_t dictionary_distance, const size_t max_distance, |
2445 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
2446 | 0 | uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); |
2447 | 0 | uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); |
2448 | 0 | uint8_t* BROTLI_RESTRICT tiny_hashes = FN(TinyHash)(self->extra[0]); |
2449 | 0 | FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra[1]); |
2450 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
2451 | | /* Don't accept a short copy from far away. */ |
2452 | 0 | score_t min_score = out->score; |
2453 | 0 | score_t best_score = out->score; |
2454 | 0 | size_t best_len = out->len; |
2455 | 0 | size_t i; |
2456 | 0 | const size_t key = FN(HashBytes)(&data[cur_ix_masked]); |
2457 | 0 | const uint8_t tiny_hash = (uint8_t)(key); |
2458 | 0 | out->len = 0; |
2459 | 0 | out->len_code_delta = 0; |
2460 | | /* Try last distance first. */ |
2461 | 0 | for (i = 0; i < NUM_LAST_DISTANCES_TO_CHECK; ++i) { |
2462 | 0 | const size_t backward = (size_t)distance_cache[i]; |
2463 | 0 | size_t prev_ix = (cur_ix - backward); |
2464 | | /* For distance code 0 we want to consider 2-byte matches. */ |
2465 | 0 | if (i > 0 && tiny_hashes[(uint16_t)prev_ix] != tiny_hash) continue; |
2466 | 0 | if (prev_ix >= cur_ix || backward > max_backward) { |
2467 | 0 | continue; |
2468 | 0 | } |
2469 | 0 | prev_ix &= ring_buffer_mask; |
2470 | 0 | { |
2471 | 0 | const size_t len = FindMatchLengthWithLimit(&data[prev_ix], |
2472 | 0 | &data[cur_ix_masked], |
2473 | 0 | max_length); |
2474 | 0 | if (len >= 2) { |
2475 | 0 | score_t score = BackwardReferenceScoreUsingLastDistance(len); |
2476 | 0 | if (best_score < score) { |
2477 | 0 | if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); |
2478 | 0 | if (best_score < score) { |
2479 | 0 | best_score = score; |
2480 | 0 | best_len = len; |
2481 | 0 | out->len = best_len; |
2482 | 0 | out->distance = backward; |
2483 | 0 | out->score = best_score; |
2484 | 0 | } |
2485 | 0 | } |
2486 | 0 | } |
2487 | 0 | } |
2488 | 0 | } |
2489 | 0 | { |
2490 | 0 | const size_t bank = key & (NUM_BANKS - 1); |
2491 | 0 | size_t backward = 0; |
2492 | 0 | size_t hops = self->max_hops; |
2493 | 0 | size_t delta = cur_ix - addr[key]; |
2494 | 0 | size_t slot = head[key]; |
2495 | 0 | while (hops--) { |
2496 | 0 | size_t prev_ix; |
2497 | 0 | size_t last = slot; |
2498 | 0 | backward += delta; |
2499 | 0 | if (backward > max_backward || (CAPPED_CHAINS && !delta)) break; |
2500 | 0 | prev_ix = (cur_ix - backward) & ring_buffer_mask; |
2501 | 0 | slot = banks[bank].slots[last].next; |
2502 | 0 | delta = banks[bank].slots[last].delta; |
2503 | 0 | if (cur_ix_masked + best_len > ring_buffer_mask || |
2504 | 0 | prev_ix + best_len > ring_buffer_mask || |
2505 | 0 | data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { |
2506 | 0 | continue; |
2507 | 0 | } |
2508 | 0 | { |
2509 | 0 | const size_t len = FindMatchLengthWithLimit(&data[prev_ix], |
2510 | 0 | &data[cur_ix_masked], |
2511 | 0 | max_length); |
2512 | 0 | if (len >= 4) { |
2513 | | /* Comparing for >= 3 does not change the semantics, but just saves |
2514 | | for a few unnecessary binary logarithms in backward reference |
2515 | | score, since we are not interested in such short matches. */ |
2516 | 0 | score_t score = BackwardReferenceScore(len, backward); |
2517 | 0 | if (best_score < score) { |
2518 | 0 | best_score = score; |
2519 | 0 | best_len = len; |
2520 | 0 | out->len = best_len; |
2521 | 0 | out->distance = backward; |
2522 | 0 | out->score = best_score; |
2523 | 0 | } |
2524 | 0 | } |
2525 | 0 | } |
2526 | 0 | } |
2527 | 0 | FN(Store)(self, data, ring_buffer_mask, cur_ix); |
2528 | 0 | } |
2529 | 0 | if (out->score == min_score) { |
2530 | 0 | SearchInStaticDictionary(dictionary, |
2531 | 0 | self->common, &data[cur_ix_masked], max_length, dictionary_distance, |
2532 | 0 | max_distance, out, BROTLI_FALSE); |
2533 | 0 | } |
2534 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH41(duckdb_brotli::H41*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH41(duckdb_brotli::H41*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH41(duckdb_brotli::H41*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH41(duckdb_brotli::H41*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
2535 | | |
2536 | | #undef BANK_SIZE |
2537 | | #undef BUCKET_SIZE |
2538 | | #undef CAPPED_CHAINS |
2539 | | |
2540 | | #undef HashForgetfulChain |
2541 | | #undef HASHER |
2542 | | #undef NUM_LAST_DISTANCES_TO_CHECK |
2543 | | #undef NUM_BANKS |
2544 | | #undef BANK_BITS |
2545 | | |
2546 | 0 | #define NUM_LAST_DISTANCES_TO_CHECK 16 |
2547 | 0 | #define NUM_BANKS 512 |
2548 | 0 | #define BANK_BITS 9 |
2549 | | #define HASHER() H42 |
2550 | | /* NOLINT(build/header_guard) */ |
2551 | | /* Copyright 2016 Google Inc. All Rights Reserved. |
2552 | | |
2553 | | Distributed under MIT license. |
2554 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
2555 | | */ |
2556 | | |
2557 | | /* template parameters: FN, BUCKET_BITS, NUM_BANKS, BANK_BITS, |
2558 | | NUM_LAST_DISTANCES_TO_CHECK */ |
2559 | | |
2560 | | /* A (forgetful) hash table to the data seen by the compressor, to |
2561 | | help create backward references to previous data. |
2562 | | |
2563 | | Hashes are stored in chains which are bucketed to groups. Group of chains |
2564 | | share a storage "bank". When more than "bank size" chain nodes are added, |
2565 | | oldest nodes are replaced; this way several chains may share a tail. */ |
2566 | | |
2567 | | #define HashForgetfulChain HASHER() |
2568 | | |
2569 | 0 | #define BANK_SIZE (1 << BANK_BITS) |
2570 | | |
2571 | | /* Number of hash buckets. */ |
2572 | 0 | #define BUCKET_SIZE (1 << BUCKET_BITS) |
2573 | | |
2574 | 0 | #define CAPPED_CHAINS 0 |
2575 | | |
2576 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH42() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH42() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH42() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH42() |
2577 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH42() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH42() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH42() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH42() |
2578 | | |
2579 | | /* HashBytes is the function that chooses the bucket to place the address in.*/ |
2580 | 0 | static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) { |
2581 | 0 | const uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; |
2582 | | /* The higher bits contain more mixture from the multiplication, |
2583 | | so we take our results from there. */ |
2584 | 0 | return h >> (32 - BUCKET_BITS); |
2585 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashBytesH42(unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashBytesH42(unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashBytesH42(unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashBytesH42(unsigned char const*) |
2586 | | |
2587 | | typedef struct FN(Slot) { |
2588 | | uint16_t delta; |
2589 | | uint16_t next; |
2590 | | } FN(Slot); |
2591 | | |
2592 | | typedef struct FN(Bank) { |
2593 | | FN(Slot) slots[BANK_SIZE]; |
2594 | | } FN(Bank); |
2595 | | |
2596 | | typedef struct HashForgetfulChain { |
2597 | | uint16_t free_slot_idx[NUM_BANKS]; /* Up to 1KiB. Move to dynamic? */ |
2598 | | size_t max_hops; |
2599 | | |
2600 | | /* Shortcuts. */ |
2601 | | void* extra[2]; |
2602 | | HasherCommon* common; |
2603 | | |
2604 | | /* --- Dynamic size members --- */ |
2605 | | |
2606 | | /* uint32_t addr[BUCKET_SIZE]; */ |
2607 | | |
2608 | | /* uint16_t head[BUCKET_SIZE]; */ |
2609 | | |
2610 | | /* Truncated hash used for quick rejection of "distance cache" candidates. */ |
2611 | | /* uint8_t tiny_hash[65536];*/ |
2612 | | |
2613 | | /* FN(Bank) banks[NUM_BANKS]; */ |
2614 | | } HashForgetfulChain; |
2615 | | |
2616 | 0 | static uint32_t* FN(Addr)(void* extra) { |
2617 | 0 | return (uint32_t*)extra; |
2618 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::AddrH42(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::AddrH42(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::AddrH42(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::AddrH42(void*) |
2619 | | |
2620 | 0 | static uint16_t* FN(Head)(void* extra) { |
2621 | 0 | return (uint16_t*)(&FN(Addr)(extra)[BUCKET_SIZE]); |
2622 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HeadH42(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HeadH42(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HeadH42(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HeadH42(void*) |
2623 | | |
2624 | 0 | static uint8_t* FN(TinyHash)(void* extra) { |
2625 | 0 | return (uint8_t*)(&FN(Head)(extra)[BUCKET_SIZE]); |
2626 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::TinyHashH42(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::TinyHashH42(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::TinyHashH42(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::TinyHashH42(void*) |
2627 | | |
2628 | 0 | static FN(Bank)* FN(Banks)(void* extra) { |
2629 | 0 | return (FN(Bank)*)(extra); |
2630 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::BanksH42(void*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::BanksH42(void*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::BanksH42(void*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::BanksH42(void*) |
2631 | | |
2632 | | static void FN(Initialize)( |
2633 | | HasherCommon* common, HashForgetfulChain* BROTLI_RESTRICT self, |
2634 | 0 | const BrotliEncoderParams* params) { |
2635 | 0 | self->common = common; |
2636 | 0 | self->extra[0] = common->extra[0]; |
2637 | 0 | self->extra[1] = common->extra[1]; |
2638 | |
|
2639 | 0 | self->max_hops = (params->quality > 6 ? 7u : 8u) << (params->quality - 4); |
2640 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH42(duckdb_brotli::HasherCommon*, duckdb_brotli::H42*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH42(duckdb_brotli::HasherCommon*, duckdb_brotli::H42*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH42(duckdb_brotli::HasherCommon*, duckdb_brotli::H42*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH42(duckdb_brotli::HasherCommon*, duckdb_brotli::H42*, BrotliEncoderParams const*) |
2641 | | |
2642 | | static void FN(Prepare)( |
2643 | | HashForgetfulChain* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
2644 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
2645 | 0 | uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); |
2646 | 0 | uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); |
2647 | 0 | uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra[0]); |
2648 | | /* Partial preparation is 100 times slower (per socket). */ |
2649 | 0 | size_t partial_prepare_threshold = BUCKET_SIZE >> 6; |
2650 | 0 | if (one_shot && input_size <= partial_prepare_threshold) { |
2651 | 0 | size_t i; |
2652 | 0 | for (i = 0; i < input_size; ++i) { |
2653 | 0 | size_t bucket = FN(HashBytes)(&data[i]); |
2654 | | /* See InitEmpty comment. */ |
2655 | 0 | addr[bucket] = 0xCCCCCCCC; |
2656 | 0 | head[bucket] = 0xCCCC; |
2657 | 0 | } |
2658 | 0 | } else { |
2659 | | /* Fill |addr| array with 0xCCCCCCCC value. Because of wrapping, position |
2660 | | processed by hasher never reaches 3GB + 64M; this makes all new chains |
2661 | | to be terminated after the first node. */ |
2662 | 0 | memset(addr, 0xCC, sizeof(uint32_t) * BUCKET_SIZE); |
2663 | 0 | memset(head, 0, sizeof(uint16_t) * BUCKET_SIZE); |
2664 | 0 | } |
2665 | 0 | memset(tiny_hash, 0, sizeof(uint8_t) * 65536); |
2666 | 0 | memset(self->free_slot_idx, 0, sizeof(self->free_slot_idx)); |
2667 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH42(duckdb_brotli::H42*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH42(duckdb_brotli::H42*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH42(duckdb_brotli::H42*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH42(duckdb_brotli::H42*, int, unsigned long, unsigned char const*) |
2668 | | |
2669 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
2670 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
2671 | 0 | size_t input_size, size_t* alloc_size) { |
2672 | 0 | BROTLI_UNUSED(params); |
2673 | 0 | BROTLI_UNUSED(one_shot); |
2674 | 0 | BROTLI_UNUSED(input_size); |
2675 | 0 | alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE + |
2676 | 0 | sizeof(uint16_t) * BUCKET_SIZE + sizeof(uint8_t) * 65536; |
2677 | 0 | alloc_size[1] = sizeof(FN(Bank)) * NUM_BANKS; |
2678 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH42(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH42(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH42(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH42(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
2679 | | |
2680 | | /* Look at 4 bytes at &data[ix & mask]. Compute a hash from these, and prepend |
2681 | | node to corresponding chain; also update tiny_hash for current position. */ |
2682 | | static BROTLI_INLINE void FN(Store)(HashForgetfulChain* BROTLI_RESTRICT self, |
2683 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
2684 | 0 | uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); |
2685 | 0 | uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); |
2686 | 0 | uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra[0]); |
2687 | 0 | FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra[1]); |
2688 | 0 | const size_t key = FN(HashBytes)(&data[ix & mask]); |
2689 | 0 | const size_t bank = key & (NUM_BANKS - 1); |
2690 | 0 | const size_t idx = self->free_slot_idx[bank]++ & (BANK_SIZE - 1); |
2691 | 0 | size_t delta = ix - addr[key]; |
2692 | 0 | tiny_hash[(uint16_t)ix] = (uint8_t)key; |
2693 | 0 | if (delta > 0xFFFF) delta = CAPPED_CHAINS ? 0 : 0xFFFF; |
2694 | 0 | banks[bank].slots[idx].delta = (uint16_t)delta; |
2695 | 0 | banks[bank].slots[idx].next = head[key]; |
2696 | 0 | addr[key] = (uint32_t)ix; |
2697 | 0 | head[key] = (uint16_t)idx; |
2698 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH42(duckdb_brotli::H42*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH42(duckdb_brotli::H42*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH42(duckdb_brotli::H42*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH42(duckdb_brotli::H42*, unsigned char const*, unsigned long, unsigned long) |
2699 | | |
2700 | | static BROTLI_INLINE void FN(StoreRange)( |
2701 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2702 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
2703 | 0 | const size_t ix_start, const size_t ix_end) { |
2704 | 0 | size_t i; |
2705 | 0 | for (i = ix_start; i < ix_end; ++i) { |
2706 | 0 | FN(Store)(self, data, mask, i); |
2707 | 0 | } |
2708 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH42(duckdb_brotli::H42*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH42(duckdb_brotli::H42*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH42(duckdb_brotli::H42*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH42(duckdb_brotli::H42*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
2709 | | |
2710 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
2711 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2712 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
2713 | 0 | size_t ring_buffer_mask) { |
2714 | 0 | if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { |
2715 | | /* Prepare the hashes for three last bytes of the last write. |
2716 | | These could not be calculated before, since they require knowledge |
2717 | | of both the previous and the current block. */ |
2718 | 0 | FN(Store)(self, ringbuffer, ring_buffer_mask, position - 3); |
2719 | 0 | FN(Store)(self, ringbuffer, ring_buffer_mask, position - 2); |
2720 | 0 | FN(Store)(self, ringbuffer, ring_buffer_mask, position - 1); |
2721 | 0 | } |
2722 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH42(duckdb_brotli::H42*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH42(duckdb_brotli::H42*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH42(duckdb_brotli::H42*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH42(duckdb_brotli::H42*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
2723 | | |
2724 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
2725 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2726 | 0 | int* BROTLI_RESTRICT distance_cache) { |
2727 | 0 | BROTLI_UNUSED(self); |
2728 | 0 | PrepareDistanceCache(distance_cache, NUM_LAST_DISTANCES_TO_CHECK); |
2729 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH42(duckdb_brotli::H42*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH42(duckdb_brotli::H42*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH42(duckdb_brotli::H42*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH42(duckdb_brotli::H42*, int*) |
2730 | | |
2731 | | /* Find a longest backward match of &data[cur_ix] up to the length of |
2732 | | max_length and stores the position cur_ix in the hash table. |
2733 | | |
2734 | | REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache |
2735 | | values; if this method is invoked repeatedly with the same distance |
2736 | | cache values, it is enough to invoke FN(PrepareDistanceCache) once. |
2737 | | |
2738 | | Does not look for matches longer than max_length. |
2739 | | Does not look for matches further away than max_backward. |
2740 | | Writes the best match into |out|. |
2741 | | |out|->score is updated only if a better match is found. */ |
2742 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
2743 | | HashForgetfulChain* BROTLI_RESTRICT self, |
2744 | | const BrotliEncoderDictionary* dictionary, |
2745 | | const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, |
2746 | | const int* BROTLI_RESTRICT distance_cache, |
2747 | | const size_t cur_ix, const size_t max_length, const size_t max_backward, |
2748 | | const size_t dictionary_distance, const size_t max_distance, |
2749 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
2750 | 0 | uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); |
2751 | 0 | uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); |
2752 | 0 | uint8_t* BROTLI_RESTRICT tiny_hashes = FN(TinyHash)(self->extra[0]); |
2753 | 0 | FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra[1]); |
2754 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
2755 | | /* Don't accept a short copy from far away. */ |
2756 | 0 | score_t min_score = out->score; |
2757 | 0 | score_t best_score = out->score; |
2758 | 0 | size_t best_len = out->len; |
2759 | 0 | size_t i; |
2760 | 0 | const size_t key = FN(HashBytes)(&data[cur_ix_masked]); |
2761 | 0 | const uint8_t tiny_hash = (uint8_t)(key); |
2762 | 0 | out->len = 0; |
2763 | 0 | out->len_code_delta = 0; |
2764 | | /* Try last distance first. */ |
2765 | 0 | for (i = 0; i < NUM_LAST_DISTANCES_TO_CHECK; ++i) { |
2766 | 0 | const size_t backward = (size_t)distance_cache[i]; |
2767 | 0 | size_t prev_ix = (cur_ix - backward); |
2768 | | /* For distance code 0 we want to consider 2-byte matches. */ |
2769 | 0 | if (i > 0 && tiny_hashes[(uint16_t)prev_ix] != tiny_hash) continue; |
2770 | 0 | if (prev_ix >= cur_ix || backward > max_backward) { |
2771 | 0 | continue; |
2772 | 0 | } |
2773 | 0 | prev_ix &= ring_buffer_mask; |
2774 | 0 | { |
2775 | 0 | const size_t len = FindMatchLengthWithLimit(&data[prev_ix], |
2776 | 0 | &data[cur_ix_masked], |
2777 | 0 | max_length); |
2778 | 0 | if (len >= 2) { |
2779 | 0 | score_t score = BackwardReferenceScoreUsingLastDistance(len); |
2780 | 0 | if (best_score < score) { |
2781 | 0 | if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); |
2782 | 0 | if (best_score < score) { |
2783 | 0 | best_score = score; |
2784 | 0 | best_len = len; |
2785 | 0 | out->len = best_len; |
2786 | 0 | out->distance = backward; |
2787 | 0 | out->score = best_score; |
2788 | 0 | } |
2789 | 0 | } |
2790 | 0 | } |
2791 | 0 | } |
2792 | 0 | } |
2793 | 0 | { |
2794 | 0 | const size_t bank = key & (NUM_BANKS - 1); |
2795 | 0 | size_t backward = 0; |
2796 | 0 | size_t hops = self->max_hops; |
2797 | 0 | size_t delta = cur_ix - addr[key]; |
2798 | 0 | size_t slot = head[key]; |
2799 | 0 | while (hops--) { |
2800 | 0 | size_t prev_ix; |
2801 | 0 | size_t last = slot; |
2802 | 0 | backward += delta; |
2803 | 0 | if (backward > max_backward || (CAPPED_CHAINS && !delta)) break; |
2804 | 0 | prev_ix = (cur_ix - backward) & ring_buffer_mask; |
2805 | 0 | slot = banks[bank].slots[last].next; |
2806 | 0 | delta = banks[bank].slots[last].delta; |
2807 | 0 | if (cur_ix_masked + best_len > ring_buffer_mask || |
2808 | 0 | prev_ix + best_len > ring_buffer_mask || |
2809 | 0 | data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { |
2810 | 0 | continue; |
2811 | 0 | } |
2812 | 0 | { |
2813 | 0 | const size_t len = FindMatchLengthWithLimit(&data[prev_ix], |
2814 | 0 | &data[cur_ix_masked], |
2815 | 0 | max_length); |
2816 | 0 | if (len >= 4) { |
2817 | | /* Comparing for >= 3 does not change the semantics, but just saves |
2818 | | for a few unnecessary binary logarithms in backward reference |
2819 | | score, since we are not interested in such short matches. */ |
2820 | 0 | score_t score = BackwardReferenceScore(len, backward); |
2821 | 0 | if (best_score < score) { |
2822 | 0 | best_score = score; |
2823 | 0 | best_len = len; |
2824 | 0 | out->len = best_len; |
2825 | 0 | out->distance = backward; |
2826 | 0 | out->score = best_score; |
2827 | 0 | } |
2828 | 0 | } |
2829 | 0 | } |
2830 | 0 | } |
2831 | 0 | FN(Store)(self, data, ring_buffer_mask, cur_ix); |
2832 | 0 | } |
2833 | 0 | if (out->score == min_score) { |
2834 | 0 | SearchInStaticDictionary(dictionary, |
2835 | 0 | self->common, &data[cur_ix_masked], max_length, dictionary_distance, |
2836 | 0 | max_distance, out, BROTLI_FALSE); |
2837 | 0 | } |
2838 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH42(duckdb_brotli::H42*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH42(duckdb_brotli::H42*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH42(duckdb_brotli::H42*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH42(duckdb_brotli::H42*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
2839 | | |
2840 | | #undef BANK_SIZE |
2841 | | #undef BUCKET_SIZE |
2842 | | #undef CAPPED_CHAINS |
2843 | | |
2844 | | #undef HashForgetfulChain |
2845 | | #undef HASHER |
2846 | | #undef NUM_LAST_DISTANCES_TO_CHECK |
2847 | | #undef NUM_BANKS |
2848 | | #undef BANK_BITS |
2849 | | |
2850 | | #undef BUCKET_BITS |
2851 | | |
2852 | | #define HASHER() H54 |
2853 | 0 | #define BUCKET_BITS 20 |
2854 | 0 | #define BUCKET_SWEEP_BITS 2 |
2855 | 0 | #define HASH_LEN 7 |
2856 | 0 | #define USE_DICTIONARY 0 |
2857 | | /* NOLINT(build/header_guard) */ |
2858 | | /* Copyright 2010 Google Inc. All Rights Reserved. |
2859 | | |
2860 | | Distributed under MIT license. |
2861 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
2862 | | */ |
2863 | | |
2864 | | /* template parameters: FN, BUCKET_BITS, BUCKET_SWEEP_BITS, HASH_LEN, |
2865 | | USE_DICTIONARY |
2866 | | */ |
2867 | | |
2868 | | #define HashLongestMatchQuickly HASHER() |
2869 | | |
2870 | 0 | #define BUCKET_SIZE (1 << BUCKET_BITS) |
2871 | 0 | #define BUCKET_MASK (BUCKET_SIZE - 1) |
2872 | 0 | #define BUCKET_SWEEP (1 << BUCKET_SWEEP_BITS) |
2873 | 0 | #define BUCKET_SWEEP_MASK ((BUCKET_SWEEP - 1) << 3) |
2874 | | |
2875 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH54() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH54() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH54() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH54() |
2876 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH54() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH54() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH54() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH54() |
2877 | | |
2878 | | /* HashBytes is the function that chooses the bucket to place |
2879 | | the address in. The HashLongestMatch and HashLongestMatchQuickly |
2880 | | classes have separate, different implementations of hashing. */ |
2881 | 0 | static uint32_t FN(HashBytes)(const uint8_t* data) { |
2882 | 0 | const uint64_t h = ((BROTLI_UNALIGNED_LOAD64LE(data) << (64 - 8 * HASH_LEN)) * |
2883 | 0 | kHashMul64); |
2884 | | /* The higher bits contain more mixture from the multiplication, |
2885 | | so we take our results from there. */ |
2886 | 0 | return (uint32_t)(h >> (64 - BUCKET_BITS)); |
2887 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashBytesH54(unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashBytesH54(unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashBytesH54(unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashBytesH54(unsigned char const*) |
2888 | | |
2889 | | /* A (forgetful) hash table to the data seen by the compressor, to |
2890 | | help create backward references to previous data. |
2891 | | |
2892 | | This is a hash map of fixed size (BUCKET_SIZE). */ |
2893 | | typedef struct HashLongestMatchQuickly { |
2894 | | /* Shortcuts. */ |
2895 | | HasherCommon* common; |
2896 | | |
2897 | | /* --- Dynamic size members --- */ |
2898 | | |
2899 | | uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */ |
2900 | | } HashLongestMatchQuickly; |
2901 | | |
2902 | | static void FN(Initialize)( |
2903 | | HasherCommon* common, HashLongestMatchQuickly* BROTLI_RESTRICT self, |
2904 | 0 | const BrotliEncoderParams* params) { |
2905 | 0 | self->common = common; |
2906 | |
|
2907 | 0 | BROTLI_UNUSED(params); |
2908 | 0 | self->buckets_ = (uint32_t*)common->extra[0]; |
2909 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH54(duckdb_brotli::HasherCommon*, duckdb_brotli::H54*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH54(duckdb_brotli::HasherCommon*, duckdb_brotli::H54*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH54(duckdb_brotli::HasherCommon*, duckdb_brotli::H54*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH54(duckdb_brotli::HasherCommon*, duckdb_brotli::H54*, BrotliEncoderParams const*) |
2910 | | |
2911 | | static void FN(Prepare)( |
2912 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
2913 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
2914 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
2915 | | /* Partial preparation is 100 times slower (per socket). */ |
2916 | 0 | size_t partial_prepare_threshold = BUCKET_SIZE >> 5; |
2917 | 0 | if (one_shot && input_size <= partial_prepare_threshold) { |
2918 | 0 | size_t i; |
2919 | 0 | for (i = 0; i < input_size; ++i) { |
2920 | 0 | const uint32_t key = FN(HashBytes)(&data[i]); |
2921 | 0 | if (BUCKET_SWEEP == 1) { |
2922 | 0 | buckets[key] = 0; |
2923 | 0 | } else { |
2924 | 0 | uint32_t j; |
2925 | 0 | for (j = 0; j < BUCKET_SWEEP; ++j) { |
2926 | 0 | buckets[(key + (j << 3)) & BUCKET_MASK] = 0; |
2927 | 0 | } |
2928 | 0 | } |
2929 | 0 | } |
2930 | 0 | } else { |
2931 | | /* It is not strictly necessary to fill this buffer here, but |
2932 | | not filling will make the results of the compression stochastic |
2933 | | (but correct). This is because random data would cause the |
2934 | | system to find accidentally good backward references here and there. */ |
2935 | 0 | memset(buckets, 0, sizeof(uint32_t) * BUCKET_SIZE); |
2936 | 0 | } |
2937 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH54(duckdb_brotli::H54*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH54(duckdb_brotli::H54*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH54(duckdb_brotli::H54*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH54(duckdb_brotli::H54*, int, unsigned long, unsigned char const*) |
2938 | | |
2939 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
2940 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
2941 | 0 | size_t input_size, size_t* alloc_size) { |
2942 | 0 | BROTLI_UNUSED(params); |
2943 | 0 | BROTLI_UNUSED(one_shot); |
2944 | 0 | BROTLI_UNUSED(input_size); |
2945 | 0 | alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE; |
2946 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH54(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH54(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH54(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH54(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
2947 | | |
2948 | | /* Look at 5 bytes at &data[ix & mask]. |
2949 | | Compute a hash from these, and store the value somewhere within |
2950 | | [ix .. ix+3]. */ |
2951 | | static BROTLI_INLINE void FN(Store)( |
2952 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
2953 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
2954 | 0 | const uint32_t key = FN(HashBytes)(&data[ix & mask]); |
2955 | 0 | if (BUCKET_SWEEP == 1) { |
2956 | 0 | self->buckets_[key] = (uint32_t)ix; |
2957 | 0 | } else { |
2958 | | /* Wiggle the value with the bucket sweep range. */ |
2959 | 0 | const uint32_t off = ix & BUCKET_SWEEP_MASK; |
2960 | 0 | self->buckets_[(key + off) & BUCKET_MASK] = (uint32_t)ix; |
2961 | 0 | } |
2962 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH54(duckdb_brotli::H54*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH54(duckdb_brotli::H54*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH54(duckdb_brotli::H54*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH54(duckdb_brotli::H54*, unsigned char const*, unsigned long, unsigned long) |
2963 | | |
2964 | | static BROTLI_INLINE void FN(StoreRange)( |
2965 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
2966 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
2967 | 0 | const size_t ix_start, const size_t ix_end) { |
2968 | 0 | size_t i; |
2969 | 0 | for (i = ix_start; i < ix_end; ++i) { |
2970 | 0 | FN(Store)(self, data, mask, i); |
2971 | 0 | } |
2972 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH54(duckdb_brotli::H54*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH54(duckdb_brotli::H54*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH54(duckdb_brotli::H54*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH54(duckdb_brotli::H54*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
2973 | | |
2974 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
2975 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
2976 | | size_t num_bytes, size_t position, |
2977 | 0 | const uint8_t* ringbuffer, size_t ringbuffer_mask) { |
2978 | 0 | if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { |
2979 | | /* Prepare the hashes for three last bytes of the last write. |
2980 | | These could not be calculated before, since they require knowledge |
2981 | | of both the previous and the current block. */ |
2982 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); |
2983 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); |
2984 | 0 | FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); |
2985 | 0 | } |
2986 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH54(duckdb_brotli::H54*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH54(duckdb_brotli::H54*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH54(duckdb_brotli::H54*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH54(duckdb_brotli::H54*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
2987 | | |
2988 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
2989 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
2990 | 0 | int* BROTLI_RESTRICT distance_cache) { |
2991 | 0 | BROTLI_UNUSED(self); |
2992 | 0 | BROTLI_UNUSED(distance_cache); |
2993 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH54(duckdb_brotli::H54*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH54(duckdb_brotli::H54*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH54(duckdb_brotli::H54*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH54(duckdb_brotli::H54*, int*) |
2994 | | |
2995 | | /* Find a longest backward match of &data[cur_ix & ring_buffer_mask] |
2996 | | up to the length of max_length and stores the position cur_ix in the |
2997 | | hash table. |
2998 | | |
2999 | | Does not look for matches longer than max_length. |
3000 | | Does not look for matches further away than max_backward. |
3001 | | Writes the best match into |out|. |
3002 | | |out|->score is updated only if a better match is found. */ |
3003 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
3004 | | HashLongestMatchQuickly* BROTLI_RESTRICT self, |
3005 | | const BrotliEncoderDictionary* dictionary, |
3006 | | const uint8_t* BROTLI_RESTRICT data, |
3007 | | const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, |
3008 | | const size_t cur_ix, const size_t max_length, const size_t max_backward, |
3009 | | const size_t dictionary_distance, const size_t max_distance, |
3010 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
3011 | 0 | uint32_t* BROTLI_RESTRICT buckets = self->buckets_; |
3012 | 0 | const size_t best_len_in = out->len; |
3013 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
3014 | 0 | int compare_char = data[cur_ix_masked + best_len_in]; |
3015 | 0 | size_t key = FN(HashBytes)(&data[cur_ix_masked]); |
3016 | 0 | size_t key_out; |
3017 | 0 | score_t min_score = out->score; |
3018 | 0 | score_t best_score = out->score; |
3019 | 0 | size_t best_len = best_len_in; |
3020 | 0 | size_t cached_backward = (size_t)distance_cache[0]; |
3021 | 0 | size_t prev_ix = cur_ix - cached_backward; |
3022 | 0 | out->len_code_delta = 0; |
3023 | 0 | if (prev_ix < cur_ix) { |
3024 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
3025 | 0 | if (compare_char == data[prev_ix + best_len]) { |
3026 | 0 | const size_t len = FindMatchLengthWithLimit( |
3027 | 0 | &data[prev_ix], &data[cur_ix_masked], max_length); |
3028 | 0 | if (len >= 4) { |
3029 | 0 | const score_t score = BackwardReferenceScoreUsingLastDistance(len); |
3030 | 0 | if (best_score < score) { |
3031 | 0 | out->len = len; |
3032 | 0 | out->distance = cached_backward; |
3033 | 0 | out->score = score; |
3034 | 0 | if (BUCKET_SWEEP == 1) { |
3035 | 0 | buckets[key] = (uint32_t)cur_ix; |
3036 | 0 | return; |
3037 | 0 | } else { |
3038 | 0 | best_len = len; |
3039 | 0 | best_score = score; |
3040 | 0 | compare_char = data[cur_ix_masked + len]; |
3041 | 0 | } |
3042 | 0 | } |
3043 | 0 | } |
3044 | 0 | } |
3045 | 0 | } |
3046 | 0 | if (BUCKET_SWEEP == 1) { |
3047 | 0 | size_t backward; |
3048 | 0 | size_t len; |
3049 | | /* Only one to look for, don't bother to prepare for a loop. */ |
3050 | 0 | prev_ix = buckets[key]; |
3051 | 0 | buckets[key] = (uint32_t)cur_ix; |
3052 | 0 | backward = cur_ix - prev_ix; |
3053 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
3054 | 0 | if (compare_char != data[prev_ix + best_len_in]) { |
3055 | 0 | return; |
3056 | 0 | } |
3057 | 0 | if (BROTLI_PREDICT_FALSE(backward == 0 || backward > max_backward)) { |
3058 | 0 | return; |
3059 | 0 | } |
3060 | 0 | len = FindMatchLengthWithLimit(&data[prev_ix], |
3061 | 0 | &data[cur_ix_masked], |
3062 | 0 | max_length); |
3063 | 0 | if (len >= 4) { |
3064 | 0 | const score_t score = BackwardReferenceScore(len, backward); |
3065 | 0 | if (best_score < score) { |
3066 | 0 | out->len = len; |
3067 | 0 | out->distance = backward; |
3068 | 0 | out->score = score; |
3069 | 0 | return; |
3070 | 0 | } |
3071 | 0 | } |
3072 | 0 | } else { |
3073 | 0 | size_t keys[BUCKET_SWEEP]; |
3074 | 0 | size_t i; |
3075 | 0 | for (i = 0; i < BUCKET_SWEEP; ++i) { |
3076 | 0 | keys[i] = (key + (i << 3)) & BUCKET_MASK; |
3077 | 0 | } |
3078 | 0 | key_out = keys[(cur_ix & BUCKET_SWEEP_MASK) >> 3]; |
3079 | 0 | for (i = 0; i < BUCKET_SWEEP; ++i) { |
3080 | 0 | size_t len; |
3081 | 0 | size_t backward; |
3082 | 0 | prev_ix = buckets[keys[i]]; |
3083 | 0 | backward = cur_ix - prev_ix; |
3084 | 0 | prev_ix &= (uint32_t)ring_buffer_mask; |
3085 | 0 | if (compare_char != data[prev_ix + best_len]) { |
3086 | 0 | continue; |
3087 | 0 | } |
3088 | 0 | if (BROTLI_PREDICT_FALSE(backward == 0 || backward > max_backward)) { |
3089 | 0 | continue; |
3090 | 0 | } |
3091 | 0 | len = FindMatchLengthWithLimit(&data[prev_ix], |
3092 | 0 | &data[cur_ix_masked], |
3093 | 0 | max_length); |
3094 | 0 | if (len >= 4) { |
3095 | 0 | const score_t score = BackwardReferenceScore(len, backward); |
3096 | 0 | if (best_score < score) { |
3097 | 0 | best_len = len; |
3098 | 0 | out->len = len; |
3099 | 0 | compare_char = data[cur_ix_masked + len]; |
3100 | 0 | best_score = score; |
3101 | 0 | out->score = score; |
3102 | 0 | out->distance = backward; |
3103 | 0 | } |
3104 | 0 | } |
3105 | 0 | } |
3106 | 0 | } |
3107 | 0 | if (USE_DICTIONARY && min_score == out->score) { |
3108 | 0 | SearchInStaticDictionary(dictionary, |
3109 | 0 | self->common, &data[cur_ix_masked], max_length, dictionary_distance, |
3110 | 0 | max_distance, out, BROTLI_TRUE); |
3111 | 0 | } |
3112 | 0 | if (BUCKET_SWEEP != 1) { |
3113 | 0 | buckets[key_out] = (uint32_t)cur_ix; |
3114 | 0 | } |
3115 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH54(duckdb_brotli::H54*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH54(duckdb_brotli::H54*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH54(duckdb_brotli::H54*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH54(duckdb_brotli::H54*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
3116 | | |
3117 | | #undef BUCKET_SWEEP_MASK |
3118 | | #undef BUCKET_SWEEP |
3119 | | #undef BUCKET_MASK |
3120 | | #undef BUCKET_SIZE |
3121 | | |
3122 | | #undef HashLongestMatchQuickly |
3123 | | #undef USE_DICTIONARY |
3124 | | #undef HASH_LEN |
3125 | | #undef BUCKET_SWEEP_BITS |
3126 | | #undef BUCKET_BITS |
3127 | | #undef HASHER |
3128 | | |
3129 | | /* fast large window hashers */ |
3130 | | |
3131 | | #define HASHER() HROLLING_FAST |
3132 | 0 | #define CHUNKLEN 32 |
3133 | 0 | #define JUMP 4 |
3134 | 0 | #define NUMBUCKETS 16777216 |
3135 | 0 | #define MASK ((NUMBUCKETS * 64) - 1) |
3136 | | /* NOLINT(build/header_guard) */ |
3137 | | /* Copyright 2018 Google Inc. All Rights Reserved. |
3138 | | |
3139 | | Distributed under MIT license. |
3140 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
3141 | | */ |
3142 | | |
3143 | | /* template parameters: FN, JUMP, NUMBUCKETS, MASK, CHUNKLEN */ |
3144 | | /* NUMBUCKETS / (MASK + 1) = probability of storing and using hash code. */ |
3145 | | /* JUMP = skip bytes for speedup */ |
3146 | | |
3147 | | /* Rolling hash for long distance long string matches. Stores one position |
3148 | | per bucket, bucket key is computed over a long region. */ |
3149 | | |
3150 | | #define HashRolling HASHER() |
3151 | | |
3152 | | static const uint32_t FN(kRollingHashMul32) = 69069; |
3153 | | static const uint32_t FN(kInvalidPos) = 0xffffffff; |
3154 | | |
3155 | | /* This hasher uses a longer forward length, but returning a higher value here |
3156 | | will hurt compression by the main hasher when combined with a composite |
3157 | | hasher. The hasher tests for forward itself instead. */ |
3158 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthHROLLING_FAST() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthHROLLING_FAST() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthHROLLING_FAST() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthHROLLING_FAST() |
3159 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadHROLLING_FAST() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadHROLLING_FAST() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadHROLLING_FAST() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadHROLLING_FAST() |
3160 | | |
3161 | | /* Computes a code from a single byte. A lookup table of 256 values could be |
3162 | | used, but simply adding 1 works about as good. */ |
3163 | 0 | static uint32_t FN(HashByte)(uint8_t byte) { |
3164 | 0 | return (uint32_t)byte + 1u; |
3165 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashByteHROLLING_FAST(unsigned char) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashByteHROLLING_FAST(unsigned char) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashByteHROLLING_FAST(unsigned char) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashByteHROLLING_FAST(unsigned char) |
3166 | | |
3167 | | static uint32_t FN(HashRollingFunctionInitial)(uint32_t state, uint8_t add, |
3168 | 0 | uint32_t factor) { |
3169 | 0 | return (uint32_t)(factor * state + FN(HashByte)(add)); |
3170 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashRollingFunctionInitialHROLLING_FAST(unsigned int, unsigned char, unsigned int) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashRollingFunctionInitialHROLLING_FAST(unsigned int, unsigned char, unsigned int) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashRollingFunctionInitialHROLLING_FAST(unsigned int, unsigned char, unsigned int) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashRollingFunctionInitialHROLLING_FAST(unsigned int, unsigned char, unsigned int) |
3171 | | |
3172 | | static uint32_t FN(HashRollingFunction)(uint32_t state, uint8_t add, |
3173 | | uint8_t rem, uint32_t factor, |
3174 | 0 | uint32_t factor_remove) { |
3175 | 0 | return (uint32_t)(factor * state + |
3176 | 0 | FN(HashByte)(add) - factor_remove * FN(HashByte)(rem)); |
3177 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashRollingFunctionHROLLING_FAST(unsigned int, unsigned char, unsigned char, unsigned int, unsigned int) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashRollingFunctionHROLLING_FAST(unsigned int, unsigned char, unsigned char, unsigned int, unsigned int) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashRollingFunctionHROLLING_FAST(unsigned int, unsigned char, unsigned char, unsigned int, unsigned int) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashRollingFunctionHROLLING_FAST(unsigned int, unsigned char, unsigned char, unsigned int, unsigned int) |
3178 | | |
3179 | | typedef struct HashRolling { |
3180 | | uint32_t state; |
3181 | | uint32_t* table; |
3182 | | size_t next_ix; |
3183 | | |
3184 | | uint32_t chunk_len; |
3185 | | uint32_t factor; |
3186 | | uint32_t factor_remove; |
3187 | | } HashRolling; |
3188 | | |
3189 | | static void FN(Initialize)( |
3190 | | HasherCommon* common, HashRolling* BROTLI_RESTRICT self, |
3191 | 0 | const BrotliEncoderParams* params) { |
3192 | 0 | size_t i; |
3193 | 0 | self->state = 0; |
3194 | 0 | self->next_ix = 0; |
3195 | |
|
3196 | 0 | self->factor = FN(kRollingHashMul32); |
3197 | | |
3198 | | /* Compute the factor of the oldest byte to remove: factor**steps modulo |
3199 | | 0xffffffff (the multiplications rely on 32-bit overflow) */ |
3200 | 0 | self->factor_remove = 1; |
3201 | 0 | for (i = 0; i < CHUNKLEN; i += JUMP) { |
3202 | 0 | self->factor_remove *= self->factor; |
3203 | 0 | } |
3204 | |
|
3205 | 0 | self->table = (uint32_t*)common->extra[0]; |
3206 | 0 | for (i = 0; i < NUMBUCKETS; i++) { |
3207 | 0 | self->table[i] = FN(kInvalidPos); |
3208 | 0 | } |
3209 | |
|
3210 | 0 | BROTLI_UNUSED(params); |
3211 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeHROLLING_FAST(duckdb_brotli::HasherCommon*, duckdb_brotli::HROLLING_FAST*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeHROLLING_FAST(duckdb_brotli::HasherCommon*, duckdb_brotli::HROLLING_FAST*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeHROLLING_FAST(duckdb_brotli::HasherCommon*, duckdb_brotli::HROLLING_FAST*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeHROLLING_FAST(duckdb_brotli::HasherCommon*, duckdb_brotli::HROLLING_FAST*, BrotliEncoderParams const*) |
3212 | | |
3213 | | static void FN(Prepare)(HashRolling* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
3214 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
3215 | 0 | size_t i; |
3216 | | /* Too small size, cannot use this hasher. */ |
3217 | 0 | if (input_size < CHUNKLEN) return; |
3218 | 0 | self->state = 0; |
3219 | 0 | for (i = 0; i < CHUNKLEN; i += JUMP) { |
3220 | 0 | self->state = FN(HashRollingFunctionInitial)( |
3221 | 0 | self->state, data[i], self->factor); |
3222 | 0 | } |
3223 | 0 | BROTLI_UNUSED(one_shot); |
3224 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, int, unsigned long, unsigned char const*) |
3225 | | |
3226 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
3227 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
3228 | 0 | size_t input_size, size_t* alloc_size) { |
3229 | 0 | BROTLI_UNUSED(params); |
3230 | 0 | BROTLI_UNUSED(one_shot); |
3231 | 0 | BROTLI_UNUSED(input_size); |
3232 | 0 | alloc_size[0] = NUMBUCKETS * sizeof(uint32_t); |
3233 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesHROLLING_FAST(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesHROLLING_FAST(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesHROLLING_FAST(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesHROLLING_FAST(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
3234 | | |
3235 | | static BROTLI_INLINE void FN(Store)(HashRolling* BROTLI_RESTRICT self, |
3236 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
3237 | 0 | BROTLI_UNUSED(self); |
3238 | 0 | BROTLI_UNUSED(data); |
3239 | 0 | BROTLI_UNUSED(mask); |
3240 | 0 | BROTLI_UNUSED(ix); |
3241 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned char const*, unsigned long, unsigned long) |
3242 | | |
3243 | | static BROTLI_INLINE void FN(StoreRange)(HashRolling* BROTLI_RESTRICT self, |
3244 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
3245 | 0 | const size_t ix_start, const size_t ix_end) { |
3246 | 0 | BROTLI_UNUSED(self); |
3247 | 0 | BROTLI_UNUSED(data); |
3248 | 0 | BROTLI_UNUSED(mask); |
3249 | 0 | BROTLI_UNUSED(ix_start); |
3250 | 0 | BROTLI_UNUSED(ix_end); |
3251 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
3252 | | |
3253 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
3254 | | HashRolling* BROTLI_RESTRICT self, |
3255 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
3256 | 0 | size_t ring_buffer_mask) { |
3257 | | /* In this case we must re-initialize the hasher from scratch from the |
3258 | | current position. */ |
3259 | 0 | size_t position_masked; |
3260 | 0 | size_t available = num_bytes; |
3261 | 0 | if ((position & (JUMP - 1)) != 0) { |
3262 | 0 | size_t diff = JUMP - (position & (JUMP - 1)); |
3263 | 0 | available = (diff > available) ? 0 : (available - diff); |
3264 | 0 | position += diff; |
3265 | 0 | } |
3266 | 0 | position_masked = position & ring_buffer_mask; |
3267 | | /* wrapping around ringbuffer not handled. */ |
3268 | 0 | if (available > ring_buffer_mask - position_masked) { |
3269 | 0 | available = ring_buffer_mask - position_masked; |
3270 | 0 | } |
3271 | |
|
3272 | 0 | FN(Prepare)(self, BROTLI_FALSE, available, |
3273 | 0 | ringbuffer + (position & ring_buffer_mask)); |
3274 | 0 | self->next_ix = position; |
3275 | 0 | BROTLI_UNUSED(num_bytes); |
3276 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
3277 | | |
3278 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
3279 | | HashRolling* BROTLI_RESTRICT self, |
3280 | 0 | int* BROTLI_RESTRICT distance_cache) { |
3281 | 0 | BROTLI_UNUSED(self); |
3282 | 0 | BROTLI_UNUSED(distance_cache); |
3283 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, int*) |
3284 | | |
3285 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
3286 | | HashRolling* BROTLI_RESTRICT self, |
3287 | | const BrotliEncoderDictionary* dictionary, |
3288 | | const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, |
3289 | | const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, |
3290 | | const size_t max_length, const size_t max_backward, |
3291 | | const size_t dictionary_distance, const size_t max_distance, |
3292 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
3293 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
3294 | 0 | size_t pos; |
3295 | |
|
3296 | 0 | if ((cur_ix & (JUMP - 1)) != 0) return; |
3297 | | |
3298 | | /* Not enough lookahead */ |
3299 | 0 | if (max_length < CHUNKLEN) return; |
3300 | | |
3301 | 0 | for (pos = self->next_ix; pos <= cur_ix; pos += JUMP) { |
3302 | 0 | uint32_t code = self->state & MASK; |
3303 | |
|
3304 | 0 | uint8_t rem = data[pos & ring_buffer_mask]; |
3305 | 0 | uint8_t add = data[(pos + CHUNKLEN) & ring_buffer_mask]; |
3306 | 0 | size_t found_ix = FN(kInvalidPos); |
3307 | |
|
3308 | 0 | self->state = FN(HashRollingFunction)( |
3309 | 0 | self->state, add, rem, self->factor, self->factor_remove); |
3310 | |
|
3311 | 0 | if (code < NUMBUCKETS) { |
3312 | 0 | found_ix = self->table[code]; |
3313 | 0 | self->table[code] = (uint32_t)pos; |
3314 | 0 | if (pos == cur_ix && found_ix != FN(kInvalidPos)) { |
3315 | | /* The cast to 32-bit makes backward distances up to 4GB work even |
3316 | | if cur_ix is above 4GB, despite using 32-bit values in the table. */ |
3317 | 0 | size_t backward = (uint32_t)(cur_ix - found_ix); |
3318 | 0 | if (backward <= max_backward) { |
3319 | 0 | const size_t found_ix_masked = found_ix & ring_buffer_mask; |
3320 | 0 | const size_t len = FindMatchLengthWithLimit(&data[found_ix_masked], |
3321 | 0 | &data[cur_ix_masked], |
3322 | 0 | max_length); |
3323 | 0 | if (len >= 4 && len > out->len) { |
3324 | 0 | score_t score = BackwardReferenceScore(len, backward); |
3325 | 0 | if (score > out->score) { |
3326 | 0 | out->len = len; |
3327 | 0 | out->distance = backward; |
3328 | 0 | out->score = score; |
3329 | 0 | out->len_code_delta = 0; |
3330 | 0 | } |
3331 | 0 | } |
3332 | 0 | } |
3333 | 0 | } |
3334 | 0 | } |
3335 | 0 | } |
3336 | |
|
3337 | 0 | self->next_ix = cur_ix + JUMP; |
3338 | | |
3339 | | /* NOTE: this hasher does not search in the dictionary. It is used as |
3340 | | backup-hasher, the main hasher already searches in it. */ |
3341 | 0 | BROTLI_UNUSED(dictionary); |
3342 | 0 | BROTLI_UNUSED(distance_cache); |
3343 | 0 | BROTLI_UNUSED(dictionary_distance); |
3344 | 0 | BROTLI_UNUSED(max_distance); |
3345 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchHROLLING_FAST(duckdb_brotli::HROLLING_FAST*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
3346 | | |
3347 | | #undef HashRolling |
3348 | | #undef JUMP |
3349 | | #undef HASHER |
3350 | | |
3351 | | |
3352 | | #define HASHER() HROLLING |
3353 | 0 | #define JUMP 1 |
3354 | | /* NOLINT(build/header_guard) */ |
3355 | | /* Copyright 2018 Google Inc. All Rights Reserved. |
3356 | | |
3357 | | Distributed under MIT license. |
3358 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
3359 | | */ |
3360 | | |
3361 | | /* template parameters: FN, JUMP, NUMBUCKETS, MASK, CHUNKLEN */ |
3362 | | /* NUMBUCKETS / (MASK + 1) = probability of storing and using hash code. */ |
3363 | | /* JUMP = skip bytes for speedup */ |
3364 | | |
3365 | | /* Rolling hash for long distance long string matches. Stores one position |
3366 | | per bucket, bucket key is computed over a long region. */ |
3367 | | |
3368 | | #define HashRolling HASHER() |
3369 | | |
3370 | | static const uint32_t FN(kRollingHashMul32) = 69069; |
3371 | | static const uint32_t FN(kInvalidPos) = 0xffffffff; |
3372 | | |
3373 | | /* This hasher uses a longer forward length, but returning a higher value here |
3374 | | will hurt compression by the main hasher when combined with a composite |
3375 | | hasher. The hasher tests for forward itself instead. */ |
3376 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthHROLLING() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthHROLLING() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthHROLLING() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthHROLLING() |
3377 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; }Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadHROLLING() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadHROLLING() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadHROLLING() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadHROLLING() |
3378 | | |
3379 | | /* Computes a code from a single byte. A lookup table of 256 values could be |
3380 | | used, but simply adding 1 works about as good. */ |
3381 | 0 | static uint32_t FN(HashByte)(uint8_t byte) { |
3382 | 0 | return (uint32_t)byte + 1u; |
3383 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashByteHROLLING(unsigned char) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashByteHROLLING(unsigned char) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashByteHROLLING(unsigned char) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashByteHROLLING(unsigned char) |
3384 | | |
3385 | | static uint32_t FN(HashRollingFunctionInitial)(uint32_t state, uint8_t add, |
3386 | 0 | uint32_t factor) { |
3387 | 0 | return (uint32_t)(factor * state + FN(HashByte)(add)); |
3388 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashRollingFunctionInitialHROLLING(unsigned int, unsigned char, unsigned int) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashRollingFunctionInitialHROLLING(unsigned int, unsigned char, unsigned int) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashRollingFunctionInitialHROLLING(unsigned int, unsigned char, unsigned int) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashRollingFunctionInitialHROLLING(unsigned int, unsigned char, unsigned int) |
3389 | | |
3390 | | static uint32_t FN(HashRollingFunction)(uint32_t state, uint8_t add, |
3391 | | uint8_t rem, uint32_t factor, |
3392 | 0 | uint32_t factor_remove) { |
3393 | 0 | return (uint32_t)(factor * state + |
3394 | 0 | FN(HashByte)(add) - factor_remove * FN(HashByte)(rem)); |
3395 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashRollingFunctionHROLLING(unsigned int, unsigned char, unsigned char, unsigned int, unsigned int) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashRollingFunctionHROLLING(unsigned int, unsigned char, unsigned char, unsigned int, unsigned int) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashRollingFunctionHROLLING(unsigned int, unsigned char, unsigned char, unsigned int, unsigned int) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashRollingFunctionHROLLING(unsigned int, unsigned char, unsigned char, unsigned int, unsigned int) |
3396 | | |
3397 | | typedef struct HashRolling { |
3398 | | uint32_t state; |
3399 | | uint32_t* table; |
3400 | | size_t next_ix; |
3401 | | |
3402 | | uint32_t chunk_len; |
3403 | | uint32_t factor; |
3404 | | uint32_t factor_remove; |
3405 | | } HashRolling; |
3406 | | |
3407 | | static void FN(Initialize)( |
3408 | | HasherCommon* common, HashRolling* BROTLI_RESTRICT self, |
3409 | 0 | const BrotliEncoderParams* params) { |
3410 | 0 | size_t i; |
3411 | 0 | self->state = 0; |
3412 | 0 | self->next_ix = 0; |
3413 | |
|
3414 | 0 | self->factor = FN(kRollingHashMul32); |
3415 | | |
3416 | | /* Compute the factor of the oldest byte to remove: factor**steps modulo |
3417 | | 0xffffffff (the multiplications rely on 32-bit overflow) */ |
3418 | 0 | self->factor_remove = 1; |
3419 | 0 | for (i = 0; i < CHUNKLEN; i += JUMP) { |
3420 | 0 | self->factor_remove *= self->factor; |
3421 | 0 | } |
3422 | |
|
3423 | 0 | self->table = (uint32_t*)common->extra[0]; |
3424 | 0 | for (i = 0; i < NUMBUCKETS; i++) { |
3425 | 0 | self->table[i] = FN(kInvalidPos); |
3426 | 0 | } |
3427 | |
|
3428 | 0 | BROTLI_UNUSED(params); |
3429 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeHROLLING(duckdb_brotli::HasherCommon*, duckdb_brotli::HROLLING*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeHROLLING(duckdb_brotli::HasherCommon*, duckdb_brotli::HROLLING*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeHROLLING(duckdb_brotli::HasherCommon*, duckdb_brotli::HROLLING*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeHROLLING(duckdb_brotli::HasherCommon*, duckdb_brotli::HROLLING*, BrotliEncoderParams const*) |
3430 | | |
3431 | | static void FN(Prepare)(HashRolling* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
3432 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
3433 | 0 | size_t i; |
3434 | | /* Too small size, cannot use this hasher. */ |
3435 | 0 | if (input_size < CHUNKLEN) return; |
3436 | 0 | self->state = 0; |
3437 | 0 | for (i = 0; i < CHUNKLEN; i += JUMP) { |
3438 | 0 | self->state = FN(HashRollingFunctionInitial)( |
3439 | 0 | self->state, data[i], self->factor); |
3440 | 0 | } |
3441 | 0 | BROTLI_UNUSED(one_shot); |
3442 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareHROLLING(duckdb_brotli::HROLLING*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareHROLLING(duckdb_brotli::HROLLING*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareHROLLING(duckdb_brotli::HROLLING*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareHROLLING(duckdb_brotli::HROLLING*, int, unsigned long, unsigned char const*) |
3443 | | |
3444 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
3445 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
3446 | 0 | size_t input_size, size_t* alloc_size) { |
3447 | 0 | BROTLI_UNUSED(params); |
3448 | 0 | BROTLI_UNUSED(one_shot); |
3449 | 0 | BROTLI_UNUSED(input_size); |
3450 | 0 | alloc_size[0] = NUMBUCKETS * sizeof(uint32_t); |
3451 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesHROLLING(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesHROLLING(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesHROLLING(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesHROLLING(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
3452 | | |
3453 | | static BROTLI_INLINE void FN(Store)(HashRolling* BROTLI_RESTRICT self, |
3454 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
3455 | 0 | BROTLI_UNUSED(self); |
3456 | 0 | BROTLI_UNUSED(data); |
3457 | 0 | BROTLI_UNUSED(mask); |
3458 | 0 | BROTLI_UNUSED(ix); |
3459 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreHROLLING(duckdb_brotli::HROLLING*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreHROLLING(duckdb_brotli::HROLLING*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreHROLLING(duckdb_brotli::HROLLING*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreHROLLING(duckdb_brotli::HROLLING*, unsigned char const*, unsigned long, unsigned long) |
3460 | | |
3461 | | static BROTLI_INLINE void FN(StoreRange)(HashRolling* BROTLI_RESTRICT self, |
3462 | | const uint8_t* BROTLI_RESTRICT data, const size_t mask, |
3463 | 0 | const size_t ix_start, const size_t ix_end) { |
3464 | 0 | BROTLI_UNUSED(self); |
3465 | 0 | BROTLI_UNUSED(data); |
3466 | 0 | BROTLI_UNUSED(mask); |
3467 | 0 | BROTLI_UNUSED(ix_start); |
3468 | 0 | BROTLI_UNUSED(ix_end); |
3469 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeHROLLING(duckdb_brotli::HROLLING*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeHROLLING(duckdb_brotli::HROLLING*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeHROLLING(duckdb_brotli::HROLLING*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeHROLLING(duckdb_brotli::HROLLING*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
3470 | | |
3471 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
3472 | | HashRolling* BROTLI_RESTRICT self, |
3473 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
3474 | 0 | size_t ring_buffer_mask) { |
3475 | | /* In this case we must re-initialize the hasher from scratch from the |
3476 | | current position. */ |
3477 | 0 | size_t position_masked; |
3478 | 0 | size_t available = num_bytes; |
3479 | 0 | if ((position & (JUMP - 1)) != 0) { |
3480 | 0 | size_t diff = JUMP - (position & (JUMP - 1)); |
3481 | 0 | available = (diff > available) ? 0 : (available - diff); |
3482 | 0 | position += diff; |
3483 | 0 | } |
3484 | 0 | position_masked = position & ring_buffer_mask; |
3485 | | /* wrapping around ringbuffer not handled. */ |
3486 | 0 | if (available > ring_buffer_mask - position_masked) { |
3487 | 0 | available = ring_buffer_mask - position_masked; |
3488 | 0 | } |
3489 | |
|
3490 | 0 | FN(Prepare)(self, BROTLI_FALSE, available, |
3491 | 0 | ringbuffer + (position & ring_buffer_mask)); |
3492 | 0 | self->next_ix = position; |
3493 | 0 | BROTLI_UNUSED(num_bytes); |
3494 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockHROLLING(duckdb_brotli::HROLLING*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockHROLLING(duckdb_brotli::HROLLING*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockHROLLING(duckdb_brotli::HROLLING*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockHROLLING(duckdb_brotli::HROLLING*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
3495 | | |
3496 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
3497 | | HashRolling* BROTLI_RESTRICT self, |
3498 | 0 | int* BROTLI_RESTRICT distance_cache) { |
3499 | 0 | BROTLI_UNUSED(self); |
3500 | 0 | BROTLI_UNUSED(distance_cache); |
3501 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheHROLLING(duckdb_brotli::HROLLING*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheHROLLING(duckdb_brotli::HROLLING*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheHROLLING(duckdb_brotli::HROLLING*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheHROLLING(duckdb_brotli::HROLLING*, int*) |
3502 | | |
3503 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
3504 | | HashRolling* BROTLI_RESTRICT self, |
3505 | | const BrotliEncoderDictionary* dictionary, |
3506 | | const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, |
3507 | | const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, |
3508 | | const size_t max_length, const size_t max_backward, |
3509 | | const size_t dictionary_distance, const size_t max_distance, |
3510 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
3511 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
3512 | 0 | size_t pos; |
3513 | |
|
3514 | 0 | if ((cur_ix & (JUMP - 1)) != 0) return; |
3515 | | |
3516 | | /* Not enough lookahead */ |
3517 | 0 | if (max_length < CHUNKLEN) return; |
3518 | | |
3519 | 0 | for (pos = self->next_ix; pos <= cur_ix; pos += JUMP) { |
3520 | 0 | uint32_t code = self->state & MASK; |
3521 | |
|
3522 | 0 | uint8_t rem = data[pos & ring_buffer_mask]; |
3523 | 0 | uint8_t add = data[(pos + CHUNKLEN) & ring_buffer_mask]; |
3524 | 0 | size_t found_ix = FN(kInvalidPos); |
3525 | |
|
3526 | 0 | self->state = FN(HashRollingFunction)( |
3527 | 0 | self->state, add, rem, self->factor, self->factor_remove); |
3528 | |
|
3529 | 0 | if (code < NUMBUCKETS) { |
3530 | 0 | found_ix = self->table[code]; |
3531 | 0 | self->table[code] = (uint32_t)pos; |
3532 | 0 | if (pos == cur_ix && found_ix != FN(kInvalidPos)) { |
3533 | | /* The cast to 32-bit makes backward distances up to 4GB work even |
3534 | | if cur_ix is above 4GB, despite using 32-bit values in the table. */ |
3535 | 0 | size_t backward = (uint32_t)(cur_ix - found_ix); |
3536 | 0 | if (backward <= max_backward) { |
3537 | 0 | const size_t found_ix_masked = found_ix & ring_buffer_mask; |
3538 | 0 | const size_t len = FindMatchLengthWithLimit(&data[found_ix_masked], |
3539 | 0 | &data[cur_ix_masked], |
3540 | 0 | max_length); |
3541 | 0 | if (len >= 4 && len > out->len) { |
3542 | 0 | score_t score = BackwardReferenceScore(len, backward); |
3543 | 0 | if (score > out->score) { |
3544 | 0 | out->len = len; |
3545 | 0 | out->distance = backward; |
3546 | 0 | out->score = score; |
3547 | 0 | out->len_code_delta = 0; |
3548 | 0 | } |
3549 | 0 | } |
3550 | 0 | } |
3551 | 0 | } |
3552 | 0 | } |
3553 | 0 | } |
3554 | |
|
3555 | 0 | self->next_ix = cur_ix + JUMP; |
3556 | | |
3557 | | /* NOTE: this hasher does not search in the dictionary. It is used as |
3558 | | backup-hasher, the main hasher already searches in it. */ |
3559 | 0 | BROTLI_UNUSED(dictionary); |
3560 | 0 | BROTLI_UNUSED(distance_cache); |
3561 | 0 | BROTLI_UNUSED(dictionary_distance); |
3562 | 0 | BROTLI_UNUSED(max_distance); |
3563 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchHROLLING(duckdb_brotli::HROLLING*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchHROLLING(duckdb_brotli::HROLLING*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchHROLLING(duckdb_brotli::HROLLING*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchHROLLING(duckdb_brotli::HROLLING*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
3564 | | |
3565 | | #undef HashRolling |
3566 | | #undef MASK |
3567 | | #undef NUMBUCKETS |
3568 | | #undef JUMP |
3569 | | #undef CHUNKLEN |
3570 | | #undef HASHER |
3571 | | |
3572 | | #define HASHER() H35 |
3573 | | #define HASHER_A H3 |
3574 | | #define HASHER_B HROLLING_FAST |
3575 | | /* NOLINT(build/header_guard) */ |
3576 | | /* Copyright 2018 Google Inc. All Rights Reserved. |
3577 | | |
3578 | | Distributed under MIT license. |
3579 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
3580 | | */ |
3581 | | |
3582 | | /* template parameters: FN, HASHER_A, HASHER_B */ |
3583 | | |
3584 | | /* Composite hasher: This hasher allows to combine two other hashers, HASHER_A |
3585 | | and HASHER_B. */ |
3586 | | |
3587 | | #define HashComposite HASHER() |
3588 | | |
3589 | 0 | #define FN_A(X) EXPAND_CAT(X, HASHER_A) |
3590 | 0 | #define FN_B(X) EXPAND_CAT(X, HASHER_B) |
3591 | | |
3592 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { |
3593 | 0 | size_t a = FN_A(HashTypeLength)(); |
3594 | 0 | size_t b = FN_B(HashTypeLength)(); |
3595 | 0 | return a > b ? a : b; |
3596 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH35() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH35() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH35() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH35() |
3597 | | |
3598 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { |
3599 | 0 | size_t a = FN_A(StoreLookahead)(); |
3600 | 0 | size_t b = FN_B(StoreLookahead)(); |
3601 | 0 | return a > b ? a : b; |
3602 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH35() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH35() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH35() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH35() |
3603 | | |
3604 | | typedef struct HashComposite { |
3605 | | HASHER_A ha; |
3606 | | HASHER_B hb; |
3607 | | HasherCommon ha_common; |
3608 | | HasherCommon hb_common; |
3609 | | |
3610 | | /* Shortcuts. */ |
3611 | | HasherCommon* common; |
3612 | | |
3613 | | BROTLI_BOOL fresh; |
3614 | | const BrotliEncoderParams* params; |
3615 | | } HashComposite; |
3616 | | |
3617 | | static void FN(Initialize)(HasherCommon* common, |
3618 | 0 | HashComposite* BROTLI_RESTRICT self, const BrotliEncoderParams* params) { |
3619 | 0 | self->common = common; |
3620 | |
|
3621 | 0 | self->ha_common = *self->common; |
3622 | 0 | self->hb_common = *self->common; |
3623 | 0 | self->fresh = BROTLI_TRUE; |
3624 | 0 | self->params = params; |
3625 | | /* TODO(lode): Initialize of the hashers is deferred to Prepare (and params |
3626 | | remembered here) because we don't get the one_shot and input_size params |
3627 | | here that are needed to know the memory size of them. Instead provide |
3628 | | those params to all hashers FN(Initialize) */ |
3629 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH35(duckdb_brotli::HasherCommon*, duckdb_brotli::H35*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH35(duckdb_brotli::HasherCommon*, duckdb_brotli::H35*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH35(duckdb_brotli::HasherCommon*, duckdb_brotli::H35*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH35(duckdb_brotli::HasherCommon*, duckdb_brotli::H35*, BrotliEncoderParams const*) |
3630 | | |
3631 | | static void FN(Prepare)( |
3632 | | HashComposite* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
3633 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
3634 | 0 | if (self->fresh) { |
3635 | 0 | self->fresh = BROTLI_FALSE; |
3636 | 0 | self->ha_common.extra[0] = self->common->extra[0]; |
3637 | 0 | self->ha_common.extra[1] = self->common->extra[1]; |
3638 | 0 | self->ha_common.extra[2] = NULL; |
3639 | 0 | self->ha_common.extra[3] = NULL; |
3640 | 0 | self->hb_common.extra[0] = self->common->extra[2]; |
3641 | 0 | self->hb_common.extra[1] = self->common->extra[3]; |
3642 | 0 | self->hb_common.extra[2] = NULL; |
3643 | 0 | self->hb_common.extra[3] = NULL; |
3644 | |
|
3645 | 0 | FN_A(Initialize)(&self->ha_common, &self->ha, self->params); |
3646 | 0 | FN_B(Initialize)(&self->hb_common, &self->hb, self->params); |
3647 | 0 | } |
3648 | 0 | FN_A(Prepare)(&self->ha, one_shot, input_size, data); |
3649 | 0 | FN_B(Prepare)(&self->hb, one_shot, input_size, data); |
3650 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH35(duckdb_brotli::H35*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH35(duckdb_brotli::H35*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH35(duckdb_brotli::H35*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH35(duckdb_brotli::H35*, int, unsigned long, unsigned char const*) |
3651 | | |
3652 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
3653 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
3654 | 0 | size_t input_size, size_t* alloc_size) { |
3655 | 0 | size_t alloc_size_a[4] = {0}; |
3656 | 0 | size_t alloc_size_b[4] = {0}; |
3657 | 0 | FN_A(HashMemAllocInBytes)(params, one_shot, input_size, alloc_size_a); |
3658 | 0 | FN_B(HashMemAllocInBytes)(params, one_shot, input_size, alloc_size_b); |
3659 | | /* Should never happen. */ |
3660 | 0 | if (alloc_size_a[2] != 0 || alloc_size_a[3] != 0) exit(EXIT_FAILURE); |
3661 | 0 | if (alloc_size_b[2] != 0 || alloc_size_b[3] != 0) exit(EXIT_FAILURE); |
3662 | 0 | alloc_size[0] = alloc_size_a[0]; |
3663 | 0 | alloc_size[1] = alloc_size_a[1]; |
3664 | 0 | alloc_size[2] = alloc_size_b[0]; |
3665 | 0 | alloc_size[3] = alloc_size_b[1]; |
3666 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH35(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH35(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH35(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH35(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
3667 | | |
3668 | | static BROTLI_INLINE void FN(Store)(HashComposite* BROTLI_RESTRICT self, |
3669 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
3670 | 0 | FN_A(Store)(&self->ha, data, mask, ix); |
3671 | 0 | FN_B(Store)(&self->hb, data, mask, ix); |
3672 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH35(duckdb_brotli::H35*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH35(duckdb_brotli::H35*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH35(duckdb_brotli::H35*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH35(duckdb_brotli::H35*, unsigned char const*, unsigned long, unsigned long) |
3673 | | |
3674 | | static BROTLI_INLINE void FN(StoreRange)( |
3675 | | HashComposite* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, |
3676 | | const size_t mask, const size_t ix_start, |
3677 | 0 | const size_t ix_end) { |
3678 | 0 | FN_A(StoreRange)(&self->ha, data, mask, ix_start, ix_end); |
3679 | 0 | FN_B(StoreRange)(&self->hb, data, mask, ix_start, ix_end); |
3680 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH35(duckdb_brotli::H35*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH35(duckdb_brotli::H35*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH35(duckdb_brotli::H35*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH35(duckdb_brotli::H35*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
3681 | | |
3682 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
3683 | | HashComposite* BROTLI_RESTRICT self, |
3684 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
3685 | 0 | size_t ring_buffer_mask) { |
3686 | 0 | FN_A(StitchToPreviousBlock)(&self->ha, num_bytes, position, |
3687 | 0 | ringbuffer, ring_buffer_mask); |
3688 | 0 | FN_B(StitchToPreviousBlock)(&self->hb, num_bytes, position, |
3689 | 0 | ringbuffer, ring_buffer_mask); |
3690 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH35(duckdb_brotli::H35*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH35(duckdb_brotli::H35*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH35(duckdb_brotli::H35*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH35(duckdb_brotli::H35*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
3691 | | |
3692 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
3693 | 0 | HashComposite* BROTLI_RESTRICT self, int* BROTLI_RESTRICT distance_cache) { |
3694 | 0 | FN_A(PrepareDistanceCache)(&self->ha, distance_cache); |
3695 | 0 | FN_B(PrepareDistanceCache)(&self->hb, distance_cache); |
3696 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH35(duckdb_brotli::H35*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH35(duckdb_brotli::H35*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH35(duckdb_brotli::H35*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH35(duckdb_brotli::H35*, int*) |
3697 | | |
3698 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
3699 | | HashComposite* BROTLI_RESTRICT self, |
3700 | | const BrotliEncoderDictionary* dictionary, |
3701 | | const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, |
3702 | | const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, |
3703 | | const size_t max_length, const size_t max_backward, |
3704 | | const size_t dictionary_distance, const size_t max_distance, |
3705 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
3706 | 0 | FN_A(FindLongestMatch)(&self->ha, dictionary, data, ring_buffer_mask, |
3707 | 0 | distance_cache, cur_ix, max_length, max_backward, dictionary_distance, |
3708 | 0 | max_distance, out); |
3709 | 0 | FN_B(FindLongestMatch)(&self->hb, dictionary, data, ring_buffer_mask, |
3710 | 0 | distance_cache, cur_ix, max_length, max_backward, dictionary_distance, |
3711 | 0 | max_distance, out); |
3712 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH35(duckdb_brotli::H35*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH35(duckdb_brotli::H35*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH35(duckdb_brotli::H35*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH35(duckdb_brotli::H35*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
3713 | | |
3714 | | #undef HashComposite |
3715 | | #undef HASHER_A |
3716 | | #undef HASHER_B |
3717 | | #undef HASHER |
3718 | | |
3719 | | #define HASHER() H55 |
3720 | | #define HASHER_A H54 |
3721 | | #define HASHER_B HROLLING_FAST |
3722 | | /* NOLINT(build/header_guard) */ |
3723 | | /* Copyright 2018 Google Inc. All Rights Reserved. |
3724 | | |
3725 | | Distributed under MIT license. |
3726 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
3727 | | */ |
3728 | | |
3729 | | /* template parameters: FN, HASHER_A, HASHER_B */ |
3730 | | |
3731 | | /* Composite hasher: This hasher allows to combine two other hashers, HASHER_A |
3732 | | and HASHER_B. */ |
3733 | | |
3734 | | #define HashComposite HASHER() |
3735 | | |
3736 | 0 | #define FN_A(X) EXPAND_CAT(X, HASHER_A) |
3737 | 0 | #define FN_B(X) EXPAND_CAT(X, HASHER_B) |
3738 | | |
3739 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { |
3740 | 0 | size_t a = FN_A(HashTypeLength)(); |
3741 | 0 | size_t b = FN_B(HashTypeLength)(); |
3742 | 0 | return a > b ? a : b; |
3743 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH55() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH55() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH55() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH55() |
3744 | | |
3745 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { |
3746 | 0 | size_t a = FN_A(StoreLookahead)(); |
3747 | 0 | size_t b = FN_B(StoreLookahead)(); |
3748 | 0 | return a > b ? a : b; |
3749 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH55() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH55() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH55() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH55() |
3750 | | |
3751 | | typedef struct HashComposite { |
3752 | | HASHER_A ha; |
3753 | | HASHER_B hb; |
3754 | | HasherCommon ha_common; |
3755 | | HasherCommon hb_common; |
3756 | | |
3757 | | /* Shortcuts. */ |
3758 | | HasherCommon* common; |
3759 | | |
3760 | | BROTLI_BOOL fresh; |
3761 | | const BrotliEncoderParams* params; |
3762 | | } HashComposite; |
3763 | | |
3764 | | static void FN(Initialize)(HasherCommon* common, |
3765 | 0 | HashComposite* BROTLI_RESTRICT self, const BrotliEncoderParams* params) { |
3766 | 0 | self->common = common; |
3767 | |
|
3768 | 0 | self->ha_common = *self->common; |
3769 | 0 | self->hb_common = *self->common; |
3770 | 0 | self->fresh = BROTLI_TRUE; |
3771 | 0 | self->params = params; |
3772 | | /* TODO(lode): Initialize of the hashers is deferred to Prepare (and params |
3773 | | remembered here) because we don't get the one_shot and input_size params |
3774 | | here that are needed to know the memory size of them. Instead provide |
3775 | | those params to all hashers FN(Initialize) */ |
3776 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH55(duckdb_brotli::HasherCommon*, duckdb_brotli::H55*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH55(duckdb_brotli::HasherCommon*, duckdb_brotli::H55*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH55(duckdb_brotli::HasherCommon*, duckdb_brotli::H55*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH55(duckdb_brotli::HasherCommon*, duckdb_brotli::H55*, BrotliEncoderParams const*) |
3777 | | |
3778 | | static void FN(Prepare)( |
3779 | | HashComposite* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
3780 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
3781 | 0 | if (self->fresh) { |
3782 | 0 | self->fresh = BROTLI_FALSE; |
3783 | 0 | self->ha_common.extra[0] = self->common->extra[0]; |
3784 | 0 | self->ha_common.extra[1] = self->common->extra[1]; |
3785 | 0 | self->ha_common.extra[2] = NULL; |
3786 | 0 | self->ha_common.extra[3] = NULL; |
3787 | 0 | self->hb_common.extra[0] = self->common->extra[2]; |
3788 | 0 | self->hb_common.extra[1] = self->common->extra[3]; |
3789 | 0 | self->hb_common.extra[2] = NULL; |
3790 | 0 | self->hb_common.extra[3] = NULL; |
3791 | |
|
3792 | 0 | FN_A(Initialize)(&self->ha_common, &self->ha, self->params); |
3793 | 0 | FN_B(Initialize)(&self->hb_common, &self->hb, self->params); |
3794 | 0 | } |
3795 | 0 | FN_A(Prepare)(&self->ha, one_shot, input_size, data); |
3796 | 0 | FN_B(Prepare)(&self->hb, one_shot, input_size, data); |
3797 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH55(duckdb_brotli::H55*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH55(duckdb_brotli::H55*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH55(duckdb_brotli::H55*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH55(duckdb_brotli::H55*, int, unsigned long, unsigned char const*) |
3798 | | |
3799 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
3800 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
3801 | 0 | size_t input_size, size_t* alloc_size) { |
3802 | 0 | size_t alloc_size_a[4] = {0}; |
3803 | 0 | size_t alloc_size_b[4] = {0}; |
3804 | 0 | FN_A(HashMemAllocInBytes)(params, one_shot, input_size, alloc_size_a); |
3805 | 0 | FN_B(HashMemAllocInBytes)(params, one_shot, input_size, alloc_size_b); |
3806 | | /* Should never happen. */ |
3807 | 0 | if (alloc_size_a[2] != 0 || alloc_size_a[3] != 0) exit(EXIT_FAILURE); |
3808 | 0 | if (alloc_size_b[2] != 0 || alloc_size_b[3] != 0) exit(EXIT_FAILURE); |
3809 | 0 | alloc_size[0] = alloc_size_a[0]; |
3810 | 0 | alloc_size[1] = alloc_size_a[1]; |
3811 | 0 | alloc_size[2] = alloc_size_b[0]; |
3812 | 0 | alloc_size[3] = alloc_size_b[1]; |
3813 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH55(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH55(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH55(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH55(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
3814 | | |
3815 | | static BROTLI_INLINE void FN(Store)(HashComposite* BROTLI_RESTRICT self, |
3816 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
3817 | 0 | FN_A(Store)(&self->ha, data, mask, ix); |
3818 | 0 | FN_B(Store)(&self->hb, data, mask, ix); |
3819 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH55(duckdb_brotli::H55*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH55(duckdb_brotli::H55*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH55(duckdb_brotli::H55*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH55(duckdb_brotli::H55*, unsigned char const*, unsigned long, unsigned long) |
3820 | | |
3821 | | static BROTLI_INLINE void FN(StoreRange)( |
3822 | | HashComposite* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, |
3823 | | const size_t mask, const size_t ix_start, |
3824 | 0 | const size_t ix_end) { |
3825 | 0 | FN_A(StoreRange)(&self->ha, data, mask, ix_start, ix_end); |
3826 | 0 | FN_B(StoreRange)(&self->hb, data, mask, ix_start, ix_end); |
3827 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH55(duckdb_brotli::H55*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH55(duckdb_brotli::H55*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH55(duckdb_brotli::H55*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH55(duckdb_brotli::H55*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
3828 | | |
3829 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
3830 | | HashComposite* BROTLI_RESTRICT self, |
3831 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
3832 | 0 | size_t ring_buffer_mask) { |
3833 | 0 | FN_A(StitchToPreviousBlock)(&self->ha, num_bytes, position, |
3834 | 0 | ringbuffer, ring_buffer_mask); |
3835 | 0 | FN_B(StitchToPreviousBlock)(&self->hb, num_bytes, position, |
3836 | 0 | ringbuffer, ring_buffer_mask); |
3837 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH55(duckdb_brotli::H55*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH55(duckdb_brotli::H55*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH55(duckdb_brotli::H55*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH55(duckdb_brotli::H55*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
3838 | | |
3839 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
3840 | 0 | HashComposite* BROTLI_RESTRICT self, int* BROTLI_RESTRICT distance_cache) { |
3841 | 0 | FN_A(PrepareDistanceCache)(&self->ha, distance_cache); |
3842 | 0 | FN_B(PrepareDistanceCache)(&self->hb, distance_cache); |
3843 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH55(duckdb_brotli::H55*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH55(duckdb_brotli::H55*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH55(duckdb_brotli::H55*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH55(duckdb_brotli::H55*, int*) |
3844 | | |
3845 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
3846 | | HashComposite* BROTLI_RESTRICT self, |
3847 | | const BrotliEncoderDictionary* dictionary, |
3848 | | const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, |
3849 | | const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, |
3850 | | const size_t max_length, const size_t max_backward, |
3851 | | const size_t dictionary_distance, const size_t max_distance, |
3852 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
3853 | 0 | FN_A(FindLongestMatch)(&self->ha, dictionary, data, ring_buffer_mask, |
3854 | 0 | distance_cache, cur_ix, max_length, max_backward, dictionary_distance, |
3855 | 0 | max_distance, out); |
3856 | 0 | FN_B(FindLongestMatch)(&self->hb, dictionary, data, ring_buffer_mask, |
3857 | 0 | distance_cache, cur_ix, max_length, max_backward, dictionary_distance, |
3858 | 0 | max_distance, out); |
3859 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH55(duckdb_brotli::H55*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH55(duckdb_brotli::H55*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH55(duckdb_brotli::H55*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH55(duckdb_brotli::H55*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
3860 | | |
3861 | | #undef HashComposite |
3862 | | #undef HASHER_A |
3863 | | #undef HASHER_B |
3864 | | #undef HASHER |
3865 | | |
3866 | | #define HASHER() H65 |
3867 | | #define HASHER_A H6 |
3868 | | #define HASHER_B HROLLING |
3869 | | /* NOLINT(build/header_guard) */ |
3870 | | /* Copyright 2018 Google Inc. All Rights Reserved. |
3871 | | |
3872 | | Distributed under MIT license. |
3873 | | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT |
3874 | | */ |
3875 | | |
3876 | | /* template parameters: FN, HASHER_A, HASHER_B */ |
3877 | | |
3878 | | /* Composite hasher: This hasher allows to combine two other hashers, HASHER_A |
3879 | | and HASHER_B. */ |
3880 | | |
3881 | | #define HashComposite HASHER() |
3882 | | |
3883 | 0 | #define FN_A(X) EXPAND_CAT(X, HASHER_A) |
3884 | 0 | #define FN_B(X) EXPAND_CAT(X, HASHER_B) |
3885 | | |
3886 | 0 | static BROTLI_INLINE size_t FN(HashTypeLength)(void) { |
3887 | 0 | size_t a = FN_A(HashTypeLength)(); |
3888 | 0 | size_t b = FN_B(HashTypeLength)(); |
3889 | 0 | return a > b ? a : b; |
3890 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashTypeLengthH65() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashTypeLengthH65() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashTypeLengthH65() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashTypeLengthH65() |
3891 | | |
3892 | 0 | static BROTLI_INLINE size_t FN(StoreLookahead)(void) { |
3893 | 0 | size_t a = FN_A(StoreLookahead)(); |
3894 | 0 | size_t b = FN_B(StoreLookahead)(); |
3895 | 0 | return a > b ? a : b; |
3896 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreLookaheadH65() Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreLookaheadH65() Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreLookaheadH65() Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreLookaheadH65() |
3897 | | |
3898 | | typedef struct HashComposite { |
3899 | | HASHER_A ha; |
3900 | | HASHER_B hb; |
3901 | | HasherCommon ha_common; |
3902 | | HasherCommon hb_common; |
3903 | | |
3904 | | /* Shortcuts. */ |
3905 | | HasherCommon* common; |
3906 | | |
3907 | | BROTLI_BOOL fresh; |
3908 | | const BrotliEncoderParams* params; |
3909 | | } HashComposite; |
3910 | | |
3911 | | static void FN(Initialize)(HasherCommon* common, |
3912 | 0 | HashComposite* BROTLI_RESTRICT self, const BrotliEncoderParams* params) { |
3913 | 0 | self->common = common; |
3914 | |
|
3915 | 0 | self->ha_common = *self->common; |
3916 | 0 | self->hb_common = *self->common; |
3917 | 0 | self->fresh = BROTLI_TRUE; |
3918 | 0 | self->params = params; |
3919 | | /* TODO(lode): Initialize of the hashers is deferred to Prepare (and params |
3920 | | remembered here) because we don't get the one_shot and input_size params |
3921 | | here that are needed to know the memory size of them. Instead provide |
3922 | | those params to all hashers FN(Initialize) */ |
3923 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitializeH65(duckdb_brotli::HasherCommon*, duckdb_brotli::H65*, BrotliEncoderParams const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitializeH65(duckdb_brotli::HasherCommon*, duckdb_brotli::H65*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitializeH65(duckdb_brotli::HasherCommon*, duckdb_brotli::H65*, BrotliEncoderParams const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitializeH65(duckdb_brotli::HasherCommon*, duckdb_brotli::H65*, BrotliEncoderParams const*) |
3924 | | |
3925 | | static void FN(Prepare)( |
3926 | | HashComposite* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, |
3927 | 0 | size_t input_size, const uint8_t* BROTLI_RESTRICT data) { |
3928 | 0 | if (self->fresh) { |
3929 | 0 | self->fresh = BROTLI_FALSE; |
3930 | 0 | self->ha_common.extra[0] = self->common->extra[0]; |
3931 | 0 | self->ha_common.extra[1] = self->common->extra[1]; |
3932 | 0 | self->ha_common.extra[2] = NULL; |
3933 | 0 | self->ha_common.extra[3] = NULL; |
3934 | 0 | self->hb_common.extra[0] = self->common->extra[2]; |
3935 | 0 | self->hb_common.extra[1] = self->common->extra[3]; |
3936 | 0 | self->hb_common.extra[2] = NULL; |
3937 | 0 | self->hb_common.extra[3] = NULL; |
3938 | |
|
3939 | 0 | FN_A(Initialize)(&self->ha_common, &self->ha, self->params); |
3940 | 0 | FN_B(Initialize)(&self->hb_common, &self->hb, self->params); |
3941 | 0 | } |
3942 | 0 | FN_A(Prepare)(&self->ha, one_shot, input_size, data); |
3943 | 0 | FN_B(Prepare)(&self->hb, one_shot, input_size, data); |
3944 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareH65(duckdb_brotli::H65*, int, unsigned long, unsigned char const*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareH65(duckdb_brotli::H65*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareH65(duckdb_brotli::H65*, int, unsigned long, unsigned char const*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareH65(duckdb_brotli::H65*, int, unsigned long, unsigned char const*) |
3945 | | |
3946 | | static BROTLI_INLINE void FN(HashMemAllocInBytes)( |
3947 | | const BrotliEncoderParams* params, BROTLI_BOOL one_shot, |
3948 | 0 | size_t input_size, size_t* alloc_size) { |
3949 | 0 | size_t alloc_size_a[4] = {0}; |
3950 | 0 | size_t alloc_size_b[4] = {0}; |
3951 | 0 | FN_A(HashMemAllocInBytes)(params, one_shot, input_size, alloc_size_a); |
3952 | 0 | FN_B(HashMemAllocInBytes)(params, one_shot, input_size, alloc_size_b); |
3953 | | /* Should never happen. */ |
3954 | 0 | if (alloc_size_a[2] != 0 || alloc_size_a[3] != 0) exit(EXIT_FAILURE); |
3955 | 0 | if (alloc_size_b[2] != 0 || alloc_size_b[3] != 0) exit(EXIT_FAILURE); |
3956 | 0 | alloc_size[0] = alloc_size_a[0]; |
3957 | 0 | alloc_size[1] = alloc_size_a[1]; |
3958 | 0 | alloc_size[2] = alloc_size_b[0]; |
3959 | 0 | alloc_size[3] = alloc_size_b[1]; |
3960 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HashMemAllocInBytesH65(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HashMemAllocInBytesH65(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HashMemAllocInBytesH65(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HashMemAllocInBytesH65(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
3961 | | |
3962 | | static BROTLI_INLINE void FN(Store)(HashComposite* BROTLI_RESTRICT self, |
3963 | 0 | const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { |
3964 | 0 | FN_A(Store)(&self->ha, data, mask, ix); |
3965 | 0 | FN_B(Store)(&self->hb, data, mask, ix); |
3966 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreH65(duckdb_brotli::H65*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreH65(duckdb_brotli::H65*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreH65(duckdb_brotli::H65*, unsigned char const*, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreH65(duckdb_brotli::H65*, unsigned char const*, unsigned long, unsigned long) |
3967 | | |
3968 | | static BROTLI_INLINE void FN(StoreRange)( |
3969 | | HashComposite* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, |
3970 | | const size_t mask, const size_t ix_start, |
3971 | 0 | const size_t ix_end) { |
3972 | 0 | FN_A(StoreRange)(&self->ha, data, mask, ix_start, ix_end); |
3973 | 0 | FN_B(StoreRange)(&self->hb, data, mask, ix_start, ix_end); |
3974 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StoreRangeH65(duckdb_brotli::H65*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StoreRangeH65(duckdb_brotli::H65*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StoreRangeH65(duckdb_brotli::H65*, unsigned char const*, unsigned long, unsigned long, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StoreRangeH65(duckdb_brotli::H65*, unsigned char const*, unsigned long, unsigned long, unsigned long) |
3975 | | |
3976 | | static BROTLI_INLINE void FN(StitchToPreviousBlock)( |
3977 | | HashComposite* BROTLI_RESTRICT self, |
3978 | | size_t num_bytes, size_t position, const uint8_t* ringbuffer, |
3979 | 0 | size_t ring_buffer_mask) { |
3980 | 0 | FN_A(StitchToPreviousBlock)(&self->ha, num_bytes, position, |
3981 | 0 | ringbuffer, ring_buffer_mask); |
3982 | 0 | FN_B(StitchToPreviousBlock)(&self->hb, num_bytes, position, |
3983 | 0 | ringbuffer, ring_buffer_mask); |
3984 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::StitchToPreviousBlockH65(duckdb_brotli::H65*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::StitchToPreviousBlockH65(duckdb_brotli::H65*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::StitchToPreviousBlockH65(duckdb_brotli::H65*, unsigned long, unsigned long, unsigned char const*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::StitchToPreviousBlockH65(duckdb_brotli::H65*, unsigned long, unsigned long, unsigned char const*, unsigned long) |
3985 | | |
3986 | | static BROTLI_INLINE void FN(PrepareDistanceCache)( |
3987 | 0 | HashComposite* BROTLI_RESTRICT self, int* BROTLI_RESTRICT distance_cache) { |
3988 | 0 | FN_A(PrepareDistanceCache)(&self->ha, distance_cache); |
3989 | 0 | FN_B(PrepareDistanceCache)(&self->hb, distance_cache); |
3990 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::PrepareDistanceCacheH65(duckdb_brotli::H65*, int*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::PrepareDistanceCacheH65(duckdb_brotli::H65*, int*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::PrepareDistanceCacheH65(duckdb_brotli::H65*, int*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::PrepareDistanceCacheH65(duckdb_brotli::H65*, int*) |
3991 | | |
3992 | | static BROTLI_INLINE void FN(FindLongestMatch)( |
3993 | | HashComposite* BROTLI_RESTRICT self, |
3994 | | const BrotliEncoderDictionary* dictionary, |
3995 | | const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, |
3996 | | const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, |
3997 | | const size_t max_length, const size_t max_backward, |
3998 | | const size_t dictionary_distance, const size_t max_distance, |
3999 | 0 | HasherSearchResult* BROTLI_RESTRICT out) { |
4000 | 0 | FN_A(FindLongestMatch)(&self->ha, dictionary, data, ring_buffer_mask, |
4001 | 0 | distance_cache, cur_ix, max_length, max_backward, dictionary_distance, |
4002 | 0 | max_distance, out); |
4003 | 0 | FN_B(FindLongestMatch)(&self->hb, dictionary, data, ring_buffer_mask, |
4004 | 0 | distance_cache, cur_ix, max_length, max_backward, dictionary_distance, |
4005 | 0 | max_distance, out); |
4006 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindLongestMatchH65(duckdb_brotli::H65*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindLongestMatchH65(duckdb_brotli::H65*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindLongestMatchH65(duckdb_brotli::H65*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindLongestMatchH65(duckdb_brotli::H65*, duckdb_brotli::BrotliEncoderDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
4007 | | |
4008 | | #undef HashComposite |
4009 | | #undef HASHER_A |
4010 | | #undef HASHER_B |
4011 | | #undef HASHER |
4012 | | |
4013 | | #undef FN |
4014 | | #undef CAT |
4015 | | #undef EXPAND_CAT |
4016 | | |
4017 | 0 | #define FOR_SIMPLE_HASHERS(H) H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54) |
4018 | 0 | #define FOR_COMPOSITE_HASHERS(H) H(35) H(55) H(65) |
4019 | 0 | #define FOR_GENERIC_HASHERS(H) FOR_SIMPLE_HASHERS(H) FOR_COMPOSITE_HASHERS(H) |
4020 | 0 | #define FOR_ALL_HASHERS(H) FOR_GENERIC_HASHERS(H) H(10) |
4021 | | |
4022 | | typedef struct { |
4023 | | HasherCommon common; |
4024 | | |
4025 | | union { |
4026 | | #define MEMBER_(N) \ |
4027 | | H ## N _H ## N; |
4028 | | FOR_ALL_HASHERS(MEMBER_) |
4029 | | #undef MEMBER_ |
4030 | | } privat; |
4031 | | } Hasher; |
4032 | | |
4033 | | /* MUST be invoked before any other method. */ |
4034 | 0 | static BROTLI_INLINE void HasherInit(Hasher* hasher) { |
4035 | 0 | hasher->common.is_setup_ = BROTLI_FALSE; |
4036 | 0 | hasher->common.extra[0] = NULL; |
4037 | 0 | hasher->common.extra[1] = NULL; |
4038 | 0 | hasher->common.extra[2] = NULL; |
4039 | 0 | hasher->common.extra[3] = NULL; |
4040 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HasherInit(duckdb_brotli::Hasher*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HasherInit(duckdb_brotli::Hasher*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HasherInit(duckdb_brotli::Hasher*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HasherInit(duckdb_brotli::Hasher*) |
4041 | | |
4042 | 0 | static BROTLI_INLINE void DestroyHasher(MemoryManager* m, Hasher* hasher) { |
4043 | 0 | if (hasher->common.extra[0] != NULL) BROTLI_FREE(m, hasher->common.extra[0]); |
4044 | 0 | if (hasher->common.extra[1] != NULL) BROTLI_FREE(m, hasher->common.extra[1]); |
4045 | 0 | if (hasher->common.extra[2] != NULL) BROTLI_FREE(m, hasher->common.extra[2]); |
4046 | 0 | if (hasher->common.extra[3] != NULL) BROTLI_FREE(m, hasher->common.extra[3]); |
4047 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::DestroyHasher(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::DestroyHasher(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::DestroyHasher(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::DestroyHasher(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*) |
4048 | | |
4049 | 0 | static BROTLI_INLINE void HasherReset(Hasher* hasher) { |
4050 | 0 | hasher->common.is_prepared_ = BROTLI_FALSE; |
4051 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HasherReset(duckdb_brotli::Hasher*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HasherReset(duckdb_brotli::Hasher*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HasherReset(duckdb_brotli::Hasher*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HasherReset(duckdb_brotli::Hasher*) |
4052 | | |
4053 | | static BROTLI_INLINE void HasherSize(const BrotliEncoderParams* params, |
4054 | 0 | BROTLI_BOOL one_shot, const size_t input_size, size_t* alloc_size) { |
4055 | 0 | switch (params->hasher.type) { |
4056 | 0 | #define SIZE_(N) \ |
4057 | 0 | case N: \ |
4058 | 0 | HashMemAllocInBytesH ## N(params, one_shot, input_size, alloc_size); \ |
4059 | 0 | break; |
4060 | 0 | FOR_ALL_HASHERS(SIZE_) |
4061 | 0 | #undef SIZE_ |
4062 | 0 | default: |
4063 | 0 | break; |
4064 | 0 | } |
4065 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HasherSize(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HasherSize(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HasherSize(BrotliEncoderParams const*, int, unsigned long, unsigned long*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HasherSize(BrotliEncoderParams const*, int, unsigned long, unsigned long*) |
4066 | | |
4067 | | static BROTLI_INLINE void HasherSetup(MemoryManager* m, Hasher* hasher, |
4068 | | BrotliEncoderParams* params, const uint8_t* data, size_t position, |
4069 | 0 | size_t input_size, BROTLI_BOOL is_last) { |
4070 | 0 | BROTLI_BOOL one_shot = (position == 0 && is_last); |
4071 | 0 | if (!hasher->common.is_setup_) { |
4072 | 0 | size_t alloc_size[4] = {0}; |
4073 | 0 | size_t i; |
4074 | 0 | ChooseHasher(params, ¶ms->hasher); |
4075 | 0 | hasher->common.params = params->hasher; |
4076 | 0 | hasher->common.dict_num_lookups = 0; |
4077 | 0 | hasher->common.dict_num_matches = 0; |
4078 | 0 | HasherSize(params, one_shot, input_size, alloc_size); |
4079 | 0 | for (i = 0; i < 4; ++i) { |
4080 | 0 | if (alloc_size[i] == 0) continue; |
4081 | 0 | hasher->common.extra[i] = BROTLI_ALLOC(m, uint8_t, alloc_size[i]); |
4082 | 0 | if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(hasher->common.extra[i])) return; |
4083 | 0 | } |
4084 | 0 | switch (hasher->common.params.type) { |
4085 | 0 | #define INITIALIZE_(N) \ |
4086 | 0 | case N: \ |
4087 | 0 | InitializeH ## N(&hasher->common, \ |
4088 | 0 | &hasher->privat._H ## N, params); \ |
4089 | 0 | break; |
4090 | 0 | FOR_ALL_HASHERS(INITIALIZE_); |
4091 | 0 | #undef INITIALIZE_ |
4092 | 0 | default: |
4093 | 0 | break; |
4094 | 0 | } |
4095 | 0 | HasherReset(hasher); |
4096 | 0 | hasher->common.is_setup_ = BROTLI_TRUE; |
4097 | 0 | } |
4098 | | |
4099 | 0 | if (!hasher->common.is_prepared_) { |
4100 | 0 | switch (hasher->common.params.type) { |
4101 | 0 | #define PREPARE_(N) \ |
4102 | 0 | case N: \ |
4103 | 0 | PrepareH ## N( \ |
4104 | 0 | &hasher->privat._H ## N, \ |
4105 | 0 | one_shot, input_size, data); \ |
4106 | 0 | break; |
4107 | 0 | FOR_ALL_HASHERS(PREPARE_) |
4108 | 0 | #undef PREPARE_ |
4109 | 0 | default: break; |
4110 | 0 | } |
4111 | 0 | hasher->common.is_prepared_ = BROTLI_TRUE; |
4112 | 0 | } |
4113 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::HasherSetup(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*, BrotliEncoderParams*, unsigned char const*, unsigned long, unsigned long, int) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::HasherSetup(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*, BrotliEncoderParams*, unsigned char const*, unsigned long, unsigned long, int) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::HasherSetup(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*, BrotliEncoderParams*, unsigned char const*, unsigned long, unsigned long, int) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::HasherSetup(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*, BrotliEncoderParams*, unsigned char const*, unsigned long, unsigned long, int) |
4114 | | |
4115 | | static BROTLI_INLINE void InitOrStitchToPreviousBlock( |
4116 | | MemoryManager* m, Hasher* hasher, const uint8_t* data, size_t mask, |
4117 | | BrotliEncoderParams* params, size_t position, size_t input_size, |
4118 | 0 | BROTLI_BOOL is_last) { |
4119 | 0 | HasherSetup(m, hasher, params, data, position, input_size, is_last); |
4120 | 0 | if (BROTLI_IS_OOM(m)) return; |
4121 | 0 | switch (hasher->common.params.type) { |
4122 | 0 | #define INIT_(N) \ |
4123 | 0 | case N: \ |
4124 | 0 | StitchToPreviousBlockH ## N( \ |
4125 | 0 | &hasher->privat._H ## N, \ |
4126 | 0 | input_size, position, data, mask); \ |
4127 | 0 | break; |
4128 | 0 | FOR_ALL_HASHERS(INIT_) |
4129 | 0 | #undef INIT_ |
4130 | 0 | default: break; |
4131 | 0 | } |
4132 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::InitOrStitchToPreviousBlock(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*, unsigned char const*, unsigned long, BrotliEncoderParams*, unsigned long, unsigned long, int) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::InitOrStitchToPreviousBlock(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*, unsigned char const*, unsigned long, BrotliEncoderParams*, unsigned long, unsigned long, int) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::InitOrStitchToPreviousBlock(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*, unsigned char const*, unsigned long, BrotliEncoderParams*, unsigned long, unsigned long, int) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::InitOrStitchToPreviousBlock(duckdb_brotli::MemoryManager*, duckdb_brotli::Hasher*, unsigned char const*, unsigned long, BrotliEncoderParams*, unsigned long, unsigned long, int) |
4133 | | |
4134 | | /* NB: when seamless dictionary-ring-buffer copies are implemented, don't forget |
4135 | | to add proper guards for non-zero-BROTLI_PARAM_STREAM_OFFSET. */ |
4136 | | static BROTLI_INLINE void FindCompoundDictionaryMatch( |
4137 | | const PreparedDictionary* self, const uint8_t* BROTLI_RESTRICT data, |
4138 | | const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, |
4139 | | const size_t cur_ix, const size_t max_length, const size_t distance_offset, |
4140 | 0 | const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) { |
4141 | 0 | const uint32_t source_size = self->source_size; |
4142 | 0 | const size_t boundary = distance_offset - source_size; |
4143 | 0 | const uint32_t hash_bits = self->hash_bits; |
4144 | 0 | const uint32_t bucket_bits = self->bucket_bits; |
4145 | 0 | const uint32_t slot_bits = self->slot_bits; |
4146 | |
|
4147 | 0 | const uint32_t hash_shift = 64u - bucket_bits; |
4148 | 0 | const uint32_t slot_mask = (~((uint32_t)0U)) >> (32 - slot_bits); |
4149 | 0 | const uint64_t hash_mask = (~((uint64_t)0U)) >> (64 - hash_bits); |
4150 | |
|
4151 | 0 | const uint32_t* slot_offsets = (uint32_t*)(&self[1]); |
4152 | 0 | const uint16_t* heads = (uint16_t*)(&slot_offsets[1u << slot_bits]); |
4153 | 0 | const uint32_t* items = (uint32_t*)(&heads[1u << bucket_bits]); |
4154 | 0 | const uint8_t* source = NULL; |
4155 | |
|
4156 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
4157 | 0 | score_t best_score = out->score; |
4158 | 0 | size_t best_len = out->len; |
4159 | 0 | size_t i; |
4160 | 0 | const uint64_t h = |
4161 | 0 | (BROTLI_UNALIGNED_LOAD64LE(&data[cur_ix_masked]) & hash_mask) * |
4162 | 0 | kPreparedDictionaryHashMul64Long; |
4163 | 0 | const uint32_t key = (uint32_t)(h >> hash_shift); |
4164 | 0 | const uint32_t slot = key & slot_mask; |
4165 | 0 | const uint32_t head = heads[key]; |
4166 | 0 | const uint32_t* BROTLI_RESTRICT chain = &items[slot_offsets[slot] + head]; |
4167 | 0 | uint32_t item = (head == 0xFFFF) ? 1 : 0; |
4168 | |
|
4169 | 0 | const void* tail = (void*)&items[self->num_items]; |
4170 | 0 | if (self->magic == kPreparedDictionaryMagic) { |
4171 | 0 | source = (const uint8_t*)tail; |
4172 | 0 | } else { |
4173 | | /* kLeanPreparedDictionaryMagic */ |
4174 | 0 | source = (const uint8_t*)BROTLI_UNALIGNED_LOAD_PTR((const uint8_t**)tail); |
4175 | 0 | } |
4176 | |
|
4177 | 0 | for (i = 0; i < 4; ++i) { |
4178 | 0 | const size_t distance = (size_t)distance_cache[i]; |
4179 | 0 | size_t offset; |
4180 | 0 | size_t limit; |
4181 | 0 | size_t len; |
4182 | 0 | if (distance <= boundary || distance > distance_offset) continue; |
4183 | 0 | offset = distance_offset - distance; |
4184 | 0 | limit = source_size - offset; |
4185 | 0 | limit = limit > max_length ? max_length : limit; |
4186 | 0 | len = FindMatchLengthWithLimit(&source[offset], &data[cur_ix_masked], |
4187 | 0 | limit); |
4188 | 0 | if (len >= 2) { |
4189 | 0 | score_t score = BackwardReferenceScoreUsingLastDistance(len); |
4190 | 0 | if (best_score < score) { |
4191 | 0 | if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); |
4192 | 0 | if (best_score < score) { |
4193 | 0 | best_score = score; |
4194 | 0 | if (len > best_len) best_len = len; |
4195 | 0 | out->len = len; |
4196 | 0 | out->len_code_delta = 0; |
4197 | 0 | out->distance = distance; |
4198 | 0 | out->score = best_score; |
4199 | 0 | } |
4200 | 0 | } |
4201 | 0 | } |
4202 | 0 | } |
4203 | 0 | while (item == 0) { |
4204 | 0 | size_t offset; |
4205 | 0 | size_t distance; |
4206 | 0 | size_t limit; |
4207 | 0 | item = *chain; |
4208 | 0 | chain++; |
4209 | 0 | offset = item & 0x7FFFFFFF; |
4210 | 0 | item &= 0x80000000; |
4211 | 0 | distance = distance_offset - offset; |
4212 | 0 | limit = source_size - offset; |
4213 | 0 | limit = (limit > max_length) ? max_length : limit; |
4214 | 0 | if (distance > max_distance) continue; |
4215 | 0 | if (cur_ix_masked + best_len > ring_buffer_mask || |
4216 | 0 | best_len >= limit || |
4217 | 0 | data[cur_ix_masked + best_len] != source[offset + best_len]) { |
4218 | 0 | continue; |
4219 | 0 | } |
4220 | 0 | { |
4221 | 0 | const size_t len = FindMatchLengthWithLimit(&source[offset], |
4222 | 0 | &data[cur_ix_masked], |
4223 | 0 | limit); |
4224 | 0 | if (len >= 4) { |
4225 | 0 | score_t score = BackwardReferenceScore(len, distance); |
4226 | 0 | if (best_score < score) { |
4227 | 0 | best_score = score; |
4228 | 0 | best_len = len; |
4229 | 0 | out->len = best_len; |
4230 | 0 | out->len_code_delta = 0; |
4231 | 0 | out->distance = distance; |
4232 | 0 | out->score = best_score; |
4233 | 0 | } |
4234 | 0 | } |
4235 | 0 | } |
4236 | 0 | } |
4237 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindCompoundDictionaryMatch(duckdb_brotli::PreparedDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindCompoundDictionaryMatch(duckdb_brotli::PreparedDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindCompoundDictionaryMatch(duckdb_brotli::PreparedDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindCompoundDictionaryMatch(duckdb_brotli::PreparedDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
4238 | | |
4239 | | /* NB: when seamless dictionary-ring-buffer copies are implemented, don't forget |
4240 | | to add proper guards for non-zero-BROTLI_PARAM_STREAM_OFFSET. */ |
4241 | | static BROTLI_INLINE size_t FindAllCompoundDictionaryMatches( |
4242 | | const PreparedDictionary* self, const uint8_t* BROTLI_RESTRICT data, |
4243 | | const size_t ring_buffer_mask, const size_t cur_ix, const size_t min_length, |
4244 | | const size_t max_length, const size_t distance_offset, |
4245 | 0 | const size_t max_distance, BackwardMatch* matches, size_t match_limit) { |
4246 | 0 | const uint32_t source_size = self->source_size; |
4247 | 0 | const uint32_t hash_bits = self->hash_bits; |
4248 | 0 | const uint32_t bucket_bits = self->bucket_bits; |
4249 | 0 | const uint32_t slot_bits = self->slot_bits; |
4250 | |
|
4251 | 0 | const uint32_t hash_shift = 64u - bucket_bits; |
4252 | 0 | const uint32_t slot_mask = (~((uint32_t)0U)) >> (32 - slot_bits); |
4253 | 0 | const uint64_t hash_mask = (~((uint64_t)0U)) >> (64 - hash_bits); |
4254 | |
|
4255 | 0 | const uint32_t* slot_offsets = (uint32_t*)(&self[1]); |
4256 | 0 | const uint16_t* heads = (uint16_t*)(&slot_offsets[1u << slot_bits]); |
4257 | 0 | const uint32_t* items = (uint32_t*)(&heads[1u << bucket_bits]); |
4258 | 0 | const uint8_t* source = NULL; |
4259 | |
|
4260 | 0 | const size_t cur_ix_masked = cur_ix & ring_buffer_mask; |
4261 | 0 | size_t best_len = min_length; |
4262 | 0 | const uint64_t h = |
4263 | 0 | (BROTLI_UNALIGNED_LOAD64LE(&data[cur_ix_masked]) & hash_mask) * |
4264 | 0 | kPreparedDictionaryHashMul64Long; |
4265 | 0 | const uint32_t key = (uint32_t)(h >> hash_shift); |
4266 | 0 | const uint32_t slot = key & slot_mask; |
4267 | 0 | const uint32_t head = heads[key]; |
4268 | 0 | const uint32_t* BROTLI_RESTRICT chain = &items[slot_offsets[slot] + head]; |
4269 | 0 | uint32_t item = (head == 0xFFFF) ? 1 : 0; |
4270 | 0 | size_t found = 0; |
4271 | |
|
4272 | 0 | const void* tail = (void*)&items[self->num_items]; |
4273 | 0 | if (self->magic == kPreparedDictionaryMagic) { |
4274 | 0 | source = (const uint8_t*)tail; |
4275 | 0 | } else { |
4276 | | /* kLeanPreparedDictionaryMagic */ |
4277 | 0 | source = (const uint8_t*)BROTLI_UNALIGNED_LOAD_PTR((const uint8_t**)tail); |
4278 | 0 | } |
4279 | |
|
4280 | 0 | while (item == 0) { |
4281 | 0 | size_t offset; |
4282 | 0 | size_t distance; |
4283 | 0 | size_t limit; |
4284 | 0 | size_t len; |
4285 | 0 | item = *chain; |
4286 | 0 | chain++; |
4287 | 0 | offset = item & 0x7FFFFFFF; |
4288 | 0 | item &= 0x80000000; |
4289 | 0 | distance = distance_offset - offset; |
4290 | 0 | limit = source_size - offset; |
4291 | 0 | limit = (limit > max_length) ? max_length : limit; |
4292 | 0 | if (distance > max_distance) continue; |
4293 | 0 | if (cur_ix_masked + best_len > ring_buffer_mask || |
4294 | 0 | best_len >= limit || |
4295 | 0 | data[cur_ix_masked + best_len] != source[offset + best_len]) { |
4296 | 0 | continue; |
4297 | 0 | } |
4298 | 0 | len = FindMatchLengthWithLimit( |
4299 | 0 | &source[offset], &data[cur_ix_masked], limit); |
4300 | 0 | if (len > best_len) { |
4301 | 0 | best_len = len; |
4302 | 0 | InitBackwardMatch(matches++, distance, len); |
4303 | 0 | found++; |
4304 | 0 | if (found == match_limit) break; |
4305 | 0 | } |
4306 | 0 | } |
4307 | 0 | return found; |
4308 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::FindAllCompoundDictionaryMatches(duckdb_brotli::PreparedDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::BackwardMatch*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::FindAllCompoundDictionaryMatches(duckdb_brotli::PreparedDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::BackwardMatch*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::FindAllCompoundDictionaryMatches(duckdb_brotli::PreparedDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::BackwardMatch*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::FindAllCompoundDictionaryMatches(duckdb_brotli::PreparedDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::BackwardMatch*, unsigned long) |
4309 | | |
4310 | | static BROTLI_INLINE void LookupCompoundDictionaryMatch( |
4311 | | const CompoundDictionary* addon, const uint8_t* BROTLI_RESTRICT data, |
4312 | | const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, |
4313 | | const size_t cur_ix, const size_t max_length, |
4314 | | const size_t max_ring_buffer_distance, const size_t max_distance, |
4315 | 0 | HasherSearchResult* sr) { |
4316 | 0 | size_t base_offset = max_ring_buffer_distance + 1 + addon->total_size - 1; |
4317 | 0 | size_t d; |
4318 | 0 | for (d = 0; d < addon->num_chunks; ++d) { |
4319 | | /* Only one prepared dictionary type is currently supported. */ |
4320 | 0 | FindCompoundDictionaryMatch( |
4321 | 0 | (const PreparedDictionary*)addon->chunks[d], data, ring_buffer_mask, |
4322 | 0 | distance_cache, cur_ix, max_length, |
4323 | 0 | base_offset - addon->chunk_offsets[d], max_distance, sr); |
4324 | 0 | } |
4325 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::LookupCompoundDictionaryMatch(duckdb_brotli::CompoundDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::LookupCompoundDictionaryMatch(duckdb_brotli::CompoundDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::LookupCompoundDictionaryMatch(duckdb_brotli::CompoundDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::LookupCompoundDictionaryMatch(duckdb_brotli::CompoundDictionary const*, unsigned char const*, unsigned long, int const*, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::HasherSearchResult*) |
4326 | | |
4327 | | static BROTLI_INLINE size_t LookupAllCompoundDictionaryMatches( |
4328 | | const CompoundDictionary* addon, const uint8_t* BROTLI_RESTRICT data, |
4329 | | const size_t ring_buffer_mask, const size_t cur_ix, size_t min_length, |
4330 | | const size_t max_length, const size_t max_ring_buffer_distance, |
4331 | | const size_t max_distance, BackwardMatch* matches, |
4332 | 0 | size_t match_limit) { |
4333 | 0 | size_t base_offset = max_ring_buffer_distance + 1 + addon->total_size - 1; |
4334 | 0 | size_t d; |
4335 | 0 | size_t total_found = 0; |
4336 | 0 | for (d = 0; d < addon->num_chunks; ++d) { |
4337 | | /* Only one prepared dictionary type is currently supported. */ |
4338 | 0 | total_found += FindAllCompoundDictionaryMatches( |
4339 | 0 | (const PreparedDictionary*)addon->chunks[d], data, ring_buffer_mask, |
4340 | 0 | cur_ix, min_length, max_length, base_offset - addon->chunk_offsets[d], |
4341 | 0 | max_distance, matches + total_found, match_limit - total_found); |
4342 | 0 | if (total_found == match_limit) break; |
4343 | 0 | if (total_found > 0) { |
4344 | 0 | min_length = BackwardMatchLength(&matches[total_found - 1]); |
4345 | 0 | } |
4346 | 0 | } |
4347 | 0 | return total_found; |
4348 | 0 | } Unexecuted instantiation: encode.cpp:duckdb_brotli::LookupAllCompoundDictionaryMatches(duckdb_brotli::CompoundDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::BackwardMatch*, unsigned long) Unexecuted instantiation: encoder_dict.cpp:duckdb_brotli::LookupAllCompoundDictionaryMatches(duckdb_brotli::CompoundDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::BackwardMatch*, unsigned long) Unexecuted instantiation: backward_references.cpp:duckdb_brotli::LookupAllCompoundDictionaryMatches(duckdb_brotli::CompoundDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::BackwardMatch*, unsigned long) Unexecuted instantiation: backward_references_hq.cpp:duckdb_brotli::LookupAllCompoundDictionaryMatches(duckdb_brotli::CompoundDictionary const*, unsigned char const*, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, duckdb_brotli::BackwardMatch*, unsigned long) |
4349 | | |
4350 | | } |
4351 | | |
4352 | | #endif /* BROTLI_ENC_HASH_H_ */ |