Extract Hash14/15 to hash_base PiperOrigin-RevId: 790706104
diff --git a/c/enc/compress_fragment.c b/c/enc/compress_fragment.c index 13890ea..7600fc5 100644 --- a/c/enc/compress_fragment.c +++ b/c/enc/compress_fragment.c
@@ -23,6 +23,7 @@ #include "entropy_encode.h" #include "fast_log.h" #include "find_match_length.h" +#include "hash_base.h" #include "write_bits.h" #if defined(__cplusplus) || defined(c_plusplus) @@ -31,14 +32,6 @@ #define MAX_DISTANCE (long)BROTLI_MAX_BACKWARD_LIMIT(18) -/* kHashMul32 multiplier has these properties: - * The multiplier must be odd. Otherwise we may lose the highest bit. - * No long streaks of ones or zeros. - * There is no effort to ensure that it is a prime, the oddity is enough - for this use. - * The number has been tuned heuristically against compression benchmarks. */ -static const uint32_t kHashMul32 = 0x1E35A7BD; - static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift) { const uint64_t h = (BROTLI_UNALIGNED_LOAD64LE(p) << 24) * kHashMul32; return (uint32_t)(h >> shift);
diff --git a/c/enc/compress_fragment_two_pass.c b/c/enc/compress_fragment_two_pass.c index a762679..cca4a19 100644 --- a/c/enc/compress_fragment_two_pass.c +++ b/c/enc/compress_fragment_two_pass.c
@@ -23,6 +23,7 @@ #include "entropy_encode.h" #include "fast_log.h" #include "find_match_length.h" +#include "hash_base.h" #include "write_bits.h" #if defined(__cplusplus) || defined(c_plusplus) @@ -31,14 +32,6 @@ #define MAX_DISTANCE (long)BROTLI_MAX_BACKWARD_LIMIT(18) -/* kHashMul32 multiplier has these properties: - * The multiplier must be odd. Otherwise we may lose the highest bit. - * No long streaks of ones or zeros. - * There is no effort to ensure that it is a prime, the oddity is enough - for this use. - * The number has been tuned heuristically against compression benchmarks. */ -static const uint32_t kHashMul32 = 0x1E35A7BD; - static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift, size_t length) { const uint64_t h =
diff --git a/c/enc/hash.h b/c/enc/hash.h index f210246..6462263 100644 --- a/c/enc/hash.h +++ b/c/enc/hash.h
@@ -22,6 +22,7 @@ #include "encoder_dict.h" #include "fast_log.h" #include "find_match_length.h" +#include "hash_base.h" #include "matching_tag_mask.h" #include "memory.h" #include "quality.h" @@ -72,23 +73,6 @@ int len_code_delta; /* == len_code - len */ } HasherSearchResult; -/* kHashMul32 multiplier has these properties: - * The multiplier must be odd. Otherwise we may lose the highest bit. - * No long streaks of ones or zeros. - * There is no effort to ensure that it is a prime, the oddity is enough - for this use. - * The number has been tuned heuristically against compression benchmarks. */ -static const uint32_t kHashMul32 = 0x1E35A7BD; -static const uint64_t kHashMul64 = - BROTLI_MAKE_UINT64_T(0x1FE35A7Bu, 0xD3579BD3u); - -static BROTLI_INLINE uint32_t Hash14(const uint8_t* data) { - uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; - /* The higher bits contain more mixture from the multiplication, - so we take our results from there. */ - return h >> (32 - 14); -} - static BROTLI_INLINE void PrepareDistanceCache( int* BROTLI_RESTRICT distance_cache, const int num_distances) { if (num_distances > 4) {
diff --git a/c/enc/hash_base.h b/c/enc/hash_base.h new file mode 100644 index 0000000..f10201d --- /dev/null +++ b/c/enc/hash_base.h
@@ -0,0 +1,40 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Basic common hash functions / constants. */ + +#ifndef THIRD_PARTY_BROTLI_ENC_HASH_BASE_H_ +#define THIRD_PARTY_BROTLI_ENC_HASH_BASE_H_ + +#include <brotli/types.h> + +#include "../common/platform.h" + +/* kHashMul32 multiplier has these properties: + * The multiplier must be odd. Otherwise we may lose the highest bit. + * No long streaks of ones or zeros. + * There is no effort to ensure that it is a prime, the oddity is enough + for this use. + * The number has been tuned heuristically against compression benchmarks. */ +static const uint32_t kHashMul32 = 0x1E35A7BD; +static const uint64_t kHashMul64 = + BROTLI_MAKE_UINT64_T(0x1FE35A7Bu, 0xD3579BD3u); + +static BROTLI_INLINE uint32_t Hash14(const uint8_t* data) { + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return h >> (32 - 14); +} + +static BROTLI_INLINE uint32_t Hash15(const uint8_t* data) { + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return h >> (32 - 15); +} + +#endif // THIRD_PARTY_BROTLI_ENC_HASH_BASE_H_
diff --git a/c/enc/static_dict.c b/c/enc/static_dict.c index 291d283..1504430 100644 --- a/c/enc/static_dict.c +++ b/c/enc/static_dict.c
@@ -6,23 +6,19 @@ #include "static_dict.h" +#include <brotli/types.h> + #include "../common/dictionary.h" #include "../common/platform.h" #include "../common/transform.h" #include "encoder_dict.h" #include "find_match_length.h" +#include "hash_base.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -static BROTLI_INLINE uint32_t Hash(const uint8_t* data) { - uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kDictHashMul32; - /* The higher bits contain more mixture from the multiplication, - so we take our results from there. */ - return h >> (32 - kDictNumBits); -} - static BROTLI_INLINE void AddMatch(size_t distance, size_t len, size_t len_code, uint32_t* matches) { uint32_t match = (uint32_t)((distance << 5) + len_code); @@ -96,7 +92,7 @@ } #endif /* BROTLI_EXPERIMENTAL */ { - size_t offset = dictionary->buckets[Hash(data)]; + size_t offset = dictionary->buckets[Hash15(data)]; BROTLI_BOOL end = !offset; while (!end) { DictWord w = dictionary->dict_words[offset++]; @@ -341,7 +337,7 @@ /* Transforms with prefixes " " and "." */ if (max_length >= 5 && (data[0] == ' ' || data[0] == '.')) { BROTLI_BOOL is_space = TO_BROTLI_BOOL(data[0] == ' '); - size_t offset = dictionary->buckets[Hash(&data[1])]; + size_t offset = dictionary->buckets[Hash15(&data[1])]; BROTLI_BOOL end = !offset; while (!end) { DictWord w = dictionary->dict_words[offset++]; @@ -436,7 +432,7 @@ if ((data[1] == ' ' && (data[0] == 'e' || data[0] == 's' || data[0] == ',')) || (data[0] == 0xC2 && data[1] == 0xA0)) { - size_t offset = dictionary->buckets[Hash(&data[2])]; + size_t offset = dictionary->buckets[Hash15(&data[2])]; BROTLI_BOOL end = !offset; while (!end) { DictWord w = dictionary->dict_words[offset++]; @@ -465,7 +461,7 @@ data[3] == 'e' && data[4] == ' ') || (data[0] == '.' && data[1] == 'c' && data[2] == 'o' && data[3] == 'm' && data[4] == '/')) { - size_t offset = dictionary->buckets[Hash(&data[5])]; + size_t offset = dictionary->buckets[Hash15(&data[5])]; BROTLI_BOOL end = !offset; while (!end) { DictWord w = dictionary->dict_words[offset++];
diff --git a/c/enc/static_dict_lut.h b/c/enc/static_dict_lut.h index a465ffd..0e4243c 100644 --- a/c/enc/static_dict_lut.h +++ b/c/enc/static_dict_lut.h
@@ -23,9 +23,6 @@ } DictWord; /* GENERATED CODE START */ -static const int kDictNumBits = 15; -static const uint32_t kDictHashMul32 = 0x1E35A7BD; - static const uint16_t kStaticDictionaryBuckets[32768] = { 1,0,0,0,0,0,0,0,0,3,6,0,0,0,0,0,20,0,0,0,21,0,22,0,0,0,0,0,0,0,0,23,0,0,25,0,29, 0,53,0,0,0,0,0,0,55,0,0,0,0,0,0,61,76,0,0,0,94,0,0,0,0,0,0,96,0,97,0,98,0,0,0,0,