void put(char* key, char* value) { NODE *node = NULL; if (root) node = fetch(key, root); if (node) { // update the value strncpy(node->value, value, STR_MAX_SIZE); #ifdef SET_IS_USE promote(node); #endif } else { if (empty_count) { // root == NULL case is covered here also node = create_node(key, value); empty_count--; #ifdef SET_IS_USE promote(node); #endif #ifdef SORT_IGNORE_CASE if (root) add_leaf(node, root, false); else rebuild_tree(false); // only for the first element #else if (root) add_leaf(node, root); else rebuild_tree(); // only for the first element #endif } else { node = rear.prev; strncpy(node->key, key, STR_MAX_SIZE); strncpy(node->value, value, STR_MAX_SIZE); #ifdef SET_IS_USE promote(node); #endif #ifdef SORT_IGNORE_CASE rebuild_tree(false); #else rebuild_tree(); #endif } } }
void Search_Range::add_all_leaves( Tree_Node *node ) { // for efficiency, this should only be called after fathoming by dimension if ( node->is_leaf() ) { add_leaf( node->_sphere ); } else { add_all_leaves( node->_left ); add_all_leaves( node->_right ); } }
static void place_item(struct sort_level *sl, size_t item) { struct sort_list_item *sli; int c; sli = sl->tosort[item]; c = get_wc_index(sli, sl->level); if (c == -1) add_leaf(sl, sli); else add_to_sublevel(sl, sli, c); }
int main(int argc, char* argv[]) { int i; node * m; /* obligatory */ printf("Hello, World\r\n"); printf("\r\n---\r\n"); /* Node stuff */ printf("Creating and destroying 10000 nodes\r\n"); for (i = 0; i < 10000 ; i++) { int data = i; node * n = build_node(&data); destroy_node(n); } printf("Done\r\n"); printf("\r\n---\r\n"); printf("Building a queue, adding 10000 nodes. Printing out every 1000\r\n"); queue * q = build_queue(); for (i = 0; i < 10000 ; i++) { int data = i; node * n = build_node(&data); queue_push(q, n); } printf("Queue has the size %d\r\n", q->size); for (i = 0; i < 10000 ; i++) { node * n = queue_pop(q); if((i%1000)==0) { printf("Node has the data %d\r\n", *(int*)n->data); } destroy_node(n); } printf("Queue has the size %d\r\n", q->size); destroy_queue(q); printf("\r\n---\r\n"); printf("Building a stack, adding 10000 nodes. Printing out every 1000\r\n"); stack * s = build_stack(); for (i = 0; i < 10000 ; i++) { int data = i; node * n = build_node(&data); stack_push(s, n); } printf("Stack has the size %d\r\n", s->size); for (i = 0; i < 10000 ; i++) { node * n = stack_pop(s); if((i%1000)==0) { printf("Node has the data %d\r\n", *(int*)n->data); } destroy_node(n); } printf("Stack has the size %d\r\n", s->size); destroy_stack(s); printf("\r\n---\r\n"); printf("Building a linked list, adding 10000 nodes. Printing out every 1000\r\n"); llist * l = build_llist(); for (i = 0; i < 10000 ; i++) { int data = i; node * n = build_node(&data); llist_add(l, n); } printf("llist has the size %d\r\n", l->size); printf("Testing arbitrary access...\r\n"); m = llist_get(l, 87); printf("Node has the data %d\r\n", *(int*)m->data); m = llist_get(l, 3487); printf("Node has the data %d\r\n", *(int*)m->data); m = llist_get(l, 287); printf("Node has the data %d\r\n", *(int*)m->data); printf("Testing arbitrary delete...\r\n"); m = llist_get(l, 299); printf("Node has the data %d\r\n", *(int*)m->data); llist_delete(l, 299); m = llist_get(l, 299); printf("Node has the data %d\r\n", *(int*)m->data); printf("Testing mass delete...\r\n"); destroy_llist(l); printf("\r\n---\r\n"); printf("Creating and destroying 10000 single trees\r\n"); for (i = 0; i < 10000 ; i++) { int data = i; tree * n = build_tree(&data); destroy_tree(n); } printf("Done\r\n"); printf("\r\n---\r\n"); printf("Testing add/delete for trees\r\n"); int data = 2; tree * root = build_tree(&data); //for (i = 0; i < 3 ; i++) // { // int data = i; // tree * n = build_tree(&data); // destroy_tree(n); // add_leaf(&root, n, &tree_int_comp); // } data = 1; tree * leaf1 = build_tree(&data); add_leaf(&root, leaf1, &tree_int_comp); data = 0; tree * leaf2 = build_tree(&data); add_leaf(&root, leaf2, &tree_int_comp); printf("Root node has value %d before deletion\r\n", *(int*)root->data); delete_node(&(root)); printf("Root node has value %d after deletion\r\n", *(int*)root->data); destroy_tree(leaf1); destroy_tree(leaf2); printf("Done\r\n"); return 0; }
void Search_Range::all_near_spheres_recurse( One_Tree *tree ) { const bool debug = false; Near_Workspace &ws = near_workspace; // debug assert(ws._num_calls < num_nodes() ); ++ws._num_calls; const size_t d = tree->_d; double x_lo = ws._p[d] - ws._thresh; double x_hi = ws._p[d] + ws._thresh; // walk until the path to x_lo and x_hi diverge Tree_Node *n = find_split( tree, x_lo, x_hi ); if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << "Diverges at node "; Range_Tree::print_single_node( n, tree ); // std::cout << std::endl; } // never split, nothing is in range if (!n) { if (debug) std::cout << " no spheres were in range." << std::endl; return; } // If n is a leaf, then immediately recurse by dimension on its subtree. // For efficiency we just check the distance immediately, since the result is the same. if (n->is_leaf()) { if (debug) std::cout << " fathomed at leaf node." << std::endl; add_leaf(n->_sphere); return; } // go down right and left sides, reporting subtrees // right { if (debug) { std::cout << " Searching Right subtree " << std::endl; } Tree_Node * r = n->_right; while( r ) { const double &x = _spheres[ r->_sphere ][ d ]; if ( x_hi > x ) { // left tree is in the range if ( r->_left ) { if (r->_left->_subtree) all_near_spheres_recurse( r->_left->_subtree ); // fathomed at last dimension else { if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << " Adding left subtree rooted at node "; print_single_node(r->_left, tree); std::cout << std::endl; } assert( last_dimension(tree) || r->_left->is_leaf() ); add_all_leaves( r->_left ); } } // leaf else { assert( r->is_leaf() ); if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << " Adding leaf node "; print_single_node(r, tree); std::cout << std::endl; } add_leaf( r->_sphere ); } r = r->_right; // null if it was a leaf } else r = r->_left; // if r == 0, then its parent was a leaf and out of range } } // left { if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << "Searching Left subtree " << std::endl; } Tree_Node * lft = n->_left; while( lft ) { const double &x = _spheres[ lft->_sphere ][ tree->_d ]; if ( x_lo <= x ) { // right tree is in the range if ( lft->_right ) { if ( lft->_right->_subtree ) all_near_spheres_recurse( lft->_right->_subtree ); // fathomed at last dimension else { if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << " Adding right subtree rooted at node "; print_single_node(lft->_right, tree); std::cout << std::endl; } assert( last_dimension(tree) || lft->_right->is_leaf() ); add_all_leaves( lft->_right ); } } // leaf else { assert( lft->is_leaf() ); if (debug) { std::cout << "Search_Range [" << x_lo << ", " << x_hi << "] coordinate " << tree->_d << ". "; std::cout << " Adding leaf node "; print_single_node(lft, tree); std::cout << std::endl; } add_leaf( lft->_sphere ); } lft = lft->_left; // null if it was a leaf } else { lft = lft->_right; // if lft == 0, then its old value (parent) was a leaf and out of range } } } }
void add_leaf(NODE* leaf, NODE* node, bool ic) { if (scmp(leaf->key, node->key, ic) < 0) { #else void add_leaf(NODE* leaf, NODE* node) { if (strcmp(leaf->key, node->key) < 0) { #endif if (node->lchild) { #ifdef SORT_IGNORE_CASE add_leaf(leaf, node->lchild, ic); #else add_leaf(leaf, node->lchild); #endif } else { node->lchild = leaf; leaf->lchild = leaf->rchild = NULL; } } else { if (node->rchild) { #ifdef SORT_IGNORE_CASE add_leaf(leaf, node->rchild, ic); #else add_leaf(leaf, node->rchild); #endif } else { node->rchild = leaf; leaf->lchild = leaf->rchild = NULL; } } } void print_node(NODE* node) { if (node->lchild) print_node(node->lchild); printf("%s %s\n", node->key, node->value); if (node->rchild) print_node(node->rchild); } NODE* fetch(char* key, NODE* node) { if (! node) return NULL; int cmp = strcmp(key, node->key); if (cmp == 0) { return node; } else if (cmp < 0) { return fetch(key, node->lchild); } else { return fetch(key, node->rchild); } } #ifdef SORT_IGNORE_CASE void rebuild_tree(bool ic) { #else void rebuild_tree() { #endif NODE* p = head.next; if (p == &rear) { root = NULL; return; } root = head.next; root->lchild = root->rchild = NULL; p = root->next; while (p != &rear) { #ifdef SORT_IGNORE_CASE add_leaf(p, root, ic); #else add_leaf(p, root); #endif p = p->next; } }
int main (int argc, const char * argv[]) { FILE* file; char *current, *rest, *type, *ip_pointer; unsigned int a, b, c, d, metric; int prefix, NIC, NIC_num, id; Node* tree = (Node*) (malloc(sizeof(Node))); current = (char*) (malloc(128*sizeof(char))); /* Check arguments */ if (argc != 2) { fprintf(stderr, "Invalid arguments. You should provide a single argument.\n"); return 1; } // Open the file //file = fopen ("/Users/William/Documents/CPSC 317/a2/ip_route/ip_route/p2_medium_input.txt","r"); file = fopen(argv[1], "r"); // Check for errors when opening the file if (!file){ perror("Invalid file"); return 2; } // get the total amount of NIC fgets(current, 35, file); NIC_num = atoi(current); fgets(current, 35, file); type = strtok_r(current, " ", &rest); // assuming the first line after NIC number is of type "U" // used to initial the tree (myTree need to initial the root) if (strcmp(type, "U")==0){ ip_pointer = strtok_r(rest, ".", &rest); a = atoi(ip_pointer); ip_pointer = strtok_r(rest, ".",&rest); b = atoi(ip_pointer); ip_pointer = strtok_r(rest, ".", &rest); c = atoi(ip_pointer); ip_pointer = strtok_r(rest, "/",&rest); d = atoi(ip_pointer); ip_pointer = strtok_r(rest, " ",&rest); prefix = atoi(ip_pointer); ip_pointer = strtok_r(rest, " ",&rest); NIC = atoi(ip_pointer); ip_pointer = strtok_r(rest, " ",&rest); metric = atoi(ip_pointer); ip_pointer = strtok_r(rest, " ",&rest); id = atoi(ip_pointer); initialize_node(tree, a); tree = add_leaf(tree, a, b, c, d, prefix, NIC, metric, NIC_num); fprintf(stdout, "%s %d.%d.%d.%d/%d %d %d\n", "A", a, b, c, d, prefix, metric+1, id); } while (fgets(current, 35, file)!=NULL) { type = strtok_r(current, " ", &rest); // do the table update if is type "U" if (strcmp(type, "U")==0){ ip_pointer = strtok_r(rest, ".", &rest); a = atoi(ip_pointer); ip_pointer = strtok_r(rest, ".",&rest); b = atoi(ip_pointer); ip_pointer = strtok_r(rest, ".", &rest); c = atoi(ip_pointer); ip_pointer = strtok_r(rest, "/",&rest); d = atoi(ip_pointer); ip_pointer = strtok_r(rest, " ",&rest); prefix = atoi(ip_pointer); ip_pointer = strtok_r(rest, " \n",&rest); NIC = atoi(ip_pointer); ip_pointer = strtok_r(rest, " ",&rest); metric = atoi(ip_pointer); ip_pointer = strtok_r(rest, " ",&rest); id = atoi(ip_pointer); Leaf* leaf = find_leaf(tree, a, b, c, d,prefix); // if the address is not found, add that ip to the table if (leaf==NULL){ tree = add_leaf(tree, a, b, c, d, prefix, NIC, metric, NIC_num); fprintf(stdout, "%s %d.%d.%d.%d/%d %d %d\n", "A", a, b, c, d, prefix, metric+1, id); } // else update the table else{ if (update_leaf_nic(leaf, NIC, metric, NIC_num)==1) fprintf(stdout, "%s %d.%d.%d.%d/%d %d %d\n", "A", a, b, c, d, prefix, leaf->metric, id); } } } // check errors after opening the file if (ferror(file)) { perror("Error reading file"); fclose(file); return 3; } fprintf(stdout, "\n"); // printing the tree char* my_printer = (char*) (malloc(20*sizeof(char))); print_tree(tree, my_printer); fclose(file); return 0; }