From: Arran Cudbard-Bell Date: Sat, 26 Mar 2022 01:40:10 +0000 (-0600) Subject: Add fr_rb_delete_by_inline_node and fr_rb_remove_by_inline_node X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=140d5cef2f3fb6a76afa27e25a28dedf1e407b4c;p=thirdparty%2Ffreeradius-server.git Add fr_rb_delete_by_inline_node and fr_rb_remove_by_inline_node --- diff --git a/src/lib/util/rb.c b/src/lib/util/rb.c index 738aad1080a..92f03caea5b 100644 --- a/src/lib/util/rb.c +++ b/src/lib/util/rb.c @@ -704,6 +704,27 @@ void *fr_rb_remove(fr_rb_tree_t *tree, void const *data) return node_data; } +/** 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. + * + * @param[in] tree to remove data from. + * @param[in] node to remove. + * @return + * - The user data we removed. + * - NULL if the user data wasn't in the tree. + */ +void *fr_rb_remove_by_inline_node(fr_rb_tree_t *tree, fr_rb_node_t *node) +{ + void *node_data; + + if (!fr_rb_node_inline_in_tree(node)) return NULL; + node_data = node->data; + delete_internal(tree, node, false); /* nullified node->data */ + return node_data; +} + /** Remove node and free data (if a free function was specified) * * @param[in] tree to remove data from. @@ -727,6 +748,26 @@ bool fr_rb_delete(fr_rb_tree_t *tree, void const *data) return true; } +/** 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. + * + * @param[in] tree to remove data from. + * @param[in] node to remove/free. + * @return + * - true if we removed data. + * - false if we couldn't find any matching data. + */ +bool fr_rb_delete_by_inline_node(fr_rb_tree_t *tree, fr_rb_node_t *node) +{ + if (!fr_rb_node_inline_in_tree(node)) return false; + + delete_internal(tree, node, true); + + return true; +} + /** Return how many nodes there are in a tree * * @param[in] tree to return node count for. diff --git a/src/lib/util/rb.h b/src/lib/util/rb.h index 081aabbb820..6027492f383 100644 --- a/src/lib/util/rb.h +++ b/src/lib/util/rb.h @@ -289,8 +289,12 @@ int fr_rb_replace(void **old, fr_rb_tree_t *tree, void const *data) CC_HINT(non void *fr_rb_remove(fr_rb_tree_t *tree, void const *data) CC_HINT(nonnull); +void *fr_rb_remove_by_inline_node(fr_rb_tree_t *tree, fr_rb_node_t *node) CC_HINT(nonnull); + bool fr_rb_delete(fr_rb_tree_t *tree, void const *data) CC_HINT(nonnull); +bool fr_rb_delete_by_inline_node(fr_rb_tree_t *tree, fr_rb_node_t *node) CC_HINT(nonnull); + uint32_t fr_rb_num_elements(fr_rb_tree_t *tree) CC_HINT(nonnull); /** Check to see if an item is in a tree by examining its inline #fr_rb_node_t @@ -310,27 +314,6 @@ static inline bool fr_rb_node_inline_in_tree(fr_rb_node_t const *node) return (node->left && node->right && node->parent && !node->being_freed); } -/** Check to see if nodes are equivalent and if they are, replace one with the other - * - * @param[in] tree Used to access the comparitor. - * @param[in] to_replace Node to replace in the tree. - * @param[in] replacement Replacement. - * @return - * - true on success. - * - false if nodes were not equivalent. - */ -static inline bool fr_rb_node_inline_replace(fr_rb_tree_t *tree, fr_rb_node_t *to_replace, fr_rb_node_t *replacement) -{ - if (tree->data_cmp(to_replace->data, replacement->data) != 0) return false; - - memcpy(replacement, to_replace, sizeof(*replacement)); - memset(to_replace, 0, sizeof(*to_replace)); - - /* FIXME - Need to fix children and parent */ - - return true; -} - /** Iterator structure for in-order traversal of an rbtree */ typedef struct {