2023-01-21 16:31:22 +01:00
|
|
|
#include "acutest.h"
|
2023-01-25 22:12:22 +01:00
|
|
|
#include "vieter_heap_internal.h"
|
2023-01-24 21:19:08 +01:00
|
|
|
#include <stdlib.h>
|
2023-01-21 16:31:22 +01:00
|
|
|
|
|
|
|
#define TEST_SIZE(heap, size) \
|
|
|
|
TEST_CHECK(vieter_heap_size(heap) == size); \
|
2023-01-25 20:49:18 +01:00
|
|
|
TEST_MSG("Size: %zu, expected: %lu", vieter_heap_size(heap), (uint64_t)size)
|
2023-01-21 16:31:22 +01:00
|
|
|
|
|
|
|
void test_init() {
|
|
|
|
vieter_heap *heap = vieter_heap_init();
|
|
|
|
TEST_CHECK(heap != NULL);
|
|
|
|
TEST_SIZE(heap, 0);
|
|
|
|
vieter_heap_free(heap);
|
|
|
|
}
|
|
|
|
|
2023-01-25 22:12:22 +01:00
|
|
|
void count_nodes(uint64_t *counter, vieter_heap_node *root) {
|
|
|
|
(*counter)++;
|
|
|
|
|
|
|
|
if (root->largest_order != NULL) {
|
|
|
|
count_nodes(counter, root->largest_order);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This will also traverse the various trees
|
|
|
|
if (root->ptr.next_largest_order != NULL) {
|
|
|
|
count_nodes(counter, root->ptr.next_largest_order);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t count_nodes_heap(vieter_heap *heap) {
|
|
|
|
uint64_t counter = 0;
|
|
|
|
|
|
|
|
if (heap->tree != NULL) {
|
|
|
|
count_nodes(&counter, heap->tree);
|
|
|
|
}
|
|
|
|
|
|
|
|
return counter;
|
|
|
|
}
|
|
|
|
|
2023-01-22 20:34:05 +01:00
|
|
|
void test_insert() {
|
|
|
|
vieter_heap *heap = vieter_heap_init();
|
|
|
|
TEST_SIZE(heap, 0);
|
|
|
|
|
|
|
|
void *data;
|
|
|
|
|
2023-01-24 12:07:30 +01:00
|
|
|
for (uint64_t i = 50; i > 0; i--) {
|
2023-01-22 20:34:05 +01:00
|
|
|
vieter_heap_insert(heap, i, (void *)i);
|
|
|
|
TEST_SIZE(heap, (uint64_t)51 - i);
|
2023-01-25 22:12:22 +01:00
|
|
|
TEST_CHECK(count_nodes_heap(heap) == (uint64_t)51 - i);
|
2023-01-22 20:34:05 +01:00
|
|
|
|
2023-01-24 12:07:30 +01:00
|
|
|
data = 0;
|
|
|
|
|
2023-01-22 20:34:05 +01:00
|
|
|
TEST_CHECK(vieter_heap_peek(&data, heap) == vieter_heap_ok);
|
2023-01-24 12:07:30 +01:00
|
|
|
TEST_CHECK_(data == (void *)i, "%lX == %lX", (uint64_t)data, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
vieter_heap_free(heap);
|
|
|
|
}
|
|
|
|
|
2023-01-25 20:49:18 +01:00
|
|
|
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);
|
2023-01-25 22:12:22 +01:00
|
|
|
TEST_CHECK(count_nodes_heap(heap) == (uint64_t)i + 1);
|
2023-01-25 20:49:18 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-01-24 19:45:01 +01:00
|
|
|
void test_pop() {
|
2023-01-26 10:21:30 +01:00
|
|
|
const uint64_t n = 500;
|
|
|
|
|
2023-01-24 19:45:01 +01:00
|
|
|
vieter_heap *heap = vieter_heap_init();
|
|
|
|
TEST_SIZE(heap, 0);
|
2023-01-24 12:07:30 +01:00
|
|
|
|
2023-01-24 19:45:01 +01:00
|
|
|
void *data;
|
2023-01-24 12:07:30 +01:00
|
|
|
|
2023-01-26 10:21:30 +01:00
|
|
|
for (uint64_t i = n; i > 0; i--) {
|
2023-01-24 19:45:01 +01:00
|
|
|
vieter_heap_insert(heap, i, (void *)i);
|
2023-01-26 10:21:30 +01:00
|
|
|
TEST_SIZE(heap, (uint64_t)n + 1 - i);
|
|
|
|
TEST_CHECK(count_nodes_heap(heap) == (uint64_t)n + 1 - i);
|
2023-01-24 12:07:30 +01:00
|
|
|
|
2023-01-24 19:45:01 +01:00
|
|
|
TEST_CHECK(vieter_heap_peek(&data, heap) == vieter_heap_ok);
|
|
|
|
TEST_CHECK(data == (void*)i);
|
|
|
|
}
|
2023-01-24 12:07:30 +01:00
|
|
|
|
2023-01-24 19:45:01 +01:00
|
|
|
data = NULL;
|
2023-01-24 12:07:30 +01:00
|
|
|
|
2023-01-26 10:21:30 +01:00
|
|
|
for (uint64_t i = 1; i <= n; i++) {
|
2023-01-24 19:45:01 +01:00
|
|
|
TEST_CHECK(vieter_heap_pop(&data, heap) == vieter_heap_ok);
|
|
|
|
TEST_CHECK(data == (void*)i);
|
2023-01-26 10:21:30 +01:00
|
|
|
TEST_SIZE(heap, (uint64_t)n - i);
|
2023-01-24 19:45:01 +01:00
|
|
|
}
|
2023-01-24 12:07:30 +01:00
|
|
|
|
2023-01-24 19:45:01 +01:00
|
|
|
vieter_heap_free(heap);
|
|
|
|
}
|
2023-01-22 20:34:05 +01:00
|
|
|
|
2023-01-24 21:19:08 +01:00
|
|
|
int uint64_t_compare(const void *a, const void *b) {
|
|
|
|
if ((*(uint64_t *)a) < (*(uint64_t *)b)) {
|
|
|
|
return -1;
|
2023-01-25 20:49:18 +01:00
|
|
|
} else if ((*(uint64_t *)a) > (*(uint64_t *)b)) {
|
2023-01-24 21:19:08 +01:00
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void test_pop_random() {
|
2023-01-26 10:21:30 +01:00
|
|
|
const uint64_t n = 500;
|
2023-01-25 20:49:18 +01:00
|
|
|
|
2023-01-24 21:19:08 +01:00
|
|
|
srand(0);
|
|
|
|
|
|
|
|
vieter_heap *heap = vieter_heap_init();
|
|
|
|
|
2023-01-25 20:49:18 +01:00
|
|
|
uint64_t *numbers = malloc(n * sizeof(uint64_t));
|
2023-01-24 21:19:08 +01:00
|
|
|
uint64_t num;
|
|
|
|
|
2023-01-25 20:49:18 +01:00
|
|
|
for (uint64_t i = 0; i < n; i++) {
|
2023-01-24 21:19:08 +01:00
|
|
|
num = rand();
|
|
|
|
vieter_heap_insert(heap, num, (void *)num);
|
|
|
|
TEST_SIZE(heap, i + 1);
|
2023-01-25 22:12:22 +01:00
|
|
|
TEST_CHECK(count_nodes_heap(heap) == i + 1);
|
2023-01-24 21:19:08 +01:00
|
|
|
|
|
|
|
numbers[i] = num;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-01-25 20:49:18 +01:00
|
|
|
qsort(numbers, n, sizeof(uint64_t), uint64_t_compare);
|
2023-01-24 21:19:08 +01:00
|
|
|
|
|
|
|
void *data = NULL;
|
|
|
|
|
2023-01-25 20:49:18 +01:00
|
|
|
for (uint64_t i = 0; i < n; i++) {
|
2023-01-24 21:19:08 +01:00
|
|
|
TEST_CHECK(vieter_heap_peek(&data, heap) == vieter_heap_ok);
|
2023-01-25 20:49:18 +01:00
|
|
|
TEST_CHECK_(data == (void *)numbers[i], "peek %lx == %lx", (uint64_t)data, numbers[i]);
|
2023-01-24 21:19:08 +01:00
|
|
|
|
|
|
|
data = NULL;
|
|
|
|
|
|
|
|
TEST_CHECK(vieter_heap_pop(&data, heap) == vieter_heap_ok);
|
2023-01-25 20:49:18 +01:00
|
|
|
TEST_CHECK_(data == (void *)numbers[i], "pop %lx == %lx", (uint64_t)data, numbers[i]);
|
|
|
|
TEST_SIZE(heap, n - i - 1);
|
2023-01-25 22:12:22 +01:00
|
|
|
TEST_CHECK(count_nodes_heap(heap) == n - i - 1);
|
2023-01-27 21:59:09 +01:00
|
|
|
|
|
|
|
// Assure each size is also a valid heap after inserting
|
|
|
|
vieter_heap_insert(heap, numbers[i], (void *)numbers[i]);
|
|
|
|
TEST_SIZE(heap, n - i);
|
|
|
|
TEST_CHECK(count_nodes_heap(heap) == n - i);
|
|
|
|
|
|
|
|
data = NULL;
|
|
|
|
|
|
|
|
TEST_CHECK(vieter_heap_pop(&data, heap) == vieter_heap_ok);
|
|
|
|
TEST_CHECK_(data == (void *)numbers[i], "pop %lx == %lx", (uint64_t)data, numbers[i]);
|
|
|
|
TEST_SIZE(heap, n - i - 1);
|
|
|
|
TEST_CHECK(count_nodes_heap(heap) == n - i - 1);
|
2023-01-24 21:19:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
vieter_heap_free(heap);
|
|
|
|
free(numbers);
|
|
|
|
}
|
|
|
|
|
2023-01-21 16:31:22 +01:00
|
|
|
TEST_LIST = {
|
2023-01-28 09:30:35 +01:00
|
|
|
{"heap init", test_init},
|
|
|
|
{"heap insert", test_insert},
|
|
|
|
{"heap insert random", test_insert_random},
|
|
|
|
{"heap pop", test_pop},
|
|
|
|
{"heap pop random", test_pop_random},
|
2023-01-21 16:31:22 +01:00
|
|
|
{NULL, NULL}
|
|
|
|
};
|