/* Inserts a new node (leaf or internal node) into the B+ tree. * Returns the root of the tree after insertion. */ node * insert_into_parent(node * root, node * left, int key, node * right) { int left_index; node * parent; parent = left->parent; /* Case: new root. */ if (parent == NULL) return insert_into_new_root(left, key, right); /* Case: leaf or node. (Remainder of * function body.) */ /* Find the parent's pointer to the left * node. */ left_index = get_left_index(parent, left); /* Simple case: the new key fits into the node. */ if (parent->num_keys < order - 1) return insert_into_node(root, parent, left_index, key, right); /* Harder case: split a node in order * to preserve the B+ tree properties. */ return insert_into_node_after_splitting(root, parent, left_index, key, right); }
node *insert_into_parent(node *root, node *left, node *right, char *key) { node *parent; int index, i; parent = left->parent; if (parent == NULL){ return make_new_root(left, right, key); } for (index = 0; index < parent->num_keys && parent->pointers[index] != left; index++); ; if (parent->num_keys < size - 1){ insert_into_node(parent, right, index, key); return root; // the root remains unchanged } return insert_into_node_after_splitting(root, parent, right, index, key); }
int main(int argc, char **argv) { trie_t *dict = gen_trie(); node_t *current_node, *last_known_node; int inserts = 1, i, last_known_idx, last_known_i, sec_known_idx, total; /* Initialization */ last_known_idx = last_known_i = sec_known_idx = total = 0; current_node = last_known_node = dict->root; /* Instead of saving the entire file into an array, read the file and * process it as you read. * Trie is memory hungry enough, best to save memory where possible */ while((i=getchar()) != EOF) { total++; #if DEBUG if(i!=10) fprintf(stderr, "i = %d // char = %c\n", i, i); else fprintf(stderr, "i = 10 // char = </n>\n"); #endif if((current_node = search_node(current_node, i)) == NULL) { /* No match found. * Since at this point, its guranteed that previous values are * matching, simply add new character to the latest node */ #if DEBUG fprintf(stderr, " > NOT FOUND\n"); #endif insert_into_node(last_known_node, i, inserts++); printf("%c%d\n", i, last_known_idx); /* re-initialize */ last_known_idx = 0; current_node = last_known_node = dict->root; } else { /* Keep track of history - affects constant for n^2 * Affects program speed slightly. * To negate this, reading the input in chunks then recording * history only for the last chunk will negate unneccesary * recording of history in previous chunks but this is * too minor impact to performance compared to amount of * complexity of the code */ sec_known_idx = last_known_idx; last_known_idx = current_node->idx; last_known_node = current_node; #if DEBUG fprintf(stderr, " > FOUND under index %d\n", current_node->idx); #endif } last_known_i = i; #if DEBUG fprintf(stderr, "----------\n"); #endif } if(last_known_idx != 0) { /* Handling exception situations where the last character was still * included in the count. This means if text is: * (prev strings) . . X Y \0 * ..XY were found in previously and present in dictionary. * Therefore following the formatting for the assignment, print * index for ..X then character Y */ printf("%c%d\n", last_known_i, sec_known_idx); inserts++; } /* Free trie. May not seem necessary since the program terminates * immediately after this stage however in case of practical use of * stacked calls, there it is :) * NOTE: In my Linux system, free did not actually reduce memory usage. * This was true for this program and Alistair's malloc programs. */ free_trie(dict); fprintf(stderr, "encode: %6d bytes input\n",total); fprintf(stderr, "encode: %6d factors generated\n",inserts-1); return 0; }