/** * Return the hash function of value. */ unary_function_t hash_multimap_hash(const hash_multimap_t* cphmmap_map) { assert(cphmmap_map != NULL); assert(_pair_is_inited(&cphmmap_map->_pair_temp)); return _hashtable_hash(&cphmmap_map->_t_hashtable); }
void _hashtable_rehash(HASHTABLE *t, size_t newsize) { ARRAY table; DLIST *bucket; size_t i, j, hash; DLIST_ITER it, end; array_init(&table, sizeof(DLIST)); array_resize(&table, newsize); for (i = 0; i != newsize; ++i) { dlist_init((DLIST*)array_at(&table, i), t->element_size); } j = array_size(&t->table); for (i = 0; i != j; ++i) { bucket = (DLIST*)array_at(&t->table, i); if (dlist_size(bucket)) { end = dlist_end(bucket); for (it = dlist_begin(bucket); it != end; it = dlist_next(it)) { hash = _hashtable_hash(t, dlist_at(it)) % newsize; dlist_push((DLIST*)array_at(&table, hash), dlist_at(it)); } } } array_destroy(&t->table); memcpy(&t->table, &table, sizeof(ARRAY)); }
const void *hashtable_find(HASHTABLE *t, const void *key) { size_t hash; DLIST *bucket; DLIST_ITER it, end; hash = _hashtable_hash(t, key) % array_size(&t->table); bucket = (DLIST*)array_at(&t->table, hash); if (dlist_size(bucket) == 0) return NULL; end = dlist_end(bucket); for (it = dlist_begin(bucket); it != end; it = dlist_next(it)) { if (t->compare(key, dlist_at(it)) == 0) { return dlist_at(it); } } return NULL; }
int hashtable_remove(HASHTABLE *t, const void *key) { size_t hash; DLIST *bucket; DLIST_ITER it, end; hash = _hashtable_hash(t, key) % array_size(&t->table); bucket = (DLIST*)array_at(&t->table, hash); if (dlist_size(bucket) == 0) return -1; end = dlist_end(bucket); for (it = dlist_begin(bucket); it != end; it = dlist_next(it)) { if (t->compare(key, dlist_at(it)) == 0) { dlist_remove(bucket, it); --t->size; return 0; } } return -1; }
void hashtable_insert(HASHTABLE *t, const void *key) { size_t size, hash; DLIST *bucket; DLIST_ITER it, end; size = array_size(&t->table); if ((long double)t->size / size >= 0.77) { _hashtable_rehash(t, size*2); } size = array_size(&t->table); hash = _hashtable_hash(t, key) % size; bucket = (DLIST*)array_at(&t->table, hash); end = dlist_end(bucket); for (it = dlist_begin(bucket); it != end; it = dlist_next(it)) { if (t->compare(key, dlist_at(it)) == 0) { memcpy(dlist_at(it), key, t->element_size); return; } } dlist_push(bucket, key); ++t->size; }
/** * Return the hash function. */ unary_function_t hash_set_hash(const hash_set_t* cphset_set) { assert(cphset_set != NULL); return _hashtable_hash(&cphset_set->_t_hashtable); }