| 28 |
28 |
| 29 #include "cx/hash_key.h" |
29 #include "cx/hash_key.h" |
| 30 #include <string.h> |
30 #include <string.h> |
| 31 |
31 |
| 32 void cx_hash_murmur(CxHashKey *key) { |
32 void cx_hash_murmur(CxHashKey *key) { |
| 33 unsigned char const *data = key->data; |
33 const unsigned char *data = key->data; |
| 34 if (data == NULL) { |
34 if (data == NULL) { |
| 35 // extension: special value for NULL |
35 // extension: special value for NULL |
| 36 key->hash = 1574210520u; |
36 key->hash = 1574210520u; |
| 37 return; |
37 return; |
| 38 } |
38 } |
| 39 size_t len = key->len; |
39 size_t len = key->len; |
| 40 |
40 |
| 41 unsigned m = 0x5bd1e995; |
41 unsigned m = 0x5bd1e995; |
| 42 unsigned r = 24; |
42 unsigned r = 24; |
| 43 unsigned h = 25 ^ len; |
43 unsigned h = 25 ^ (unsigned) len; |
| 44 unsigned i = 0; |
44 unsigned i = 0; |
| 45 while (len >= 4) { |
45 while (len >= 4) { |
| 46 unsigned k = data[i + 0] & 0xFF; |
46 unsigned k = data[i + 0] & 0xFF; |
| 47 k |= (data[i + 1] & 0xFF) << 8; |
47 k |= (data[i + 1] & 0xFF) << 8; |
| 48 k |= (data[i + 2] & 0xFF) << 16; |
48 k |= (data[i + 2] & 0xFF) << 16; |
| 79 h ^= h >> 15; |
79 h ^= h >> 15; |
| 80 |
80 |
| 81 key->hash = h; |
81 key->hash = h; |
| 82 } |
82 } |
| 83 |
83 |
| 84 CxHashKey cx_hash_key_str(char const *str) { |
84 CxHashKey cx_hash_key_str(const char *str) { |
| 85 CxHashKey key; |
85 CxHashKey key; |
| 86 key.data = str; |
86 key.data = str; |
| 87 key.len = str == NULL ? 0 : strlen(str); |
87 key.len = str == NULL ? 0 : strlen(str); |
| 88 cx_hash_murmur(&key); |
88 cx_hash_murmur(&key); |
| 89 return key; |
89 return key; |
| 90 } |
90 } |
| 91 |
91 |
| 92 CxHashKey cx_hash_key_bytes( |
92 CxHashKey cx_hash_key_bytes( |
| 93 unsigned char const *bytes, |
93 const unsigned char *bytes, |
| 94 size_t len |
94 size_t len |
| 95 ) { |
95 ) { |
| 96 CxHashKey key; |
96 CxHashKey key; |
| 97 key.data = bytes; |
97 key.data = bytes; |
| 98 key.len = len; |
98 key.len = len; |
| 99 cx_hash_murmur(&key); |
99 cx_hash_murmur(&key); |
| 100 return key; |
100 return key; |
| 101 } |
101 } |
| 102 |
102 |
| 103 CxHashKey cx_hash_key( |
103 CxHashKey cx_hash_key( |
| 104 void const *obj, |
104 const void *obj, |
| 105 size_t len |
105 size_t len |
| 106 ) { |
106 ) { |
| 107 CxHashKey key; |
107 CxHashKey key; |
| 108 key.data = obj; |
108 key.data = obj; |
| 109 key.len = len; |
109 key.len = len; |