void *core_map_add(struct core_map *self, void *key) { #ifdef CORE_MAP_ALIGNMENT_ENABLED key = core_map_pad_key(self, key); #endif return core_dynamic_hash_table_add(&self->table, key); }
void *core_dynamic_hash_table_add(struct core_dynamic_hash_table *self, void *key) { float ratio; float threshold; void *bucket; void *new_bucket; int value_size; /* if no resize is in progress, the load is verified */ if (!self->resize_in_progress) { threshold = self->resize_load_threshold; ratio = (0.0 + core_hash_table_size(self->current)) / core_hash_table_buckets(self->current); if (ratio < threshold) { /* there is still place in the table. */ return core_hash_table_add(self->current, key); } else { /* the resizing must begin */ #ifdef CORE_DYNAMIC_HASH_TABLE_DEBUG_ADD printf("DEBUG core_dynamic_hash_table_add start resizing\n"); #endif core_dynamic_hash_table_start_resizing(self); /* perform a fancy recursive call */ return core_dynamic_hash_table_add(self, key); } } /* if the resizing finished, just add the item to current */ if (core_dynamic_hash_table_resize(self)) { return core_hash_table_add(self->current, key); } /* * the next table has the key * don't add anything. */ bucket = core_hash_table_get(self->next, key); if (bucket != NULL) { return bucket; } /* * Otherwise, check if it is in the old one */ bucket = core_hash_table_get(self->current, key); /* * If it is not in the current, simply add it to * the next */ if (bucket == NULL) { return core_hash_table_add(self->next, key); } /* Otherwise, add it to the next, copy the value, * and return the bucket from next */ new_bucket = core_hash_table_add(self->next, key); value_size = core_hash_table_value_size(self->current); if (value_size > 0) { core_memory_copy(new_bucket, bucket, value_size); } self->resize_current_size--; return new_bucket; }
int main(int argc, char **argv) { BEGIN_TESTS(); { struct core_dynamic_hash_table table; uint64_t i; uint64_t elements; elements = 900; core_dynamic_hash_table_init(&table, 1140, sizeof(int), 0); for (i = 0; i < elements; i++) { /* printf("insert %d\n", i); printf("before actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i); */ TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i); core_dynamic_hash_table_add(&table, &i); /* printf("after1 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1); */ TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1); /* printf("after2 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1); */ TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1); /* printf("after3 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1); */ TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1); /* printf("after4 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1); */ TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1); /* printf("after5 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1); */ TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1); /* printf("after6 actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), i + 1); */ } core_dynamic_hash_table_destroy(&table); } { struct core_dynamic_hash_table table; struct core_dynamic_hash_table_iterator iterator; int key_size; int value_size; uint64_t buckets; uint64_t i; int j; uint64_t inserted; int key; int *key_bucket; int *value_bucket; int found; key_size = sizeof(int); value_size = sizeof(int); buckets = 4; inserted = 0; core_dynamic_hash_table_init(&table, buckets, key_size, value_size); for (i = 0; i < buckets; i++) { key = inserted; value_bucket = core_dynamic_hash_table_add(&table, &key); inserted++; TEST_POINTER_NOT_EQUALS(value_bucket, NULL); *value_bucket = i; TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), inserted); value_bucket = core_dynamic_hash_table_get(&table, &key); TEST_POINTER_NOT_EQUALS(value_bucket, NULL); } key = inserted; value_bucket = core_dynamic_hash_table_add(&table, &key); inserted++; for (j = 0; j < 1000; j++) { for (i = 0; i < buckets; i++) { key = inserted; value_bucket = core_dynamic_hash_table_add(&table, &key); inserted++; TEST_POINTER_NOT_EQUALS(value_bucket, NULL); *value_bucket = i; /* printf("DEBUG actual %d expected %d\n", (int)core_dynamic_hash_table_size(&table), inserted); */ TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), inserted); value_bucket = core_dynamic_hash_table_get(&table, &key); TEST_POINTER_NOT_EQUALS(value_bucket, NULL); } } key = 9999; value_bucket = core_dynamic_hash_table_add(&table, &key); *value_bucket = 8888; core_dynamic_hash_table_iterator_init(&iterator, &table); i = 0; found = 0; while (core_dynamic_hash_table_iterator_has_next(&iterator)) { core_dynamic_hash_table_iterator_next(&iterator, (void **)&key_bucket, (void **)&value_bucket); if (*key_bucket == 9999 && *value_bucket == 8888) { found = 1; } i++; } TEST_UINT64_T_EQUALS(i, core_dynamic_hash_table_size(&table)); TEST_INT_EQUALS(found, 1); core_dynamic_hash_table_iterator_destroy(&iterator); core_dynamic_hash_table_destroy(&table); } { struct core_dynamic_hash_table table; int key; int *value; /* printf("-------------------\n"); printf("DEBUG TEST-alpha-89\n"); */ core_dynamic_hash_table_init(&table, 8, sizeof(int), sizeof(int)); for (key = 0; key < 1000000; key++) { /* printf("DEBUG key %d\n", key); */ core_dynamic_hash_table_add(&table, &key); value = (int *)core_dynamic_hash_table_get(&table, &key); TEST_POINTER_NOT_EQUALS(value, NULL); *value = key; } core_dynamic_hash_table_destroy(&table); } { struct core_dynamic_hash_table table; uint64_t i; core_dynamic_hash_table_init(&table, 2, sizeof(int), sizeof(int)); for (i = 0; i < 999; i++) { core_dynamic_hash_table_add(&table, &i); TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1); } core_dynamic_hash_table_destroy(&table); } { struct core_dynamic_hash_table table; uint64_t i; void *bucket; core_dynamic_hash_table_init(&table, 2, sizeof(int), 128); for (i = 0; i < 999; i++) { core_dynamic_hash_table_add(&table, &i); TEST_UINT64_T_EQUALS(core_dynamic_hash_table_size(&table), i + 1); } for (i = 0; i < 999; i++) { bucket = core_dynamic_hash_table_get(&table, &i); TEST_POINTER_NOT_EQUALS(bucket, NULL); } core_dynamic_hash_table_destroy(&table); } END_TESTS(); return 0; }