Skip to content

Commit ff49316

Browse files
committed
Improve secondary hashing
1 parent 4a85d56 commit ff49316

3 files changed

Lines changed: 27 additions & 22 deletions

File tree

bench/src/uhash_bench.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
#include "khashl.h"
99
#include "ulib.h"
10+
#include <stdint.h>
1011

11-
#define klib_hash_int(x) ((khint_t)(x))
12-
UHASH_INIT(uint, ulib_uint, UHASH_VAL_IGNORE, ulib_hash_int, ulib_eq)
13-
KHASHL_SET_INIT(KH_LOCAL, kh_uint_t, kh_uint, ulib_uint, klib_hash_int, ulib_eq)
12+
UHASH_INIT(uint, uint32_t, UHASH_VAL_IGNORE, ulib_hash_int32, ulib_eq)
13+
KHASHL_SET_INIT(KH_LOCAL, kh_uint_t, kh_uint, uint32_t, kh_hash_uint32, ulib_eq)
1414

1515
enum {
1616
SEED = 31,
@@ -26,9 +26,9 @@ typedef struct HashTable {
2626
char const *name;
2727
void *(*init)(void);
2828
void (*deinit)(void *);
29-
bool (*insert)(void *, ulib_uint);
30-
bool (*contains)(void *, ulib_uint);
31-
bool (*remove)(void *, ulib_uint);
29+
bool (*insert)(void *, uint32_t);
30+
bool (*contains)(void *, uint32_t);
31+
bool (*remove)(void *, uint32_t);
3232
} HashTable;
3333

3434
// UHash
@@ -44,15 +44,15 @@ static void bench_uhash_deinit(void *h) {
4444
ulib_free(h);
4545
}
4646

47-
static bool bench_uhash_insert(void *h, ulib_uint key) {
47+
static bool bench_uhash_insert(void *h, uint32_t key) {
4848
return uhset_insert(uint, h, key);
4949
}
5050

51-
static bool bench_uhash_contains(void *h, ulib_uint key) {
51+
static bool bench_uhash_contains(void *h, uint32_t key) {
5252
return uhash_contains(uint, h, key);
5353
}
5454

55-
static bool bench_uhash_remove(void *h, ulib_uint key) {
55+
static bool bench_uhash_remove(void *h, uint32_t key) {
5656
return uhset_remove(uint, h, key);
5757
}
5858

@@ -77,18 +77,18 @@ static void bench_khashl_deinit(void *h) {
7777
kh_uint_destroy(h);
7878
}
7979

80-
static bool bench_khashl_insert(void *h, ulib_uint key) {
80+
static bool bench_khashl_insert(void *h, uint32_t key) {
8181
int ret;
8282
kh_uint_put(h, key, &ret);
8383
return !!ret;
8484
}
8585

86-
static bool bench_khashl_contains(void *h, ulib_uint key) {
86+
static bool bench_khashl_contains(void *h, uint32_t key) {
8787
kh_uint_t *ht = h;
8888
return kh_uint_get(ht, key) != kh_end(ht);
8989
}
9090

91-
static bool bench_khashl_remove(void *h, ulib_uint key) {
91+
static bool bench_khashl_remove(void *h, uint32_t key) {
9292
kh_uint_t *ht = h;
9393
khint_t i = kh_uint_get(ht, key);
9494
if (i != kh_end(ht)) {
@@ -120,7 +120,7 @@ static void bench_hash(HashTable *table, ulib_uint size) {
120120
ulib_uint count = 0;
121121
ulog_perf("insert") {
122122
for (ulib_uint i = 0; i < size; ++i) {
123-
ulib_uint key = urand_range(0, size >> 1);
123+
uint32_t key = (uint32_t)urand_range(0, size >> 1);
124124
if (table->insert(h, key)) count++;
125125
}
126126
}
@@ -129,15 +129,15 @@ static void bench_hash(HashTable *table, ulib_uint size) {
129129
count = 0;
130130
ulog_perf("get") {
131131
for (ulib_uint i = 0; i < size; ++i) {
132-
ulib_uint key = urand_range(0, size >> 1);
132+
uint32_t key = (uint32_t)urand_range(0, size >> 1);
133133
if (table->contains(h, key)) count++;
134134
}
135135
}
136136
ulog_debug("Found: %" ULIB_UINT_FMT, count);
137137

138138
ulog_perf("remove") {
139139
for (ulib_uint i = 0; i < size; ++i) {
140-
ulib_uint key = urand_range(0, size >> 1);
140+
uint32_t key = (uint32_t)urand_range(0, size >> 1);
141141
if (table->remove(h, key)) count++;
142142
}
143143
}

include/uhash.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "unumber.h"
2424
#include "uutils.h"
2525
#include "uwarning.h"
26+
#include <limits.h>
2627
#include <string.h>
2728

2829
ULIB_BEGIN_DECLS
@@ -158,17 +159,21 @@ ULIB_CONST ULIB_INLINE ulib_uint p_uhash_upper_bound_default(ulib_uint buckets)
158159
#if defined(ULIB_TINY)
159160
ULIB_CONST ULIB_INLINE ulib_uint p_uhash_fib(ulib_uint hash, ulib_byte bits) {
160161
ulib_assert(bits);
161-
return (ulib_uint)((unsigned)hash * 40503U) >> (16U - bits);
162+
unsigned h = (unsigned)hash;
163+
unsigned const shift = 16U - bits;
164+
return (ulib_uint)((h ^ (h >> shift)) * 40503U) >> shift;
162165
}
163166
#elif defined(ULIB_HUGE)
164167
ULIB_CONST ULIB_INLINE ulib_uint p_uhash_fib(ulib_uint hash, ulib_byte bits) {
165168
ulib_assert(bits);
166-
return hash * (ulib_uint)11400714819323198485LLU >> (64U - bits);
169+
ulib_uint const shift = 64U - bits;
170+
return (hash ^ (hash >> shift)) * (ulib_uint)11400714819323198485LLU >> shift;
167171
}
168172
#else
169173
ULIB_CONST ULIB_INLINE ulib_uint p_uhash_fib(ulib_uint hash, ulib_byte bits) {
170174
ulib_assert(bits);
171-
return hash * (ulib_uint)2654435769LU >> (32U - bits);
175+
ulib_uint const shift = 32U - bits;
176+
return (hash ^ (hash >> shift)) * (ulib_uint)2654435769LU >> shift;
172177
}
173178
#endif
174179

include/uhash_func.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,16 @@ ULIB_BEGIN_DECLS
7979
ULIB_CONST
8080
ULIB_INLINE
8181
ulib_uint p_ulib_hash_int32(uint32_t key) {
82-
return (ulib_uint)(key >> 17U ^ key ^ key << 6U);
82+
return (ulib_uint)key ^ (ulib_uint)(key >> 16U);
8383
}
8484

8585
#define ulib_hash_int32(key) p_ulib_hash_int32((uint32_t)(key))
8686

8787
ULIB_CONST
8888
ULIB_INLINE
8989
ulib_uint p_ulib_hash_int64(uint64_t key) {
90-
return (ulib_uint)(key >> 49U ^ key >> 33U ^ key >> 17U ^ key ^ key << 6U ^ key << 23U ^
91-
key << 39U);
90+
return (ulib_uint)key ^ (ulib_uint)(key >> 16U) ^ (ulib_uint)(key >> 32U) ^
91+
(ulib_uint)(key >> 48U);
9292
}
9393

9494
#define ulib_hash_int64(key) p_ulib_hash_int64((uint32_t)(key))
@@ -105,7 +105,7 @@ ulib_uint p_ulib_hash_int64(uint64_t key) {
105105
ULIB_CONST
106106
ULIB_INLINE
107107
ulib_uint p_ulib_hash_int64(uint64_t key) {
108-
return (ulib_uint)(key >> 33U ^ key ^ key << 11U);
108+
return (ulib_uint)key ^ (ulib_uint)(key >> 32U);
109109
}
110110

111111
#define ulib_hash_int64(key) p_ulib_hash_int64((uint64_t)(key))

0 commit comments

Comments
 (0)