1*1208bc7eSAndroid Build Coastguard Worker #ifndef JEMALLOC_INTERNAL_CKH_H 2*1208bc7eSAndroid Build Coastguard Worker #define JEMALLOC_INTERNAL_CKH_H 3*1208bc7eSAndroid Build Coastguard Worker 4*1208bc7eSAndroid Build Coastguard Worker #include "jemalloc/internal/tsd.h" 5*1208bc7eSAndroid Build Coastguard Worker 6*1208bc7eSAndroid Build Coastguard Worker /* Cuckoo hashing implementation. Skip to the end for the interface. */ 7*1208bc7eSAndroid Build Coastguard Worker 8*1208bc7eSAndroid Build Coastguard Worker /******************************************************************************/ 9*1208bc7eSAndroid Build Coastguard Worker /* INTERNAL DEFINITIONS -- IGNORE */ 10*1208bc7eSAndroid Build Coastguard Worker /******************************************************************************/ 11*1208bc7eSAndroid Build Coastguard Worker 12*1208bc7eSAndroid Build Coastguard Worker /* Maintain counters used to get an idea of performance. */ 13*1208bc7eSAndroid Build Coastguard Worker /* #define CKH_COUNT */ 14*1208bc7eSAndroid Build Coastguard Worker /* Print counter values in ckh_delete() (requires CKH_COUNT). */ 15*1208bc7eSAndroid Build Coastguard Worker /* #define CKH_VERBOSE */ 16*1208bc7eSAndroid Build Coastguard Worker 17*1208bc7eSAndroid Build Coastguard Worker /* 18*1208bc7eSAndroid Build Coastguard Worker * There are 2^LG_CKH_BUCKET_CELLS cells in each hash table bucket. Try to fit 19*1208bc7eSAndroid Build Coastguard Worker * one bucket per L1 cache line. 20*1208bc7eSAndroid Build Coastguard Worker */ 21*1208bc7eSAndroid Build Coastguard Worker #define LG_CKH_BUCKET_CELLS (LG_CACHELINE - LG_SIZEOF_PTR - 1) 22*1208bc7eSAndroid Build Coastguard Worker 23*1208bc7eSAndroid Build Coastguard Worker /* Typedefs to allow easy function pointer passing. */ 24*1208bc7eSAndroid Build Coastguard Worker typedef void ckh_hash_t (const void *, size_t[2]); 25*1208bc7eSAndroid Build Coastguard Worker typedef bool ckh_keycomp_t (const void *, const void *); 26*1208bc7eSAndroid Build Coastguard Worker 27*1208bc7eSAndroid Build Coastguard Worker /* Hash table cell. */ 28*1208bc7eSAndroid Build Coastguard Worker typedef struct { 29*1208bc7eSAndroid Build Coastguard Worker const void *key; 30*1208bc7eSAndroid Build Coastguard Worker const void *data; 31*1208bc7eSAndroid Build Coastguard Worker } ckhc_t; 32*1208bc7eSAndroid Build Coastguard Worker 33*1208bc7eSAndroid Build Coastguard Worker /* The hash table itself. */ 34*1208bc7eSAndroid Build Coastguard Worker typedef struct { 35*1208bc7eSAndroid Build Coastguard Worker #ifdef CKH_COUNT 36*1208bc7eSAndroid Build Coastguard Worker /* Counters used to get an idea of performance. */ 37*1208bc7eSAndroid Build Coastguard Worker uint64_t ngrows; 38*1208bc7eSAndroid Build Coastguard Worker uint64_t nshrinks; 39*1208bc7eSAndroid Build Coastguard Worker uint64_t nshrinkfails; 40*1208bc7eSAndroid Build Coastguard Worker uint64_t ninserts; 41*1208bc7eSAndroid Build Coastguard Worker uint64_t nrelocs; 42*1208bc7eSAndroid Build Coastguard Worker #endif 43*1208bc7eSAndroid Build Coastguard Worker 44*1208bc7eSAndroid Build Coastguard Worker /* Used for pseudo-random number generation. */ 45*1208bc7eSAndroid Build Coastguard Worker uint64_t prng_state; 46*1208bc7eSAndroid Build Coastguard Worker 47*1208bc7eSAndroid Build Coastguard Worker /* Total number of items. */ 48*1208bc7eSAndroid Build Coastguard Worker size_t count; 49*1208bc7eSAndroid Build Coastguard Worker 50*1208bc7eSAndroid Build Coastguard Worker /* 51*1208bc7eSAndroid Build Coastguard Worker * Minimum and current number of hash table buckets. There are 52*1208bc7eSAndroid Build Coastguard Worker * 2^LG_CKH_BUCKET_CELLS cells per bucket. 53*1208bc7eSAndroid Build Coastguard Worker */ 54*1208bc7eSAndroid Build Coastguard Worker unsigned lg_minbuckets; 55*1208bc7eSAndroid Build Coastguard Worker unsigned lg_curbuckets; 56*1208bc7eSAndroid Build Coastguard Worker 57*1208bc7eSAndroid Build Coastguard Worker /* Hash and comparison functions. */ 58*1208bc7eSAndroid Build Coastguard Worker ckh_hash_t *hash; 59*1208bc7eSAndroid Build Coastguard Worker ckh_keycomp_t *keycomp; 60*1208bc7eSAndroid Build Coastguard Worker 61*1208bc7eSAndroid Build Coastguard Worker /* Hash table with 2^lg_curbuckets buckets. */ 62*1208bc7eSAndroid Build Coastguard Worker ckhc_t *tab; 63*1208bc7eSAndroid Build Coastguard Worker } ckh_t; 64*1208bc7eSAndroid Build Coastguard Worker 65*1208bc7eSAndroid Build Coastguard Worker /******************************************************************************/ 66*1208bc7eSAndroid Build Coastguard Worker /* BEGIN PUBLIC API */ 67*1208bc7eSAndroid Build Coastguard Worker /******************************************************************************/ 68*1208bc7eSAndroid Build Coastguard Worker 69*1208bc7eSAndroid Build Coastguard Worker /* Lifetime management. Minitems is the initial capacity. */ 70*1208bc7eSAndroid Build Coastguard Worker bool ckh_new(tsd_t *tsd, ckh_t *ckh, size_t minitems, ckh_hash_t *hash, 71*1208bc7eSAndroid Build Coastguard Worker ckh_keycomp_t *keycomp); 72*1208bc7eSAndroid Build Coastguard Worker void ckh_delete(tsd_t *tsd, ckh_t *ckh); 73*1208bc7eSAndroid Build Coastguard Worker 74*1208bc7eSAndroid Build Coastguard Worker /* Get the number of elements in the set. */ 75*1208bc7eSAndroid Build Coastguard Worker size_t ckh_count(ckh_t *ckh); 76*1208bc7eSAndroid Build Coastguard Worker 77*1208bc7eSAndroid Build Coastguard Worker /* 78*1208bc7eSAndroid Build Coastguard Worker * To iterate over the elements in the table, initialize *tabind to 0 and call 79*1208bc7eSAndroid Build Coastguard Worker * this function until it returns true. Each call that returns false will 80*1208bc7eSAndroid Build Coastguard Worker * update *key and *data to the next element in the table, assuming the pointers 81*1208bc7eSAndroid Build Coastguard Worker * are non-NULL. 82*1208bc7eSAndroid Build Coastguard Worker */ 83*1208bc7eSAndroid Build Coastguard Worker bool ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data); 84*1208bc7eSAndroid Build Coastguard Worker 85*1208bc7eSAndroid Build Coastguard Worker /* 86*1208bc7eSAndroid Build Coastguard Worker * Basic hash table operations -- insert, removal, lookup. For ckh_remove and 87*1208bc7eSAndroid Build Coastguard Worker * ckh_search, key or data can be NULL. The hash-table only stores pointers to 88*1208bc7eSAndroid Build Coastguard Worker * the key and value, and doesn't do any lifetime management. 89*1208bc7eSAndroid Build Coastguard Worker */ 90*1208bc7eSAndroid Build Coastguard Worker bool ckh_insert(tsd_t *tsd, ckh_t *ckh, const void *key, const void *data); 91*1208bc7eSAndroid Build Coastguard Worker bool ckh_remove(tsd_t *tsd, ckh_t *ckh, const void *searchkey, void **key, 92*1208bc7eSAndroid Build Coastguard Worker void **data); 93*1208bc7eSAndroid Build Coastguard Worker bool ckh_search(ckh_t *ckh, const void *searchkey, void **key, void **data); 94*1208bc7eSAndroid Build Coastguard Worker 95*1208bc7eSAndroid Build Coastguard Worker /* Some useful hash and comparison functions for strings and pointers. */ 96*1208bc7eSAndroid Build Coastguard Worker void ckh_string_hash(const void *key, size_t r_hash[2]); 97*1208bc7eSAndroid Build Coastguard Worker bool ckh_string_keycomp(const void *k1, const void *k2); 98*1208bc7eSAndroid Build Coastguard Worker void ckh_pointer_hash(const void *key, size_t r_hash[2]); 99*1208bc7eSAndroid Build Coastguard Worker bool ckh_pointer_keycomp(const void *k1, const void *k2); 100*1208bc7eSAndroid Build Coastguard Worker 101*1208bc7eSAndroid Build Coastguard Worker #endif /* JEMALLOC_INTERNAL_CKH_H */ 102