File Coverage

c/khashl.h
Criterion Covered Total %
statement 0 14 0.0
branch 0 2 0.0
condition n/a
subroutine n/a
pod n/a
total 0 16 0.0


line stmt bran cond sub pod time code
1             /* The MIT License
2              
3             Copyright (c) 2019- by Attractive Chaos
4              
5             Permission is hereby granted, free of charge, to any person obtaining
6             a copy of this software and associated documentation files (the
7             "Software"), to deal in the Software without restriction, including
8             without limitation the rights to use, copy, modify, merge, publish,
9             distribute, sublicense, and/or sell copies of the Software, and to
10             permit persons to whom the Software is furnished to do so, subject to
11             the following conditions:
12              
13             The above copyright notice and this permission notice shall be
14             included in all copies or substantial portions of the Software.
15              
16             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17             EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18             MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19             NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20             BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21             ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22             CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23             SOFTWARE.
24             */
25              
26             #ifndef __AC_KHASHL_H
27             #define __AC_KHASHL_H
28              
29             #define AC_VERSION_KHASHL_H "r30"
30              
31             #include
32             #include
33             #include
34              
35             /************************************
36             * Compiler specific configurations *
37             ************************************/
38              
39             #if UINT_MAX == 0xffffffffu
40             typedef unsigned int khint32_t;
41             #elif ULONG_MAX == 0xffffffffu
42             typedef unsigned long khint32_t;
43             #endif
44              
45             #if ULONG_MAX == ULLONG_MAX
46             typedef unsigned long khint64_t;
47             #else
48             typedef unsigned long long khint64_t;
49             #endif
50              
51             #ifndef kh_inline
52             #ifdef _MSC_VER
53             #define kh_inline __inline
54             #else
55             #define kh_inline inline
56             #endif
57             #endif /* kh_inline */
58              
59             #ifndef klib_unused
60             #if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3)
61             #define klib_unused __attribute__ ((__unused__))
62             #else
63             #define klib_unused
64             #endif
65             #endif /* klib_unused */
66              
67             #define KH_LOCAL static kh_inline klib_unused
68              
69             typedef khint32_t khint_t;
70             typedef const char *kh_cstr_t;
71              
72             /***********************
73             * Configurable macros *
74             ***********************/
75              
76             #ifndef kh_max_count /* set the max load factor */
77             #define kh_max_count(cap) (((cap)>>1) + ((cap)>>2)) /* default load factor: 75% */
78             #endif
79              
80             #ifndef kh_packed /* pack the key-value struct */
81             #define kh_packed __attribute__ ((__packed__))
82             #endif
83              
84             #if !defined(Kmalloc) || !defined(Kcalloc) || !defined(Krealloc) || !defined(Kfree)
85             #define Kmalloc(km, type, cnt) ((type*)malloc((cnt) * sizeof(type)))
86             #define Kcalloc(km, type, cnt) ((type*)calloc((cnt), sizeof(type)))
87             #define Krealloc(km, type, ptr, cnt) ((type*)realloc((ptr), (cnt) * sizeof(type)))
88             #define Kfree(km, ptr) free(ptr)
89             #endif
90              
91             /****************************
92             * Simple private functions *
93             ****************************/
94              
95             #define __kh_used(flag, i) (flag[i>>5] >> (i&0x1fU) & 1U)
96             #define __kh_set_used(flag, i) (flag[i>>5] |= 1U<<(i&0x1fU))
97             #define __kh_set_unused(flag, i) (flag[i>>5] &= ~(1U<<(i&0x1fU)))
98              
99             #define __kh_fsize(m) ((m) < 32? 1 : (m)>>5)
100              
101 0           static kh_inline khint_t __kh_h2b(khint_t hash, khint_t bits) { return hash * 2654435769U >> (32 - bits); } /* Fibonacci hashing */
102              
103             /*******************
104             * Hash table base *
105             *******************/
106              
107             #define __KHASHL_TYPE(HType, khkey_t) \
108             typedef struct HType { \
109             void *km; \
110             khint_t bits, count; \
111             khint32_t *used; \
112             khkey_t *keys; \
113             } HType;
114              
115             #define __KHASHL_PROTOTYPES(HType, prefix, khkey_t) \
116             extern HType *prefix##_init(void); \
117             extern HType *prefix##_init2(void *km); \
118             extern void prefix##_destroy(HType *h); \
119             extern void prefix##_clear(HType *h); \
120             extern khint_t prefix##_getp(const HType *h, const khkey_t *key); \
121             extern int prefix##_resize(HType *h, khint_t new_n_buckets); \
122             extern khint_t prefix##_putp(HType *h, const khkey_t *key, int *absent); \
123             extern void prefix##_del(HType *h, khint_t k);
124              
125             #define __KHASHL_IMPL_BASIC(SCOPE, HType, prefix) \
126             SCOPE HType *prefix##_init2(void *km) { \
127             HType *h = Kcalloc(km, HType, 1); \
128             h->km = km; \
129             return h; \
130             } \
131             SCOPE HType *prefix##_init(void) { return prefix##_init2(0); } \
132             SCOPE void prefix##_destroy(HType *h) { \
133             if (!h) return; \
134             Kfree(h->km, (void*)h->keys); Kfree(h->km, h->used); \
135             Kfree(h->km, h); \
136             } \
137             SCOPE void prefix##_clear(HType *h) { \
138             if (h && h->used) { \
139             khint_t n_buckets = (khint_t)1U << h->bits; \
140             memset(h->used, 0, __kh_fsize(n_buckets) * sizeof(khint32_t)); \
141             h->count = 0; \
142             } \
143             }
144              
145             #define __KHASHL_IMPL_GET(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
146             SCOPE khint_t prefix##_getp_core(const HType *h, const khkey_t *key, khint_t hash) { \
147             khint_t i, last, n_buckets, mask; \
148             if (h->keys == 0) return 0; \
149             n_buckets = (khint_t)1U << h->bits; \
150             mask = n_buckets - 1U; \
151             i = last = __kh_h2b(hash, h->bits); \
152             while (__kh_used(h->used, i) && !__hash_eq(h->keys[i], *key)) { \
153             i = (i + 1U) & mask; \
154             if (i == last) return n_buckets; \
155             } \
156             return !__kh_used(h->used, i)? n_buckets : i; \
157             } \
158             SCOPE khint_t prefix##_getp(const HType *h, const khkey_t *key) { return prefix##_getp_core(h, key, __hash_fn(*key)); } \
159             SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { return prefix##_getp_core(h, &key, __hash_fn(key)); }
160              
161             #define __KHASHL_IMPL_RESIZE(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
162             SCOPE int prefix##_resize(HType *h, khint_t new_n_buckets) { \
163             khint32_t *new_used = 0; \
164             khint_t j = 0, x = new_n_buckets, n_buckets, new_bits, new_mask; \
165             while ((x >>= 1) != 0) ++j; \
166             if (new_n_buckets & (new_n_buckets - 1)) ++j; \
167             new_bits = j > 2? j : 2; \
168             new_n_buckets = (khint_t)1U << new_bits; \
169             if (h->count > kh_max_count(new_n_buckets)) return 0; /* requested size is too small */ \
170             new_used = Kmalloc(h->km, khint32_t, __kh_fsize(new_n_buckets)); \
171             memset(new_used, 0, __kh_fsize(new_n_buckets) * sizeof(khint32_t)); \
172             if (!new_used) return -1; /* not enough memory */ \
173             n_buckets = h->keys? (khint_t)1U<bits : 0U; \
174             if (n_buckets < new_n_buckets) { /* expand */ \
175             khkey_t *new_keys = Krealloc(h->km, khkey_t, h->keys, new_n_buckets); \
176             if (!new_keys) { Kfree(h->km, new_used); return -1; } \
177             h->keys = new_keys; \
178             } /* otherwise shrink */ \
179             new_mask = new_n_buckets - 1; \
180             for (j = 0; j != n_buckets; ++j) { \
181             khkey_t key; \
182             if (!__kh_used(h->used, j)) continue; \
183             key = h->keys[j]; \
184             __kh_set_unused(h->used, j); \
185             while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \
186             khint_t i; \
187             i = __kh_h2b(__hash_fn(key), new_bits); \
188             while (__kh_used(new_used, i)) i = (i + 1) & new_mask; \
189             __kh_set_used(new_used, i); \
190             if (i < n_buckets && __kh_used(h->used, i)) { /* kick out the existing element */ \
191             { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
192             __kh_set_unused(h->used, i); /* mark it as deleted in the old hash table */ \
193             } else { /* write the element and jump out of the loop */ \
194             h->keys[i] = key; \
195             break; \
196             } \
197             } \
198             } \
199             if (n_buckets > new_n_buckets) /* shrink the hash table */ \
200             h->keys = Krealloc(h->km, khkey_t, (void*)h->keys, new_n_buckets); \
201             Kfree(h->km, h->used); /* free the working space */ \
202             h->used = new_used, h->bits = new_bits; \
203             return 0; \
204             }
205              
206             #define __KHASHL_IMPL_PUT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
207             SCOPE khint_t prefix##_putp_core(HType *h, const khkey_t *key, khint_t hash, int *absent) { \
208             khint_t n_buckets, i, last, mask; \
209             n_buckets = h->keys? (khint_t)1U<bits : 0U; \
210             *absent = -1; \
211             if (h->count >= kh_max_count(n_buckets)) { /* rehashing */ \
212             if (prefix##_resize(h, n_buckets + 1U) < 0) \
213             return n_buckets; \
214             n_buckets = (khint_t)1U<bits; \
215             } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \
216             mask = n_buckets - 1; \
217             i = last = __kh_h2b(hash, h->bits); \
218             while (__kh_used(h->used, i) && !__hash_eq(h->keys[i], *key)) { \
219             i = (i + 1U) & mask; \
220             if (i == last) break; \
221             } \
222             if (!__kh_used(h->used, i)) { /* not present at all */ \
223             h->keys[i] = *key; \
224             __kh_set_used(h->used, i); \
225             ++h->count; \
226             *absent = 1; \
227             } else *absent = 0; /* Don't touch h->keys[i] if present */ \
228             return i; \
229             } \
230             SCOPE khint_t prefix##_putp(HType *h, const khkey_t *key, int *absent) { return prefix##_putp_core(h, key, __hash_fn(*key), absent); } \
231             SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { return prefix##_putp_core(h, &key, __hash_fn(key), absent); }
232              
233             #define __KHASHL_IMPL_DEL(SCOPE, HType, prefix, khkey_t, __hash_fn) \
234             SCOPE int prefix##_del(HType *h, khint_t i) { \
235             khint_t j = i, k, mask, n_buckets; \
236             if (h->keys == 0) return 0; \
237             n_buckets = (khint_t)1U<bits; \
238             mask = n_buckets - 1U; \
239             while (1) { \
240             j = (j + 1U) & mask; \
241             if (j == i || !__kh_used(h->used, j)) break; /* j==i only when the table is completely full */ \
242             k = __kh_h2b(__hash_fn(h->keys[j]), h->bits); \
243             if ((j > i && (k <= i || k > j)) || (j < i && (k <= i && k > j))) \
244             h->keys[i] = h->keys[j], i = j; \
245             } \
246             __kh_set_unused(h->used, i); \
247             --h->count; \
248             return 1; \
249             }
250              
251             #define KHASHL_DECLARE(HType, prefix, khkey_t) \
252             __KHASHL_TYPE(HType, khkey_t) \
253             __KHASHL_PROTOTYPES(HType, prefix, khkey_t)
254              
255             #define KHASHL_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
256             __KHASHL_TYPE(HType, khkey_t) \
257             __KHASHL_IMPL_BASIC(SCOPE, HType, prefix) \
258             __KHASHL_IMPL_GET(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
259             __KHASHL_IMPL_RESIZE(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
260             __KHASHL_IMPL_PUT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
261             __KHASHL_IMPL_DEL(SCOPE, HType, prefix, khkey_t, __hash_fn)
262              
263             /***************************
264             * Ensemble of hash tables *
265             ***************************/
266              
267             typedef struct {
268             khint_t sub, pos;
269             } kh_ensitr_t;
270              
271             #define KHASHE_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
272             KHASHL_INIT(KH_LOCAL, HType##_sub, prefix##_sub, khkey_t, __hash_fn, __hash_eq) \
273             typedef struct HType { \
274             void *km; \
275             khint64_t count:54, bits:8; \
276             HType##_sub *sub; \
277             } HType; \
278             SCOPE HType *prefix##_init2(void *km, int bits) { \
279             HType *g; \
280             g = Kcalloc(km, HType, 1); \
281             g->bits = bits, g->km = km; \
282             g->sub = Kcalloc(km, HType##_sub, 1U<
283             return g; \
284             } \
285             SCOPE HType *prefix##_init(int bits) { return prefix##_init2(0, bits); } \
286             SCOPE void prefix##_destroy(HType *g) { \
287             int t; \
288             if (!g) return; \
289             for (t = 0; t < 1<bits; ++t) { Kfree(g->km, (void*)g->sub[t].keys); Kfree(g->km, g->sub[t].used); } \
290             Kfree(g->km, g->sub); Kfree(g->km, g); \
291             } \
292             SCOPE kh_ensitr_t prefix##_getp(const HType *g, const khkey_t *key) { \
293             khint_t hash, low, ret; \
294             kh_ensitr_t r; \
295             HType##_sub *h; \
296             hash = __hash_fn(*key); \
297             low = hash & ((1U<bits) - 1); \
298             h = &g->sub[low]; \
299             ret = prefix##_sub_getp_core(h, key, hash); \
300             if (ret == kh_end(h)) r.sub = low, r.pos = (khint_t)-1; \
301             else r.sub = low, r.pos = ret; \
302             return r; \
303             } \
304             SCOPE kh_ensitr_t prefix##_get(const HType *g, const khkey_t key) { return prefix##_getp(g, &key); } \
305             SCOPE kh_ensitr_t prefix##_putp(HType *g, const khkey_t *key, int *absent) { \
306             khint_t hash, low, ret; \
307             kh_ensitr_t r; \
308             HType##_sub *h; \
309             hash = __hash_fn(*key); \
310             low = hash & ((1U<bits) - 1); \
311             h = &g->sub[low]; \
312             ret = prefix##_sub_putp_core(h, key, hash, absent); \
313             if (*absent) ++g->count; \
314             r.sub = low, r.pos = ret; \
315             return r; \
316             } \
317             SCOPE kh_ensitr_t prefix##_put(HType *g, const khkey_t key, int *absent) { return prefix##_putp(g, &key, absent); } \
318             SCOPE int prefix##_del(HType *g, kh_ensitr_t itr) { \
319             HType##_sub *h = &g->sub[itr.sub]; \
320             int ret; \
321             ret = prefix##_sub_del(h, itr.pos); \
322             if (ret) --g->count; \
323             return ret; \
324             } \
325             SCOPE void prefix##_clear(HType *g) { \
326             int i; \
327             for (i = 0; i < 1U<bits; ++i) prefix##_sub_clear(&g->sub[i]); \
328             g->count = 0; \
329             }
330              
331             /*****************************
332             * More convenient interface *
333             *****************************/
334              
335             /* common */
336              
337             #define KHASHL_SET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
338             typedef struct { khkey_t key; } kh_packed HType##_s_bucket_t; \
339             static kh_inline khint_t prefix##_s_hash(HType##_s_bucket_t x) { return __hash_fn(x.key); } \
340             static kh_inline int prefix##_s_eq(HType##_s_bucket_t x, HType##_s_bucket_t y) { return __hash_eq(x.key, y.key); } \
341             KHASHL_INIT(KH_LOCAL, HType, prefix##_s, HType##_s_bucket_t, prefix##_s_hash, prefix##_s_eq) \
342             SCOPE HType *prefix##_init(void) { return prefix##_s_init(); } \
343             SCOPE HType *prefix##_init2(void *km) { return prefix##_s_init2(km); } \
344             SCOPE void prefix##_destroy(HType *h) { prefix##_s_destroy(h); } \
345             SCOPE void prefix##_resize(HType *h, khint_t new_n_buckets) { prefix##_s_resize(h, new_n_buckets); } \
346             SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_s_bucket_t t; t.key = key; return prefix##_s_getp(h, &t); } \
347             SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_s_del(h, k); } \
348             SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_s_bucket_t t; t.key = key; return prefix##_s_putp(h, &t, absent); } \
349             SCOPE void prefix##_clear(HType *h) { prefix##_s_clear(h); }
350              
351             #define KHASHL_MAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
352             typedef struct { khkey_t key; kh_val_t val; } kh_packed HType##_m_bucket_t; \
353             static kh_inline khint_t prefix##_m_hash(HType##_m_bucket_t x) { return __hash_fn(x.key); } \
354             static kh_inline int prefix##_m_eq(HType##_m_bucket_t x, HType##_m_bucket_t y) { return __hash_eq(x.key, y.key); } \
355             KHASHL_INIT(KH_LOCAL, HType, prefix##_m, HType##_m_bucket_t, prefix##_m_hash, prefix##_m_eq) \
356             SCOPE HType *prefix##_init(void) { return prefix##_m_init(); } \
357             SCOPE HType *prefix##_init2(void *km) { return prefix##_m_init2(km); } \
358             SCOPE void prefix##_destroy(HType *h) { prefix##_m_destroy(h); } \
359             SCOPE void prefix##_resize(HType *h, khint_t new_n_buckets) { prefix##_m_resize(h, new_n_buckets); } \
360             SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_m_bucket_t t; t.key = key; return prefix##_m_getp(h, &t); } \
361             SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_m_del(h, k); } \
362             SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_m_bucket_t t; t.key = key; return prefix##_m_putp(h, &t, absent); } \
363             SCOPE void prefix##_clear(HType *h) { prefix##_m_clear(h); }
364              
365             /* cached hashes to trade memory for performance when hashing and comparison are expensive */
366              
367             #define __kh_cached_hash(x) ((x).hash)
368              
369             #define KHASHL_CSET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
370             typedef struct { khkey_t key; khint_t hash; } kh_packed HType##_cs_bucket_t; \
371             static kh_inline int prefix##_cs_eq(HType##_cs_bucket_t x, HType##_cs_bucket_t y) { return x.hash == y.hash && __hash_eq(x.key, y.key); } \
372             KHASHL_INIT(KH_LOCAL, HType, prefix##_cs, HType##_cs_bucket_t, __kh_cached_hash, prefix##_cs_eq) \
373             SCOPE HType *prefix##_init(void) { return prefix##_cs_init(); } \
374             SCOPE void prefix##_destroy(HType *h) { prefix##_cs_destroy(h); } \
375             SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_cs_bucket_t t; t.key = key; t.hash = __hash_fn(key); return prefix##_cs_getp(h, &t); } \
376             SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_cs_del(h, k); } \
377             SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_cs_bucket_t t; t.key = key, t.hash = __hash_fn(key); return prefix##_cs_putp(h, &t, absent); } \
378             SCOPE void prefix##_clear(HType *h) { prefix##_cs_clear(h); }
379              
380             #define KHASHL_CMAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
381             typedef struct { khkey_t key; kh_val_t val; khint_t hash; } kh_packed HType##_cm_bucket_t; \
382             static kh_inline int prefix##_cm_eq(HType##_cm_bucket_t x, HType##_cm_bucket_t y) { return x.hash == y.hash && __hash_eq(x.key, y.key); } \
383             KHASHL_INIT(KH_LOCAL, HType, prefix##_cm, HType##_cm_bucket_t, __kh_cached_hash, prefix##_cm_eq) \
384             SCOPE HType *prefix##_init(void) { return prefix##_cm_init(); } \
385             SCOPE void prefix##_destroy(HType *h) { prefix##_cm_destroy(h); } \
386             SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_cm_bucket_t t; t.key = key; t.hash = __hash_fn(key); return prefix##_cm_getp(h, &t); } \
387             SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_cm_del(h, k); } \
388             SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_cm_bucket_t t; t.key = key, t.hash = __hash_fn(key); return prefix##_cm_putp(h, &t, absent); } \
389             SCOPE void prefix##_clear(HType *h) { prefix##_cm_clear(h); }
390              
391             /* ensemble for huge hash tables */
392              
393             #define KHASHE_SET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
394             typedef struct { khkey_t key; } kh_packed HType##_es_bucket_t; \
395             static kh_inline khint_t prefix##_es_hash(HType##_es_bucket_t x) { return __hash_fn(x.key); } \
396             static kh_inline int prefix##_es_eq(HType##_es_bucket_t x, HType##_es_bucket_t y) { return __hash_eq(x.key, y.key); } \
397             KHASHE_INIT(KH_LOCAL, HType, prefix##_es, HType##_es_bucket_t, prefix##_es_hash, prefix##_es_eq) \
398             SCOPE HType *prefix##_init(int bits) { return prefix##_es_init(bits); } \
399             SCOPE void prefix##_destroy(HType *h) { prefix##_es_destroy(h); } \
400             SCOPE kh_ensitr_t prefix##_get(const HType *h, khkey_t key) { HType##_es_bucket_t t; t.key = key; return prefix##_es_getp(h, &t); } \
401             SCOPE int prefix##_del(HType *h, kh_ensitr_t k) { return prefix##_es_del(h, k); } \
402             SCOPE kh_ensitr_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_es_bucket_t t; t.key = key; return prefix##_es_putp(h, &t, absent); } \
403             SCOPE void prefix##_clear(HType *h) { prefix##_es_clear(h); }
404              
405             #define KHASHE_MAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
406             typedef struct { khkey_t key; kh_val_t val; } kh_packed HType##_em_bucket_t; \
407             static kh_inline khint_t prefix##_em_hash(HType##_em_bucket_t x) { return __hash_fn(x.key); } \
408             static kh_inline int prefix##_em_eq(HType##_em_bucket_t x, HType##_em_bucket_t y) { return __hash_eq(x.key, y.key); } \
409             KHASHE_INIT(KH_LOCAL, HType, prefix##_em, HType##_em_bucket_t, prefix##_em_hash, prefix##_em_eq) \
410             SCOPE HType *prefix##_init(int bits) { return prefix##_em_init(bits); } \
411             SCOPE void prefix##_destroy(HType *h) { prefix##_em_destroy(h); } \
412             SCOPE kh_ensitr_t prefix##_get(const HType *h, khkey_t key) { HType##_em_bucket_t t; t.key = key; return prefix##_em_getp(h, &t); } \
413             SCOPE int prefix##_del(HType *h, kh_ensitr_t k) { return prefix##_em_del(h, k); } \
414             SCOPE kh_ensitr_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_em_bucket_t t; t.key = key; return prefix##_em_putp(h, &t, absent); } \
415             SCOPE void prefix##_clear(HType *h) { prefix##_em_clear(h); }
416              
417             /**************************
418             * Public macro functions *
419             **************************/
420              
421             #define kh_bucket(h, x) ((h)->keys[x])
422             #define kh_size(h) ((h)->count)
423             #define kh_capacity(h) ((h)->keys? 1U<<(h)->bits : 0U)
424             #define kh_end(h) kh_capacity(h)
425              
426             #define kh_key(h, x) ((h)->keys[x].key)
427             #define kh_val(h, x) ((h)->keys[x].val)
428             #define kh_exist(h, x) __kh_used((h)->used, (x))
429              
430             #define kh_foreach(h, x) for ((x) = 0; (x) != kh_end(h); ++(x)) if (kh_exist((h), (x)))
431              
432             #define kh_ens_key(g, x) kh_key(&(g)->sub[(x).sub], (x).pos)
433             #define kh_ens_val(g, x) kh_val(&(g)->sub[(x).sub], (x).pos)
434             #define kh_ens_exist(g, x) kh_exist(&(g)->sub[(x).sub], (x).pos)
435             #define kh_ens_is_end(x) ((x).pos == (khint_t)-1)
436             #define kh_ens_size(g) ((g)->count)
437              
438             #define kh_ens_foreach(g, x) for ((x).sub = 0; (x).sub != 1<<(g)->bits; ++(x).sub) for ((x).pos = 0; (x).pos != kh_end(&(g)->sub[(x).sub]); ++(x).pos) if (kh_ens_exist((g), (x)))
439              
440             /**************************************
441             * Common hash and equality functions *
442             **************************************/
443              
444             #define kh_eq_generic(a, b) ((a) == (b))
445             #define kh_eq_str(a, b) (strcmp((a), (b)) == 0)
446             #define kh_hash_dummy(x) ((khint_t)(x))
447              
448 0           static kh_inline khint_t kh_hash_uint32(khint_t x) { /* murmur finishing */
449 0           x ^= x >> 16;
450 0           x *= 0x85ebca6bU;
451 0           x ^= x >> 13;
452 0           x *= 0xc2b2ae35U;
453 0           x ^= x >> 16;
454 0           return x;
455             }
456              
457             static kh_inline khint_t kh_hash_uint64(khint64_t x) { /* splitmix64; see https://nullprogram.com/blog/2018/07/31/ for inversion */
458             x ^= x >> 30;
459             x *= 0xbf58476d1ce4e5b9ULL;
460             x ^= x >> 27;
461             x *= 0x94d049bb133111ebULL;
462             x ^= x >> 31;
463             return (khint_t)x;
464             }
465              
466 0           static kh_inline khint_t kh_hash_str(kh_cstr_t s) { /* FNV1a */
467 0           khint_t h = 2166136261U;
468 0           const unsigned char *t = (const unsigned char*)s;
469 0 0         for (; *t; ++t)
470 0           h ^= *t, h *= 16777619;
471 0           return h;
472             }
473              
474             static kh_inline khint_t kh_hash_bytes(int len, const unsigned char *s) {
475             khint_t h = 2166136261U;
476             int i;
477             for (i = 0; i < len; ++i)
478             h ^= s[i], h *= 16777619;
479             return h;
480             }
481              
482             #endif /* __AC_KHASHL_H */