From f8b41ed1c5214061549cb16b98f9d60a6efa83e0 Mon Sep 17 00:00:00 2001 From: "L. Pereira" Date: Thu, 9 May 2024 19:31:08 -0700 Subject: [PATCH] Avoid a mod in the status lookup perfect hash table --- src/bin/tools/statuslookupgen.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/bin/tools/statuslookupgen.c b/src/bin/tools/statuslookupgen.c index 5a73892a0..37070a747 100644 --- a/src/bin/tools/statuslookupgen.c +++ b/src/bin/tools/statuslookupgen.c @@ -13,6 +13,11 @@ static inline uint32_t rotate(uint32_t v, int n) return v << (32 - n) | v >> n; } +static inline uint32_t map_0_to_n(uint32_t value, uint32_t n) +{ + return (uint32_t)(((uint64_t)value * (uint64_t)n) >> 32); +} + int main(void) { uint32_t max_key = 0; @@ -49,7 +54,8 @@ int main(void) int set_bits = 0; for (int key = 0; key < N_KEYS; key++) { - uint32_t k = rotate((uint32_t)keys[key] - subtract, rot) % mod; + uint32_t k = map_0_to_n( + rotate((uint32_t)keys[key] - subtract, rot), mod); if (set & 1ull<> %d)) %% %d];\n", 32 - best_rot, best_rot, best_mod); + printf(" const uint32_t hash = (k << %d) | (k >> %d);\n", 32 - best_rot, best_rot); + printf(" const char *ret = table[(uint32_t)(((uint64_t)hash * (uint64_t)%d) >> 32)];\n", best_mod); printf(" assert((uint32_t)(ret[2] - '0') == ((uint32_t)status %% 10));\n"); printf(" assert((uint32_t)(ret[1] - '0') == ((uint32_t)(status / 10) %% 10));\n"); printf(" assert((uint32_t)(ret[0] - '0') == ((uint32_t)(status / 100) %% 10));\n"); printf(" return ret;\n"); printf("}\n"); - }