Skip to content

Commit d82c3e7

Browse files
committed
feat: add splitmix hash to hashmap
1 parent 53c5d90 commit d82c3e7

2 files changed

Lines changed: 27 additions & 4 deletions

File tree

src/alfred/data_structure/hashmap.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef AFDS_HASHMAP
22
#define AFDS_HASHMAP
33

4+
#include "splitmix.hpp"
45
#include <utility>
56
#include <vector>
67

@@ -12,6 +13,7 @@ struct HashMap { // HashMap for integer keys.
1213
V val;
1314
u32 ne;
1415
};
16+
Splitmix<K> hash;
1517
u32 lim, mask, tot;
1618
std::vector<u32> fi;
1719
std::vector<Node> e;
@@ -22,7 +24,7 @@ struct HashMap { // HashMap for integer keys.
2224
mask = lim - 1, e.resize(sz);
2325
}
2426
inline void inc(K x, V delta) {
25-
u32 u = x & mask;
27+
u32 u = hash(x) & mask;
2628
for (u32 i = fi[u]; i; i = e[i].ne) {
2729
if (e[i].key == x) {
2830
e[i].val += delta;
@@ -32,7 +34,7 @@ struct HashMap { // HashMap for integer keys.
3234
e[++tot] = {x, V() + delta, fi[u]}, fi[u] = tot;
3335
}
3436
inline void set(K x, V v) {
35-
u32 u = x & mask;
37+
u32 u = hash(x) & mask;
3638
for (u32 i = fi[u]; i; i = e[i].ne) {
3739
if (e[i].key == x) {
3840
e[i].val = v;
@@ -43,15 +45,15 @@ struct HashMap { // HashMap for integer keys.
4345
}
4446
// this method does not create new element, returns V() by default.
4547
inline V get(K x) {
46-
u32 u = x & mask;
48+
u32 u = hash(x) & mask;
4749
for (u32 i = fi[u]; i; i = e[i].ne) {
4850
if (e[i].key == x) return e[i].val;
4951
}
5052
return V();
5153
}
5254
// this method creates new element.
5355
inline V &operator[](K x) {
54-
u32 u = x & mask;
56+
u32 u = hash(x) & mask;
5557
for (u32 i = fi[u]; i; i = e[i].ne) {
5658
if (e[i].key == x) return e[i].val;
5759
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef AFDS_SPLITMIX
2+
#define AFDS_SPLITMIX
3+
4+
template <class T>
5+
struct Splitmix {
6+
inline T operator()(T x) {
7+
if constexpr (sizeof(T) == 8) {
8+
T z = (x += 0x9e3779b97f4a7c15);
9+
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
10+
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
11+
return z ^ (z >> 31);
12+
} else {
13+
T z = (x += 0x9e3779b9);
14+
z = (z ^ (z >> 16)) * 0x85ebca6b;
15+
z = (z ^ (z >> 13)) * 0xc2b2ae35;
16+
return z ^ (z >> 16);
17+
}
18+
}
19+
};
20+
21+
#endif

0 commit comments

Comments
 (0)