The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
|
Red/black tree implementation. More...
#include <freeradius-devel/util/rb.h>
#include <freeradius-devel/util/strerror.h>
Go to the source code of this file.
Macros | |
#define | DEF_RB_FLATTEN_FUNC(_order) |
#define | NIL &sentinel /* all leafs are sentinels */ |
#define | RB_MAGIC (0x5ad09c42) |
Functions | |
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. | |
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. | |
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. | |
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 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. | |
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 int | _tree_free (fr_rb_tree_t *tree) |
Free the rbtree cleaning up any nodes. | |
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. | |
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) | |
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_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_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_iter_delete_inorder (fr_rb_iter_inorder_t *iter) |
Remove the current node from the tree. | |
void * | fr_rb_iter_init_inorder (fr_rb_iter_inorder_t *iter, fr_rb_tree_t *tree) |
Initialise an in-order iterator. | |
void * | fr_rb_iter_init_postorder (fr_rb_iter_postorder_t *iter, fr_rb_tree_t *tree) |
Initialise a post-order iterator. | |
void * | fr_rb_iter_init_preorder (fr_rb_iter_preorder_t *iter, fr_rb_tree_t *tree) |
Initialise a pre-order iterator. | |
void * | fr_rb_iter_next_inorder (fr_rb_iter_inorder_t *iter) |
Return the next node. | |
void * | fr_rb_iter_next_postorder (fr_rb_iter_postorder_t *iter) |
Return the next node. | |
void * | fr_rb_iter_next_preorder (fr_rb_iter_preorder_t *iter) |
Return the next node. | |
void * | fr_rb_last (fr_rb_tree_t *tree) |
uint32_t | fr_rb_num_elements (fr_rb_tree_t *tree) |
Return how many nodes there are in a tree. | |
void * | fr_rb_remove (fr_rb_tree_t *tree, void const *data) |
Remove an entry from the tree, without freeing the data. | |
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. | |
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 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! | |
static void | insert_fixup (fr_rb_tree_t *tree, fr_rb_node_t *x) |
Maintain red-black tree balance after inserting node x. | |
static int | insert_node (fr_rb_node_t **existing, fr_rb_tree_t *tree, void *data) |
Insert an element into the tree. | |
static void | node_data_free (fr_rb_tree_t const *tree, fr_rb_node_t *node) |
static void | rotate_left (fr_rb_tree_t *tree, fr_rb_node_t *x) |
Rotate Node x to left. | |
static void | rotate_right (fr_rb_tree_t *tree, fr_rb_node_t *x) |
Rotate Node x to right. | |
Variables | |
static fr_rb_node_t | sentinel = { NIL, NIL, NULL, NULL, BLACK, false } |
Red/black tree implementation.
Definition in file rb.c.
#define DEF_RB_FLATTEN_FUNC | ( | _order | ) |
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.
[in] | ctx | to allocate the tree in. Only the tree is allocated in this context, the memory for the fr_rb_node_t is allocated as part of the data being inserted into the tree. |
[in] | offset | offsetof the fr_rb_node_t field in the data being inserted. If < 0, nodes will be allocated on the heap. |
[in] | type | Talloc type of structures being inserted, may be NULL. |
[in] | data_cmp | Comparator function for ordering data in the tree. |
[in] | data_free | Free function to call whenever data is deleted or replaced. |
Definition at line 202 of file rb.c.
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.
[out] | tree | to initialise. |
[in] | node_ctx | the ctx used to allocate fr_rb_node_t if the tree isn't using inline fr_rb_node_t. |
[in] | offset | offsetof the fr_rb_node_t field in the data being inserted. If < 0, nodes will be allocated on the heap. |
[in] | type | Talloc type of structures being inserted, may be NULL. |
[in] | data_cmp | Comparator function for ordering data in the tree. |
[in] | data_free | Free function to call whenever data is deleted or replaced. |
Definition at line 147 of file rb.c.
|
static |
|
static |
|
static |
|
static |
|
static |
Free the rbtree cleaning up any nodes.
Walk the tree deleting nodes, then free any children of the tree.
[in] | tree | to tree. |
Definition at line 104 of file rb.c.
|
static |
|
static |
|
inlinestatic |
bool fr_rb_delete | ( | fr_rb_tree_t * | tree, |
void const * | data | ||
) |
Remove node and free data (if a free function was specified)
[in] | tree | to remove data from. |
[in] | data | to remove/free. |
Definition at line 741 of file rb.c.
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)
This function can help where multiple items may be in the tree with the same comparator value.
[in] | tree | to remove data from. |
[in] | node | to remove/free. |
Definition at line 767 of file rb.c.
void * fr_rb_find | ( | fr_rb_tree_t const * | tree, |
void const * | data | ||
) |
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.
[out] | found | Pre-existing data we found. |
[in] | tree | to search/insert into. |
[in] | data | to find. |
Definition at line 598 of file rb.c.
void * fr_rb_first | ( | fr_rb_tree_t * | tree | ) |
bool fr_rb_insert | ( | fr_rb_tree_t * | tree, |
void const * | data | ||
) |
void fr_rb_iter_delete_inorder | ( | fr_rb_iter_inorder_t * | iter | ) |
Remove the current node from the tree.
[in] | iter | previously initialised with fr_rb_iter_init_inorder |
Definition at line 898 of file rb.c.
void * fr_rb_iter_init_inorder | ( | fr_rb_iter_inorder_t * | iter, |
fr_rb_tree_t * | tree | ||
) |
void * fr_rb_iter_init_postorder | ( | fr_rb_iter_postorder_t * | iter, |
fr_rb_tree_t * | tree | ||
) |
void * fr_rb_iter_init_preorder | ( | fr_rb_iter_preorder_t * | iter, |
fr_rb_tree_t * | tree | ||
) |
void * fr_rb_iter_next_inorder | ( | fr_rb_iter_inorder_t * | iter | ) |
Return the next node.
[in] | iter | previously initialised with fr_rb_iter_init_inorder |
Definition at line 850 of file rb.c.
void * fr_rb_iter_next_postorder | ( | fr_rb_iter_postorder_t * | iter | ) |
Return the next node.
[in] | iter | previously initialised with fr_rb_iter_init_postorder |
Definition at line 1025 of file rb.c.
void * fr_rb_iter_next_preorder | ( | fr_rb_iter_preorder_t * | iter | ) |
Return the next node.
[in] | iter | previously initialised with fr_rb_iter_init_preorder |
Definition at line 941 of file rb.c.
void * fr_rb_last | ( | fr_rb_tree_t * | tree | ) |
uint32_t fr_rb_num_elements | ( | fr_rb_tree_t * | tree | ) |
void * fr_rb_remove | ( | fr_rb_tree_t * | tree, |
void const * | data | ||
) |
Remove an entry from the tree, without freeing the data.
[in] | tree | to remove data from. |
[in] | data | to remove. |
Definition at line 695 of file rb.c.
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.
This function can help where multiple items may be in the tree with the same comparator value.
[in] | tree | to remove data from. |
[in] | node | to remove. |
Definition at line 722 of file rb.c.
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.
[out] | old | data that was replaced. If this argument is not NULL, then the old data will not be freed, even if a free function is configured. |
[in] | tree | to insert data into. |
[in] | data | to replace. |
Definition at line 647 of file rb.c.
|
static |
|
inlinestatic |
|
static |
Insert an element into the tree.
[out] | existing | if a node exists, and existing is not NULL this will be populated with the node. |
[in] | tree | to search in. |
[in] | data | to search for. |
Definition at line 345 of file rb.c.
|
inlinestatic |
|
inlinestatic |
|
inlinestatic |