|
@@ -74,9 +74,9 @@ private:
|
|
return hash;
|
|
return hash;
|
|
}
|
|
}
|
|
|
|
|
|
- _FORCE_INLINE_ uint32_t _get_probe_length(uint32_t p_pos, uint32_t p_hash, uint32_t p_capacity) const {
|
|
|
|
- uint32_t original_pos = p_hash % p_capacity;
|
|
|
|
- return (p_pos - original_pos + p_capacity) % p_capacity;
|
|
|
|
|
|
+ static _FORCE_INLINE_ uint32_t _get_probe_length(const uint32_t p_pos, const uint32_t p_hash, const uint32_t p_capacity, const uint64_t p_capacity_inv) {
|
|
|
|
+ const uint32_t original_pos = fastmod(p_hash, p_capacity_inv, p_capacity);
|
|
|
|
+ return fastmod(p_pos - original_pos + p_capacity, p_capacity_inv, p_capacity);
|
|
}
|
|
}
|
|
|
|
|
|
bool _lookup_pos(const TKey &p_key, uint32_t &r_pos) const {
|
|
bool _lookup_pos(const TKey &p_key, uint32_t &r_pos) const {
|
|
@@ -84,9 +84,10 @@ private:
|
|
return false; // Failed lookups, no elements
|
|
return false; // Failed lookups, no elements
|
|
}
|
|
}
|
|
|
|
|
|
- uint32_t capacity = hash_table_size_primes[capacity_index];
|
|
|
|
|
|
+ const uint32_t capacity = hash_table_size_primes[capacity_index];
|
|
|
|
+ const uint64_t capacity_inv = hash_table_size_primes_inv[capacity_index];
|
|
uint32_t hash = _hash(p_key);
|
|
uint32_t hash = _hash(p_key);
|
|
- uint32_t pos = hash % capacity;
|
|
|
|
|
|
+ uint32_t pos = fastmod(hash, capacity_inv, capacity);
|
|
uint32_t distance = 0;
|
|
uint32_t distance = 0;
|
|
|
|
|
|
while (true) {
|
|
while (true) {
|
|
@@ -94,7 +95,7 @@ private:
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- if (distance > _get_probe_length(pos, hashes[pos], capacity)) {
|
|
|
|
|
|
+ if (distance > _get_probe_length(pos, hashes[pos], capacity, capacity_inv)) {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -103,17 +104,18 @@ private:
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
- pos = (pos + 1) % capacity;
|
|
|
|
|
|
+ pos = fastmod(pos + 1, capacity_inv, capacity);
|
|
distance++;
|
|
distance++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
uint32_t _insert_with_hash(uint32_t p_hash, uint32_t p_index) {
|
|
uint32_t _insert_with_hash(uint32_t p_hash, uint32_t p_index) {
|
|
- uint32_t capacity = hash_table_size_primes[capacity_index];
|
|
|
|
|
|
+ const uint32_t capacity = hash_table_size_primes[capacity_index];
|
|
|
|
+ const uint64_t capacity_inv = hash_table_size_primes_inv[capacity_index];
|
|
uint32_t hash = p_hash;
|
|
uint32_t hash = p_hash;
|
|
uint32_t index = p_index;
|
|
uint32_t index = p_index;
|
|
uint32_t distance = 0;
|
|
uint32_t distance = 0;
|
|
- uint32_t pos = hash % capacity;
|
|
|
|
|
|
+ uint32_t pos = fastmod(hash, capacity_inv, capacity);
|
|
|
|
|
|
while (true) {
|
|
while (true) {
|
|
if (hashes[pos] == EMPTY_HASH) {
|
|
if (hashes[pos] == EMPTY_HASH) {
|
|
@@ -124,7 +126,7 @@ private:
|
|
}
|
|
}
|
|
|
|
|
|
// Not an empty slot, let's check the probing length of the existing one.
|
|
// Not an empty slot, let's check the probing length of the existing one.
|
|
- uint32_t existing_probe_len = _get_probe_length(pos, hashes[pos], capacity);
|
|
|
|
|
|
+ uint32_t existing_probe_len = _get_probe_length(pos, hashes[pos], capacity, capacity_inv);
|
|
if (existing_probe_len < distance) {
|
|
if (existing_probe_len < distance) {
|
|
key_to_hash[index] = pos;
|
|
key_to_hash[index] = pos;
|
|
SWAP(hash, hashes[pos]);
|
|
SWAP(hash, hashes[pos]);
|
|
@@ -132,7 +134,7 @@ private:
|
|
distance = existing_probe_len;
|
|
distance = existing_probe_len;
|
|
}
|
|
}
|
|
|
|
|
|
- pos = (pos + 1) % capacity;
|
|
|
|
|
|
+ pos = fastmod(pos + 1, capacity_inv, capacity);
|
|
distance++;
|
|
distance++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -265,9 +267,10 @@ public:
|
|
uint32_t key_pos = pos;
|
|
uint32_t key_pos = pos;
|
|
pos = key_to_hash[pos]; //make hash pos
|
|
pos = key_to_hash[pos]; //make hash pos
|
|
|
|
|
|
- uint32_t capacity = hash_table_size_primes[capacity_index];
|
|
|
|
- uint32_t next_pos = (pos + 1) % capacity;
|
|
|
|
- while (hashes[next_pos] != EMPTY_HASH && _get_probe_length(next_pos, hashes[next_pos], capacity) != 0) {
|
|
|
|
|
|
+ const uint32_t capacity = hash_table_size_primes[capacity_index];
|
|
|
|
+ const uint64_t capacity_inv = hash_table_size_primes_inv[capacity_index];
|
|
|
|
+ uint32_t next_pos = fastmod(pos + 1, capacity_inv, capacity);
|
|
|
|
+ while (hashes[next_pos] != EMPTY_HASH && _get_probe_length(next_pos, hashes[next_pos], capacity, capacity_inv) != 0) {
|
|
uint32_t kpos = hash_to_key[pos];
|
|
uint32_t kpos = hash_to_key[pos];
|
|
uint32_t kpos_next = hash_to_key[next_pos];
|
|
uint32_t kpos_next = hash_to_key[next_pos];
|
|
SWAP(key_to_hash[kpos], key_to_hash[kpos_next]);
|
|
SWAP(key_to_hash[kpos], key_to_hash[kpos_next]);
|
|
@@ -275,7 +278,7 @@ public:
|
|
SWAP(hash_to_key[next_pos], hash_to_key[pos]);
|
|
SWAP(hash_to_key[next_pos], hash_to_key[pos]);
|
|
|
|
|
|
pos = next_pos;
|
|
pos = next_pos;
|
|
- next_pos = (pos + 1) % capacity;
|
|
|
|
|
|
+ next_pos = fastmod(pos + 1, capacity_inv, capacity);
|
|
}
|
|
}
|
|
|
|
|
|
hashes[pos] = EMPTY_HASH;
|
|
hashes[pos] = EMPTY_HASH;
|