1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

add helpers to add/lookup/delete nodes in a tree where the key is an

array of uint32

(This used to be ctdb commit b7e0996e7735c8629d07453b9d335990c2dbc3db)
This commit is contained in:
Ronnie Sahlberg 2007-08-08 12:30:12 +10:00
parent c1bfda5772
commit 9525b010aa
3 changed files with 196 additions and 2 deletions

View 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)
{

View 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);

View 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;
}