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
109 ASSERT(hash_func != NULL);
131 ASSERT(hash_func != NULL);
141 dct->
_vtable = &hashtable2_vtable;
156insert(
hashtable2* table,
void *key,
unsigned hash)
172 if (++node == table_end)
174 }
while (node != first);
179static inline unsigned
182 const unsigned hash = hash_func(key);
183 return hash ? hash : ~(unsigned)0;
195 const unsigned hash = nonzero_hash(table->
hash_func, key);
205 const unsigned hash = nonzero_hash(table->
hash_func, key);
216 if (++node == table_end)
218 }
while (node != first);
224index_of_node_to_shift(
hashtable2* table,
unsigned truncated_hash,
unsigned index)
232 if (node->
hash % table->
size == truncated_hash) {
235 if (++index == table->
size) {
238 }
while (index != truncated_hash);
248 const unsigned hash = node->
hash;
252 void*
const datum = node->
datum;
262 if (++node == table_end)
264 }
while (node != first);
276 if (++node == table->
table + table->
size)
278 remove_cleanup(table, first, node);
284 const unsigned hash = nonzero_hash(table->
hash_func, key);
294 remove_node(table, first, node);
298 if (++node == table_end)
300 }
while (node != first);
309 for (; node != end; ++node) {
311 if (delete_func) delete_func(node->
key, node->
datum);
317 const size_t count = table->
count;
330 if (!visit(node->
key, node->
datum, user_data))
break;
360 if (table->
size == new_size)
363 if (table->
count > new_size) {
368 const unsigned old_size = table->
size;
369 const size_t old_count = table->
count;
374 table->
table = old_table;
378 table->
size = new_size;
380 for (
unsigned i = 0; i < old_size; ++i) {
381 if (old_table[i].hash) {
383 insert(table, old_table[i].key, old_table[i].hash);
386 table->
table = old_table;
387 table->
size = old_size;
388 table->
count = old_count;
404 for (; node != end; ++node) {
435 itor->
_vtable = &hashtable2_itor_vtable;
481 while (itor->
slot-- > 0) {
495 return itor->
slot >= 0;
504 return itor->
slot >= 0;
510 for (
unsigned slot = 0; slot < itor->
table->
size; ++slot) {
512 itor->
slot = (int) slot;
523 for (
unsigned slot = itor->
table->
size; slot > 0;) {
525 itor->
slot = (int) slot;
537 const unsigned truncated_hash = hash % itor->
table->
size;
538 unsigned index = truncated_hash;
544 itor->
slot = (int) index;
549 }
while (index != truncated_hash);
571 remove_node(itor->
table,
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)
bool hashtable2_verify(const hashtable2 *table)
hashtable2_itor * hashtable2_itor_new(hashtable2 *table)
dict_itor * hashtable2_dict_itor_new(hashtable2 *table)
void ** hashtable2_search(hashtable2 *table, const void *key)
bool hashtable2_itor_nextn(hashtable2_itor *itor, size_t count)
#define LOADFACTOR_NUMERATOR
size_t hashtable2_free(hashtable2 *table, dict_delete_func delete_func)
bool hashtable2_itor_valid(const hashtable2_itor *itor)
bool hashtable2_itor_prev(hashtable2_itor *itor)
void ** hashtable2_itor_datum(hashtable2_itor *itor)
bool hashtable2_itor_remove(hashtable2_itor *itor)
size_t hashtable2_clear(hashtable2 *table, dict_delete_func delete_func)
#define LOADFACTOR_DENOMINATOR
dict_insert_result hashtable2_insert(hashtable2 *table, void *key)
void hashtable2_itor_invalidate(hashtable2_itor *itor)
hashtable2 * hashtable2_new(dict_compare_func cmp_func, dict_hash_func hash_func, unsigned initial_size)
size_t hashtable2_count(const hashtable2 *table)
size_t hashtable2_slots_used(const hashtable2 *table)
size_t hashtable2_size(const hashtable2 *table)
void hashtable2_itor_free(hashtable2_itor *itor)
bool hashtable2_resize(hashtable2 *table, unsigned new_size)
bool hashtable2_itor_prevn(hashtable2_itor *itor, size_t count)
bool hashtable2_itor_first(hashtable2_itor *itor)
const void * hashtable2_itor_key(const hashtable2_itor *itor)
bool hashtable2_itor_next(hashtable2_itor *itor)
dict_remove_result hashtable2_remove(hashtable2 *table, const void *key)
size_t hashtable2_traverse(hashtable2 *table, dict_visit_func visit, void *user_data)
bool hashtable2_itor_search(hashtable2_itor *itor, const void *key)
bool hashtable2_itor_last(hashtable2_itor *itor)
dict * hashtable2_dict_new(dict_compare_func cmp_func, dict_hash_func hash_func, unsigned initial_size)
unsigned dict_prime_geq(unsigned n)
const itor_vtable * _vtable
const dict_vtable * _vtable
dict_compare_func cmp_func