Files
C-Macro-Collections/tests/main/unt/bidimap.c
T
Leonardo 0089abc84a Added cor folder and cmc_callbacks is now common to all collections
Now every file includes core.h and hashtable-based collections include hashtable.h

The definition of cmc_heap_order has been kept inside heap.h because it is the only collection to use it
2020-03-17 16:10:12 -03:00

534 lines
17 KiB
C

#include "utl.c"
#include <utl/assert.h>
#include <utl/log.h>
#include <utl/test.h>
#include <cmc/bidimap.h>
CMC_GENERATE_BIDIMAP(bm, bidimap, size_t, size_t)
struct bidimap_ftab_key *bm_ftab_key =
&(struct bidimap_ftab_key){ .cmp = cmp,
.cpy = copy,
.str = str,
.free = custom_free,
.hash = hash,
.pri = pri };
struct bidimap_ftab_val *bm_ftab_val =
&(struct bidimap_ftab_val){ .cmp = cmp,
.cpy = copy,
.str = str,
.free = custom_free,
.hash = hash,
.pri = pri };
CMC_CREATE_UNIT(bidimap_test, true, {
CMC_CREATE_TEST(new, {
struct bidimap *map = bm_new(100, 0.6, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map);
cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
bm_free(map);
});
CMC_CREATE_TEST(new[null buffer], {
struct bidimap *map = bm_new(100, 0.6, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map);
for (size_t i = 0; i < map->capacity; i++)
{
cmc_assert_equals(ptr, NULL, map->key_buffer[i]);
cmc_assert_equals(ptr, NULL, map->val_buffer[i]);
}
bm_free(map);
});
CMC_CREATE_TEST(new_custom, {
struct bidimap *map =
bm_new_custom(100, 0.6, bm_ftab_key, bm_ftab_val,
&(struct cmc_alloc_node){ .malloc = malloc,
.calloc = calloc,
.realloc = realloc,
.free = free },
&(struct cmc_callbacks){ 0 });
cmc_assert_not_equals(ptr, NULL, map);
bm_free(map);
});
CMC_CREATE_TEST(new_custom[insert remove], {
struct bidimap *map =
bm_new_custom(500, 0.6, bm_ftab_key, bm_ftab_val,
&(struct cmc_alloc_node){ .malloc = malloc,
.calloc = calloc,
.realloc = realloc,
.free = free },
&(struct cmc_callbacks){ 0 });
cmc_assert_not_equals(ptr, NULL, map);
for (size_t i = 0; i < 500; i++)
cmc_assert(bm_insert(map, i, i));
cmc_assert_equals(size_t, 500, bm_count(map));
for (size_t i = 0; i < 500; i++)
{
if (i % 2 == 0)
{
cmc_assert(bm_remove_by_key(map, i, NULL, NULL));
}
else
{
cmc_assert(bm_remove_by_val(map, i, NULL, NULL));
}
}
cmc_assert_equals(size_t, 0, bm_count(map));
bm_free(map);
});
CMC_CREATE_TEST(clear[count], {
struct bidimap *map = bm_new(100, 0.6, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map);
for (size_t i = 0; i < 500; i++)
cmc_assert(bm_insert(map, i, i));
cmc_assert_equals(size_t, 500, bm_count(map));
bm_clear(map);
cmc_assert_equals(size_t, 0, bm_count(map));
bm_free(map);
});
CMC_CREATE_TEST(buffer_growth[capacity = 1], {
struct bidimap *map = bm_new(1, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map);
for (size_t i = 1; i <= 10000; i++)
cmc_assert(bm_insert(map, i, i));
size_t sum = 0;
for (size_t i = 0; i < bm_capacity(map); i++)
{
if (map->key_buffer[i] && map->key_buffer[i] != CMC_ENTRY_DELETED)
{
sum += map->key_buffer[i]->key;
}
}
cmc_assert_equals(size_t, 50005000, sum);
bm_free(map);
});
CMC_CREATE_TEST(insert, {
struct bidimap *map = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map);
cmc_assert(bm_insert(map, 1, 1));
cmc_assert(!bm_insert(map, 1, 1));
cmc_assert(!bm_insert(map, 2, 1));
cmc_assert(!bm_insert(map, 1, 2));
cmc_assert(bm_insert(map, 2, 2));
cmc_assert_equals(size_t, 2, bm_count(map));
bm_free(map);
});
CMC_CREATE_TEST(insert[growth remove clear], {
struct bidimap *map = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map);
for (size_t i = 1; i <= 1000; i++)
cmc_assert(bm_insert(map, i, i));
cmc_assert_equals(size_t, 1000, bm_count(map));
size_t j = 1;
while (!bm_empty(map))
{
if (bm_count(map) % 2 == 0)
cmc_assert(bm_remove_by_key(map, j++, NULL, NULL));
else
cmc_assert(bm_remove_by_val(map, j++, NULL, NULL));
}
cmc_assert_equals(size_t, 0, bm_count(map));
for (size_t i = 1; i <= 1000; i++)
cmc_assert(bm_insert(map, i, i));
cmc_assert_equals(size_t, 1000, bm_count(map));
bm_clear(map);
cmc_assert_equals(size_t, 0, bm_count(map));
bm_free(map);
});
CMC_CREATE_TEST(update_key, {
struct bidimap *map = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map);
cmc_assert_equals(int32_t, cmc_flags.OK, map->flag);
for (size_t i = 1; i <= 100; i++)
cmc_assert(bm_insert(map, i, i));
cmc_assert_equals(size_t, 100, bm_count(map));
for (size_t i = 100; i > 0; i--)
cmc_assert(bm_update_key(map, i, i + 10));
cmc_assert_equals(size_t, 100, bm_count(map));
for (size_t i = 1; i <= 100; i++)
cmc_assert_equals(size_t, i + 10, bm_get_key(map, i));
cmc_assert_equals(size_t, 100, bm_count(map));
bm_free(map);
});
CMC_CREATE_TEST(update_val, {
struct bidimap *map = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map);
for (size_t i = 1; i <= 100; i++)
cmc_assert(bm_insert(map, i, i));
cmc_assert_equals(size_t, 100, bm_count(map));
for (size_t i = 100; i > 0; i--)
cmc_assert(bm_update_val(map, i, i + 10));
cmc_assert_equals(size_t, 100, bm_count(map));
for (size_t i = 1; i <= 100; i++)
cmc_assert_equals(size_t, i + 10, bm_get_val(map, i));
cmc_assert_equals(size_t, 100, bm_count(map));
bm_free(map);
});
CMC_CREATE_TEST(remove_by_key[cleanup custom], {
struct bidimap *map =
bm_new_custom(10000, 0.6, bm_ftab_key, bm_ftab_val,
&(struct cmc_alloc_node){ .malloc = malloc,
.calloc = calloc,
.realloc = realloc,
.free = free },
&(struct cmc_callbacks){ 0 });
cmc_assert_not_equals(ptr, NULL, map);
for (size_t i = 0; i < 10000; i++)
{
cmc_assert(bm_insert(map, i, i));
}
for (size_t i = 0; i < 10000; i++)
{
cmc_assert(bm_remove_by_key(map, i, NULL, NULL));
}
for (size_t i = 0; i < map->capacity; i++)
{
struct bidimap_entry *k = map->key_buffer[i];
struct bidimap_entry *v = map->val_buffer[i];
cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) &&
(v == NULL || v == CMC_ENTRY_DELETED));
}
bm_free(map);
});
CMC_CREATE_TEST(remove_by_val[cleanup custom], {
struct bidimap *map =
bm_new_custom(10000, 0.6, bm_ftab_key, bm_ftab_val,
&(struct cmc_alloc_node){ .malloc = malloc,
.calloc = calloc,
.realloc = realloc,
.free = free },
&(struct cmc_callbacks){ 0 });
cmc_assert_not_equals(ptr, NULL, map);
for (size_t i = 0; i < 10000; i++)
{
cmc_assert(bm_insert(map, i, i));
}
for (size_t i = 0; i < 10000; i++)
{
cmc_assert(bm_remove_by_val(map, i, NULL, NULL));
}
for (size_t i = 0; i < map->capacity; i++)
{
struct bidimap_entry *k = map->key_buffer[i];
struct bidimap_entry *v = map->val_buffer[i];
cmc_assert((k == NULL || k == CMC_ENTRY_DELETED) &&
(v == NULL || v == CMC_ENTRY_DELETED));
}
bm_free(map);
});
CMC_CREATE_TEST(copy_of, {
struct bidimap *map1 = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
for (size_t i = 0; i < 100; i++)
cmc_assert(bm_insert(map1, i, i));
struct bidimap *map2 = bm_copy_of(map1);
cmc_assert_not_equals(ptr, NULL, map2);
cmc_assert_equals(size_t, bm_count(map1), bm_count(map2));
for (size_t i = 0; i < 100; i++)
{
cmc_assert(bm_contains_key(map2, i) && bm_contains_key(map1, i));
cmc_assert(bm_contains_val(map2, i) && bm_contains_val(map1, i));
}
bm_free(map1);
bm_free(map2);
});
CMC_CREATE_TEST(equals, {
struct bidimap *map1 = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
struct bidimap *map2 = bm_new(1000, 0.9, bm_ftab_key, bm_ftab_val);
for (size_t i = 0; i < 100; i++)
{
cmc_assert(bm_insert(map1, i, i));
cmc_assert(bm_insert(map2, 99 - i, 99 - i));
}
cmc_assert_not_equals(ptr, NULL, map1);
cmc_assert_not_equals(ptr, NULL, map2);
cmc_assert_equals(size_t, bm_count(map1), bm_count(map2));
for (size_t i = 0; i < 100; i++)
{
cmc_assert(bm_contains_key(map2, i) && bm_contains_key(map1, i));
cmc_assert(bm_contains_val(map2, i) && bm_contains_val(map1, i));
}
bm_free(map1);
bm_free(map2);
});
CMC_CREATE_TEST(equals[from copy], {
struct bidimap *map1 = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
for (size_t i = 0; i < 100; i++)
cmc_assert(bm_insert(map1, i, i));
struct bidimap *map2 = bm_copy_of(map1);
cmc_assert_not_equals(ptr, NULL, map2);
cmc_assert(bm_equals(map1, map2));
bm_free(map1);
bm_free(map2);
});
CMC_CREATE_TEST(flags, {
struct bidimap *map = bm_new(100, 0.7, bm_ftab_key, bm_ftab_val);
cmc_assert_not_equals(ptr, NULL, map);
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
// customize
bm_customize(map, &cmc_alloc_node_default,
&(struct cmc_callbacks){ 0 });
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
// Insert
cmc_assert(bm_insert(map, 1, 1));
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
cmc_assert(!bm_insert(map, 1, 2));
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
map->flag = cmc_flags.ERROR;
cmc_assert(!bm_insert(map, 2, 1));
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
// clear
bm_clear(map);
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
// update_key
cmc_assert(!bm_update_key(map, 1, 1));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map));
cmc_assert(bm_insert(map, 1, 1));
cmc_assert(!bm_update_key(map, 2, 1));
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map));
cmc_assert(bm_insert(map, 2, 2));
cmc_assert(!bm_update_key(map, 1, 2));
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
map->flag = cmc_flags.ERROR;
cmc_assert(!bm_update_key(map, 2, 1));
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
// clear
bm_clear(map);
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
// update_key_by_val
cmc_assert(!bm_update_key_by_val(map, 1, 1));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map));
cmc_assert(bm_insert(map, 1, 1));
cmc_assert(!bm_update_key_by_val(map, 2, 1));
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map));
cmc_assert(bm_insert(map, 2, 2));
cmc_assert(!bm_update_key_by_val(map, 2, 1));
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
map->flag = cmc_flags.ERROR;
cmc_assert(!bm_update_key_by_val(map, 1, 2));
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
// clear
bm_clear(map);
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
// update_val
cmc_assert(!bm_update_val(map, 1, 1));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map));
cmc_assert(bm_insert(map, 1, 1));
cmc_assert(!bm_update_val(map, 2, 1));
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map));
cmc_assert(bm_insert(map, 2, 2));
cmc_assert(!bm_update_val(map, 1, 2));
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
map->flag = cmc_flags.ERROR;
cmc_assert(!bm_update_val(map, 2, 1));
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
// clear
bm_clear(map);
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
// update_val_by_key
cmc_assert(!bm_update_val_by_key(map, 1, 1));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map));
cmc_assert(bm_insert(map, 1, 1));
cmc_assert(!bm_update_val_by_key(map, 2, 1));
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map));
cmc_assert(bm_insert(map, 2, 2));
cmc_assert(!bm_update_val_by_key(map, 2, 1));
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
map->flag = cmc_flags.ERROR;
cmc_assert(!bm_update_val_by_key(map, 1, 2));
cmc_assert_equals(int32_t, cmc_flags.DUPLICATE, bm_flag(map));
// remove_by_key
cmc_assert(bm_remove_by_key(map, 1, NULL, NULL));
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
cmc_assert(!bm_remove_by_key(map, 1, NULL, NULL));
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map));
cmc_assert(bm_remove_by_key(map, 2, NULL, NULL));
cmc_assert(!bm_remove_by_key(map, 2, NULL, NULL));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map));
// remove_by_val
cmc_assert(bm_insert(map, 1, 1) && bm_insert(map, 2, 2));
cmc_assert(bm_remove_by_val(map, 1, NULL, NULL));
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
cmc_assert(!bm_remove_by_val(map, 1, NULL, NULL));
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map));
cmc_assert(bm_remove_by_val(map, 2, NULL, NULL));
cmc_assert(!bm_remove_by_val(map, 2, NULL, NULL));
cmc_assert_equals(int32_t, cmc_flags.EMPTY, bm_flag(map));
// get_key and get_val
cmc_assert(bm_insert(map, 2, 1));
cmc_assert_equals(size_t, 2, bm_get_key(map, 1));
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
map->flag = cmc_flags.ERROR;
cmc_assert_equals(size_t, 1, bm_get_val(map, 2));
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
cmc_assert_equals(size_t, 0, bm_get_key(map, 2));
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map));
map->flag = cmc_flags.ERROR;
cmc_assert_equals(size_t, 0, bm_get_val(map, 1));
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map));
// contains_key
cmc_assert(bm_contains_key(map, 2));
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
// contains_val
map->flag = cmc_flags.ERROR;
cmc_assert(bm_contains_val(map, 1));
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
// copy_of
struct bidimap *map2 = bm_copy_of(map);
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map2));
size_t tmp = map->capacity;
map->capacity = 0;
struct bidimap *map3 = bm_copy_of(map);
cmc_assert_equals(ptr, NULL, map3);
cmc_assert_equals(int32_t, cmc_flags.ERROR, bm_flag(map));
map->capacity = tmp;
// equals
bm_get_key(map, 100);
bm_get_key(map2, 100);
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map));
cmc_assert_equals(int32_t, cmc_flags.NOT_FOUND, bm_flag(map2));
map->flag = cmc_flags.ERROR;
cmc_assert(bm_equals(map, map2));
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map));
cmc_assert_equals(int32_t, cmc_flags.OK, bm_flag(map2));
bm_free(map);
bm_free(map2);
});
});