39#define LOADFACTOR_NUMERATOR 2
40#define LOADFACTOR_DENOMINATOR 3
41#if LOADFACTOR_NUMERATOR > LOADFACTOR_DENOMINATOR
42# error LOADFACTOR_NUMERATOR must be less than LOADFACTOR_DENOMINATOR
114 ASSERT(hash_func != NULL);
136 ASSERT(hash_func != NULL);
146 dct->
_vtable = &hashtable_vtable;
170 const unsigned hash = table->
hash_func(key);
171 const unsigned mhash = hash % table->
size;
174 while (node && hash >= node->
hash) {
193 table->
table[mhash] = add;
206 const unsigned hash = table->
hash_func(key);
208 while (node && hash >= node->
hash) {
235 const unsigned hash = table->
hash_func(key);
236 const unsigned mhash = hash % table->
size;
239 while (node && hash >= node->
hash) {
242 remove_node(table, node, mhash);
253 for (
unsigned slot = 0; slot < table->
size; slot++) {
255 while (node != NULL) {
257 if (delete_func) delete_func(node->
key, node->
datum);
261 table->
table[slot] = NULL;
264 const size_t count = table->
count;
273 for (
unsigned i = 0; i < table->
size; i++) {
276 if (!visit(node->
key, node->
datum, user_data))
return count;
298 for (
unsigned i = 0; i < table->
size; i++)
310 if (table->
size == new_size)
return true;
314 if (!ntable)
return false;
316 memset(ntable, 0, new_size *
sizeof(
hash_node*));
318 for (
unsigned i = 0; i < table->
size; i++) {
321 const unsigned mhash = node->
hash % new_size;
324 while (search && node->
hash >= search->
hash) {
326 search = search->
next;
328 if ((node->next = search) != NULL)
330 if ((node->prev = prev) != NULL)
333 ntable[mhash] = node;
339 table->
table = ntable;
340 table->
size = new_size;
347 for (
unsigned slot = 0; slot < table->
size; ++slot) {
349 if (n == table->
table[slot]) {
353 VERIFY(n->prev->next == n);
356 VERIFY(n->next->prev == n);
357 VERIFY(n->hash <= n->next->hash);
386 itor->
_vtable = &hashtable_itor_vtable;
400 return itor->
node != NULL;
419 unsigned slot = itor->
slot;
420 while (++slot < itor->table->
size) {
429 return itor->
node != NULL;
441 unsigned slot = itor->
slot;
464 return itor->
node != NULL;
474 return itor->
node != NULL;
480 for (
unsigned slot = 0; slot < itor->
table->
size; ++slot) {
495 for (
unsigned slot = itor->
table->
size; slot > 0;) {
514 const unsigned mhash = hash % itor->
table->
size;
516 while (node && hash >= node->
hash) {
dict_remove_result(* dict_remove_func)(void *obj, const void *key)
int(* dict_compare_func)(const void *, const void *)
bool(* dict_select_func)(void *obj, size_t n, const void **key, void **datum)
void(* dict_invalidate_func)(void *itor)
size_t(* dict_traverse_func)(void *obj, dict_visit_func visit, void *user_data)
dict_insert_result(* dict_insert_func)(void *obj, void *key)
void(* dict_delete_func)(void *, void *)
int(* dict_icompare_func)(void *itor1, void *itor2)
bool(* dict_nextn_func)(void *itor, size_t count)
bool(* dict_valid_func)(const void *itor)
size_t(* dict_count_func)(const void *obj)
bool(* dict_first_func)(void *itor)
bool(* dict_next_func)(void *itor)
void *(* dict_key_func)(void *itor)
unsigned(* dict_hash_func)(const void *)
size_t(* dict_dfree_func)(void *obj, dict_delete_func delete_func)
void **(* dict_datum_func)(void *itor)
bool(* dict_prevn_func)(void *itor, size_t count)
void **(* dict_search_func)(void *obj, const void *key)
bool(* dict_isearch_func)(void *itor, const void *key)
bool(* dict_iremove_func)(void *itor)
bool(* dict_prev_func)(void *itor)
dict_itor *(* dict_inew_func)(void *obj)
bool(* dict_last_func)(void *itor)
bool(* dict_verify_func)(const void *obj)
bool(* dict_visit_func)(const void *, void *, void *)
size_t(* dict_clear_func)(void *obj, dict_delete_func delete_func)
void(* dict_ifree_func)(void *itor)
size_t hashtable_free(hashtable *table, dict_delete_func delete_func)
#define LOADFACTOR_NUMERATOR
bool hashtable_itor_search(hashtable_itor *itor, const void *key)
dict_remove_result hashtable_remove(hashtable *table, const void *key)
dict_itor * hashtable_dict_itor_new(hashtable *table)
hashtable_itor * hashtable_itor_new(hashtable *table)
bool hashtable_verify(const hashtable *table)
bool hashtable_itor_last(hashtable_itor *itor)
bool hashtable_itor_next(hashtable_itor *itor)
bool hashtable_itor_first(hashtable_itor *itor)
size_t hashtable_count(const hashtable *table)
bool hashtable_itor_prevn(hashtable_itor *itor, size_t count)
#define LOADFACTOR_DENOMINATOR
dict_insert_result hashtable_insert(hashtable *table, void *key)
void ** hashtable_itor_datum(hashtable_itor *itor)
bool hashtable_itor_remove(hashtable_itor *itor)
void hashtable_itor_free(hashtable_itor *itor)
bool hashtable_resize(hashtable *table, unsigned new_size)
bool hashtable_itor_nextn(hashtable_itor *itor, size_t count)
size_t hashtable_clear(hashtable *table, dict_delete_func delete_func)
bool hashtable_itor_prev(hashtable_itor *itor)
void hashtable_itor_invalidate(hashtable_itor *itor)
size_t hashtable_traverse(hashtable *table, dict_visit_func visit, void *user_data)
dict * hashtable_dict_new(dict_compare_func cmp_func, dict_hash_func hash_func, unsigned size)
bool hashtable_itor_valid(const hashtable_itor *itor)
void ** hashtable_search(hashtable *table, const void *key)
size_t hashtable_size(const hashtable *table)
size_t hashtable_slots_used(const hashtable *table)
const void * hashtable_itor_key(const hashtable_itor *itor)
hashtable * hashtable_new(dict_compare_func cmp_func, dict_hash_func hash_func, unsigned size)
unsigned dict_prime_geq(unsigned n)
const itor_vtable * _vtable
const dict_vtable * _vtable
dict_compare_func cmp_func