test(heap): some more tests to expose flaws
parent
63100c5b99
commit
dc557f57ab
|
@ -56,14 +56,6 @@ vieter_heap_error vieter_heap_pop(void **out, vieter_heap *heap) {
|
|||
return vieter_heap_empty;
|
||||
}
|
||||
|
||||
if (heap->tree->order == 0 && heap->tree->ptr.next_tree == NULL) {
|
||||
*out = heap->tree->data;
|
||||
vieter_heap_tree_free(heap->tree);
|
||||
heap->tree = NULL;
|
||||
|
||||
return vieter_heap_ok;
|
||||
}
|
||||
|
||||
heap->tree = vieter_heap_tree_pop(out, heap->tree);
|
||||
|
||||
return vieter_heap_ok;
|
||||
|
|
|
@ -167,6 +167,9 @@ vieter_heap_node *vieter_heap_tree_pop(void **out, vieter_heap_node *tree) {
|
|||
return original_root;
|
||||
}
|
||||
|
||||
// Each child has a pointer to its sibling with the next largest order. If we
|
||||
// want to convert this list of children into their own tree, these pointers
|
||||
// have to be reversed.
|
||||
previous_tree = tree_to_pop->largest_order;
|
||||
vieter_heap_node_free(tree_to_pop);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#define TEST_SIZE(heap, size) \
|
||||
TEST_CHECK(vieter_heap_size(heap) == size); \
|
||||
TEST_MSG("Size: %zu", vieter_heap_size(heap))
|
||||
TEST_MSG("Size: %zu, expected: %lu", vieter_heap_size(heap), (uint64_t)size)
|
||||
|
||||
void test_init() {
|
||||
vieter_heap *heap = vieter_heap_init();
|
||||
|
@ -14,25 +14,6 @@ void test_init() {
|
|||
vieter_heap_free(heap);
|
||||
}
|
||||
|
||||
void test_merge_same_order() {
|
||||
vieter_heap_node *root_a = vieter_heap_node_init();
|
||||
root_a->key = 1;
|
||||
root_a->order = 0;
|
||||
|
||||
vieter_heap_node *root_b = vieter_heap_node_init();
|
||||
root_b->key = 2;
|
||||
root_b->order = 0;
|
||||
|
||||
vieter_heap_node *merged = vieter_heap_tree_merge_same_order(root_a, root_b);
|
||||
|
||||
TEST_CHECK(merged == root_a);
|
||||
TEST_CHECK(merged->key == 1);
|
||||
TEST_CHECK(merged->largest_order == root_b);
|
||||
TEST_CHECK(merged->ptr.next_largest_order == NULL);
|
||||
|
||||
vieter_heap_tree_free(merged);
|
||||
}
|
||||
|
||||
void test_insert() {
|
||||
vieter_heap *heap = vieter_heap_init();
|
||||
TEST_SIZE(heap, 0);
|
||||
|
@ -52,6 +33,36 @@ void test_insert() {
|
|||
vieter_heap_free(heap);
|
||||
}
|
||||
|
||||
void test_insert_random() {
|
||||
srand(1);
|
||||
|
||||
vieter_heap *heap = vieter_heap_init();
|
||||
TEST_SIZE(heap, 0);
|
||||
|
||||
uint64_t num = rand();
|
||||
uint64_t smallest = num;
|
||||
|
||||
void *data = NULL;
|
||||
|
||||
for (uint64_t i = 0; i < 5000; i++) {
|
||||
vieter_heap_insert(heap, num, (void *)num);
|
||||
TEST_SIZE(heap, i + 1);
|
||||
|
||||
if (num < smallest) {
|
||||
smallest = num;
|
||||
}
|
||||
|
||||
TEST_CHECK(vieter_heap_peek(&data, heap) == vieter_heap_ok);
|
||||
TEST_CHECK(data == (void *)smallest);
|
||||
|
||||
data = NULL;
|
||||
|
||||
num = rand();
|
||||
}
|
||||
|
||||
vieter_heap_free(heap);
|
||||
}
|
||||
|
||||
void test_pop() {
|
||||
vieter_heap *heap = vieter_heap_init();
|
||||
TEST_SIZE(heap, 0);
|
||||
|
@ -80,7 +91,7 @@ void test_pop() {
|
|||
int uint64_t_compare(const void *a, const void *b) {
|
||||
if ((*(uint64_t *)a) < (*(uint64_t *)b)) {
|
||||
return -1;
|
||||
} else if ((*(uint64_t *)a) < (*(uint64_t *)b)) {
|
||||
} else if ((*(uint64_t *)a) > (*(uint64_t *)b)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -88,14 +99,16 @@ int uint64_t_compare(const void *a, const void *b) {
|
|||
}
|
||||
|
||||
void test_pop_random() {
|
||||
const uint64_t n = 29;
|
||||
|
||||
srand(0);
|
||||
|
||||
vieter_heap *heap = vieter_heap_init();
|
||||
|
||||
uint64_t *numbers = malloc(500 * sizeof(uint64_t));
|
||||
uint64_t *numbers = malloc(n * sizeof(uint64_t));
|
||||
uint64_t num;
|
||||
|
||||
for (uint64_t i = 0; i < 500; i++) {
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
num = rand();
|
||||
vieter_heap_insert(heap, num, (void *)num);
|
||||
TEST_SIZE(heap, i + 1);
|
||||
|
@ -104,19 +117,19 @@ void test_pop_random() {
|
|||
}
|
||||
|
||||
|
||||
qsort(numbers, 500, sizeof(uint64_t), uint64_t_compare);
|
||||
qsort(numbers, n, sizeof(uint64_t), uint64_t_compare);
|
||||
|
||||
void *data = NULL;
|
||||
|
||||
for (uint64_t i = 0; i < 500; i++) {
|
||||
for (uint64_t i = 0; i < n; i++) {
|
||||
TEST_CHECK(vieter_heap_peek(&data, heap) == vieter_heap_ok);
|
||||
TEST_CHECK(data == (void *)numbers[i]);
|
||||
TEST_CHECK_(data == (void *)numbers[i], "peek %lx == %lx", (uint64_t)data, numbers[i]);
|
||||
|
||||
data = NULL;
|
||||
|
||||
TEST_CHECK(vieter_heap_pop(&data, heap) == vieter_heap_ok);
|
||||
TEST_CHECK(data == (void *)numbers[i]);
|
||||
TEST_SIZE(heap, (uint64_t)500 - i - 1);
|
||||
TEST_CHECK_(data == (void *)numbers[i], "pop %lx == %lx", (uint64_t)data, numbers[i]);
|
||||
TEST_SIZE(heap, n - i - 1);
|
||||
}
|
||||
|
||||
vieter_heap_free(heap);
|
||||
|
@ -125,8 +138,8 @@ void test_pop_random() {
|
|||
|
||||
TEST_LIST = {
|
||||
{"init", test_init},
|
||||
{"merge same order", test_merge_same_order},
|
||||
{"insert", test_insert},
|
||||
{"insert random", test_insert_random},
|
||||
{"pop", test_pop},
|
||||
{"pop random", test_pop_random},
|
||||
{NULL, NULL}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#include "acutest.h"
|
||||
#include "vieter_heap.h"
|
||||
#include "vieter_heap_tree.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
void test_merge_same_order() {
|
||||
vieter_heap_node *root_a = vieter_heap_node_init();
|
||||
root_a->key = 1;
|
||||
root_a->order = 0;
|
||||
|
||||
vieter_heap_node *root_b = vieter_heap_node_init();
|
||||
root_b->key = 2;
|
||||
root_b->order = 0;
|
||||
|
||||
vieter_heap_node *merged = vieter_heap_tree_merge_same_order(root_a, root_b);
|
||||
|
||||
TEST_CHECK(merged == root_a);
|
||||
TEST_CHECK(merged->key == 1);
|
||||
TEST_CHECK(merged->largest_order == root_b);
|
||||
TEST_CHECK(merged->ptr.next_largest_order == NULL);
|
||||
|
||||
vieter_heap_tree_free(merged);
|
||||
}
|
||||
|
||||
TEST_LIST = {
|
||||
{"merge same order", test_merge_same_order},
|
||||
{NULL, NULL}
|
||||
};
|
Loading…
Reference in New Issue