Files
PixelDefense/engine/libs/flecs/test/collections/src/Map.c

500 lines
12 KiB
C

#include <collections.h>
#include <stdlib.h>
static
uint64_t* generate_keys(
int count)
{
uint64_t *keys = ecs_os_malloc_n(uint64_t, count);
for (int i = 0; i < count; i ++) {
keys[i] = i + 1;
}
return keys;
}
static
uint64_t* generate_random_keys(
int count)
{
uint64_t *keys = ecs_os_malloc_n(uint64_t, count);
for (int i = 0; i < count; i ++) {
uint64_t key;
int j = 0;
do {
key = rand() % RAND_MAX;
if (rand() % 2) {
key = ecs_pair(key, rand() % RAND_MAX);
}
for (j = 0; j < i; j ++) {
if (keys[j] == key) {
break;
}
}
} while (j != i); /* no duplicate keys */
keys[i] = key;
}
return keys;
}
static
void insert_map(
ecs_map_t *map,
uint64_t *keys,
int count)
{
for (int i = 0; i < count; i ++) {
for (int j = 0; j < i; j ++) {
uint64_t *v = ecs_map_get(map, keys[j]);
test_assert(v != NULL);
test_assert(v[0] == keys[j]);
}
test_assert(ecs_map_count(map) == i);
test_assert(ecs_map_get(map, keys[i]) == NULL);
ecs_map_insert(map, keys[i], keys[i]);
test_assert(ecs_map_get(map, keys[i])[0] == keys[i]);
test_assert(ecs_map_count(map) == (i + 1));
}
}
static
ecs_map_t populate_map(
uint64_t *keys,
int count)
{
ecs_map_t map;
ecs_map_init(&map, NULL);
insert_map(&map, keys, count);
return map;
}
static
void free_map(
ecs_map_t *map,
uint64_t *keys,
int count)
{
for (int i = 0; i < count; i ++) {
for (int j = i; j < count; j ++) {
uint64_t *v = ecs_map_get(map, keys[j]);
test_assert(v != NULL);
test_assert(v[0] == keys[j]);
}
test_assert(ecs_map_count(map) == (count - i));
test_assert(ecs_map_get(map, keys[i]) != NULL);
ecs_map_remove(map, keys[i]);
test_assert(ecs_map_count(map) == ((count - i) - 1));
test_assert(ecs_map_get(map, keys[i]) == NULL);
}
}
static int32_t malloc_count;
static
void *test_malloc(ecs_size_t size) {
malloc_count ++;
return malloc(size);
}
static
void *test_calloc(ecs_size_t size) {
malloc_count ++;
return calloc(1, size);
}
static
void *test_realloc(void *old_ptr, ecs_size_t size) {
malloc_count ++;
return realloc(old_ptr, size);
}
void Map_setup(void) {
ecs_os_set_api_defaults();
ecs_os_api_t os_api = ecs_os_api;
os_api.malloc_ = test_malloc;
os_api.calloc_ = test_calloc;
os_api.realloc_ = test_realloc;
ecs_os_set_api(&os_api);
}
void Map_count(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
test_int(ecs_map_count(&map), 4);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_count_empty(void) {
ecs_map_t map;
ecs_map_init(&map, NULL);
test_int(ecs_map_count(&map), 0);
ecs_map_fini(&map);
}
void Map_set_overwrite(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
uint64_t *val = ecs_map_get(&map, 1);
test_int(*val, 1);
uint64_t *el = ecs_map_ensure(&map, 1);
test_assert(val == el);
test_int(ecs_map_count(&map), 4);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_set_rehash(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
test_int(map.bucket_count, 4);
int i;
for (i = 5; i < 16; i ++) {
uint64_t *ptr = ecs_map_ensure(&map, i);
*ptr = i;
}
test_int(map.bucket_count, 32);
for (i = 1; i < 16; i ++) {
test_int(ecs_map_get(&map, i)[0], i);
}
for (i = 1; i < 8; i ++) {
uint64_t *ptr = ecs_map_ensure(&map, i + 1000000);
*ptr = i + 1000000;
}
test_int(map.bucket_count, 32);
for (i = 1; i < 16; i ++) {
test_int(ecs_map_get(&map, i)[0], i);
}
for (i = 1; i < 8; i ++) {
test_int(ecs_map_get(&map, i + 1000000)[0], i + 1000000);
}
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_get(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
uint64_t *value = ecs_map_get(&map, 1);
test_assert(value != NULL);
test_int(value[0], 1);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_get_all(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
uint64_t *value = ecs_map_get(&map, 1);
test_assert(value != NULL);
test_int(*value, 1);
value = ecs_map_get(&map, 2);
test_assert(value != NULL);
test_int(*value, 2);
value = ecs_map_get(&map, 3);
test_assert(value != NULL);
test_int(*value, 3);
value = ecs_map_get(&map, 4);
test_assert(value != NULL);
test_int(*value, 4);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_get_empty(void) {
ecs_map_t map;
ecs_map_init(&map, NULL);
uint64_t *value = ecs_map_get(&map, 1);
test_assert(value == NULL);
ecs_map_fini(&map);
}
void Map_get_unknown(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
uint64_t *value = ecs_map_get(&map, 5);
test_assert(value == NULL);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_get_0_from_empty(void) {
ecs_map_t map;
ecs_map_init(&map, NULL);
uint64_t *value = ecs_map_get(&map, 0);
test_assert(value == NULL);
ecs_map_fini(&map);
}
void Map_get_0_from_populated(void) {
uint64_t *keys = generate_keys(32);
ecs_map_t map = populate_map(keys, 32);
uint64_t *value = ecs_map_get(&map, 0);
test_assert(value == NULL);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_get_0_after_insert(void) {
ecs_map_t map;
ecs_map_init(&map, NULL);
ecs_map_insert(&map, 0, 10);
uint64_t *value = ecs_map_get(&map, 0);
test_assert(value != NULL);
test_int(value[0], 10);
ecs_map_fini(&map);
}
void Map_get_0_after_ensure(void) {
ecs_map_t map;
ecs_map_init(&map, NULL);
ecs_map_ensure(&map, 0)[0] = 10;
uint64_t *value = ecs_map_get(&map, 0);
test_assert(value != NULL);
test_int(value[0], 10);
ecs_map_fini(&map);
}
void Map_iter(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
int i = 0;
ecs_map_iter_t it = ecs_map_iter(&map);
while (ecs_map_next(&it)) {
ecs_map_key_t key = ecs_map_key(&it);
uint64_t val = ecs_map_value(&it);
test_assert(key == val);
i ++;
}
test_int(i, 4);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_iter_empty(void) {
ecs_map_t map;
ecs_map_init(&map, NULL);
ecs_map_iter_t it = ecs_map_iter(&map);
test_assert(!ecs_map_next(&it));
ecs_map_fini(&map);
}
void Map_iter_null(void) {
ecs_map_iter_t it = ecs_map_iter(NULL);
test_assert(!ecs_map_next(&it));
}
void Map_remove(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
test_assert(ecs_map_get(&map, 3) != NULL);
test_int(ecs_map_count(&map), 4);
ecs_map_remove(&map, 3);
test_assert(ecs_map_get(&map, 3) == NULL);
test_int(ecs_map_count(&map), 3);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_remove_empty(void) {
ecs_map_t map;
ecs_map_init(&map, NULL);
ecs_map_remove(&map, 3);
test_int(ecs_map_count(&map), 0);
ecs_map_fini(&map);
}
void Map_remove_unknown(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
test_assert(ecs_map_get(&map, 5) == NULL);
test_int(ecs_map_count(&map), 4);
ecs_map_remove(&map, 5);
test_int(ecs_map_get(&map, 1)[0], 1);
test_int(ecs_map_get(&map, 2)[0], 2);
test_int(ecs_map_get(&map, 3)[0], 3);
test_int(ecs_map_get(&map, 4)[0], 4);
test_int(ecs_map_count(&map), 4);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_remove_twice(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
test_assert(ecs_map_get(&map, 3) != NULL);
test_int(ecs_map_count(&map), 4);
ecs_map_remove(&map, 3);
test_assert(ecs_map_get(&map, 3) == NULL);
test_int(ecs_map_count(&map), 3);
ecs_map_remove(&map, 3);
test_assert(ecs_map_get(&map, 3) == NULL);
test_int(ecs_map_count(&map), 3);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_clear_empty(void) {
ecs_map_t map;
ecs_map_init(&map, NULL);
ecs_map_clear(&map);
test_int(ecs_map_count(&map), 0);
ecs_map_fini(&map);
}
void Map_clear_populated(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
test_int(ecs_map_count(&map), 4);
ecs_map_clear(&map);
test_int(ecs_map_count(&map), 0);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_clear_empty_twice(void) {
ecs_map_t map;
ecs_map_init(&map, NULL);
ecs_map_clear(&map);
test_int(ecs_map_count(&map), 0);
ecs_map_clear(&map);
test_int(ecs_map_count(&map), 0);
ecs_map_fini(&map);
}
void Map_clear_populated_twice(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
test_int(ecs_map_count(&map), 4);
ecs_map_clear(&map);
test_int(ecs_map_count(&map), 0);
ecs_map_clear(&map);
test_int(ecs_map_count(&map), 0);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_populate_after_clear(void) {
uint64_t *keys = generate_keys(4);
ecs_map_t map = populate_map(keys, 4);
test_int(ecs_map_count(&map), 4);
ecs_map_clear(&map);
test_int(ecs_map_count(&map), 0);
insert_map(&map, keys, 4);
test_int(ecs_map_count(&map), 4);
ecs_map_clear(&map);
test_int(ecs_map_count(&map), 0);
ecs_os_free(keys);
ecs_map_fini(&map);
}
void Map_randomized_insert(void) {
uint64_t *keys = generate_random_keys(100);
for (int count = 0; count < 100; count ++) {
ecs_map_t map = populate_map(keys, count);
test_int(ecs_map_count(&map), count);
ecs_map_fini(&map);
}
ecs_os_free(keys);
}
void Map_randomized_remove(void) {
uint64_t *keys = generate_random_keys(100);
for (int count = 0; count < 100; count ++) {
ecs_map_t map = populate_map(keys, count);
test_int(ecs_map_count(&map), count);
free_map(&map, keys, count);
test_int(ecs_map_count(&map), 0);
ecs_map_fini(&map);
}
ecs_os_free(keys);
}
void Map_randomized_insert_large(void) {
uint64_t *keys = generate_random_keys(1000);
for (int count = 0; count < 1000; count += 27) {
ecs_map_t map = populate_map(keys, count);
test_int(ecs_map_count(&map), count);
ecs_map_fini(&map);
}
ecs_os_free(keys);
}
void Map_randomized_remove_large(void) {
uint64_t *keys = generate_random_keys(1000);
for (int count = 0; count < 1000; count += 50) {
ecs_map_t map = populate_map(keys, count);
test_int(ecs_map_count(&map), count);
free_map(&map, keys, count);
test_int(ecs_map_count(&map), 0);
ecs_map_fini(&map);
}
ecs_os_free(keys);
}
void Map_randomized_after_clear(void) {
uint64_t *keys = generate_random_keys(1000);
for (int count = 0; count < 1000; count += 50) {
ecs_map_t map = populate_map(keys, count);
test_int(ecs_map_count(&map), count);
ecs_map_clear(&map);
test_int(ecs_map_count(&map), 0);
insert_map(&map, keys, count);
test_int(ecs_map_count(&map), count);
ecs_map_fini(&map);
}
ecs_os_free(keys);
}