Branch data Line data Source code
1 : : #ifndef HT_HASH_FUNCTION_H
2 : : #define HT_HASH_FUNCTION_H
3 : :
4 : : #include <stddef.h>
5 : :
6 : : #ifdef _MSC_VER
7 : : /* `inline` only advisory anyway. */
8 : : #pragma warning(disable: 4710) /* function not inlined */
9 : : #endif
10 : :
11 : : #ifndef HT_HASH_SEED
12 : : #define HT_HASH_SEED 0x2f693b52UL
13 : : #endif
14 : :
15 : : #ifndef HT_HASH_32
16 : :
17 : : #include "cmetrohash.h"
18 : :
19 : : static inline size_t ht_default_hash_function(const void *key, size_t len)
20 : : {
21 : : uint64_t out;
22 : :
23 : 3677 : cmetrohash64_1((const uint8_t *)key, len, HT_HASH_SEED, (uint8_t *)&out);
24 : 3677 : return (unsigned int)out;
25 : : }
26 : :
27 : : /* When using the pointer directly as a hash key. */
28 : : static inline size_t ht_ptr_hash_function(const void *key, size_t len)
29 : : {
30 : : /* MurmurHash3 64-bit finalizer */
31 : : uint64_t x;
32 : :
33 : : (void)len;
34 : :
35 : : x = ((uint64_t)(size_t)key) ^ (HT_HASH_SEED);
36 : :
37 : : x ^= x >> 33;
38 : : x *= 0xff51afd7ed558ccdULL;
39 : : x ^= x >> 33;
40 : : x *= 0xc4ceb9fe1a85ec53ULL;
41 : : x ^= x >> 33;
42 : : return (size_t)x;
43 : : }
44 : :
45 : : #else
46 : :
47 : : #include "PMurHash.h"
48 : :
49 : : static inline size_t ht_default_hash_function(const void *key, size_t len)
50 : : {
51 : : return (size_t)PMurHash32((HT_HASH_SEED), key, (int)len);
52 : : }
53 : :
54 : : /* When using the pointer directly as a hash key. */
55 : : static inline size_t ht_ptr_hash_function(const void *key, size_t len)
56 : : {
57 : : /* http://stackoverflow.com/a/12996028 */
58 : : size_t x;
59 : :
60 : : x = (size_t)key ^ (HT_HASH_SEED);
61 : :
62 : : x = ((x >> 16) ^ x) * 0x45d9f3bUL;
63 : : x = ((x >> 16) ^ x) * 0x45d9f3bUL;
64 : : x = ((x >> 16) ^ x);
65 : : return x;
66 : : }
67 : :
68 : : #endif /* HT_HASH_32 */
69 : :
70 : : /* Same as ht_ptr_hash_function but faster and better suited for low valued ints. */
71 : : static inline size_t ht_int_hash_function(const void *key, size_t len)
72 : : {
73 : : (void)len;
74 : 435 : return ((size_t)key ^ (HT_HASH_SEED)) * 2654435761UL;
75 : : }
76 : :
77 : : /* Bernsteins hash function, assumes string is zero terminated, len is ignored. */
78 : : static inline size_t ht_str_hash_function(const void *key, size_t len)
79 : : {
80 : : const unsigned char *str = key;
81 : : size_t hash = 5381 ^ (HT_HASH_SEED);
82 : : int c;
83 : :
84 : : (void)len;
85 : :
86 : : while ((c = *str++))
87 : : hash = ((hash << 5) + hash) ^ c; /* (hash * 33) xor c */
88 : :
89 : : return hash;
90 : : }
91 : :
92 : : /* Hashes at most len characters or until zero terminatation. */
93 : : static inline size_t ht_strn_hash_function(const void *key, size_t len)
94 : : {
95 : : const unsigned char *str = key;
96 : : size_t hash = 5381 ^ (HT_HASH_SEED);
97 : : int c;
98 : :
99 [ + + ][ + - ]: 2085 : while (--len && (c = *str++))
[ + + ][ + - ]
100 : 1825 : hash = ((hash << 5) + hash) ^ c; /* (hash * 33) xor c */
101 : :
102 : : return hash;
103 : : }
104 : :
105 : : #endif /* HT_HASH_FUNCTION_H */
|