24RCSID(
"$Id: 49f598d553ee2e541f4e773d22b0cea1bcdaf324 $")
 
   26#include <freeradius-devel/util/rb.h> 
   27#include <freeradius-devel/util/strerror.h> 
   33#  define RB_MAGIC (0x5ad09c42) 
  128        talloc_free_children(tree);
 
 
  152        if (
unlikely(offset >= UINT16_MAX)) {
 
  154                                   "Expected <= %zu, got %zd", (
size_t) UINT16_MAX, offset);
 
  163                .node_ctx = node_ctx,
 
  164                .offset = offset < 0 ? 0 : (
uint16_t)offset,
 
  167                .data_free = data_free,
 
 
  351#ifndef TALLOC_GET_TYPE_ABORT_NOOP 
  352        if (tree->
type) (void)_talloc_get_type_abort(
data, tree->
type, __location__);
 
  366                        if (existing) *existing = 
current;
 
 
  477        if (!z || z == 
NIL) 
return;
 
  510                void *y_data = y->
data;
 
  521                memcpy(y, z, 
sizeof(*y));
 
 
  558                if (result == 0) 
return current;
 
 
  581        if (
unlikely(tree->being_freed)) 
return NULL;
 
 
  604                if (found) *found = existing->
data;
 
  608                if (found) *found = NULL;
 
  612                if (found) *found = NULL;
 
 
  654                void    *old_data = node->
data;
 
  671                } 
else if (tree->data_free) {
 
  672                        tree->data_free(old_data);
 
  677                if (old) *old = NULL;
 
  681                if (old) *old = NULL;
 
 
  700        if (
unlikely(tree->being_freed)) 
return NULL;
 
  702        if (!node) 
return NULL;
 
  706        node_data = node->
data;
 
 
  727        node_data = node->
data;
 
 
  745        if (
unlikely(tree->being_freed)) 
return false;
 
  747        if (!node) 
return false;
 
 
  783        return tree->num_elements;
 
 
  790        if (x == 
NIL) 
return NULL;
 
 
  805        if (x == 
NIL) 
return NULL;
 
 
  828        if (x == 
NIL) 
return NULL;
 
 
  882        while ((x != 
NIL) && (y == x->
right)) {
 
 
  921        if (x == 
NIL) 
return NULL;
 
 
  971                if (y->right != 
NIL && y->right != x) {
 
 
  998        if (x == 
NIL) 
return NULL;
 
 
 1052        if (y->right == 
NIL || y->right == x) {
 
 
 1071#define DEF_RB_FLATTEN_FUNC(_order) \ 
 1072int fr_rb_flatten_##_order(TALLOC_CTX *ctx, void **out[], fr_rb_tree_t *tree) \ 
 1074        uint32_t num = fr_rb_num_elements(tree), i; \ 
 1075        fr_rb_iter_##_order##_t iter; \ 
 1076        void *item, **list; \ 
 1077        if (unlikely(!(list = talloc_array(ctx, void *, num)))) return -1; \ 
 1078        for (item = fr_rb_iter_init_##_order(&iter, tree), i = 0; \ 
 1080             item = fr_rb_iter_next_##_order(&iter), i++) list[i] = item; \ 
 
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
#define CC_NO_UBSAN(_sanitize)
int8_t(* fr_cmp_t)(void const *a, void const *b)
void(* fr_free_t)(void *)
static rc_request_t * current
uint32_t fr_rb_num_elements(fr_rb_tree_t *tree)
Return how many nodes there are in a tree.
void * fr_rb_iter_init_inorder(fr_rb_iter_inorder_t *iter, fr_rb_tree_t *tree)
Initialise an in-order iterator.
static fr_rb_node_t sentinel
int fr_rb_find_or_insert(void **found, fr_rb_tree_t *tree, void const *data)
Attempt to find current data in the tree, if it does not exist insert it.
void fr_rb_iter_delete_inorder(fr_rb_iter_inorder_t *iter)
Remove the current node from the tree.
void * fr_rb_remove(fr_rb_tree_t *tree, void const *data)
Remove an entry from the tree, without freeing the data.
#define DEF_RB_FLATTEN_FUNC(_order)
static int insert_node(fr_rb_node_t **existing, fr_rb_tree_t *tree, void *data))
Insert an element into the tree.
static void delete_fixup(fr_rb_tree_t *tree, fr_rb_node_t *x, fr_rb_node_t *parent)
Maintain RED-BLACK tree balance after deleting node x.
static void delete_internal(fr_rb_tree_t *tree, fr_rb_node_t *z, bool free_data)
Delete an element (z) from the tree.
int fr_rb_replace(void **old, fr_rb_tree_t *tree, void const *data)
Replace old data with new data, OR insert if there is no old.
static fr_rb_node_t * _node_inline_alloc(fr_rb_tree_t const *tree, void *data)
Return the fr_rb_node_t that was allocated as part of the data structure.
void * fr_rb_iter_next_preorder(fr_rb_iter_preorder_t *iter)
Return the next node.
void * fr_rb_iter_init_preorder(fr_rb_iter_preorder_t *iter, fr_rb_tree_t *tree)
Initialise a pre-order iterator.
static fr_rb_node_t * _node_heap_alloc(fr_rb_tree_t const *tree, UNUSED void *data)
Allocate a new fr_rb_node_t on the heap.
fr_rb_tree_t * _fr_rb_alloc(TALLOC_CTX *ctx, ssize_t offset, char const *type, fr_cmp_t data_cmp, fr_free_t data_free)
Alloc a new RED-BLACK tree.
static void free_walker(fr_rb_tree_t *tree, fr_rb_node_t *x)
Walks the tree to delete all nodes Does NOT re-balance it!
void * fr_rb_iter_init_postorder(fr_rb_iter_postorder_t *iter, fr_rb_tree_t *tree)
Initialise a post-order iterator.
static void node_data_free(fr_rb_tree_t const *tree, fr_rb_node_t *node)
void * fr_rb_iter_next_inorder(fr_rb_iter_inorder_t *iter)
Return the next node.
static int _tree_free(fr_rb_tree_t *tree)
Free the rbtree cleaning up any nodes.
void * fr_rb_iter_next_postorder(fr_rb_iter_postorder_t *iter)
Return the next node.
void * fr_rb_remove_by_inline_node(fr_rb_tree_t *tree, fr_rb_node_t *node)
Remove an entry from the tree, using the node structure, without freeing the data.
bool fr_rb_delete_by_inline_node(fr_rb_tree_t *tree, fr_rb_node_t *node)
Remove node and free data (if a free function was specified)
void * fr_rb_find(fr_rb_tree_t const *tree, void const *data)
Find an element in the tree, returning the data, not the node.
int _fr_rb_init(fr_rb_tree_t *tree, TALLOC_CTX *node_ctx, ssize_t offset, char const *type, fr_cmp_t data_cmp, fr_free_t data_free)
Initialise a new RED-BLACK tree.
void * fr_rb_first(fr_rb_tree_t *tree)
bool fr_rb_insert(fr_rb_tree_t *tree, void const *data)
Insert data into a tree.
void * fr_rb_last(fr_rb_tree_t *tree)
static fr_rb_node_t * find_node(fr_rb_tree_t const *tree, void const *data)
bool fr_rb_delete(fr_rb_tree_t *tree, void const *data)
Remove node and free data (if a free function was specified)
static void rotate_right(fr_rb_tree_t *tree, fr_rb_node_t *x)
Rotate Node x to right.
static void _node_heap_free(fr_rb_tree_t const *tree, fr_rb_node_t *node, bool free_data)
Clear the fr_rb_node_t that was allocated as part of the data structure.
static void _node_inline_free(fr_rb_tree_t const *tree, fr_rb_node_t *node, bool free_data)
Clear the fr_rb_node_t that was allocated as part of the data structure.
static void rotate_left(fr_rb_tree_t *tree, fr_rb_node_t *x)
Rotate Node x to left.
static void insert_fixup(fr_rb_tree_t *tree, fr_rb_node_t *x)
Maintain red-black tree balance after inserting node x.
fr_rb_tree_t * tree
Tree being iterated over.
fr_rb_node_t * node
current node
fr_rb_node_t * parent
Parent.
struct fr_rb_node_s fr_rb_node_t
fr_rb_node_t * left
Left child.
bool being_freed
Disable frees if we're currently calling a free function.
struct fr_rb_tree_s fr_rb_tree_t
fr_rb_node_t * next
if non-NULL, next node cached by fr_rb_iter_delete()
fr_rb_node_t * node
current node
fr_cmp_t data_cmp
Callback to compare node data.
TALLOC_CTX * node_ctx
Talloc ctx to allocate nodes in.
fr_rb_node_t * right
Right child.
char const  * type
Talloc type to check elements against.
static bool fr_rb_node_inline_in_tree(fr_rb_node_t const *node)
Check to see if an item is in a tree by examining its inline fr_rb_node_t.
void * data
data stored in node
uint32_t num_elements
How many elements are inside the tree.
fr_free_t data_free
Callback to free node data.
fr_rb_tree_t * tree
Tree being iterated over.
uint16_t offset
Where's the fr_rb_node_t is located in the structure being inserted.
rb_node_free_t node_free
Callback to free a node.
bool being_freed
Prevent double frees in talloc_destructor.
fr_rb_tree_t * tree
Tree being iterated over.
fr_rb_node_t * node
current nodeāset to NULL (not NIL) by fr_rb_iter_delete()
fr_rb_colour_t colour
Node colour (BLACK, RED)
rb_node_alloc_t node_alloc
Callback to allocate a new node.
fr_rb_node_t * root
Root of the rbtree.
Iterator structure for in-order traversal of an rbtree.
Iterator structure for post-order traversal of an rbtree.
Iterator structure for pre-order traversal of an rbtree.
The main red black tree structure.
static int8_t data_cmp(const void *one, const void *two)
fr_aka_sim_id_type_t type
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.