#include #include 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); }