Пример #1
0
/* 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);
}
Пример #2
0
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;
}