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 test_dlist_reverse_existing(void) { unsigned long old_size, val_check; unsigned long *val; DListIterator *it; old_size = dlist_size(test_dlist); assert_true(dlist_reverse(test_dlist) == 0); /* Verify */ val = NULL; assert_true(old_size == dlist_size(test_dlist)); for(it = dlist_begin(test_dlist), val_check = 999; it != NULL; it = dlist_next(it), val_check--) { val = (unsigned long *)dlist_get_data(it); assert_ulong_equal(val_check, *val); } }
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; }