blob: 3354fd195595c69a119cfb0c1c4e18b65dee0123 [file]
/*
* Embedded Linux library
* Copyright (C) 2023 Cruise LLC
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
#include <ell/ell.h>
#include "ell/useful.h"
static inline void swap_int(void *l, void *r)
{
int *li = l;
int *ri = r;
SWAP(*li, *ri);
}
static inline bool less(const void *l, const void *r)
{
const int *li = l;
const int *ri = r;
return *li < *ri;
}
static const struct l_minheap_ops ops = {
.less = less,
.swap = swap_int,
.elem_size = sizeof(int),
};
static const int test_values[] = {
3, 1, 2, 4, INT_MAX, INT_MIN, -4, -2, -1, -3, 0, INT_MIN, INT_MAX
};
static void verify_pop(struct l_minheap *minheap)
{
size_t size = minheap->used;
int *values = minheap->data;
int last;
last = values[0];
while (size) {
assert(last <= values[0]);
last = values[0];
assert(l_minheap_pop(minheap, &ops, NULL));
size -= 1;
}
}
static void test_minheap_init(const void *data)
{
struct l_minheap minheap;
int *values = alloca(sizeof(test_values));
memcpy(values, test_values, sizeof(test_values));
l_minheap_init(&minheap, values, L_ARRAY_SIZE(test_values),
L_ARRAY_SIZE(test_values), &ops);
verify_pop(&minheap);
}
static void test_minheap_push(const void *data)
{
struct l_minheap minheap;
int *values = l_newa(int, L_ARRAY_SIZE(test_values));
unsigned int i;
l_minheap_init(&minheap, values, 0, L_ARRAY_SIZE(test_values), &ops);
for (i = 0; i < L_ARRAY_SIZE(test_values); i++)
assert(l_minheap_push(&minheap, &ops, &test_values[i]));
verify_pop(&minheap);
}
static void test_minheap_push_random(const void *data)
{
struct l_minheap minheap;
unsigned int n_items = 1024 * 1024;
int *values = l_malloc(sizeof(int) * n_items);
unsigned int i;
l_minheap_init(&minheap, values, 0, n_items, &ops);
for (i = 0; i < n_items; i++) {
unsigned int r = random();
assert(l_minheap_push(&minheap, &ops, &r));
}
verify_pop(&minheap);
l_free(values);
}
static void test_minheap_pop_push(const void *data)
{
struct l_minheap minheap;
int *values = alloca(sizeof(test_values));
unsigned int i;
int tmp;
for (i = 0; i < L_ARRAY_SIZE(test_values); i++)
values[i] = INT_MIN;
l_minheap_init(&minheap, values, L_ARRAY_SIZE(test_values),
L_ARRAY_SIZE(test_values), &ops);
for (i = 0; i < L_ARRAY_SIZE(test_values); i++) {
tmp = test_values[i];
assert(l_minheap_pop_push(&minheap, &ops, &tmp));
assert(tmp == INT_MIN);
}
verify_pop(&minheap);
}
static void test_minheap_delete(const void *data)
{
struct l_minheap minheap;
int *values = l_newa(int, L_ARRAY_SIZE(test_values));
unsigned int i;
for (i = 0; i < L_ARRAY_SIZE(test_values); i++) {
l_minheap_init(&minheap, values, L_ARRAY_SIZE(test_values),
L_ARRAY_SIZE(test_values), &ops);
assert(l_minheap_delete(&minheap, i, &ops));
verify_pop(&minheap);
}
}
int main(int argc, char *argv[])
{
l_test_init(&argc, &argv);
l_test_add("minheap/init", test_minheap_init, NULL);
l_test_add("minheap/push", test_minheap_push, NULL);
l_test_add("minheap/push_random", test_minheap_push_random, NULL);
l_test_add("minheap/pop_push", test_minheap_pop_push, NULL);
l_test_add("minheap/delete", test_minheap_delete, NULL);
return l_test_run();
}