88#include  <stdlib.h> 
99#include  <string.h> 
1010#include  <sys/queue.h> 
11+ #include  <time.h> 
12+ 1113#ifdef  WIN32 
1214#include  <vc_compat.h> 
15+ #else 
16+ #include  <sys/time.h> 
17+ #include  <unistd.h> 
1318#endif 
1419
1520#include  "lsquic_hash.h" 
16- #include  "lsquic_xxhash .h" 
21+ #include  "lsquic_rapidhash .h" 
1722
1823TAILQ_HEAD (hels_head , lsquic_hash_elem );
1924
@@ -26,15 +31,47 @@ struct lsquic_hash
2631 qh_all ;
2732 struct  lsquic_hash_elem  * qh_iter_next ;
2833 int  (* qh_cmp )(const  void  * , const  void  * , size_t );
29-  unsigned  (* qh_hash )(const  void  * , size_t , unsigned  seed );
34+  uint64_t  (* qh_hash )(const  void  * , size_t , uint64_t  seed );
3035 unsigned  qh_count ;
3136 unsigned  qh_nbits ;
37+  uint64_t  qh_hash_seed ;
3238};
3339
3440
41+ static  uint64_t  get_seed ()
42+ {
43+  static  uint64_t  seed  =  0 ;
44+  if  (seed  ==  0 )
45+  {
46+ #if  defined(WIN32 )
47+  LARGE_INTEGER  counter ;
48+  QueryPerformanceCounter (& counter );
49+  seed  =  counter .QuadPart ;
50+ #elif  defined(_POSIX_TIMERS ) &&  _POSIX_TIMERS  >  0 
51+  struct  timespec  ts ;
52+  (void ) clock_gettime (CLOCK_MONOTONIC , & ts );
53+  seed  =  ts .tv_sec  *  1000000000  +  ts .tv_nsec ;
54+ #elif  defined(__APPLE__ )
55+  seed  =  mach_absolute_time ();
56+ #else 
57+  struct  timeval  tv ;
58+  gettimeofday (& tv , NULL );
59+  seed  =  tv .tv_sec  *  1000000000  +  tv .tv_usec  *  1000 ;
60+ #endif 
61+  srand (seed );
62+  for (unsigned  i  =  0 ; i  <  (seed  &  0xf ) +  1 ; ++ i )
63+  {
64+  seed  =  (seed  << 8 ) | (seed  >> 56 );
65+  seed  ^= rand ();
66+  }
67+  }
68+  return  seed ;
69+ }
70+ 71+ 3572struct  lsquic_hash  * 
3673lsquic_hash_create_ext  (int  (* cmp )(const  void  * , const  void  * , size_t ),
37-  unsigned  (* hashf )(const  void  * , size_t , unsigned  seed ))
74+  uint64_t  (* hashf )(const  void  * , size_t , uint64_t  seed ))
3875{
3976 struct  hels_head  * buckets ;
4077 struct  lsquic_hash  * hash ;
@@ -62,14 +99,26 @@ lsquic_hash_create_ext (int (*cmp)(const void *, const void *, size_t),
6299 hash -> qh_nbits  =  nbits ;
63100 hash -> qh_iter_next  =  NULL ;
64101 hash -> qh_count  =  0 ;
102+  hash -> qh_hash_seed  =  get_seed () ^ (uint64_t )hash 
103+  ^ ((uint64_t )buckets  << 32 ) ^ rand ();
65104 return  hash ;
66105}
67106
68107
69108struct  lsquic_hash  * 
70109lsquic_hash_create  (void )
71110{
72-  return  lsquic_hash_create_ext (memcmp , XXH32 );
111+  return  lsquic_hash_create_ext (memcmp , rapidhash_withSeed );
112+ }
113+ 114+ 115+ int 
116+ lsquic_hash_set_seed  (struct  lsquic_hash  *  hash , uint64_t  seed )
117+ {
118+  if  (hash -> qh_count  >  0 )
119+  return  -1 ;
120+  hash -> qh_hash_seed  =  seed ;
121+  return  0 ;
73122}
74123
75124
@@ -119,7 +168,8 @@ struct lsquic_hash_elem *
119168lsquic_hash_insert  (struct  lsquic_hash  * hash , const  void  * key ,
120169 unsigned  key_sz , void  * value , struct  lsquic_hash_elem  * el )
121170{
122-  unsigned  buckno , hash_val ;
171+  uint64_t  hash_val ;
172+  unsigned  buckno ;
123173
124174 if  (el -> qhe_flags  &  QHE_HASHED )
125175 return  NULL ;
@@ -128,7 +178,7 @@ lsquic_hash_insert (struct lsquic_hash *hash, const void *key,
128178 0  !=  lsquic_hash_grow (hash ))
129179 return  NULL ;
130180
131-  hash_val  =  hash -> qh_hash (key , key_sz , ( uintptr_t )  hash );
181+  hash_val  =  hash -> qh_hash (key , key_sz , hash -> qh_hash_seed );
132182 buckno  =  BUCKNO (hash -> qh_nbits , hash_val );
133183 TAILQ_INSERT_TAIL (& hash -> qh_all , el , qhe_next_all );
134184 TAILQ_INSERT_TAIL (& hash -> qh_buckets [buckno ], el , qhe_next_bucket );
@@ -145,10 +195,11 @@ lsquic_hash_insert (struct lsquic_hash *hash, const void *key,
145195struct  lsquic_hash_elem  * 
146196lsquic_hash_find  (struct  lsquic_hash  * hash , const  void  * key , unsigned  key_sz )
147197{
148-  unsigned  buckno , hash_val ;
198+  uint64_t  hash_val ;
199+  unsigned  buckno ;
149200 struct  lsquic_hash_elem  * el ;
150201
151-  hash_val  =  hash -> qh_hash (key , key_sz , ( uintptr_t )  hash );
202+  hash_val  =  hash -> qh_hash (key , key_sz , hash -> qh_hash_seed );
152203 buckno  =  BUCKNO (hash -> qh_nbits , hash_val );
153204 TAILQ_FOREACH (el , & hash -> qh_buckets [buckno ], qhe_next_bucket )
154205 if  (hash_val  ==  el -> qhe_hash_val  && 
0 commit comments