18#define HashForgetfulChain HASHER()
20#define BANK_SIZE (1 << BANK_BITS)
23#define BUCKET_SIZE (1 << BUCKET_BITS)
25#define CAPPED_CHAINS 0
32 const uint32_t
h = BROTLI_UNALIGNED_LOAD32LE(
data) * kHashMul32;
38typedef struct FN(Slot) {
43typedef struct FN(Bank) {
67static uint32_t*
FN(Addr)(
void* extra) {
68 return (uint32_t*)extra;
71static uint16_t*
FN(Head)(
void* extra) {
75static uint8_t*
FN(TinyHash)(
void* extra) {
79static FN(Bank)*
FN(Banks)(
void* extra) {
80 return (
FN(Bank)*)(extra);
83static void FN(Initialize)(
86 self->common = common;
87 self->extra[0] = common->extra[0];
88 self->extra[1] = common->extra[1];
90 self->max_hops = (params->quality > 6 ? 7u : 8u) << (params->quality - 4);
93static void FN(Prepare)(
100 size_t partial_prepare_threshold =
BUCKET_SIZE >> 6;
101 if (one_shot && input_size <= partial_prepare_threshold) {
103 for (
i = 0;
i < input_size; ++
i) {
104 size_t bucket =
FN(HashBytes)(&
data[
i]);
106 addr[bucket] = 0xCCCCCCCC;
107 head[bucket] = 0xCCCC;
113 memset(addr, 0xCC,
sizeof(uint32_t) *
BUCKET_SIZE);
116 memset(tiny_hash, 0,
sizeof(uint8_t) * 65536);
117 memset(self->free_slot_idx, 0,
sizeof(self->free_slot_idx));
122 size_t input_size,
size_t* alloc_size) {
127 sizeof(uint16_t) *
BUCKET_SIZE +
sizeof(uint8_t) * 65536;
139 const size_t key =
FN(HashBytes)(&
data[ix & mask]);
140 const size_t bank = key & (
NUM_BANKS - 1);
141 const size_t idx = self->free_slot_idx[bank]++ & (
BANK_SIZE - 1);
142 size_t delta = ix - addr[key];
143 tiny_hash[(uint16_t)ix] = (uint8_t)key;
145 banks[bank].slots[idx].delta = (uint16_t)delta;
146 banks[bank].slots[idx].next =
head[key];
147 addr[key] = (uint32_t)ix;
148 head[key] = (uint16_t)idx;
154 const size_t ix_start,
const size_t ix_end) {
156 for (
i = ix_start;
i < ix_end; ++
i) {
157 FN(Store)(self,
data, mask,
i);
163 size_t num_bytes,
size_t position,
const uint8_t* ringbuffer,
164 size_t ring_buffer_mask) {
165 if (num_bytes >=
FN(HashTypeLength)() - 1 && position >= 3) {
169 FN(Store)(self, ringbuffer, ring_buffer_mask, position - 3);
170 FN(Store)(self, ringbuffer, ring_buffer_mask, position - 2);
171 FN(Store)(self, ringbuffer, ring_buffer_mask, position - 1);
198 const size_t cur_ix,
const size_t max_length,
const size_t max_backward,
199 const size_t dictionary_distance,
const size_t max_distance,
205 const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
209 size_t best_len =
out->len;
211 const size_t key =
FN(HashBytes)(&
data[cur_ix_masked]);
212 const uint8_t tiny_hash = (uint8_t)(key);
214 out->len_code_delta = 0;
217 const size_t backward = (size_t)distance_cache[
i];
218 size_t prev_ix = (cur_ix - backward);
220 if (
i > 0 && tiny_hashes[(uint16_t)prev_ix] != tiny_hash)
continue;
221 if (prev_ix >= cur_ix || backward > max_backward) {
224 prev_ix &= ring_buffer_mask;
226 const size_t len = FindMatchLengthWithLimit(&
data[prev_ix],
227 &
data[cur_ix_masked],
230 score_t score = BackwardReferenceScoreUsingLastDistance(
len);
231 if (best_score < score) {
232 if (
i != 0) score -= BackwardReferencePenaltyUsingLastDistance(
i);
233 if (best_score < score) {
237 out->distance = backward;
238 out->score = best_score;
245 const size_t bank = key & (
NUM_BANKS - 1);
247 size_t hops = self->max_hops;
248 size_t delta = cur_ix - addr[key];
249 size_t slot =
head[key];
254 if (backward > max_backward || (
CAPPED_CHAINS && !delta))
break;
255 prev_ix = (cur_ix - backward) & ring_buffer_mask;
256 slot = banks[bank].slots[last].next;
257 delta = banks[bank].slots[last].delta;
258 if (cur_ix_masked + best_len > ring_buffer_mask ||
259 prev_ix + best_len > ring_buffer_mask ||
260 data[cur_ix_masked + best_len] !=
data[prev_ix + best_len]) {
264 const size_t len = FindMatchLengthWithLimit(&
data[prev_ix],
265 &
data[cur_ix_masked],
271 score_t score = BackwardReferenceScore(
len, backward);
272 if (best_score < score) {
276 out->distance = backward;
277 out->score = best_score;
282 FN(Store)(self,
data, ring_buffer_mask, cur_ix);
284 if (
out->score == min_score) {
286 self->common, &
data[cur_ix_masked], max_length, dictionary_distance,
295#undef HashForgetfulChain
static const void * data
Definition XzCrc64.c:50
#define FN(X)
Definition backward_references.c:51
#define NUM_LAST_DISTANCES_TO_CHECK
Definition hash.h:287
#define score_t
Definition hash.h:43
#define BUCKET_BITS
Definition hash.h:232
#define NUM_BANKS
Definition hash.h:288
#define BUCKET_SIZE
Definition hash_forgetful_chain_inc.h:23
#define CAPPED_CHAINS
Definition hash_forgetful_chain_inc.h:25
#define HashForgetfulChain
Definition hash_forgetful_chain_inc.h:18
#define BANK_SIZE
Definition hash_forgetful_chain_inc.h:20
str head
Definition test-lz4-abi.py:25
Definition encoder_dict.h:20
Definition hash_forgetful_chain_inc.h:47
Definition poolTests.c:28
Definition zstd_decompress.c:306
#define BROTLI_FALSE
Definition types.h:53
#define BROTLI_BOOL
Definition types.h:49
#define h(i)
Definition sha256.c:48
const lzma_allocator const uint8_t size_t uint8_t * out
Definition block.h:528
lzma_index ** i
Definition index.h:629
static uint32_t const uint8_t uint32_t len
Definition memcmplen.h:44
struct dictionary_s dictionary