]> git.proxmox.com Git - libgit2.git/blame - src/khash.h
Merge pull request #646 from arrbee/ignore-pat-leading-slash
[libgit2.git] / src / khash.h
CommitLineData
ada488bf
RB
1/* The MIT License
2
3 Copyright (c) 2008, 2009, 2011 by Attractive Chaos <attractor@live.co.uk>
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/*
27 An example:
28
29#include "khash.h"
30KHASH_MAP_INIT_INT(32, char)
31int main() {
32 int ret, is_missing;
33 khiter_t k;
34 khash_t(32) *h = kh_init(32);
35 k = kh_put(32, h, 5, &ret);
36 kh_value(h, k) = 10;
37 k = kh_get(32, h, 10);
38 is_missing = (k == kh_end(h));
39 k = kh_get(32, h, 5);
40 kh_del(32, h, k);
41 for (k = kh_begin(h); k != kh_end(h); ++k)
42 if (kh_exist(h, k)) kh_value(h, k) = 1;
43 kh_destroy(32, h);
44 return 0;
45}
46*/
47
48/*
49 2011-12-29 (0.2.7):
50
51 * Minor code clean up; no actual effect.
52
53 2011-09-16 (0.2.6):
54
55 * The capacity is a power of 2. This seems to dramatically improve the
56 speed for simple keys. Thank Zilong Tan for the suggestion. Reference:
57
58 - http://code.google.com/p/ulib/
59 - http://nothings.org/computer/judy/
60
61 * Allow to optionally use linear probing which usually has better
62 performance for random input. Double hashing is still the default as it
63 is more robust to certain non-random input.
64
65 * Added Wang's integer hash function (not used by default). This hash
66 function is more robust to certain non-random input.
67
68 2011-02-14 (0.2.5):
69
70 * Allow to declare global functions.
71
72 2009-09-26 (0.2.4):
73
74 * Improve portability
75
76 2008-09-19 (0.2.3):
77
78 * Corrected the example
79 * Improved interfaces
80
81 2008-09-11 (0.2.2):
82
83 * Improved speed a little in kh_put()
84
85 2008-09-10 (0.2.1):
86
87 * Added kh_clear()
88 * Fixed a compiling error
89
90 2008-09-02 (0.2.0):
91
92 * Changed to token concatenation which increases flexibility.
93
94 2008-08-31 (0.1.2):
95
96 * Fixed a bug in kh_get(), which has not been tested previously.
97
98 2008-08-31 (0.1.1):
99
100 * Added destructor
101*/
102
103
104#ifndef __AC_KHASH_H
105#define __AC_KHASH_H
106
107/*!
108 @header
109
110 Generic hash table library.
111 */
112
113#define AC_VERSION_KHASH_H "0.2.6"
114
115#include <stdlib.h>
116#include <string.h>
117#include <limits.h>
118
119/* compipler specific configuration */
120
121#if UINT_MAX == 0xffffffffu
122typedef unsigned int khint32_t;
123#elif ULONG_MAX == 0xffffffffu
124typedef unsigned long khint32_t;
125#endif
126
127#if ULONG_MAX == ULLONG_MAX
128typedef unsigned long khint64_t;
129#else
130typedef unsigned long long khint64_t;
131#endif
132
133#ifdef _MSC_VER
134#define inline __inline
135#endif
136
137typedef khint32_t khint_t;
138typedef khint_t khiter_t;
139
140#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2)
141#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1)
142#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3)
143#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1)))
144#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1)))
145#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1)))
146#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1))
147
148#ifdef KHASH_LINEAR
149#define __ac_inc(k, m) 1
150#else
151#define __ac_inc(k, m) (((k)>>3 ^ (k)<<3) | 1) & (m)
152#endif
153
154#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4)
155
156#ifndef kroundup32
157#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
158#endif
159
01fed0a8
RB
160#ifndef kcalloc
161#define kcalloc(N,Z) calloc(N,Z)
162#endif
163#ifndef kmalloc
164#define kmalloc(Z) malloc(Z)
165#endif
166#ifndef krealloc
167#define krealloc(P,Z) realloc(P,Z)
168#endif
169#ifndef kfree
170#define kfree(P) free(P)
171#endif
172
ada488bf
RB
173static const double __ac_HASH_UPPER = 0.77;
174
175#define __KHASH_TYPE(name, khkey_t, khval_t) \
176 typedef struct { \
177 khint_t n_buckets, size, n_occupied, upper_bound; \
178 khint32_t *flags; \
179 khkey_t *keys; \
180 khval_t *vals; \
181 } kh_##name##_t;
182
01fed0a8
RB
183#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \
184 extern kh_##name##_t *kh_init_##name(void); \
ada488bf
RB
185 extern void kh_destroy_##name(kh_##name##_t *h); \
186 extern void kh_clear_##name(kh_##name##_t *h); \
187 extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \
01fed0a8 188 extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
ada488bf
RB
189 extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \
190 extern void kh_del_##name(kh_##name##_t *h, khint_t x);
191
01fed0a8
RB
192#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
193 SCOPE kh_##name##_t *kh_init_##name(void) { \
194 return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \
ada488bf
RB
195 } \
196 SCOPE void kh_destroy_##name(kh_##name##_t *h) \
197 { \
198 if (h) { \
01fed0a8
RB
199 kfree(h->keys); kfree(h->flags); \
200 kfree(h->vals); \
201 kfree(h); \
ada488bf
RB
202 } \
203 } \
204 SCOPE void kh_clear_##name(kh_##name##_t *h) \
205 { \
206 if (h && h->flags) { \
207 memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \
208 h->size = h->n_occupied = 0; \
209 } \
210 } \
211 SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
212 { \
213 if (h->n_buckets) { \
214 khint_t inc, k, i, last, mask; \
215 mask = h->n_buckets - 1; \
216 k = __hash_func(key); i = k & mask; \
217 inc = __ac_inc(k, mask); last = i; /* inc==1 for linear probing */ \
218 while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
219 i = (i + inc) & mask; \
220 if (i == last) return h->n_buckets; \
221 } \
222 return __ac_iseither(h->flags, i)? h->n_buckets : i; \
223 } else return 0; \
224 } \
01fed0a8 225 SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
ada488bf
RB
226 { /* This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \
227 khint32_t *new_flags = 0; \
228 khint_t j = 1; \
229 { \
230 kroundup32(new_n_buckets); \
231 if (new_n_buckets < 4) new_n_buckets = 4; \
232 if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \
233 else { /* hash table size to be changed (shrink or expand); rehash */ \
01fed0a8
RB
234 new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
235 if (!new_flags) return -1; \
ada488bf
RB
236 memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
237 if (h->n_buckets < new_n_buckets) { /* expand */ \
01fed0a8
RB
238 khkey_t *new_keys = (khkey_t*)krealloc(h->keys, new_n_buckets * sizeof(khkey_t)); \
239 if (!new_keys) return -1; \
240 h->keys = new_keys; \
241 if (kh_is_map) { \
242 khval_t *new_vals = (khval_t*)krealloc(h->vals, new_n_buckets * sizeof(khval_t)); \
243 if (!new_vals) return -1; \
244 h->vals = new_vals; \
245 } \
ada488bf
RB
246 } /* otherwise shrink */ \
247 } \
248 } \
249 if (j) { /* rehashing is needed */ \
250 for (j = 0; j != h->n_buckets; ++j) { \
251 if (__ac_iseither(h->flags, j) == 0) { \
252 khkey_t key = h->keys[j]; \
253 khval_t val; \
254 khint_t new_mask; \
255 new_mask = new_n_buckets - 1; \
256 if (kh_is_map) val = h->vals[j]; \
257 __ac_set_isdel_true(h->flags, j); \
258 while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \
259 khint_t inc, k, i; \
260 k = __hash_func(key); \
261 i = k & new_mask; \
262 inc = __ac_inc(k, new_mask); \
263 while (!__ac_isempty(new_flags, i)) i = (i + inc) & new_mask; \
264 __ac_set_isempty_false(new_flags, i); \
265 if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \
266 { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
267 if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \
268 __ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \
269 } else { /* write the element and jump out of the loop */ \
270 h->keys[i] = key; \
271 if (kh_is_map) h->vals[i] = val; \
272 break; \
273 } \
274 } \
275 } \
276 } \
277 if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \
01fed0a8
RB
278 h->keys = (khkey_t*)krealloc(h->keys, new_n_buckets * sizeof(khkey_t)); \
279 if (kh_is_map) h->vals = (khval_t*)krealloc(h->vals, new_n_buckets * sizeof(khval_t)); \
ada488bf 280 } \
01fed0a8 281 kfree(h->flags); /* free the working space */ \
ada488bf
RB
282 h->flags = new_flags; \
283 h->n_buckets = new_n_buckets; \
284 h->n_occupied = h->size; \
285 h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \
286 } \
01fed0a8 287 return 0; \
ada488bf
RB
288 } \
289 SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \
290 { \
291 khint_t x; \
292 if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \
01fed0a8
RB
293 if (h->n_buckets > (h->size<<1)) { \
294 if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \
295 *ret = -1; return h->n_buckets; \
296 } \
297 } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \
298 *ret = -1; return h->n_buckets; \
299 } \
ada488bf
RB
300 } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \
301 { \
302 khint_t inc, k, i, site, last, mask = h->n_buckets - 1; \
303 x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \
304 if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \
305 else { \
306 inc = __ac_inc(k, mask); last = i; \
307 while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
308 if (__ac_isdel(h->flags, i)) site = i; \
309 i = (i + inc) & mask; \
310 if (i == last) { x = site; break; } \
311 } \
312 if (x == h->n_buckets) { \
313 if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \
314 else x = i; \
315 } \
316 } \
317 } \
318 if (__ac_isempty(h->flags, x)) { /* not present at all */ \
319 h->keys[x] = key; \
320 __ac_set_isboth_false(h->flags, x); \
321 ++h->size; ++h->n_occupied; \
322 *ret = 1; \
323 } else if (__ac_isdel(h->flags, x)) { /* deleted */ \
324 h->keys[x] = key; \
325 __ac_set_isboth_false(h->flags, x); \
326 ++h->size; \
327 *ret = 2; \
328 } else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \
329 return x; \
330 } \
331 SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \
332 { \
333 if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \
334 __ac_set_isdel_true(h->flags, x); \
335 --h->size; \
336 } \
337 }
338
01fed0a8
RB
339#define KHASH_DECLARE(name, khkey_t, khval_t) \
340 __KHASH_TYPE(name, khkey_t, khval_t) \
341 __KHASH_PROTOTYPES(name, khkey_t, khval_t)
342
343#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
344 __KHASH_TYPE(name, khkey_t, khval_t) \
345 __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
346
ada488bf
RB
347#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
348 KHASH_INIT2(name, static inline, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
349
350/* --- BEGIN OF HASH FUNCTIONS --- */
351
352/*! @function
353 @abstract Integer hash function
354 @param key The integer [khint32_t]
355 @return The hash value [khint_t]
356 */
357#define kh_int_hash_func(key) (khint32_t)(key)
358/*! @function
359 @abstract Integer comparison function
360 */
361#define kh_int_hash_equal(a, b) ((a) == (b))
362/*! @function
363 @abstract 64-bit integer hash function
364 @param key The integer [khint64_t]
365 @return The hash value [khint_t]
366 */
367#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11)
368/*! @function
369 @abstract 64-bit integer comparison function
370 */
371#define kh_int64_hash_equal(a, b) ((a) == (b))
372/*! @function
373 @abstract const char* hash function
374 @param s Pointer to a null terminated string
375 @return The hash value
376 */
377static inline khint_t __ac_X31_hash_string(const char *s)
378{
379 khint_t h = *s;
380 if (h) for (++s ; *s; ++s) h = (h << 5) - h + *s;
381 return h;
382}
383/*! @function
384 @abstract Another interface to const char* hash function
385 @param key Pointer to a null terminated string [const char*]
386 @return The hash value [khint_t]
387 */
388#define kh_str_hash_func(key) __ac_X31_hash_string(key)
389/*! @function
390 @abstract Const char* comparison function
391 */
392#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0)
393
394static inline khint_t __ac_Wang_hash(khint_t key)
395{
396 key += ~(key << 15);
397 key ^= (key >> 10);
398 key += (key << 3);
399 key ^= (key >> 6);
400 key += ~(key << 11);
401 key ^= (key >> 16);
402 return key;
403}
404#define kh_int_hash_func2(k) __ac_Wang_hash((khint_t)key)
405
406/* --- END OF HASH FUNCTIONS --- */
407
408/* Other convenient macros... */
409
410/*!
411 @abstract Type of the hash table.
412 @param name Name of the hash table [symbol]
413 */
414#define khash_t(name) kh_##name##_t
415
416/*! @function
417 @abstract Initiate a hash table.
418 @param name Name of the hash table [symbol]
419 @return Pointer to the hash table [khash_t(name)*]
420 */
421#define kh_init(name) kh_init_##name()
422
423/*! @function
424 @abstract Destroy a hash table.
425 @param name Name of the hash table [symbol]
426 @param h Pointer to the hash table [khash_t(name)*]
427 */
428#define kh_destroy(name, h) kh_destroy_##name(h)
429
430/*! @function
431 @abstract Reset a hash table without deallocating memory.
432 @param name Name of the hash table [symbol]
433 @param h Pointer to the hash table [khash_t(name)*]
434 */
435#define kh_clear(name, h) kh_clear_##name(h)
436
437/*! @function
438 @abstract Resize a hash table.
439 @param name Name of the hash table [symbol]
440 @param h Pointer to the hash table [khash_t(name)*]
441 @param s New size [khint_t]
442 */
443#define kh_resize(name, h, s) kh_resize_##name(h, s)
444
445/*! @function
446 @abstract Insert a key to the hash table.
447 @param name Name of the hash table [symbol]
448 @param h Pointer to the hash table [khash_t(name)*]
449 @param k Key [type of keys]
450 @param r Extra return code: 0 if the key is present in the hash table;
451 1 if the bucket is empty (never used); 2 if the element in
452 the bucket has been deleted [int*]
453 @return Iterator to the inserted element [khint_t]
454 */
455#define kh_put(name, h, k, r) kh_put_##name(h, k, r)
456
457/*! @function
458 @abstract Retrieve a key from the hash table.
459 @param name Name of the hash table [symbol]
460 @param h Pointer to the hash table [khash_t(name)*]
461 @param k Key [type of keys]
462 @return Iterator to the found element, or kh_end(h) is the element is absent [khint_t]
463 */
464#define kh_get(name, h, k) kh_get_##name(h, k)
465
466/*! @function
467 @abstract Remove a key from the hash table.
468 @param name Name of the hash table [symbol]
469 @param h Pointer to the hash table [khash_t(name)*]
470 @param k Iterator to the element to be deleted [khint_t]
471 */
472#define kh_del(name, h, k) kh_del_##name(h, k)
473
474/*! @function
475 @abstract Test whether a bucket contains data.
476 @param h Pointer to the hash table [khash_t(name)*]
477 @param x Iterator to the bucket [khint_t]
478 @return 1 if containing data; 0 otherwise [int]
479 */
480#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x)))
481
482/*! @function
483 @abstract Get key given an iterator
484 @param h Pointer to the hash table [khash_t(name)*]
485 @param x Iterator to the bucket [khint_t]
486 @return Key [type of keys]
487 */
488#define kh_key(h, x) ((h)->keys[x])
489
490/*! @function
491 @abstract Get value given an iterator
492 @param h Pointer to the hash table [khash_t(name)*]
493 @param x Iterator to the bucket [khint_t]
494 @return Value [type of values]
495 @discussion For hash sets, calling this results in segfault.
496 */
497#define kh_val(h, x) ((h)->vals[x])
498
499/*! @function
500 @abstract Alias of kh_val()
501 */
502#define kh_value(h, x) ((h)->vals[x])
503
504/*! @function
505 @abstract Get the start iterator
506 @param h Pointer to the hash table [khash_t(name)*]
507 @return The start iterator [khint_t]
508 */
509#define kh_begin(h) (khint_t)(0)
510
511/*! @function
512 @abstract Get the end iterator
513 @param h Pointer to the hash table [khash_t(name)*]
514 @return The end iterator [khint_t]
515 */
516#define kh_end(h) ((h)->n_buckets)
517
518/*! @function
519 @abstract Get the number of elements in the hash table
520 @param h Pointer to the hash table [khash_t(name)*]
521 @return Number of elements in the hash table [khint_t]
522 */
523#define kh_size(h) ((h)->size)
524
525/*! @function
526 @abstract Get the number of buckets in the hash table
527 @param h Pointer to the hash table [khash_t(name)*]
528 @return Number of buckets in the hash table [khint_t]
529 */
530#define kh_n_buckets(h) ((h)->n_buckets)
531
01fed0a8
RB
532/*! @function
533 @abstract Iterate over the entries in the hash table
534 @param h Pointer to the hash table [khash_t(name)*]
535 @param kvar Variable to which key will be assigned
536 @param vvar Variable to which value will be assigned
537 @param code Block of code to execute
538 */
539#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \
540 for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
541 if (!kh_exist(h,__i)) continue; \
542 (kvar) = kh_key(h,__i); \
543 (vvar) = kh_val(h,__i); \
544 code; \
545 } }
546
547/*! @function
548 @abstract Iterate over the values in the hash table
549 @param h Pointer to the hash table [khash_t(name)*]
550 @param vvar Variable to which value will be assigned
551 @param code Block of code to execute
552 */
553#define kh_foreach_value(h, vvar, code) { khint_t __i; \
554 for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \
555 if (!kh_exist(h,__i)) continue; \
556 (vvar) = kh_val(h,__i); \
557 code; \
558 } }
559
ada488bf
RB
560/* More conenient interfaces */
561
562/*! @function
563 @abstract Instantiate a hash set containing integer keys
564 @param name Name of the hash table [symbol]
565 */
566#define KHASH_SET_INIT_INT(name) \
567 KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
568
569/*! @function
570 @abstract Instantiate a hash map containing integer keys
571 @param name Name of the hash table [symbol]
572 @param khval_t Type of values [type]
573 */
574#define KHASH_MAP_INIT_INT(name, khval_t) \
575 KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
576
577/*! @function
578 @abstract Instantiate a hash map containing 64-bit integer keys
579 @param name Name of the hash table [symbol]
580 */
581#define KHASH_SET_INIT_INT64(name) \
582 KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
583
584/*! @function
585 @abstract Instantiate a hash map containing 64-bit integer keys
586 @param name Name of the hash table [symbol]
587 @param khval_t Type of values [type]
588 */
589#define KHASH_MAP_INIT_INT64(name, khval_t) \
590 KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
591
592typedef const char *kh_cstr_t;
593/*! @function
594 @abstract Instantiate a hash map containing const char* keys
595 @param name Name of the hash table [symbol]
596 */
597#define KHASH_SET_INIT_STR(name) \
598 KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
599
600/*! @function
601 @abstract Instantiate a hash map containing const char* keys
602 @param name Name of the hash table [symbol]
603 @param khval_t Type of values [type]
604 */
605#define KHASH_MAP_INIT_STR(name, khval_t) \
606 KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
607
608#endif /* __AC_KHASH_H */