]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Allow replacement of inline rbnodes
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 19 Apr 2021 14:00:22 +0000 (09:00 -0500)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 19 Apr 2021 14:00:22 +0000 (09:00 -0500)
Much more efficient that a normal replace!

src/lib/util/rb.h

index 2fb2be09aac0e218b143398d5afe24a980374f71..32fec89b257f905d09cf2bfc461037beb204cbc1 100644 (file)
@@ -302,14 +302,33 @@ uint32_t  fr_rb_num_elements(fr_rb_tree_t *tree) CC_HINT(nonnull);
  *
  * @param[in] node     to check.
  * @return
- *     - True if node is in the tree.
- *     - False if node is not in the tree.
+ *     - true if node is in the tree.
+ *     - talse if node is not in the tree.
  */
 static inline bool fr_rb_node_inline_in_tree(fr_rb_node_t *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));
+
+       return true;
+}
+
 /** Iterator structure for in-order traversal of an rbtree
  */
 typedef struct {