8
8
#include <stdlib.h>
9
9
#include <string.h>
10
10
#include <sys/queue.h>
11
+ #include <time.h>
12
+
11
13
#ifdef WIN32
12
14
#include <vc_compat.h>
15
+ #else
16
+ #include <sys/time.h>
17
+ #include <unistd.h>
18
+ #endif
19
+
20
+ #if !(defined(_POSIX_TIMERS ) && _POSIX_TIMERS > 0 ) && defined(__APPLE__ )
21
+ #include <mach/mach_time.h>
13
22
#endif
14
23
15
24
#include "lsquic_hash.h"
16
- #include "lsquic_xxhash .h"
25
+ #include "lsquic_rapidhash .h"
17
26
18
27
TAILQ_HEAD (hels_head , lsquic_hash_elem );
19
28
@@ -26,15 +35,47 @@ struct lsquic_hash
26
35
qh_all ;
27
36
struct lsquic_hash_elem * qh_iter_next ;
28
37
int (* qh_cmp )(const void * , const void * , size_t );
29
- unsigned (* qh_hash )(const void * , size_t , unsigned seed );
38
+ uint64_t (* qh_hash )(const void * , size_t , uint64_t seed );
30
39
unsigned qh_count ;
31
40
unsigned qh_nbits ;
41
+ uint64_t qh_hash_seed ;
32
42
};
33
43
34
44
45
+ static uint64_t get_seed ()
46
+ {
47
+ static uint64_t seed = 0 ;
48
+ if (seed == 0 )
49
+ {
50
+ #if defined(WIN32 )
51
+ LARGE_INTEGER counter ;
52
+ QueryPerformanceCounter (& counter );
53
+ seed = counter .QuadPart ;
54
+ #elif defined(_POSIX_TIMERS ) && _POSIX_TIMERS > 0
55
+ struct timespec ts ;
56
+ (void ) clock_gettime (CLOCK_MONOTONIC , & ts );
57
+ seed = ts .tv_sec * 1000000000 + ts .tv_nsec ;
58
+ #elif defined(__APPLE__ )
59
+ seed = mach_absolute_time ();
60
+ #else
61
+ struct timeval tv ;
62
+ gettimeofday (& tv , NULL );
63
+ seed = tv .tv_sec * 1000000000 + tv .tv_usec * 1000 ;
64
+ #endif
65
+ srand (seed );
66
+ for (unsigned i = 0 ; i < (seed & 0xf ) + 1 ; ++ i )
67
+ {
68
+ seed = (seed << 8 ) | (seed >> 56 );
69
+ seed ^= rand ();
70
+ }
71
+ }
72
+ return seed ;
73
+ }
74
+
75
+
35
76
struct lsquic_hash *
36
77
lsquic_hash_create_ext (int (* cmp )(const void * , const void * , size_t ),
37
- unsigned (* hashf )(const void * , size_t , unsigned seed ))
78
+ uint64_t (* hashf )(const void * , size_t , uint64_t seed ))
38
79
{
39
80
struct hels_head * buckets ;
40
81
struct lsquic_hash * hash ;
@@ -62,14 +103,26 @@ lsquic_hash_create_ext (int (*cmp)(const void *, const void *, size_t),
62
103
hash -> qh_nbits = nbits ;
63
104
hash -> qh_iter_next = NULL ;
64
105
hash -> qh_count = 0 ;
106
+ hash -> qh_hash_seed = get_seed () ^ (uint64_t )hash
107
+ ^ ((uint64_t )buckets << 32 ) ^ rand ();
65
108
return hash ;
66
109
}
67
110
68
111
69
112
struct lsquic_hash *
70
113
lsquic_hash_create (void )
71
114
{
72
- return lsquic_hash_create_ext (memcmp , XXH32 );
115
+ return lsquic_hash_create_ext (memcmp , rapidhash_withSeed );
116
+ }
117
+
118
+
119
+ int
120
+ lsquic_hash_set_seed (struct lsquic_hash * hash , uint64_t seed )
121
+ {
122
+ if (hash -> qh_count > 0 )
123
+ return -1 ;
124
+ hash -> qh_hash_seed = seed ;
125
+ return 0 ;
73
126
}
74
127
75
128
@@ -119,7 +172,8 @@ struct lsquic_hash_elem *
119
172
lsquic_hash_insert (struct lsquic_hash * hash , const void * key ,
120
173
unsigned key_sz , void * value , struct lsquic_hash_elem * el )
121
174
{
122
- unsigned buckno , hash_val ;
175
+ uint64_t hash_val ;
176
+ unsigned buckno ;
123
177
124
178
if (el -> qhe_flags & QHE_HASHED )
125
179
return NULL ;
@@ -128,7 +182,7 @@ lsquic_hash_insert (struct lsquic_hash *hash, const void *key,
128
182
0 != lsquic_hash_grow (hash ))
129
183
return NULL ;
130
184
131
- hash_val = hash -> qh_hash (key , key_sz , ( uintptr_t ) hash );
185
+ hash_val = hash -> qh_hash (key , key_sz , hash -> qh_hash_seed );
132
186
buckno = BUCKNO (hash -> qh_nbits , hash_val );
133
187
TAILQ_INSERT_TAIL (& hash -> qh_all , el , qhe_next_all );
134
188
TAILQ_INSERT_TAIL (& hash -> qh_buckets [buckno ], el , qhe_next_bucket );
@@ -145,10 +199,11 @@ lsquic_hash_insert (struct lsquic_hash *hash, const void *key,
145
199
struct lsquic_hash_elem *
146
200
lsquic_hash_find (struct lsquic_hash * hash , const void * key , unsigned key_sz )
147
201
{
148
- unsigned buckno , hash_val ;
202
+ uint64_t hash_val ;
203
+ unsigned buckno ;
149
204
struct lsquic_hash_elem * el ;
150
205
151
- hash_val = hash -> qh_hash (key , key_sz , ( uintptr_t ) hash );
206
+ hash_val = hash -> qh_hash (key , key_sz , hash -> qh_hash_seed );
152
207
buckno = BUCKNO (hash -> qh_nbits , hash_val );
153
208
TAILQ_FOREACH (el , & hash -> qh_buckets [buckno ], qhe_next_bucket )
154
209
if (hash_val == el -> qhe_hash_val &&
0 commit comments