23 RCSID(
"$Id: f7256c103ab736d4e2dac7441a1f4503b466b0b2 $")
25 #include <freeradius-devel/util/minmax_heap.h>
26 #include <freeradius-devel/util/strerror.h>
27 #include <freeradius-devel/util/debug.h>
28 #include <freeradius-devel/util/misc.h>
67 #define INITIAL_CAPACITY 2048
74 #define HEAP_PARENT(_x) ((_x) >> 1)
75 #define HEAP_GRANDPARENT(_x) HEAP_PARENT(HEAP_PARENT(_x))
76 #define HEAP_LEFT(_x) (2 * (_x))
77 #define HEAP_RIGHT(_x) (2 * (_x) + 1 )
78 #define HEAP_SWAP(_a, _b) do { void *_tmp = _a; _a = _b; _b = _tmp; } while (0)
90 return (
depth(i) & 1) == 0;
103 if (
unlikely(candidate_depth < ancestor_depth))
return false;
106 return (candidate - level_min) < level_min;
109 #define is_max_level_index(_i) (!(is_min_level_index(_i)))
147 h->
p[0] = (
void *)UINTPTR_MAX;
165 if (h->
size == UINT_MAX) {
171 n_size = 2 * h->
size;
177 n_size, (n_size *
sizeof(
void *)));
208 #define OFFSET_SET(_heap, _idx) index_set(_heap, _heap->p[_idx], _idx)
209 #define OFFSET_RESET(_heap, _idx) index_set(_heap, _heap->p[_idx], 0)
294 if (h->
cmp(h->
p[i], h->
p[max]) > 0) max = i;
310 if (h->
cmp(h->
p[m], h->
p[idx]) >= 0)
break;
337 if (h->
cmp(h->
p[m], h->
p[idx]) <= 0)
break;
474 return h->
p[2 + (h->
cmp(h->
p[2], h->
p[3]) < 0)];
583 #ifndef TALLOC_GET_TYPE_ABORT_NOOP
605 "CONSISTENCY CHECK FAILED %s[%i]: num_elements exceeds size",
file,
line);
608 "CONSISTENCY CHECK FAILED %s[%i]: zeroeth element special value overwritten",
file,
line);
611 void *
data = h->
p[i];
614 if (h->
type) (void)_talloc_get_type_abort(
data, h->
type, __location__);
616 "CONSISTENCY CHECK FAILED %s[%i]: node %u index != %u",
file,
line, i, i);
652 int8_t cmp_result = h->
cmp(h->
p[i], h->
p[others[j]]);
655 "CONSISTENCY CHECK FAILED %s[%i]: node %u violates %s level condition",
656 file,
line, i, on_min_level ?
"min" :
"max");
#define fr_fatal_assert_msg(_x, _fmt,...)
Calls panic_action ifndef NDEBUG, else logs error and causes the server to exit immediately with code...
static uint8_t fr_high_bit_pos(uint64_t num)
Find the highest order high bit in an unsigned 64 bit integer.
static void push_down_max(minmax_heap_t *h, fr_minmax_heap_index_t idx)
precondition: idx is the index of an existing entry on a max level (Just like push_down_min() save fo...
int fr_minmax_heap_insert(fr_minmax_heap_t *hp, void *data)
static bool has_grandchildren(minmax_heap_t *h, fr_minmax_heap_index_t i)
static void index_set(minmax_heap_t *h, void *data, fr_minmax_heap_index_t idx)
#define OFFSET_SET(_heap, _idx)
static void push_up_min(minmax_heap_t *h, fr_minmax_heap_index_t idx)
static int minmax_heap_expand(fr_minmax_heap_t *hp)
static void push_down_min(minmax_heap_t *h, fr_minmax_heap_index_t idx)
precondition: idx is the index of an existing entry on a min level
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.
static bool has_children(minmax_heap_t *h, fr_minmax_heap_index_t idx)
#define OFFSET_RESET(_heap, _idx)
#define is_max_level_index(_i)
static void push_up(minmax_heap_t *h, fr_minmax_heap_index_t idx)
#define HEAP_GRANDPARENT(_x)
static uint8_t depth(fr_minmax_heap_index_t i)
void * fr_minmax_heap_max_peek(fr_minmax_heap_t *hp)
static void push_down(minmax_heap_t *h, fr_minmax_heap_index_t idx)
fr_minmax_heap_cmp_t cmp
Comparator function.
unsigned int fr_minmax_heap_num_elements(fr_minmax_heap_t *hp)
Return the number of elements in the minmax heap.
static fr_minmax_heap_index_t max_child_or_grandchild(minmax_heap_t *h, fr_minmax_heap_index_t idx)
#define HEAP_SWAP(_a, _b)
struct fr_minmax_heap_s minmax_heap_t
fr_minmax_heap_t * _fr_minmax_heap_alloc(TALLOC_CTX *ctx, fr_minmax_heap_cmp_t cmp, char const *type, size_t offset, unsigned int init)
static bool is_min_level_index(fr_minmax_heap_index_t i)
static bool is_descendant(fr_minmax_heap_index_t candidate, fr_minmax_heap_index_t ancestor)
size_t offset
Offset of heap index in element structure.
int fr_minmax_heap_extract(fr_minmax_heap_t *hp, void *data)
static void push_up_max(minmax_heap_t *h, fr_minmax_heap_index_t idx)
static fr_minmax_heap_index_t min_child_or_grandchild(minmax_heap_t *h, fr_minmax_heap_index_t idx)
Find the index of the minimum child or grandchild of the entry at a given index.
unsigned int size
Number of nodes allocated.
char const * type
Talloc type of elements.
void * fr_minmax_heap_iter_init(fr_minmax_heap_t *hp, fr_minmax_heap_iter_t *iter)
Iterate over entries in a minmax heap.
static fr_minmax_heap_index_t index_get(minmax_heap_t *h, void *data)
void fr_minmax_heap_verify(char const *file, int line, fr_minmax_heap_t const *hp)
unsigned int num_elements
Number of nodes used.
int8_t(* fr_minmax_heap_cmp_t)(void const *a, void const *b)
Comparator to order elements.
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
unsigned int fr_minmax_heap_index_t
static size_t min(size_t x, size_t y)
init
Enter the EAP-IDENTITY state.
fr_aka_sim_id_type_t type
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)