]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
when inserting data in the tree, if there was already a node with the
authorRonnie Sahlberg <sahlberg@ronnie>
Tue, 7 Aug 2007 22:20:46 +0000 (08:20 +1000)
committerRonnie Sahlberg <sahlberg@ronnie>
Tue, 7 Aug 2007 22:20:46 +0000 (08:20 +1000)
same key then replace the data in the node with the new data and return
the pointer to the previous data held in the node.

this allows a caller to avoid having to first check if a node already
exists before inserting a possibly duplicate/colliding entry and lets
the caller do whatever it needs to do after the fact.

(This used to be ctdb commit 6634cabb910c26400780d51727ff2d1ba5e16e36)

ctdb/common/rb_tree.c
ctdb/common/rb_tree.h

index 002d505f17dea7285f3a4f8d5c9aefa39a10489c..57b0a86ab09d824a2e87b05dc94e311eb17cd47d 100644 (file)
@@ -530,9 +530,10 @@ trbt_create_node(trbt_tree_t *tree, trbt_node_t *parent, uint32_t key, void *dat
 
 /* insert a new node in the tree. 
    if there is already a node with a matching key in the tree 
-   we reurn an error
+   we replace it with the new data and return a pointer to the old data
+   in case the caller wants to take any special action
  */
-int
+void *
 trbt_insert32(trbt_tree_t *tree, uint32_t key, void *data)
 {
        trbt_node_t *node;
@@ -544,16 +545,23 @@ trbt_insert32(trbt_tree_t *tree, uint32_t key, void *data)
                node = trbt_create_node(tree, NULL, key, data);
 
                tree->tree=node;
-               return 0;
+               return NULL;
        }
 
        /* it was not the new root so walk the tree until we find where to
         * insert this new leaf.
         */
        while(1){
-               /* this node already exists, so just return an error */
+               /* this node already exists, replace data and return the 
+                  old data
+                */
                if(key==node->key32){
-                       return -1;
+                       void *old_data;
+
+                       old_data = node->data;
+                       node->data  = talloc_steal(node, data);
+
+                       return old_data;
                }
                if(key<node->key32) {
                        if(!node->left){
@@ -587,7 +595,7 @@ trbt_insert32(trbt_tree_t *tree, uint32_t key, void *data)
        /* node will now point to the newly created node */
        node->rb_color=TRBT_RED;
        trbt_insert_case1(tree, node);
-       return 0;
+       return NULL;
 }
 
 void *
index e53a092bfc3c857952e8295f9ecb5fd511d503d9..603ebfad34bea54603c82adaeb2379e6aa99ee42 100644 (file)
@@ -37,10 +37,19 @@ typedef struct _trbt_tree_t {
 
 
 
-
+/* Create a RB tree */
 trbt_tree_t *trbt_create(TALLOC_CTX *memctx);
+
+/* Lookup a node in the tree and return a pointer to data or NULL */
 void *trbt_lookup32(trbt_tree_t *tree, uint32_t key);
-int trbt_insert32(trbt_tree_t *tree, uint32_t key, void *data);
+
+/* Insert a new node into the tree. If there was already a node with this
+   key the pointer to the previous data is returned.
+   The tree will talloc_steal() the data inserted into the tree .
+*/
+void *trbt_insert32(trbt_tree_t *tree, uint32_t key, void *data);
+
+/* Delete a node from the tree and free all data associated with it */
 void trbt_delete32(trbt_tree_t *tree, uint32_t key);