1111
1212#define XXH_INLINE_ALL 1
1313#include " xxhash.h"
14+ #include " wyhash.h"
1415
1516template <typename K> struct GHashKey_xxHash32 { // K generic (class, primitive, pointer except const char* )
1617 // template <typename T=K> inline typename std::enable_if< std::is_trivial<T>::value, uint32_t>::type
@@ -40,6 +41,21 @@ template <> struct GHashKey_xxHash<const char*> {
4041 }
4142};
4243
44+
45+ template <typename K> struct GHashKey_wyHash { // K generic (class, primitive, pointer except const char* )
46+ // template <typename T=K> inline typename std::enable_if< std::is_trivial<T>::value, uint32_t>::type
47+ uint64_t operator ()(const K& s) const { // only works for trivial types!
48+ static_assert (std::is_trivial<K>::value, " Error: cannot use this for non-trivial types!\n " );
49+ return wyhash ((const void *) &s, sizeof (K), 0 , _wyp);
50+ }
51+ };
52+
53+ template <> struct GHashKey_wyHash <const char *> {
54+ inline uint32_t operator ()(const char * s) const {
55+ return wyhash (s, strlen (s), 0 , _wyp);
56+ }
57+ };
58+
4359template <typename K> struct GHashKey_Eq { // K is a type having the == operator defined
4460 inline bool operator ()(const K& x, const K& y) const {
4561 return (x == y); // requires == operator to be defined for K
@@ -52,8 +68,9 @@ template <> struct GHashKey_Eq<const char*> {
5268 }
5369};
5470
55- // GHashSet is never making a deep copy of the char* key, it only stores the pointer
56- template <typename K=const char *, class Hash =GHashKey_xxHash<K>, class Eq =GHashKey_Eq<K>, typename khInt_t=uint64_t >
71+ // GHashSet<KType> never makes a deep copy of a char* key, it only stores the pointer
72+ // - for pointer keys like char*, key allocation must be managed separately (and should always survive the GHashSet)
73+ template <typename K=const char *, class Hash =GHashKey_wyHash<K>, class Eq =GHashKey_Eq<K>, typename khInt_t=uint64_t >
5774 class GHashSet : public std ::conditional< is_char_ptr<K>::value,
5875 klib::KHashSetCached< K, Hash, Eq, khInt_t >,
5976 klib::KHashSet< K, Hash, Eq, khInt_t > >::type {
@@ -125,9 +142,9 @@ public:
125142
126143};
127144
128- // GStrSet always allocates a copy of each added string;
129- // if you don't want that (keys are shared) , just use GHashSet<const char*> instead
130- template <class Hash =GHashKey_xxHash <const char *>, class Eq =GHashKey_Eq<const char *>, typename khInt_t=uint64_t >
145+ // GStrSet always allocates a new copy of each added string;
146+ // if you don't want that, just use GHashSet<const char*> instead and manage the key allocation separately
147+ template <class Hash =GHashKey_wyHash <const char *>, class Eq =GHashKey_Eq<const char *>, typename khInt_t=uint64_t >
131148 class GStrSet : public GHashSet <const char *, Hash, Eq, khInt_t> {
132149 protected:
133150 const char * lastKey=NULL ;
@@ -183,9 +200,12 @@ template <class Hash=GHashKey_xxHash<const char*>, class Eq=GHashKey_Eq<const ch
183200
184201};
185202
186- // generic hash map where keys and values can be of any type
187- // Warning: keys are always copied (shared), including const char* keys -- no deep copy!
188- template <class K , class V , class Hash =GHashKey_xxHash<K>, class Eq =GHashKey_Eq<K>, typename khInt_t=uint64_t >
203+ // Generic hash map where keys and values can be of any type
204+ // Note: keys are always copied (shared) as simple value, there is no deep copy/allocation for pointers
205+ // so pointer keys must me managed separately
206+ // Note: pointer values are automatically deallocated on container destruction by default,
207+ // use GHashMap(false) to disable that when V is a pointer
208+ template <class K , class V , class Hash =GHashKey_wyHash<K>, class Eq =GHashKey_Eq<K>, typename khInt_t=uint64_t >
189209 class GHashMap :public std ::conditional< is_char_ptr<K>::value,
190210 klib::KHashMapCached< K, V, Hash, Eq, khInt_t>,
191211 klib::KHashMap< K, V, Hash, Eq, khInt_t> >::type {
@@ -227,7 +247,6 @@ public:
227247 return -1 ;
228248 }
229249
230-
231250 template <typename T=V> inline
232251 typename std::enable_if< std::is_pointer<T>::value, void >::type
233252 Clear () {
@@ -258,7 +277,6 @@ public:
258277 }
259278
260279 // -- these can be shared with GHash:
261-
262280 GHashMap (bool doFree=std::is_pointer<V>::value):freeItems(doFree) {
263281 static_assert (std::is_trivial<K>::value,
264282 " Error: cannot use this for non-trivial types!\n " );
@@ -361,13 +379,14 @@ public:
361379 return val;
362380 }
363381
364-
365-
366382 inline uint32_t Count () { return this ->count ; }
367383
368384};
369385
370- template <class V , class Hash =GHashKey_xxHash<const char *>, class Eq =GHashKey_Eq<const char *>, typename khInt_t=uint64_t >
386+ // GHash<VType>(doFree=true) -- basic string hashmap
387+ // Note: this hash map always makes a copy of the string key which can be costly
388+ // use GHashMap<const char*, VTYPE> for a faster alternative
389+ template <class V , class Hash =GHashKey_wyHash<const char *>, class Eq =GHashKey_Eq<const char *>, typename khInt_t=uint64_t >
371390 class GHash :public GHashMap <const char *, V, Hash, Eq, khInt_t> {
372391protected:
373392 const char * lastKey=NULL ;
0 commit comments