1 #include <freeradius-devel/util/acutest.h>
2 #include <freeradius-devel/util/heap.h>
3 #include <freeradius-devel/util/rand.h>
4 #include <freeradius-devel/util/time.h>
18 for (
unsigned int i = 1; i <= h->
num_elements; i++)
if (h->
p[i] ==
data)
return true;
31 #define is_power_of_2(_n) !((_n) & ((_n) - 1))
43 fprintf(stderr,
"%3u: ", num_elements);
49 fprintf(stderr,
"\n");
58 for (i = 0; i < len; i++) {
68 for (i = 0; i < len; i++) {
70 int temp = values[i].
data;
73 values[j].
data = temp;
91 for (
unsigned int i = 0; i <
NVALUES; i++) {
96 for (
unsigned int i = 0; i <
NVALUES; i++) {
108 for (
unsigned int i = 0; i <
NVALUES; i++) {
113 for (
unsigned int i =
NVALUES; --i > 0; ) {
125 #define MINMAX_HEAP_TEST_SIZE (4096)
156 TEST_MSG(
"element %i inserted but not in heap", i);
168 TEST_MSG(
"element %i removed out of order", entry);
174 TEST_MSG(
"element %i removed but still in heap", entry);
177 TEST_MSG(
"element %i removed out of order", entry);
182 for (i = 0; i < left; i++) {
187 TEST_MSG(
"expected %i elements remaining in the heap", left - i);
190 TEST_MSG(
"failed extracting %i", i);
194 TEST_MSG(
"%i elements remaining", ret);
219 #define BURN_IN_OPS (10000000)
226 int insert_count = 0;
274 #define MINMAX_HEAP_CYCLE_SIZE (1600000)
306 TEST_MSG(
"element %i inserted but not in heap", i);
331 TEST_MSG(
"element %i inserted but not in heap", i);
356 unsigned int idx = 0;
358 for (
unsigned int j = 0; j <
count; j++) {
359 if (!
array[j])
continue;
366 if (low)
array[idx] = NULL;
389 fr_time_t start_alloc, end_alloc, start_insert, end_insert, start_pop, end_pop, end_pop_first =
fr_time_wrap(0);
403 for (i = 0; i <
count; i++) {
405 if (i == 0) end_pop_first =
fr_time();
407 TEST_MSG(
"expected %u elements remaining in the minmax heap",
count - i);
408 TEST_MSG(
"failed extracting %u", i);
424 fr_time_t start_alloc, end_alloc, start_insert, end_insert, start_pop, end_pop, end_pop_first =
fr_time_min();
438 for (i = 0; i <
count; i++) {
440 if (i == 0) end_pop_first =
fr_time();
442 TEST_MSG(
"expected %u elements remaining in the heap",
count - i);
443 TEST_MSG(
"failed extracting %u", i);
461 fr_time_t start_alloc, end_alloc, start_insert, end_insert, start_pop, end_pop, end_pop_first;
471 for (i = 0; i <
count; i++)
array[i] = &values[i];
475 for (i = 0; i <
count; i++) {
477 if (i == 0) end_pop_first =
fr_time();
519 int inserted, removed;
521 fr_time_t start_insert, start_remove, start_swap, end;
552 for (i = 0; i < to_remove; i++) {
556 TEST_MSG(
"expected %i elements remaining in the heap", to_remove - i);
620 data->visited =
true;
#define TEST_MSG_ALWAYS(...)
#define CMP_PREFER_SMALLER(_a, _b)
Evaluates to +1 for a > b, and -1 for a < b.
void * fr_heap_pop(fr_heap_t **hp)
Remove a node from the heap.
int fr_heap_insert(fr_heap_t **hp, void *data)
Insert a new element into the heap.
#define fr_heap_alloc(_ctx, _cmp, _type, _field, _init)
Creates a heap that can be used with non-talloced elements.
#define is_power_of_2(_n)
static size_t array[MY_ARRAY_SIZE]
Functions for a minmax heap.
int fr_minmax_heap_insert(fr_minmax_heap_t *hp, void *data)
void * fr_minmax_heap_iter_next(fr_minmax_heap_t *hp, fr_minmax_heap_iter_t *iter)
Get the next entry in a minmax heap.
void * fr_minmax_heap_min_peek(fr_minmax_heap_t *hp)
void * fr_minmax_heap_max_pop(fr_minmax_heap_t *hp)
void * fr_minmax_heap_min_pop(fr_minmax_heap_t *hp)
void * p[]
Array of nodes.
void * fr_minmax_heap_max_peek(fr_minmax_heap_t *hp)
unsigned int fr_minmax_heap_num_elements(fr_minmax_heap_t *hp)
Return the number of elements in the minmax heap.
int fr_minmax_heap_extract(fr_minmax_heap_t *hp, void *data)
void * fr_minmax_heap_iter_init(fr_minmax_heap_t *hp, fr_minmax_heap_iter_t *iter)
Iterate over entries in a minmax heap.
unsigned int num_elements
Number of nodes used.
#define FR_MINMAX_HEAP_VERIFY(_hp)
#define fr_minmax_heap_foreach(_hp, _type, _data)
Iterate over the contents of a minmax_heap.
static bool fr_minmax_heap_entry_inserted(fr_minmax_heap_index_t heap_idx)
Check if an entry is inserted into a heap.
unsigned int fr_minmax_heap_iter_t
#define fr_minmax_heap_alloc(_ctx, _cmp, _type, _field, _init)
Creates a minmax heap that can be used with non-talloced elements.
unsigned int fr_minmax_heap_index_t
static void queue_cmp_100(void)
static void queue_cmp(unsigned int count)
Benchmarks for minmax heaps vs heaps when used as queues.
#define MINMAX_HEAP_TEST_SIZE
static bool minmax_heap_contains(fr_minmax_heap_t *hp, void *data)
#define MINMAX_HEAP_CYCLE_SIZE
static void queue_cmp_50(void)
static void minmax_heap_test_order(void)
static void minmax_heap_test_skip_2(void)
fr_minmax_heap_index_t idx
static minmax_heap_thing * array_pop(minmax_heap_thing **array, unsigned int count)
static void minmax_heap_test_skip_0(void)
static void minmax_heap_cycle(void)
static void queue_cmp_1000(void)
static void queue_cmp_10(void)
static void minmax_heap_test_skip_10(void)
static void minmax_heap_test(int skip)
static void minmax_heap_test_basic(void)
static void minmax_heap_burn_in(void)
static void populate_values(minmax_heap_thing values[], unsigned int len)
static int8_t minmax_heap_cmp(void const *one, void const *two)
static void minmax_heap_iter(void)
uint32_t fr_fast_rand(fr_fast_rand_t *ctx)
uint32_t fr_rand(void)
Return a 32-bit random number.
Smaller fast random number generator.
#define fr_time()
Allow us to arbitrarily manipulate time.
#define fr_time_wrap(_time)
static int64_t fr_time_delta_to_usec(fr_time_delta_t delta)
#define fr_time_sub(_a, _b)
Subtract one time from another.
char const * fr_strerror(void)
Get the last library error.