23RCSID(
"$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");
 
 
static size_t min(size_t x, size_t y)
#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...
void * fr_minmax_heap_max_pop(fr_minmax_heap_t *hp)
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)
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.
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 * p[]
Array of nodes.
static bool has_children(minmax_heap_t *h, fr_minmax_heap_index_t idx)
void * fr_minmax_heap_min_peek(fr_minmax_heap_t *hp)
#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)
static void push_down(minmax_heap_t *h, fr_minmax_heap_index_t idx)
void * fr_minmax_heap_min_pop(fr_minmax_heap_t *hp)
fr_minmax_heap_cmp_t cmp
Comparator function.
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.
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.
void * fr_minmax_heap_iter_init(fr_minmax_heap_t *hp, fr_minmax_heap_iter_t *iter)
Iterate over entries in a minmax heap.
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.
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
fr_aka_sim_id_type_t type
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)