]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add fr_rb_delete_by_inline_node and fr_rb_remove_by_inline_node
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 26 Mar 2022 01:40:10 +0000 (19:40 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 26 Mar 2022 01:45:55 +0000 (19:45 -0600)
src/lib/util/rb.c
src/lib/util/rb.h

index 738aad1080a83e93b4221f0b5da263a85561756b..92f03caea5bfde976eec18da25a46b9e84e879e2 100644 (file)
@@ -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.
index 081aabbb820ab46e0e01fecde7d0fdd748ed989c..6027492f38370eac4fa4df3ff825da909b3d381b 100644 (file)
@@ -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 {