forked from vieter-v/libvieter
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;
|
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);
|
heap->tree = vieter_heap_tree_pop(out, heap->tree);
|
||||||
|
|
||||||
return vieter_heap_ok;
|
return vieter_heap_ok;
|
||||||
|
|
|
@ -167,6 +167,9 @@ vieter_heap_node *vieter_heap_tree_pop(void **out, vieter_heap_node *tree) {
|
||||||
return original_root;
|
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;
|
previous_tree = tree_to_pop->largest_order;
|
||||||
vieter_heap_node_free(tree_to_pop);
|
vieter_heap_node_free(tree_to_pop);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#define TEST_SIZE(heap, size) \
|
#define TEST_SIZE(heap, size) \
|
||||||
TEST_CHECK(vieter_heap_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() {
|
void test_init() {
|
||||||
vieter_heap *heap = vieter_heap_init();
|
vieter_heap *heap = vieter_heap_init();
|
||||||
|
@ -14,25 +14,6 @@ void test_init() {
|
||||||
vieter_heap_free(heap);
|
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() {
|
void test_insert() {
|
||||||
vieter_heap *heap = vieter_heap_init();
|
vieter_heap *heap = vieter_heap_init();
|
||||||
TEST_SIZE(heap, 0);
|
TEST_SIZE(heap, 0);
|
||||||
|
@ -52,6 +33,36 @@ void test_insert() {
|
||||||
vieter_heap_free(heap);
|
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() {
|
void test_pop() {
|
||||||
vieter_heap *heap = vieter_heap_init();
|
vieter_heap *heap = vieter_heap_init();
|
||||||
TEST_SIZE(heap, 0);
|
TEST_SIZE(heap, 0);
|
||||||
|
@ -80,7 +91,7 @@ void test_pop() {
|
||||||
int uint64_t_compare(const void *a, const void *b) {
|
int uint64_t_compare(const void *a, const void *b) {
|
||||||
if ((*(uint64_t *)a) < (*(uint64_t *)b)) {
|
if ((*(uint64_t *)a) < (*(uint64_t *)b)) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if ((*(uint64_t *)a) < (*(uint64_t *)b)) {
|
} else if ((*(uint64_t *)a) > (*(uint64_t *)b)) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -88,14 +99,16 @@ int uint64_t_compare(const void *a, const void *b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_pop_random() {
|
void test_pop_random() {
|
||||||
|
const uint64_t n = 29;
|
||||||
|
|
||||||
srand(0);
|
srand(0);
|
||||||
|
|
||||||
vieter_heap *heap = vieter_heap_init();
|
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;
|
uint64_t num;
|
||||||
|
|
||||||
for (uint64_t i = 0; i < 500; i++) {
|
for (uint64_t i = 0; i < n; i++) {
|
||||||
num = rand();
|
num = rand();
|
||||||
vieter_heap_insert(heap, num, (void *)num);
|
vieter_heap_insert(heap, num, (void *)num);
|
||||||
TEST_SIZE(heap, i + 1);
|
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;
|
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(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;
|
data = NULL;
|
||||||
|
|
||||||
TEST_CHECK(vieter_heap_pop(&data, heap) == vieter_heap_ok);
|
TEST_CHECK(vieter_heap_pop(&data, heap) == vieter_heap_ok);
|
||||||
TEST_CHECK(data == (void *)numbers[i]);
|
TEST_CHECK_(data == (void *)numbers[i], "pop %lx == %lx", (uint64_t)data, numbers[i]);
|
||||||
TEST_SIZE(heap, (uint64_t)500 - i - 1);
|
TEST_SIZE(heap, n - i - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
vieter_heap_free(heap);
|
vieter_heap_free(heap);
|
||||||
|
@ -125,8 +138,8 @@ void test_pop_random() {
|
||||||
|
|
||||||
TEST_LIST = {
|
TEST_LIST = {
|
||||||
{"init", test_init},
|
{"init", test_init},
|
||||||
{"merge same order", test_merge_same_order},
|
|
||||||
{"insert", test_insert},
|
{"insert", test_insert},
|
||||||
|
{"insert random", test_insert_random},
|
||||||
{"pop", test_pop},
|
{"pop", test_pop},
|
||||||
{"pop random", test_pop_random},
|
{"pop random", test_pop_random},
|
||||||
{NULL, NULL}
|
{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