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:
parent
c1bfda5772
commit
9525b010aa
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user