| 76 * @note If @c data is @c NULL, the hash is defined as 1574210520. |
72 * @note If @c data is @c NULL, the hash is defined as 1574210520. |
| 77 * |
73 * |
| 78 * @param key the key, the hash shall be computed for |
74 * @param key the key, the hash shall be computed for |
| 79 * @see cx_hash_key() |
75 * @see cx_hash_key() |
| 80 */ |
76 */ |
| 81 cx_attr_nonnull |
77 CX_EXTERN CX_NONNULL |
| 82 CX_EXPORT void cx_hash_murmur(CxHashKey *key); |
78 void cx_hash_murmur(CxHashKey *key); |
| 83 |
79 |
| 84 /** |
80 /** |
| 85 * Mixes up a 32-bit integer to be used as a hash. |
81 * Mixes up a 32-bit integer to be used as a hash. |
| 86 * |
82 * |
| 87 * This function produces no collisions and has a good statistical distribution. |
83 * This function produces no collisions and has a good statistical distribution. |
| 88 * |
84 * |
| 89 * @param x the integer |
85 * @param x the integer |
| 90 * @return the hash |
86 * @return the hash |
| 91 */ |
87 */ |
| 92 CX_INLINE uint32_t cx_hash_u32(uint32_t x) { |
88 CX_INLINE |
| |
89 uint32_t cx_hash_u32(uint32_t x) { |
| 93 x = ((x >> 16) ^ x) * 0x45d9f3bu; |
90 x = ((x >> 16) ^ x) * 0x45d9f3bu; |
| 94 x = ((x >> 16) ^ x) * 0x45d9f3bu; |
91 x = ((x >> 16) ^ x) * 0x45d9f3bu; |
| 95 x = (x >> 16) ^ x; |
92 x = (x >> 16) ^ x; |
| 96 return x; |
93 return x; |
| 97 } |
94 } |
| 120 * |
118 * |
| 121 * @param obj a pointer to an arbitrary object |
119 * @param obj a pointer to an arbitrary object |
| 122 * @param len the length of the object in memory |
120 * @param len the length of the object in memory |
| 123 * @return the hash key |
121 * @return the hash key |
| 124 */ |
122 */ |
| 125 cx_attr_nodiscard |
123 CX_EXTERN CX_NODISCARD CX_ACCESS_R(1, 2) |
| 126 cx_attr_access_r(1, 2) |
124 CxHashKey cx_hash_key(const void *obj, size_t len); |
| 127 CX_EXPORT CxHashKey cx_hash_key(const void *obj, size_t len); |
|
| 128 |
125 |
| 129 /** |
126 /** |
| 130 * Computes a hash key from a 32-bit integer. |
127 * Computes a hash key from a 32-bit integer. |
| 131 * |
128 * |
| 132 * @param x the integer |
129 * @param x the integer |
| 133 * @return the hash key |
130 * @return the hash key |
| 134 */ |
131 */ |
| 135 cx_attr_nodiscard |
132 CX_NODISCARD CX_INLINE |
| 136 CX_INLINE CxHashKey cx_hash_key_u32(uint32_t x) { |
133 CxHashKey cx_hash_key_u32(uint32_t x) { |
| 137 CxHashKey key; |
134 CxHashKey key; |
| 138 key.data = NULL; |
135 key.data = NULL; |
| 139 key.len = 0; |
136 key.len = 0; |
| 140 key.hash = cx_hash_u32(x); |
137 key.hash = cx_hash_u32(x); |
| 141 return key; |
138 return key; |
| 162 * The string needs to be zero-terminated. |
159 * The string needs to be zero-terminated. |
| 163 * |
160 * |
| 164 * @param str the string |
161 * @param str the string |
| 165 * @return the hash key |
162 * @return the hash key |
| 166 */ |
163 */ |
| 167 cx_attr_nodiscard cx_attr_cstr_arg(1) |
164 CX_NODISCARD CX_CSTR_ARG(1) CX_INLINE |
| 168 CX_INLINE CxHashKey cx_hash_key_str(const char *str) { |
165 CxHashKey cx_hash_key_str(const char *str) { |
| 169 return cx_hash_key((const void*)str, str == NULL ? 0 : strlen(str)); |
166 return cx_hash_key((const void*)str, str == NULL ? 0 : strlen(str)); |
| 170 } |
167 } |
| 171 |
168 |
| 172 /** |
169 /** |
| 173 * Computes a hash key from a string. |
170 * Computes a hash key from a string. |
| 178 * The string needs to be zero-terminated. |
175 * The string needs to be zero-terminated. |
| 179 * |
176 * |
| 180 * @param str the string |
177 * @param str the string |
| 181 * @return the hash key |
178 * @return the hash key |
| 182 */ |
179 */ |
| 183 cx_attr_nodiscard cx_attr_cstr_arg(1) |
180 CX_NODISCARD CX_CSTR_ARG(1) CX_INLINE |
| 184 CX_INLINE CxHashKey cx_hash_key_ustr(const unsigned char *str) { |
181 CxHashKey cx_hash_key_ustr(const unsigned char *str) { |
| 185 return cx_hash_key((const void*)str, str == NULL ? 0 : strlen((const char*)str)); |
182 return cx_hash_key((const void*)str, str == NULL ? 0 : strlen((const char*)str)); |
| 186 } |
183 } |
| 187 |
184 |
| 188 /** |
185 /** |
| 189 * Computes a hash key from a byte array. |
186 * Computes a hash key from a byte array. |
| 190 * |
187 * |
| 191 * @param bytes the array |
188 * @param bytes the array |
| 192 * @param len the length |
189 * @param len the length |
| 193 * @return the hash key |
190 * @return the hash key |
| 194 */ |
191 */ |
| 195 cx_attr_nodiscard cx_attr_access_r(1, 2) |
192 CX_NODISCARD CX_ACCESS_R(1, 2) CX_INLINE |
| 196 CX_INLINE CxHashKey cx_hash_key_bytes(const unsigned char *bytes, size_t len) { |
193 CxHashKey cx_hash_key_bytes(const unsigned char *bytes, size_t len) { |
| 197 return cx_hash_key((const void*)bytes, len); |
194 return cx_hash_key((const void*)bytes, len); |
| 198 } |
195 } |
| 199 |
196 |
| 200 /** |
197 /** |
| 201 * Computes a hash key from a UCX string. |
198 * Computes a hash key from a UCX string. |
| 202 * |
199 * |
| 203 * @param str the string |
200 * @param str the string |
| 204 * @return the hash key |
201 * @return the hash key |
| 205 */ |
202 */ |
| 206 cx_attr_nodiscard |
203 CX_NODISCARD CX_INLINE |
| 207 CX_INLINE CxHashKey cx_hash_key_cxstr(cxstring str) { |
204 CxHashKey cx_hash_key_cxstr(cxstring str) { |
| 208 return cx_hash_key((void*)str.ptr, str.length); |
205 return cx_hash_key((void*)str.ptr, str.length); |
| 209 } |
206 } |
| 210 |
207 |
| 211 /** |
208 /** |
| 212 * Computes a hash key from a UCX string. |
209 * Computes a hash key from a UCX string. |
| 213 * |
210 * |
| 214 * @param str the string |
211 * @param str the string |
| 215 * @return the hash key |
212 * @return the hash key |
| 216 */ |
213 */ |
| 217 cx_attr_nodiscard |
214 CX_NODISCARD CX_INLINE |
| 218 CX_INLINE CxHashKey cx_hash_key_mutstr(cxmutstr str) { |
215 CxHashKey cx_hash_key_mutstr(cxmutstr str) { |
| 219 return cx_hash_key((void*)str.ptr, str.length); |
216 return cx_hash_key((void*)str.ptr, str.length); |
| 220 } |
217 } |
| 221 |
218 |
| 222 /** |
219 /** |
| 223 * The identity function for the CX_HASH_KEY() macro. |
220 * The identity function for the CX_HASH_KEY() macro. |
| 224 * You should never need to use this manually. |
221 * You should never need to use this manually. |
| 225 * |
222 * |
| 226 * @param key the key |
223 * @param key the key |
| 227 * @return a copy of the key (not the data) |
224 * @return a copy of the key (not the data) |
| 228 */ |
225 */ |
| 229 cx_attr_nodiscard |
226 CX_NODISCARD CX_INLINE |
| 230 CX_INLINE CxHashKey cx_hash_key_identity(CxHashKey key) { |
227 CxHashKey cx_hash_key_identity(CxHashKey key) { |
| 231 return key; |
228 return key; |
| 232 } |
229 } |
| 233 |
230 |
| 234 /** |
231 /** |
| 235 * The dereference function for the CX_HASH_KEY() macro. |
232 * The dereference function for the CX_HASH_KEY() macro. |
| 236 * You should never need to use this manually. |
233 * You should never need to use this manually. |
| 237 * |
234 * |
| 238 * @param key a pointer to a key |
235 * @param key a pointer to a key |
| 239 * @return a copy of the key (not the data) |
236 * @return a copy of the key (not the data) |
| 240 */ |
237 */ |
| 241 cx_attr_nodiscard |
238 CX_NODISCARD CX_INLINE |
| 242 CX_INLINE CxHashKey cx_hash_key_deref(const CxHashKey *key) { |
239 CxHashKey cx_hash_key_deref(const CxHashKey *key) { |
| 243 return *key; |
240 return *key; |
| 244 } |
241 } |
| 245 |
242 |
| 246 #ifndef __cplusplus |
243 #ifndef __cplusplus |
| 247 /** |
244 /** |
| 277 * |
274 * |
| 278 * @param left (@c CxHashKey*) the first key |
275 * @param left (@c CxHashKey*) the first key |
| 279 * @param right (@c CxHashKey*) the second key |
276 * @param right (@c CxHashKey*) the second key |
| 280 * @return zero when the keys equal, non-zero when they differ |
277 * @return zero when the keys equal, non-zero when they differ |
| 281 */ |
278 */ |
| 282 cx_attr_nodiscard cx_attr_nonnull |
279 CX_EXTERN CX_NODISCARD CX_NONNULL |
| 283 CX_EXPORT int cx_hash_key_cmp(const void *left, const void *right); |
280 int cx_hash_key_cmp(const void *left, const void *right); |
| 284 |
281 |
| 285 /** |
282 /** |
| 286 * Interprets the key data as a string and returns it. |
283 * Interprets the key data as a string and returns it. |
| 287 * |
284 * |
| 288 * @param key the key |
285 * @param key the key |
| 289 * @return the key data as a string |
286 * @return the key data as a string |
| 290 */ |
287 */ |
| 291 CX_EXPORT cxstring cx_hash_key_as_string(const CxHashKey *key); |
288 CX_EXTERN |
| |
289 cxstring cx_hash_key_as_string(const CxHashKey *key); |
| 292 |
290 |
| 293 #ifdef __cplusplus |
291 #ifdef __cplusplus |
| 294 } // extern "C" |
|
| 295 |
|
| 296 // ---------------------------------------------------------- |
292 // ---------------------------------------------------------- |
| 297 // Overloads of CX_HASH_KEY (the C++ version of a _Generic) |
293 // Overloads of CX_HASH_KEY (the C++ version of a _Generic) |
| 298 // ---------------------------------------------------------- |
294 // ---------------------------------------------------------- |
| 299 |
295 |
| 300 CX_CPPDECL CxHashKey CX_HASH_KEY(CxHashKey key) { |
296 CX_CPPDECL CxHashKey CX_HASH_KEY(CxHashKey key) { |