/* check whether a server id exists */ int32_t ctdb_control_check_server_id(struct ctdb_context *ctdb, TDB_DATA indata) { struct ctdb_server_id *server_id = (struct ctdb_server_id *)indata.dptr; return trbt_lookuparray32(ctdb->server_ids, SERVER_ID_KEY_SIZE, get_server_id_key(server_id)) == NULL? 0 : 1; }
/* unregisters a server id */ int32_t ctdb_control_unregister_server_id(struct ctdb_context *ctdb, TDB_DATA indata) { struct ctdb_server_id *server_id = (struct ctdb_server_id *)indata.dptr; talloc_free(trbt_lookuparray32(ctdb->server_ids, SERVER_ID_KEY_SIZE, get_server_id_key(server_id))); return 0; }
/* 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]); }
/* main program */ int main(int argc, const char *argv[]) { int traverse_count; int i,j,k; trbt_tree_t *tree; uint32_t *data; uint32_t key[3]; uint32_t key1[3] = {0,10,20}; uint32_t key2[3] = {0,10,21}; uint32_t key3[3] = {0,11,20}; uint32_t key4[3] = {2,10,20}; TALLOC_CTX *memctx; uint32_t **u32array; uint32_t checksum; /* testing trbt_insert32_callback for num_records */ memctx = talloc_new(NULL); assert(memctx != NULL); u32array = talloc_array(memctx, uint32_t *, num_records); assert(u32array != NULL); tree = trbt_create(memctx, 0); assert(tree != NULL); for (i=0; i<num_records; i++) { u32array[i] = talloc(u32array, uint32_t); assert(u32array[i] != NULL); *u32array[i] = 0; trbt_insert32_callback(tree, i, callback, u32array[i]); } for (i=3; i<num_records; i++) { trbt_insert32_callback(tree, i, callback, NULL); } /* first 3 keys should have data == 1 * the rest of the keys should have data == 2 */ for (i=0; i<num_records; i++) { data = trbt_lookup32(tree, i); if (i < 3) { assert(*data == 1); } else { assert(*data == 2); } } /* deleting key 2 */ talloc_free(u32array[2]); /* deleting key 1 */ talloc_free(u32array[1]); assert(talloc_total_size(memctx) == 212); /* freeing tree */ talloc_free(memctx); printf("testing trbt_insertarray32_callback\n"); memctx = talloc_new(NULL); assert(memctx != NULL); tree = trbt_create(memctx, 0); assert(tree != NULL); u32array = talloc_array(memctx, uint32_t *, 4); assert(u32array != NULL); for (i=0; i<4; i++) { u32array[i] = talloc(u32array, uint32_t); assert(u32array[i] != NULL); *u32array[i] = 0; } trbt_insertarray32_callback(tree, 3, key1, callback, u32array[0]); trbt_insertarray32_callback(tree, 3, key1, callback, u32array[0]); trbt_insertarray32_callback(tree, 3, key2, callback, u32array[1]); trbt_insertarray32_callback(tree, 3, key3, callback, u32array[2]); trbt_insertarray32_callback(tree, 3, key2, callback, u32array[1]); trbt_insertarray32_callback(tree, 3, key1, callback, u32array[0]); data = trbt_lookuparray32(tree, 3, key1); assert(data != NULL && *data == 3); data = trbt_lookuparray32(tree, 3, key2); assert(data != NULL && *data == 2); data = trbt_lookuparray32(tree, 3, key3); assert(data != NULL && *data == 1); data = trbt_lookuparray32(tree, 3, key4); assert(data == NULL); trbt_traversearray32(tree, 3, traverse, NULL); printf("\ndeleting key4\n"); talloc_free(trbt_lookuparray32(tree, 3, key4)); data = trbt_lookuparray32(tree, 3, key1); assert(data != NULL && *data == 3); data = trbt_lookuparray32(tree, 3, key2); assert(data != NULL && *data == 2); data = trbt_lookuparray32(tree, 3, key3); assert(data != NULL && *data == 1); data = trbt_lookuparray32(tree, 3, key4); assert(data == NULL); trbt_traversearray32(tree, 3, traverse, NULL); printf("\ndeleting key2\n"); talloc_free(trbt_lookuparray32(tree, 3, key2)); data = trbt_lookuparray32(tree, 3, key1); assert(data != NULL && *data == 3); data = trbt_lookuparray32(tree, 3, key2); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key3); assert(data != NULL && *data == 1); data = trbt_lookuparray32(tree, 3, key4); assert(data == NULL); trbt_traversearray32(tree, 3, traverse, NULL); printf("\ndeleting key3\n"); talloc_free(trbt_lookuparray32(tree, 3, key3)); data = trbt_lookuparray32(tree, 3, key1); assert(data != NULL && *data == 3); data = trbt_lookuparray32(tree, 3, key2); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key3); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key4); assert(data == NULL); trbt_traversearray32(tree, 3, traverse, NULL); printf("\ndeleting key1\n"); talloc_free(trbt_lookuparray32(tree, 3, key1)); data = trbt_lookuparray32(tree, 3, key1); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key2); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key3); assert(data == NULL); data = trbt_lookuparray32(tree, 3, key4); assert(data == NULL); trbt_traversearray32(tree, 3, traverse, NULL); talloc_free(tree); talloc_free(memctx); printf("\nrun random insert and delete for 60 seconds\n"); memctx = talloc_new(NULL); assert(memctx != NULL); tree = trbt_create(memctx, 0); assert(tree != NULL); i=0; start_timer(); checksum = 0; /* add and delete nodes from a 3 level tree fro 60 seconds. each time a node is added or deleted, traverse the tree and compute a checksum over the data stored in the tree and compare this with a checksum we keep which contains what the checksum should be */ while(end_timer() < 60.0) { char *str; i++; key[0]=random()%10; key[1]=random()%10; key[2]=random()%10; if (random()%2) { if (trbt_lookuparray32(tree, 3, key) == NULL) { /* this node does not yet exist, add it to the tree and update the checksum */ str=talloc_asprintf(memctx, "%d.%d.%d", key[0],key[1],key[2]); trbt_insertarray32_callback(tree, 3, key, random_add, str); checksum += key[0]*100+key[1]*10+key[2]; } } else { if ((str=trbt_lookuparray32(tree, 3, key)) != NULL) { /* this node does exist in the tree, delete it and update the checksum accordingly */ talloc_free(str); checksum -= key[0]*100+key[1]*10+key[2]; } } /* traverse all nodes in the tree and calculate the checksum it better match the one we keep track of in 'checksum' */ calc_checksum = 0; trbt_traversearray32(tree, 3, traverse_checksum, NULL); assert(checksum == calc_checksum); } /* printf("\niterations passed:%d\n", i); trbt_traversearray32(tree, 3, random_traverse, NULL); printf("\n"); printf("first node: %s\n", (char *)trbt_findfirstarray32(tree, 3)); */ traverse_count = 0; trbt_traversearray32(tree, 3, count_traverse, &traverse_count); assert(traverse_count > 0); traverse_count = 0; trbt_traversearray32(tree, 3, count_traverse_abort, &traverse_count); assert(traverse_count == 1); printf("\ndeleting all entries\n"); for(i=0; i<10; i++) { for(j=0; j<10; j++) { for(k=0; k<10; k++) { key[0]=i; key[1]=j; key[2]=k; talloc_free(trbt_lookuparray32(tree, 3, key)); } } } trbt_traversearray32(tree, 3, random_traverse, NULL); assert(talloc_total_size(memctx) == 16); return 0; }