Ejemplo n.º 1
0
static void
non_leaf_remove(struct tree *tree, struct non_leaf *node, int remove, int level)
{
int i, j, k;
struct non_leaf *sibling;
if (node->children <= (DEGREE + 1) / 2) {
struct non_leaf *parent = node->parent;
if (parent != NULL) {
int borrow = 0;
/* find which sibling node with same parent to be borrowed from */
i = key_binary_search(parent->key, parent->children - 1, node->key[0]);
assert(i < 0);
i = -i - 1;
if (i == 0) {
/* no left sibling, choose right one */
sibling = (struct non_leaf *)parent->sub_ptr[i + 1];
borrow = BORROW_FROM_RIGHT;
} else if (i == parent->children - 1) {
/* no right sibling, choose left one */
sibling = (struct non_leaf *)parent->sub_ptr[i - 1];
borrow = BORROW_FROM_LEFT;
} else {
struct non_leaf *l_sib = (struct non_leaf *)parent->sub_ptr[i - 1];
struct non_leaf *r_sib = (struct non_leaf *)parent->sub_ptr[i + 1];
/* if both left and right sibling found, choose the one with more children */
sibling = l_sib->children >= r_sib->children ? l_sib : r_sib;
borrow = l_sib->children >= r_sib->children ? BORROW_FROM_LEFT : BORROW_FROM_RIGHT;
}
/* locate parent node key index */
if (i > 0) {
i = i - 1;
}
if (borrow == BORROW_FROM_LEFT) {
if (sibling->children > (DEGREE + 1) / 2) {
/* node right shift */
for (j = remove; j > 0; j--) {
node->key[j] = node->key[j - 1];
}
for (j = remove + 1; j > 0; j--) {
node->sub_ptr[j] = node->sub_ptr[j - 1];
}
/* right rotate key */
node->key[0] = parent->key[i];
parent->key[i] = sibling->key[sibling->children - 2];
/* move left sibling's last sub-node into node's first location */
node->sub_ptr[0] = sibling->sub_ptr[sibling->children - 1];
sibling->sub_ptr[sibling->children - 1]->parent = node;
sibling->children--;
} else {
/* move parent key down */
sibling->key[sibling->children - 1] = parent->key[i];
/* merge node and left sibling */
for (j = sibling->children, k = 0; k < node->children - 1; k++) {
if (k != remove) {
sibling->key[j] = node->key[k];
j++;
}
}
for (j = sibling->children, k = 0; k < node->children - 1; k++) {
if (k != remove + 1) {
sibling->sub_ptr[j] = node->sub_ptr[k];
node->sub_ptr[k]->parent = sibling;
j++;
}
}
sibling->children = j;
/* delete merged node */
sibling->next = node->next;
non_leaf_delete(node);
/* trace upwards */
non_leaf_remove(tree, parent, i, level + 1);
}
} else {
/* remove key first in case of overflow merging with sibling node */
for (; remove < node->children - 2; remove++) {
node->key[remove] = node->key[remove + 1];
node->sub_ptr[remove + 1] = node->sub_ptr[remove + 2];
}
node->children--;
if (sibling->children > (DEGREE + 1) / 2) {
/* left rotate key */
node->key[node->children - 1] = parent->key[i];
parent->key[i] = sibling->key[0];
node->children++;
/* move right sibling's first sub-node into node's last location */
node->sub_ptr[node->children - 1] = sibling->sub_ptr[0];
sibling->sub_ptr[0]->parent = node;
/* right sibling left shift */
for (j = 0; j < sibling->children - 2; j++) {
sibling->key[j] = sibling->key[j + 1];
}
for (j = 0; j < sibling->children - 1; j++) {
sibling->sub_ptr[j] = sibling->sub_ptr[j + 1];
}
sibling->children--;
} else {
/* move parent key down */
node->key[node->children - 1] = parent->key[i];
node->children++;
/* merge node and right sibling */
for (j = node->children - 1, k = 0; k < sibling->children - 1; j++, k++) {
node->key[j] = sibling->key[k];
}
for (j = node->children - 1, k = 0; k < sibling->children; j++, k++) {
node->sub_ptr[j] = sibling->sub_ptr[k];
sibling->sub_ptr[k]->parent = node;
}
node->children = j;
/* delete merged sibling */
node->next = sibling->next;
non_leaf_delete(sibling);
/* trace upwards */
non_leaf_remove(tree, parent, i, level + 1);
}
}
/* deletion finishes */
return;
} else {
if (node->children == 2) {
/* delete old root node */
assert(remove == 0);
node->sub_ptr[0]->parent = NULL;
tree->root = node->sub_ptr[0];
tree->head[level] = NULL;
non_leaf_delete(node);
return;
}
}
}
/* simple deletion */
assert(node->children > 2);
for (; remove < node->children - 2; remove++) {
node->key[remove] = node->key[remove + 1];
node->sub_ptr[remove + 1] = node->sub_ptr[remove + 2];
}
node->children--;
}
Ejemplo n.º 2
0
static int
non_leaf_insert(struct bplus_tree *tree, struct bplus_non_leaf *node, struct bplus_node *sub_node, int key, int level)
{
        int i, j, split_key;
        int split = 0;
        struct bplus_non_leaf *sibling;

        int insert = key_binary_search(node->key, node->children - 1, key);
        assert(insert < 0);
        insert = -insert - 1;

        /* node full */
        if (node->children == tree->order) {
                /* split key index */
                split = (tree->order + 1) / 2;
                /* splited sibling node */
                sibling = non_leaf_new();
                sibling->next = node->next;
                node->next = sibling;
                node->children = split + 1;
                /* sibling node replication */
                if (insert < split) {
                        i = split - 1, j = 0;
                        split_key = node->key[i];
                        sibling->sub_ptr[j] = node->sub_ptr[i + 1];
                        node->sub_ptr[i + 1]->parent = sibling;
                        i++;
                        for (; i < tree->order - 1; i++, j++) {
                                sibling->key[j] = node->key[i];
                                sibling->sub_ptr[j + 1] = node->sub_ptr[i + 1];
                                node->sub_ptr[i + 1]->parent = sibling;
                        }
                        sibling->children = j + 1;
                        /* node insertion and its children count stays unchanged(split + 1) */
                        for (i = node->children - 1; i > insert; i--) {
                                node->key[i] = node->key[i - 1];
                                node->sub_ptr[i + 1] = node->sub_ptr[i];
                        }
                        node->key[i] = key;
                        node->sub_ptr[i + 1] = sub_node;
                } else if (insert == split) {
                        i = split, j = 0;
                        split_key = key;
                        sibling->sub_ptr[j] = sub_node;
                        sub_node->parent = sibling;
                        i++;
                        for (; i < tree->order - 1; i++, j++) {
                                sibling->key[j] = node->key[i];
                                sibling->sub_ptr[j + 1] = node->sub_ptr[i + 1];
                                node->sub_ptr[i + 1]->parent = sibling;
                        }
                        sibling->children = j + 1;
                } else {
                        i = split, j = 0;
                        split_key = node->key[i];
                        sibling->sub_ptr[j] = node->sub_ptr[i + 1];
                        node->sub_ptr[i + 1]->parent = sibling;
                        i++;
                        while (i < tree->order - 1) {
                                if (j != insert - split) {
                                        sibling->key[j] = node->key[i];
                                        sibling->sub_ptr[j + 1] = node->sub_ptr[i + 1];
                                        node->sub_ptr[i + 1]->parent = sibling;
                                        i++;
                                }
                                j++;
                        }
                        /* sibling node children count */
                        if (j > insert - split) {
                                sibling->children = j + 1;
                        } else {
                                sibling->children = insert - split + 1;
                        }
                        /* insert new key */
                        j = insert - split - 1;
                        sibling->key[j] = key;
                        sibling->sub_ptr[j + 1] = sub_node;
                        sub_node->parent = sibling;
                }
        } else {
                /* simple insertion */
                for (i = node->children - 1; i > insert; i--) {
                        node->key[i] = node->key[i - 1];
                        node->sub_ptr[i + 1] = node->sub_ptr[i];
                }
                node->key[i] = key;
                node->sub_ptr[i + 1] = sub_node;
                node->children++;
        }

        if (split) {
                struct bplus_non_leaf *parent = node->parent;
                if (parent == NULL) {
                        if (++level >= tree->level) {
                                fprintf(stderr, "!!Panic: Level exceeded, please expand the tree level, non-leaf order or leaf entries for element capacity!\n");
                                node->next = sibling->next;
                                non_leaf_delete(sibling);
                                return -1;
                        }
                        /* new parent */
                        parent = non_leaf_new();
                        parent->key[0] = split_key;
                        parent->sub_ptr[0] = (struct bplus_node *)node;
                        parent->sub_ptr[1] = (struct bplus_node *)sibling;
                        parent->children = 2;
                        /* new root */
                        tree->root = (struct bplus_node *)parent;
                        tree->head[level] = (struct bplus_node *)parent;
                        node->parent = parent;
                        sibling->parent = parent;
                } else {
                        /* Trace upwards */
                        sibling->parent = parent;
                        return non_leaf_insert(tree, parent, (struct bplus_node *)sibling, split_key, level + 1);
                }
        }

        return 0;
}