mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
AK: Use a full-period xorshift PRNG for double_hash
The previous implementation had some pretty short cycles and two fixed points (1711463637 and 2389024350). If two keys hashed to one of these values insertions and lookups would loop forever. This version is based on a standard xorshift PRNG with period 2**32-1. The all-zero state is usually forbidden, so we insert it into the cycle at an arbitrary location.
This commit is contained in:
parent
aa6e5e8cdc
commit
55a7738837
Notes:
sideshowbarker
2024-07-17 21:29:51 +09:00
Author: https://github.com/Schlufi 🔰 Commit: https://github.com/SerenityOS/serenity/commit/55a77388373 Pull-request: https://github.com/SerenityOS/serenity/pull/11671 Reviewed-by: https://github.com/kleinesfilmroellchen ✅
2 changed files with 12 additions and 7 deletions
|
@ -21,11 +21,15 @@ constexpr unsigned int_hash(u32 key)
|
|||
|
||||
constexpr unsigned double_hash(u32 key)
|
||||
{
|
||||
key = ~key + (key >> 23);
|
||||
key ^= (key << 12);
|
||||
key ^= (key >> 7);
|
||||
key ^= (key << 2);
|
||||
key ^= (key >> 20);
|
||||
const unsigned magic = 0xBA5EDB01;
|
||||
if (key == magic)
|
||||
return 0u;
|
||||
if (key == 0u)
|
||||
key = magic;
|
||||
|
||||
key ^= key << 13;
|
||||
key ^= key >> 17;
|
||||
key ^= key << 5;
|
||||
return key;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,9 @@ TEST_CASE(int_hash)
|
|||
|
||||
TEST_CASE(double_hash)
|
||||
{
|
||||
static_assert(double_hash(42) == 524450u);
|
||||
static_assert(double_hash(0) == 12384u);
|
||||
static_assert(double_hash(666) == 171644115u);
|
||||
static_assert(double_hash(0) == 1189591134u);
|
||||
static_assert(double_hash(0xBA5EDB01) == 0u);
|
||||
}
|
||||
|
||||
TEST_CASE(pair_int_hash)
|
||||
|
|
Loading…
Reference in a new issue