void *collections_list_get_ith_item(collections_listnode *start, uint32_t item) { uint32_t n = collections_list_size(start); if (item >= n) { return NULL; } else if (item <= n / 2) { collections_listnode* cur = start->next; while (item != 0) { cur = cur->next; item--; } return cur->data; } else { collections_listnode *cur = start; do { cur = cur->prev; item++; } while (item != n); return cur->data; } }
static collections_listnode* collections_hash_get_next_valid_bucket(collections_hash_table* t) { collections_listnode* bucket; do { t->cur_bucket_num ++; if (t->cur_bucket_num < t->num_buckets) { if (!t->buckets[t->cur_bucket_num]) { continue; } } else { return NULL; } } while (collections_list_size(t->buckets[t->cur_bucket_num]) <= 0); bucket = t->buckets[t->cur_bucket_num]; collections_list_traverse_start(bucket); return bucket; }
// delete the entire hash table void collections_hash_release(collections_hash_table *t) { int bucket_num; int bucket_size; collections_listnode *bucket; for (bucket_num = 0; bucket_num < t->num_buckets; bucket_num ++) { uint32_t before, after; bucket = t->buckets[bucket_num]; bucket_size = collections_list_size(bucket); before = t->num_elems; collections_list_visit(bucket, collections_hash_release_elem, t); after = t->num_elems; assert(before - after == bucket_size); collections_list_release(bucket); } assert(t->num_elems == 0); free(t->buckets); free(t); }