]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
add helpers to add/lookup/delete nodes in a tree where the key is an
authorRonnie Sahlberg <sahlberg@ronnie>
Wed, 8 Aug 2007 02:30:12 +0000 (12:30 +1000)
committerRonnie Sahlberg <sahlberg@ronnie>
Wed, 8 Aug 2007 02:30:12 +0000 (12:30 +1000)
array of uint32

(This used to be ctdb commit b7e0996e7735c8629d07453b9d335990c2dbc3db)

ctdb/common/rb_tree.c
ctdb/common/rb_tree.h
ctdb/tests/rb_test.c

index 5139560ae29a5d1fbda3e34e8567d194b22aa3e3..17388f9562aa84cb3c86a3848ed3c5fda7aa774c 100644 (file)
@@ -713,6 +713,125 @@ trbt_insert32_callback(trbt_tree_t *tree, uint32_t key, void *(*callback)(void *
 
 
 
+struct trbt_array_param {
+       void *(*callback)(void *param, void *data);
+       void *param;
+       uint32_t keylen;
+       uint32_t *key;
+       trbt_tree_t *tree;
+};
+static void *array_insert_callback(void *p, void *data)
+{
+       struct trbt_array_param *param = (struct trbt_array_param *)p;
+       trbt_tree_t *tree = NULL;
+
+
+       /* if keylen has reached 0 we are done and can call the users 
+          callback function with the users parameters
+       */
+       if (param->keylen == 0) {
+               return param->callback(param->param, data);
+       }
+
+
+       /* keylen is not zero yes so we must create/process more subtrees */
+       /* if data is NULL this means we did not yet have a subtree here
+          and we must create one.
+       */
+       if (data == NULL) {
+               /* create a new subtree and hang it off our current tree */
+               tree = trbt_create(param->tree);
+       } else {
+               /* we already have a subtree for this path */
+               tree = (trbt_tree_t *)data;
+       }
+               
+       trbt_insertarray32_callback(tree, param->keylen, param->key, param->callback, param->param);
+
+       /* now return either the old tree we got in *data or the new tree
+          we created to our caller so he can update his pointer in his
+          tree to point to our subtree
+       */
+       return tree;
+}
+
+
+
+/* insert into the tree using an array of uint32 as a key */
+void 
+trbt_insertarray32_callback(trbt_tree_t *tree, uint32_t keylen, uint32_t *key, void *(*cb)(void *param, void *data), void *pm)
+{
+       struct trbt_array_param tap;
+
+       /* keylen-1 and key[1]  since the call to insert32 will consume the
+          first part of the key.
+       */
+       tap.callback= cb;
+       tap.param   = pm;
+       tap.keylen  = keylen-1;
+       tap.key     = &key[1];
+       tap.tree    = tree;
+
+       trbt_insert32_callback(tree, key[0], array_insert_callback, &tap);
+}
+
+
+/* lookup the tree using an array of uint32 as a key */
+void *
+trbt_lookuparray32(trbt_tree_t *tree, uint32_t keylen, uint32_t *key)
+{
+       /* if keylen is 1 we can do a regular lookup and return this to the
+          user 
+       */
+       if (keylen == 1) {
+               return trbt_lookup32(tree, key[0]);
+       }
+
+       /* we need to lookup the next subtree */
+       tree = trbt_lookup32(tree, key[0]);
+       if (tree == NULL) {
+               /* the key does not exist, return NULL */
+               return NULL;
+       }
+
+       /* now lookup the next part of the key in our new tree */
+       return trbt_lookuparray32(tree, keylen-1, &key[1]);
+}
+
+
+/*  delete a node from the tree using an array of uint32 as a key */
+void
+trbt_deletearray32(trbt_tree_t *tree, uint32_t keylen, uint32_t *key)
+{
+       trbt_tree_t *next_tree;
+
+       /* if we have reached the leaftree we can just delete the node
+          if it exists
+       */
+       if (keylen == 1) {
+               trbt_delete32(tree, key[0]);
+               return;
+       }
+
+
+       /* find the next subtree and recurse into it if it exists */
+       next_tree = trbt_lookup32(tree, key[0]);
+       if (next_tree == NULL) {
+               return;
+       }
+
+       trbt_deletearray32(next_tree, keylen-1, &key[1]);
+
+
+       /* when we returned from recursing into the the subtree,
+          that subtree might have become empty in which case we can delete it
+          as well
+        */
+       if (next_tree->root == NULL) {
+               trbt_delete32(tree, key[0]);
+       }
+}
+
 # if 0
 static void printtree(trbt_node_t *node, int levels)
 {
index ad095dd50ff0ee22e80786afcc44015376a17bdd..f94a4b6a2709bb0225723777bd6e813267ddea4c 100644 (file)
@@ -63,3 +63,14 @@ void trbt_insert32_callback(trbt_tree_t *tree, uint32_t key, void *(*callback)(v
 /* Delete a node from the tree and free all data associated with it */
 void trbt_delete32(trbt_tree_t *tree, uint32_t key);
 
+
+/* insert into the tree with a key based on an array of uint32 */
+void trbt_insertarray32_callback(trbt_tree_t *tree, uint32_t keylen, uint32_t *key, void *(*callback)(void *param, void *data), void *param);
+
+/* Lookup a node in the tree with a key based on an array of uint32 
+   and return a pointer to data or NULL */
+void *trbt_lookuparray32(trbt_tree_t *tree, uint32_t keylen, uint32_t *key);
+
+/* Delete a node in the tree with a key based on an array of uint32 
+   and return a pointer to data or NULL */
+void trbt_deletearray32(trbt_tree_t *tree, uint32_t keylen, uint32_t *key);
index b1c62a3447e2a18e78bd1661ff57130e40a12061..04ae7d2cf156d763eaae18796bff806aa5ebb112 100644 (file)
@@ -62,6 +62,11 @@ int main(int argc, const char *argv[])
        struct event_context *ev;
        int i;
        trbt_tree_t *tree;
+       uint32_t *data;
+       uint32_t key1[3] = {0,0,0};
+       uint32_t key2[3] = {0,0,1};
+       uint32_t key3[3] = {0,1,0};
+       uint32_t key4[3] = {2,0,0};
 
        pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
 
@@ -96,13 +101,72 @@ int main(int argc, const char *argv[])
        printf("first 3 keys should have data==1\n");
        printf("the rest of the keys should have data==2\n");
        for (i=0; i<num_records; i++) {
-               uint32_t *data;
-
                data = trbt_lookup32(tree, i);
                printf("key:%d data:%d\n", i, *data);
        }
 
 
+       printf("testing trbt_insertarray32_callback\n");
+       tree = trbt_create(NULL);
+       trbt_insertarray32_callback(tree, 3, key1, callback, NULL);
+       trbt_insertarray32_callback(tree, 3, key1, callback, NULL);
+       trbt_insertarray32_callback(tree, 3, key2, callback, NULL);
+       trbt_insertarray32_callback(tree, 3, key3, callback, NULL);
+       trbt_insertarray32_callback(tree, 3, key2, callback, NULL);
+       trbt_insertarray32_callback(tree, 3, key1, callback, NULL);
+       data = trbt_lookuparray32(tree, 3, key1);
+       printf("key1 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key2);
+       printf("key2 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key3);
+       printf("key3 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key4);
+       printf("key4 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+
+       printf("\ndeleting key4\n");
+       trbt_deletearray32(tree, 3, key4);
+       data = trbt_lookuparray32(tree, 3, key1);
+       printf("key1 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key2);
+       printf("key2 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key3);
+       printf("key3 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key4);
+       printf("key4 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+
+       printf("\ndeleting key2\n");
+       trbt_deletearray32(tree, 3, key2);
+       data = trbt_lookuparray32(tree, 3, key1);
+       printf("key1 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key2);
+       printf("key2 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key3);
+       printf("key3 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key4);
+       printf("key4 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       
+       printf("\ndeleting key3\n");
+       trbt_deletearray32(tree, 3, key3);
+       data = trbt_lookuparray32(tree, 3, key1);
+       printf("key1 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key2);
+       printf("key2 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key3);
+       printf("key3 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key4);
+       printf("key4 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       
+       printf("\ndeleting key1\n");
+       trbt_deletearray32(tree, 3, key1);
+       data = trbt_lookuparray32(tree, 3, key1);
+       printf("key1 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key2);
+       printf("key2 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key3);
+       printf("key3 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       data = trbt_lookuparray32(tree, 3, key4);
+       printf("key4 dataptr:0x%08x == %d\n",(int)data,data?*data:-1);
+       
 
        return 0;
 }