forked from vieter-v/libvieter
test(heap): add random test that exposes some faults
parent
6845e67cb6
commit
63100c5b99
|
@ -9,28 +9,45 @@ typedef struct vieter_heap_node {
|
||||||
void *data;
|
void *data;
|
||||||
struct vieter_heap_node *largest_order;
|
struct vieter_heap_node *largest_order;
|
||||||
union {
|
union {
|
||||||
|
// Roots point to next tree in the heap, other nodes point to their first
|
||||||
|
// neighbour.
|
||||||
struct vieter_heap_node *next_tree;
|
struct vieter_heap_node *next_tree;
|
||||||
struct vieter_heap_node *next_largest_order;
|
struct vieter_heap_node *next_largest_order;
|
||||||
} ptr;
|
} ptr;
|
||||||
uint8_t order;
|
uint8_t order;
|
||||||
} vieter_heap_node;
|
} vieter_heap_node;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate an initialize a heap node object.
|
||||||
|
*/
|
||||||
vieter_heap_node *vieter_heap_node_init();
|
vieter_heap_node *vieter_heap_node_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deallocate a node object.
|
||||||
|
*/
|
||||||
void vieter_heap_node_free(vieter_heap_node *node);
|
void vieter_heap_node_free(vieter_heap_node *node);
|
||||||
|
|
||||||
/* vieter_heap_tree *vieter_heap_tree_init(vieter_heap_node *root, vieter_heap_tree *next, uint8_t order); */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deallocate a tree object, along with its underlying tree structure.
|
* Deallocate a node's entire structure.
|
||||||
*/
|
*/
|
||||||
void vieter_heap_tree_free(vieter_heap_node *root);
|
void vieter_heap_tree_free(vieter_heap_node *root);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given the roots of the smallest trees in two heaps, merge them into a single
|
||||||
|
* large heap.
|
||||||
|
*/
|
||||||
vieter_heap_node *vieter_heap_tree_merge(vieter_heap_node *root_a, vieter_heap_node *root_b);
|
vieter_heap_node *vieter_heap_tree_merge(vieter_heap_node *root_a, vieter_heap_node *root_b);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given the roots of two trees of the same order, merge them into a heap of one
|
||||||
|
* order larger.
|
||||||
|
*/
|
||||||
vieter_heap_node *vieter_heap_tree_merge_same_order(vieter_heap_node *root_a,
|
vieter_heap_node *vieter_heap_tree_merge_same_order(vieter_heap_node *root_a,
|
||||||
vieter_heap_node *root_b);
|
vieter_heap_node *root_b);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove the smallest element from the given heap.
|
||||||
|
*/
|
||||||
vieter_heap_node *vieter_heap_tree_pop(void **out, vieter_heap_node *root);
|
vieter_heap_node *vieter_heap_tree_pop(void **out, vieter_heap_node *root);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "acutest.h"
|
#include "acutest.h"
|
||||||
#include "vieter_heap.h"
|
#include "vieter_heap.h"
|
||||||
#include "vieter_heap_tree.h"
|
#include "vieter_heap_tree.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define TEST_SIZE(heap, size) \
|
#define TEST_SIZE(heap, size) \
|
||||||
TEST_CHECK(vieter_heap_size(heap) == size); \
|
TEST_CHECK(vieter_heap_size(heap) == size); \
|
||||||
|
@ -76,10 +77,57 @@ void test_pop() {
|
||||||
vieter_heap_free(heap);
|
vieter_heap_free(heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_pop_random() {
|
||||||
|
srand(0);
|
||||||
|
|
||||||
|
vieter_heap *heap = vieter_heap_init();
|
||||||
|
|
||||||
|
uint64_t *numbers = malloc(500 * sizeof(uint64_t));
|
||||||
|
uint64_t num;
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < 500; i++) {
|
||||||
|
num = rand();
|
||||||
|
vieter_heap_insert(heap, num, (void *)num);
|
||||||
|
TEST_SIZE(heap, i + 1);
|
||||||
|
|
||||||
|
numbers[i] = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qsort(numbers, 500, sizeof(uint64_t), uint64_t_compare);
|
||||||
|
|
||||||
|
void *data = NULL;
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < 500; i++) {
|
||||||
|
TEST_CHECK(vieter_heap_peek(&data, heap) == vieter_heap_ok);
|
||||||
|
TEST_CHECK(data == (void *)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);
|
||||||
|
}
|
||||||
|
|
||||||
|
vieter_heap_free(heap);
|
||||||
|
free(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_LIST = {
|
TEST_LIST = {
|
||||||
{"init", test_init},
|
{"init", test_init},
|
||||||
{"merge same order", test_merge_same_order},
|
{"merge same order", test_merge_same_order},
|
||||||
{"insert", test_insert},
|
{"insert", test_insert},
|
||||||
{"pop", test_pop},
|
{"pop", test_pop},
|
||||||
|
{"pop random", test_pop_random},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue