1
1
/* The MIT License
2
2
3
3
Copyright (c) 2008, 2009, 2011 by Attractive Chaos <[email protected] >
4
- Copyright (C) 2014-2015, 2018 Genome Research Ltd.
4
+ Copyright (C) 2014-2015, 2018, 2024 Genome Research Ltd.
5
5
6
6
Permission is hereby granted, free of charge, to any person obtaining
7
7
a copy of this software and associated documentation files (the
@@ -356,7 +356,39 @@ static const double __ac_HASH_UPPER = 0.77;
356
356
__ac_set_isdel_true(h->flags, x); \
357
357
--h->size; \
358
358
} \
359
- }
359
+ } \
360
+ SCOPE int kh_stats_##name(kh_##name##_t *h, khint_t *empty, \
361
+ khint_t *deleted, khint_t *hist_size, \
362
+ khint_t **hist_out) \
363
+ { \
364
+ khint_t i, *hist = NULL, dist_max = 0, k, dist, step; \
365
+ khint_t mask = h->n_buckets - 1; \
366
+ *empty = *deleted = *hist_size = 0; \
367
+ hist = (khint_t *) calloc(1, sizeof(*hist)); \
368
+ if (!hist) { return -1; } \
369
+ for (i = kh_begin(h); i < kh_end(h); ++i) { \
370
+ if (__ac_isempty(h->flags, i)) { (*empty)++; continue; } \
371
+ if (__ac_isdel(h->flags, i)) { (*deleted)++; continue; } \
372
+ k = __hash_func(h->keys[i]) & (h->n_buckets - 1); \
373
+ dist = 0; \
374
+ step = 0; \
375
+ while (k != i) { \
376
+ dist++; \
377
+ k = (k + (++step)) & mask; \
378
+ } \
379
+ if (dist_max <= dist) { \
380
+ khint_t *new_hist = (khint_t *) realloc(hist, sizeof(*new_hist) * (dist + 1)); \
381
+ if (!new_hist) { free(hist); return -1; } \
382
+ for (k = dist_max + 1; k <= dist; k++) new_hist[k] = 0; \
383
+ hist = new_hist; \
384
+ dist_max = dist; \
385
+ } \
386
+ hist[dist]++; \
387
+ } \
388
+ *hist_out = hist; \
389
+ *hist_size = dist_max + 1; \
390
+ return 0; \
391
+ }
360
392
361
393
#define KHASH_DECLARE (name , khkey_t , khval_t ) \
362
394
__KHASH_TYPE(name, khkey_t, khval_t) \
@@ -391,6 +423,7 @@ static const double __ac_HASH_UPPER = 0.77;
391
423
@abstract 64-bit integer comparison function
392
424
*/
393
425
#define kh_int64_hash_equal (a , b ) ((a) == (b))
426
+
394
427
/*! @function
395
428
@abstract const char* hash function
396
429
@param s Pointer to a null terminated string
@@ -402,12 +435,28 @@ static kh_inline khint_t __ac_X31_hash_string(const char *s)
402
435
if (h ) for (++ s ; * s ; ++ s ) h = (h << 5 ) - h + (khint_t )* s ;
403
436
return h ;
404
437
}
438
+
439
+ /*! @function
440
+ @abstract const char* FNV1a hash function
441
+ @param s Pointer to a null terminated string
442
+ @return The hash value
443
+ */
444
+ static kh_inline khint_t __ac_FNV1a_hash_string (const char * s )
445
+ {
446
+ const khint_t offset_basis = 2166136261 ;
447
+ const khint_t FNV_prime = 16777619 ;
448
+ khint_t h = offset_basis ;
449
+ for (; * s ; ++ s ) h = (h ^ (uint8_t ) * s ) * FNV_prime ;
450
+ return h ;
451
+ }
452
+
405
453
/*! @function
406
454
@abstract Another interface to const char* hash function
407
455
@param key Pointer to a nul terminated string [const char*]
408
456
@return The hash value [khint_t]
409
457
*/
410
- #define kh_str_hash_func (key ) __ac_X31_hash_string(key)
458
+ #define kh_str_hash_func (key ) __ac_FNV1a_hash_string(key)
459
+
411
460
/*! @function
412
461
@abstract Const char* comparison function
413
462
*/
@@ -426,12 +475,29 @@ static kh_inline khint_t __ac_X31_hash_kstring(const kstring_t ks)
426
475
h = (h << 5 ) - h + (khint_t )ks .s [i ];
427
476
return h ;
428
477
}
478
+
479
+ /*! @function
480
+ @abstract Kstring hash function
481
+ @param s Pointer to a kstring
482
+ @return The hash value
483
+ */
484
+ static kh_inline khint_t __ac_FNV1a_hash_kstring (const kstring_t ks )
485
+ {
486
+ const khint_t offset_basis = 2166136261 ;
487
+ const khint_t FNV_prime = 16777619 ;
488
+ khint_t h = offset_basis ;
489
+ size_t i ;
490
+ for (i = 0 ; i < ks .l ; i ++ )
491
+ h = (h ^ (uint8_t ) ks .s [i ]) * FNV_prime ;
492
+ return h ;
493
+ }
494
+
429
495
/*! @function
430
496
@abstract Interface to kstring hash function.
431
497
@param key Pointer to a khash; permits hashing on non-nul terminated strings.
432
498
@return The hash value [khint_t]
433
499
*/
434
- #define kh_kstr_hash_func (key ) __ac_X31_hash_kstring (key)
500
+ #define kh_kstr_hash_func (key ) __ac_FNV1a_hash_kstring (key)
435
501
/*! @function
436
502
@abstract kstring comparison function
437
503
*/
@@ -604,6 +670,19 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
604
670
code; \
605
671
} }
606
672
673
+ /*! @function
674
+ @abstract Gather hash table statistics
675
+ @param name Name of the hash table [symbol]
676
+ @param h Pointer to the hash table [khash_t(name)*]
677
+ @param empty[out] Number of empty hash bins
678
+ @param deleted[out] Number of hash bins with the deleted flag
679
+ @param hist_size[out] Size of @p hist array
680
+ @param hist[out] Probe count histogram
681
+ @return 0 on success; -1 on failure
682
+ */
683
+ #define kh_stats (name , h , empty , deleted , hist_size , hist ) \
684
+ kh_stats_##name(h, empty, deleted, hist_size, hist)
685
+
607
686
/* More convenient interfaces */
608
687
609
688
/*! @function
0 commit comments