mirror of
https://github.com/Z3Prover/z3
synced 2026-07-15 03:25:43 +00:00
Improve hash combining to avoid bitvector hash-table cliff
This commit is contained in:
parent
eddbc43f03
commit
0452362e9f
2 changed files with 20 additions and 5 deletions
|
|
@ -20,6 +20,7 @@ Revision History:
|
|||
#include "util/hashtable.h"
|
||||
#include "util/hash.h"
|
||||
#include "util/util.h"
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
typedef chashtable<int, int_hash, default_eq<int> > int_table;
|
||||
|
|
@ -172,6 +173,22 @@ static void tst6() {
|
|||
});
|
||||
}
|
||||
|
||||
static void tst_combine_hash_low_bits() {
|
||||
constexpr unsigned num_buckets = 1 << 12;
|
||||
constexpr unsigned mask = num_buckets - 1;
|
||||
std::array<bool, num_buckets> seen{};
|
||||
unsigned num_seen = 0;
|
||||
for (unsigned i = 0; i < (1u << 16); ++i) {
|
||||
unsigned h = combine_hash(i << 12, 0x12345678u);
|
||||
unsigned b = h & mask;
|
||||
if (!seen[b]) {
|
||||
seen[b] = true;
|
||||
++num_seen;
|
||||
}
|
||||
}
|
||||
ENSURE(num_seen > 3000);
|
||||
}
|
||||
|
||||
void tst_chashtable() {
|
||||
tst1();
|
||||
tst2();
|
||||
|
|
@ -180,5 +197,6 @@ void tst_chashtable() {
|
|||
tst4<dint_table>(1000,10);
|
||||
tst4<dint_table>(10000,10);
|
||||
tst4<int_table>(50000,1000);
|
||||
tst_combine_hash_low_bits();
|
||||
tst5();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,10 +57,8 @@ static inline unsigned hash_ull(unsigned long long a) {
|
|||
}
|
||||
|
||||
static inline unsigned combine_hash(unsigned h1, unsigned h2) {
|
||||
h2 -= h1; h2 ^= (h1 << 8);
|
||||
h1 -= h2; h2 ^= (h1 << 16);
|
||||
h2 -= h1; h2 ^= (h1 << 10);
|
||||
return h2;
|
||||
h1 ^= h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2);
|
||||
return hash_u(h1);
|
||||
}
|
||||
|
||||
static inline unsigned hash_u_u(unsigned a, unsigned b) {
|
||||
|
|
@ -256,4 +254,3 @@ static inline unsigned mk_mix(unsigned a, unsigned b, unsigned c) {
|
|||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue