src/cx/hash_key.h

changeset 1675
36c0fb2b60b2
parent 1665
b79405fbf91d
equal deleted inserted replaced
1674:8b0f162ac88e 1675:36c0fb2b60b2
37 #ifndef UCX_HASH_KEY_H 37 #ifndef UCX_HASH_KEY_H
38 #define UCX_HASH_KEY_H 38 #define UCX_HASH_KEY_H
39 39
40 #include "common.h" 40 #include "common.h"
41 #include "string.h" 41 #include "string.h"
42
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 42
47 /** Internal structure for a key within a hash map. */ 43 /** Internal structure for a key within a hash map. */
48 struct cx_hash_key_s { 44 struct cx_hash_key_s {
49 /** 45 /**
50 * The key data. 46 * The key data.
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 }
102 * This function produces no collisions and has a good statistical distribution. 99 * This function produces no collisions and has a good statistical distribution.
103 * 100 *
104 * @param x the integer 101 * @param x the integer
105 * @return the hash 102 * @return the hash
106 */ 103 */
107 CX_INLINE uint64_t cx_hash_u64(uint64_t x){ 104 CX_INLINE
105 uint64_t cx_hash_u64(uint64_t x){
108 x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9); 106 x = (x ^ (x >> 30)) * UINT64_C(0xbf58476d1ce4e5b9);
109 x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb); 107 x = (x ^ (x >> 27)) * UINT64_C(0x94d049bb133111eb);
110 x = x ^ (x >> 31); 108 x = x ^ (x >> 31);
111 return x; 109 return x;
112 } 110 }
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;
145 * Computes a hash key from a 64-bit integer. 142 * Computes a hash key from a 64-bit integer.
146 * 143 *
147 * @param x the integer 144 * @param x the integer
148 * @return the hash key 145 * @return the hash key
149 */ 146 */
150 cx_attr_nodiscard 147 CX_NODISCARD CX_INLINE
151 CX_INLINE CxHashKey cx_hash_key_u64(uint64_t x) { 148 CxHashKey cx_hash_key_u64(uint64_t x) {
152 CxHashKey key; 149 CxHashKey key;
153 key.data = NULL; 150 key.data = NULL;
154 key.len = 0; 151 key.len = 0;
155 key.hash = cx_hash_u64(x); 152 key.hash = cx_hash_u64(x);
156 return key; 153 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) {

mercurial