1 #include <freeradius-devel/util/acutest.h>
2 #include <freeradius-devel/util/acutest_helpers.h>
3 #include <freeradius-devel/util/rand.h>
4 #include <freeradius-devel/util/time.h>
5 #include <freeradius-devel/util/heap.h>
21 static void lst_validate(
fr_lst_t *lst);
28 for (
unsigned int i = 0; i < size; i++)
if (
item(lst, i + lst->
idx) ==
data)
return true;
33 static int8_t
lst_cmp(
void const *one,
void const *two)
35 lst_thing const *item1 = one, *item2 = two;
37 return CMP(item1->
data, item2->data);
45 for (i = 0; i < len; i++) {
55 for (i = 0; i < len; i++) {
57 int temp = values[i].
data;
60 values[j].
data = temp;
75 for (
unsigned int i = 0; i <
NUM_ELEMENTS(values); i++) {
80 for (
unsigned int i = 0; i <
NUM_ELEMENTS(values); i++) {
91 #define LST_TEST_SIZE (4096)
118 TEST_MSG(
"element %i inserted but not in LST", i);
125 TEST_MSG(
"element %i removed out of order", entry);
128 TEST_MSG(
"element %i removal failed, returned %i", entry, ret);
131 TEST_MSG(
"element %i removed but still in LST", entry);
134 TEST_MSG(
"element %i removed out of order", entry);
138 for (i = 0; i < left; i++) {
141 TEST_MSG(
"expected %i elements remaining in the lst", left - i);
142 TEST_MSG(
"failed extracting %i", i);
146 TEST_MSG(
"%i elements remaining", ret);
241 #define BURN_IN_OPS (10000000)
248 int insert_count = 0;
288 #define LST_CYCLE_SIZE (1600000)
296 int inserted, removed;
298 fr_time_t start_insert, start_remove, start_swap, end;
325 for (i = 0; i < to_remove; i++) {
327 TEST_MSG(
"failed extracting %i", i);
328 TEST_MSG(
"expected %i elements remaining in the LST", to_remove - i);
340 if (values[i].idx == 0) {
346 TEST_MSG(
"element %i removal failed, returned %i", i, ret);
390 data->visited =
true;
407 unsigned int idx = 0;
409 for (
unsigned int j = 0; j <
count; j++) {
410 if (!
array[j])
continue;
417 if (low)
array[idx] = NULL;
440 fr_time_t start_alloc, end_alloc, start_insert, end_insert, start_pop, end_pop, end_pop_first =
fr_time_wrap(0);
454 for (i = 0; i <
count; i++) {
456 if (i == 0) end_pop_first =
fr_time();
458 TEST_MSG(
"expected %u elements remaining in the lst",
count - i);
459 TEST_MSG(
"failed extracting %u", i);
476 fr_time_t start_alloc, end_alloc, start_insert, end_insert, start_pop, end_pop, end_pop_first =
fr_time_wrap(0);
490 for (i = 0; i <
count; i++) {
492 if (i == 0) end_pop_first =
fr_time();
494 TEST_MSG(
"expected %u elements remaining in the heap",
count - i);
495 TEST_MSG(
"failed extracting %u", i);
513 fr_time_t start_alloc, end_alloc, start_insert, end_insert, start_pop, end_pop, end_pop_first;
523 for (i = 0; i <
count; i++)
array[i] = &values[i];
527 for (i = 0; i <
count; i++) {
529 if (i == 0) end_pop_first =
fr_time();
#define TEST_MSG_ALWAYS(...)
#define CMP(_a, _b)
Same as CMP_PREFER_SMALLER use when you don't really care about ordering, you just want an ordering.
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.
static unsigned int fr_heap_num_elements(fr_heap_t *h)
Return the number of elements in the heap.
Functions for a Leftmost Skeleton Tree.
int fr_lst_extract(fr_lst_t *lst, void *data)
Remove an element from an LST.
void * fr_lst_pop(fr_lst_t *lst)
void * fr_lst_iter_next(fr_lst_t *lst, fr_lst_iter_t *iter)
Get the next entry in an LST.
fr_lst_index_t idx
Starting index, initially zero.
int fr_lst_insert(fr_lst_t *lst, void *data)
unsigned int fr_lst_num_elements(fr_lst_t *lst)
void * fr_lst_peek(fr_lst_t *lst)
void * fr_lst_iter_init(fr_lst_t *lst, fr_lst_iter_t *iter)
Iterate over entries in LST.
#define FR_LST_VERIFY(_lst)
#define fr_lst_alloc(_ctx, _cmp, _type, _field, _init)
Creates an LST that can be used with non-talloced elements.
static bool fr_lst_entry_inserted(fr_lst_index_t lst_id)
Check if an entry is inserted into an LST.
fr_lst_index_t fr_lst_iter_t
unsigned int fr_lst_index_t
#define fr_lst_foreach(_lst, _type, _data)
Iterate over the contents of an LST.
static void queue_cmp_100(void)
static void queue_cmp(unsigned int count)
Benchmarks for LSTs vs heaps when used as queues.
static void lst_test_skip_10(void)
static void lst_test(int skip)
static int8_t lst_cmp(void const *one, void const *two)
static void queue_cmp_50(void)
static void lst_cycle(void)
static void lst_burn_in(void)
static void lst_test_basic(void)
static void lst_iter(void)
static void queue_cmp_1000(void)
static void lst_test_skip_2(void)
static void queue_cmp_10(void)
static bool fr_lst_contains(fr_lst_t *lst, void *data)
static void lst_test_skip_1(void)
static void lst_stress_realloc(void)
static void populate_values(lst_thing values[], unsigned int len)
static lst_thing * array_pop(lst_thing **array, unsigned int count)
static size_t array[MY_ARRAY_SIZE]
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.
static int64_t fr_time_delta_unwrap(fr_time_delta_t time)
#define fr_time_wrap(_time)
#define fr_time_sub(_a, _b)
Subtract one time from another.
char const * fr_strerror(void)
Get the last library error.