static void check_rehash(struct chashtable *cht) { if(cht->used / cht->size < MAX_REHASH_RATIO) { return; } int new_size = cht->size * 2; struct chashtable*new_cht; new_cht = chash_init(new_size, cht->comp_func, cht->hash_func); if(!new_cht) { return; } chash_set_dup_func(new_cht, cht->dk_func, cht->dv_func); chash_set_free_func(new_cht, cht->fk_func, cht->fv_func); int i; uint64_t ind; struct bucket *curr, *next; for(i = 0; i < cht->size; i++) { curr = cht->buckets[i]; while(curr) { next = curr->next; ind = new_cht->hash_func(curr->key) & (new_size - 1); curr->next = new_cht->buckets[ind]; new_cht->buckets[ind] = curr; new_cht->used++; curr = next; } } // replace new buckets to old chashtbale. struct bucket **tmp_buckets; cht->size = new_size; tmp_buckets = cht->buckets; cht->buckets = new_cht->buckets; new_cht->buckets = tmp_buckets; free(new_cht->buckets); free(new_cht); }
static int test_chash(void) { test_start("chash"); chash_t h; chash_init(&h, 12); for (int i = 0; i < 1024; i++) { chash_set(&h, i, (chash_item_t) 0x3F1); } for (int i = 0; i < 1024; i++) { int t = (int) chash_get(&h, i); test_assert(t == 0x3F1); } chash_remove(&h, 123); test_assert(chash_get(&h, 123) == NULL); int f = chash_find_free(&h, 100, 200); test_assert(f == 123); for (int i = 0; i < 1024; i++) { chash_remove(&h, i); } chash_release(&h); return test_success(); }