@@ -218,9 +218,10 @@ khint32_t PANDAS_INLINE murmur2_64to32(khint64_t k){
218
218
return murmur2_32_32to32 (k1 , k2 );
219
219
}
220
220
221
+ #define __ac_inc_linear (k , m ) 1
221
222
222
223
#ifdef KHASH_LINEAR
223
- #define __ac_inc (k , m ) 1
224
+ #define __ac_inc (k , m ) __ac_inc_linear(k, m)
224
225
#else
225
226
#define __ac_inc (k , m ) (murmur2_32to32(k) | 1) & (m)
226
227
#endif
@@ -248,7 +249,7 @@ static const double __ac_HASH_UPPER = 0.77;
248
249
extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \
249
250
extern void kh_del_##name(kh_##name##_t *h, khint_t x);
250
251
251
- #define KHASH_INIT2 (name , SCOPE , khkey_t , khval_t , kh_is_map , __hash_func , __hash_equal ) \
252
+ #define KHASH_INIT2 (name , SCOPE , khkey_t , khval_t , kh_is_map , __hash_func , __hash_equal , LINEAR_STEPS ) \
252
253
typedef struct { \
253
254
khint_t n_buckets, size, n_occupied, upper_bound; \
254
255
khint32_t *flags; \
@@ -276,13 +277,18 @@ static const double __ac_HASH_UPPER = 0.77;
276
277
SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
277
278
{ \
278
279
if (h->n_buckets) { \
279
- khint_t inc, k, i, last, mask; \
280
+ khint_t inc, k, i, last, mask, cnt ; \
280
281
mask = h->n_buckets - 1; \
281
282
k = __hash_func(key); i = k & mask; \
282
- inc = __ac_inc(k, mask); last = i; /* inc==1 for linear probing */ \
283
+ cnt=0; \
284
+ inc = __ac_inc_linear(k, mask); last = i; \
283
285
while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
286
+ if (cnt == LINEAR_STEPS){ \
287
+ inc = __ac_inc(k, mask); last = i; \
288
+ } \
284
289
i = (i + inc) & mask; \
285
290
if (i == last) return h->n_buckets; \
291
+ cnt++; \
286
292
} \
287
293
return __ac_iseither(h->flags, i)? h->n_buckets : i; \
288
294
} else return 0; \
@@ -314,11 +320,18 @@ static const double __ac_HASH_UPPER = 0.77;
314
320
if (kh_is_map ) val = h -> vals [j ]; \
315
321
__ac_set_isempty_true (h -> flags , j ); \
316
322
while (1 ) { /* kick-out process; sort of like in Cuckoo hashing */ \
317
- khint_t inc , k , i ; \
323
+ khint_t inc , k , i , cnt ; \
318
324
k = __hash_func (key ); \
319
325
i = k & new_mask ; \
320
- inc = __ac_inc (k , new_mask ); \
321
- while (!__ac_isempty (new_flags , i )) i = (i + inc ) & new_mask ; \
326
+ cnt = 0 ; \
327
+ inc = __ac_inc_linear (k , new_mask ); \
328
+ while (!__ac_isempty (new_flags , i )){ \
329
+ if (cnt == LINEAR_STEPS ){ \
330
+ inc = __ac_inc (k , new_mask ); \
331
+ } \
332
+ i = (i + inc ) & new_mask ; \
333
+ cnt ++ ; \
334
+ } \
322
335
__ac_set_isempty_false (new_flags , i ); \
323
336
if (i < h -> n_buckets && __ac_iseither (h -> flags , i ) == 0 ) { /* kick out the existing element */ \
324
337
{ khkey_t tmp = h -> keys [i ]; h -> keys [i ] = key ; key = tmp ; } \
@@ -351,14 +364,19 @@ static const double __ac_HASH_UPPER = 0.77;
351
364
else kh_resize_ ##name (h, h->n_buckets + 1); /* expand the hash table */ \
352
365
} /* TODO: to implement automatically shrinking; resize() already support shrinking */ \
353
366
{ \
354
- khint_t inc , k , i , site , last , mask = h -> n_buckets - 1 ; \
367
+ khint_t inc , k , i , site , last , cnt , mask = h -> n_buckets - 1 ; \
355
368
x = site = h -> n_buckets ; k = __hash_func (key ); i = k & mask ; \
356
369
if (__ac_isempty (h -> flags , i )) x = i ; /* for speed up */ \
357
370
else { \
358
- inc = __ac_inc (k , mask ); last = i ; \
371
+ cnt = 0 ; \
372
+ inc = __ac_inc_linear (k , mask ); last = i ; \
359
373
while (!__ac_isempty (h -> flags , i ) && (__ac_isdel (h -> flags , i ) || !__hash_equal (h -> keys [i ], key ))) { \
374
+ if (cnt == LINEAR_STEPS ){ \
375
+ inc = __ac_inc (k , mask ); last = i ; \
376
+ } \
360
377
if (__ac_isdel (h -> flags , i )) site = i ; \
361
378
i = (i + inc ) & mask ; \
379
+ cnt ++ ; \
362
380
if (i == last ) { x = site ; break ; } \
363
381
} \
364
382
if (x == h -> n_buckets ) { \
@@ -388,8 +406,8 @@ static const double __ac_HASH_UPPER = 0.77;
388
406
} \
389
407
}
390
408
391
- #define KHASH_INIT (name , khkey_t , khval_t , kh_is_map , __hash_func , __hash_equal ) \
392
- KHASH_INIT2(name, PANDAS_INLINE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal)
409
+ #define KHASH_INIT (name , khkey_t , khval_t , kh_is_map , __hash_func , __hash_equal , LINEAR_STEPS ) \
410
+ KHASH_INIT2(name, PANDAS_INLINE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal, LINEAR_STEPS )
393
411
394
412
/* --- BEGIN OF HASH FUNCTIONS --- */
395
413
@@ -576,41 +594,45 @@ PANDAS_INLINE khint_t __ac_Wang_hash(khint_t key)
576
594
577
595
/* More convenient interfaces */
578
596
597
+ #define LINEAR_STEPS_BIG_OBJECT 0
598
+ #define LINEAR_STEPS_32BIT 3
599
+ #define LINEAR_STEPS_64BIT 3
600
+
579
601
/*! @function
580
602
@abstract Instantiate a hash set containing integer keys
581
603
@param name Name of the hash table [symbol]
582
604
*/
583
605
#define KHASH_SET_INIT_INT (name ) \
584
- KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal)
606
+ KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal, LINEAR_STEPS_32BIT )
585
607
586
608
/*! @function
587
609
@abstract Instantiate a hash map containing integer keys
588
610
@param name Name of the hash table [symbol]
589
611
@param khval_t Type of values [type]
590
612
*/
591
613
#define KHASH_MAP_INIT_INT (name , khval_t ) \
592
- KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal)
614
+ KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal, LINEAR_STEPS_32BIT )
593
615
594
616
/*! @function
595
617
@abstract Instantiate a hash map containing 64-bit integer keys
596
618
@param name Name of the hash table [symbol]
597
619
*/
598
620
#define KHASH_SET_INIT_UINT64 (name ) \
599
- KHASH_INIT(name, khuint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
621
+ KHASH_INIT(name, khuint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal, LINEAR_STEPS_64BIT )
600
622
601
623
#define KHASH_SET_INIT_INT64 (name ) \
602
- KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal)
624
+ KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal, LINEAR_STEPS_64BIT )
603
625
604
626
/*! @function
605
627
@abstract Instantiate a hash map containing 64-bit integer keys
606
628
@param name Name of the hash table [symbol]
607
629
@param khval_t Type of values [type]
608
630
*/
609
631
#define KHASH_MAP_INIT_UINT64 (name , khval_t ) \
610
- KHASH_INIT(name, khuint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
632
+ KHASH_INIT(name, khuint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal, LINEAR_STEPS_64BIT )
611
633
612
634
#define KHASH_MAP_INIT_INT64 (name , khval_t ) \
613
- KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal)
635
+ KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal, LINEAR_STEPS_64BIT )
614
636
615
637
616
638
typedef const char * kh_cstr_t ;
@@ -619,15 +641,15 @@ typedef const char *kh_cstr_t;
619
641
@param name Name of the hash table [symbol]
620
642
*/
621
643
#define KHASH_SET_INIT_STR (name ) \
622
- KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal)
644
+ KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal, LINEAR_STEPS_BIG_OBJECT )
623
645
624
646
/*! @function
625
647
@abstract Instantiate a hash map containing const char* keys
626
648
@param name Name of the hash table [symbol]
627
649
@param khval_t Type of values [type]
628
650
*/
629
651
#define KHASH_MAP_INIT_STR (name , khval_t ) \
630
- KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
652
+ KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal, LINEAR_STEPS_BIG_OBJECT )
631
653
632
654
633
655
#define kh_exist_str (h , k ) (kh_exist(h, k))
0 commit comments