Skip to content
Snippets Groups Projects
Commit e504eee7 authored by florian.burgener's avatar florian.burgener
Browse files

Done B+ Tree deletion

parent e245e099
No related branches found
No related tags found
No related merge requests found
......@@ -39,6 +39,7 @@ void IntegerArray_destroy(IntegerArray **array) {
int IntegerArray_insert_sorted(IntegerArray *array, uint64_t item) {
int index = lower_bound(array, item);
// TODO : use IntegerArray_insert_at_index
for (int i = array->size - 1; i >= index; i--) {
array->items[i + 1] = array->items[i];
......@@ -95,6 +96,12 @@ void IntegerArray_delete_at_index(IntegerArray *array, int index) {
array->size--;
}
void IntegerArray_delete_sorted(IntegerArray *array, uint64_t item) {
int index;
IntegerArray_binary_search(array, item, &index);
IntegerArray_delete_at_index(array, index);
}
void IntegerArray_print(IntegerArray *array) {
printf("[");
......
......@@ -20,8 +20,8 @@ int IntegerArray_insert_sorted(IntegerArray *array, uint64_t item);
void IntegerArray_insert_at_index(IntegerArray *array, int index, uint64_t item);
void IntegerArray_append(IntegerArray *array, uint64_t item);
bool IntegerArray_binary_search(IntegerArray *array, uint64_t item, int *index);
void IntegerArray_delete_sorted(IntegerArray *array, uint64_t item);
void IntegerArray_delete_at_index(IntegerArray *array, int index);
void IntegerArray_delete_sorted(IntegerArray *array, uint64_t item);
void IntegerArray_print(IntegerArray *array);
void IntegerArray_clear(IntegerArray *array);
void IntegerArray_copy(IntegerArray *src, IntegerArray *dest);
......
......@@ -7,17 +7,34 @@
#include "Array.h"
// static bool has_minimum_keys(BPTreeNode *node);
static bool has_maximum_keys(BPTreeNode *node);
// static bool has_minimum_keys(BPTreeNode *node) {
// return node->keys_length == node->order;
// }
static BPTreeNode *find_leaf(BPTreeNode *root, uint64_t key, BPTreeNodeArray **parents);
static bool has_maximum_keys(BPTreeNode *node) {
return node->keys->size == 2 * node->order;
}
static BPTreeNode *find_leaf(BPTreeNode *root, uint64_t key, BPTreeNodeArray **parents) {
BPTreeNode *current = root;
// TODO : 10 is not enough.
*parents = BPTreeNodeArray_init(10);
while (!current->is_leaf) {
BPTreeNodeArray_append(*parents, current);
int child_index = lower_bound(current->keys, key);
if (child_index < current->keys->size && current->keys->items[child_index] == key) {
child_index += 1;
}
current = current->children->items[child_index];
}
return current;
}
// =======
BPTreeNode *BPTree_init(int order) {
BPTreeNode *root = (BPTreeNode *)malloc(sizeof(BPTreeNode));
root->order = order;
......@@ -81,7 +98,6 @@ static void redistribute_children(BPTreeNode *left_node, BPTreeNode *right_node,
static uint64_t split_internal(BPTreeNode *node, uint64_t key, BPTreeNode *right_child_node, BPTreeNode **right_node);
static uint64_t split_leaf(BPTreeNode *node, uint64_t key, uint64_t data, BPTreeNode **right_node);
static void grow(BPTreeNode *root, uint64_t median_value, BPTreeNode *split_right_node);
static BPTreeNode *find_leaf(BPTreeNode *root, uint64_t key, BPTreeNodeArray **parents);
static void insert_full(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key, uint64_t data, BPTreeNode *previous_split_right_node);
static void insert_non_full(BPTreeNode *node, uint64_t key, uint64_t data, BPTreeNode *previous_split_right_node);
......@@ -187,25 +203,6 @@ static void grow(BPTreeNode *root, uint64_t median_value, BPTreeNode *split_righ
BPTreeNodeArray_append(root->children, split_right_node);
}
static BPTreeNode *find_leaf(BPTreeNode *root, uint64_t key, BPTreeNodeArray **parents) {
BPTreeNode *current = root;
// TODO : 10 is not enough.
*parents = BPTreeNodeArray_init(10);
while (!current->is_leaf) {
BPTreeNodeArray_append(*parents, current);
int child_index = lower_bound(current->keys, key);
if (child_index < current->keys->size && current->keys->items[child_index] == key) {
child_index += 1;
}
current = current->children->items[child_index];
}
return current;
}
static void insert_full(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key, uint64_t data, BPTreeNode *previous_split_right_node) {
uint64_t median_value;
BPTreeNode *split_right_node;
......@@ -247,7 +244,11 @@ void BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data) {
BPTreeNodeArray *parents;
BPTreeNode *leaf = find_leaf(root, key, &parents);
// TODO : vérifier si la clé existe dans leaf.
int index;
if (IntegerArray_binary_search(leaf->keys, key, &index)) {
BPTreeNodeArray_destroy(&parents);
return;
}
if (has_maximum_keys(leaf)) {
insert_full(root, parents, leaf, key, data, NULL);
......@@ -260,6 +261,8 @@ void BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data) {
// Deletion
// CAUTION : data is not processed
static uint64_t find_smallest_key(BPTreeNode *root);
static int find_child_index(BPTreeNode *parent, BPTreeNode *child);
static bool is_sibling_left_side(BPTreeNode *parent, BPTreeNode *node, BPTreeNode *sibling);
......@@ -269,8 +272,9 @@ static void steal_leaf(BPTreeNode *parent, BPTreeNode *node, int child_index, BP
static void _bptree_merge(BPTreeNode *parent, BPTreeNode *main_node, BPTreeNode *secondary_node, int pivot_index);
static void bptree_merge(BPTreeNode *parent, BPTreeNode *node, BPTreeNode *sibling);
static BPTreeNode *find_sibling(BPTreeNode *parent, BPTreeNode *node);
static void _BPTree_delete(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key);
static uint64_t find_smallest_key(BPTreeNode *root) {
static uint64_t find_smallest_key(BPTreeNode *root) {
if (root->is_leaf) {
return root->keys->items[0];
}
......@@ -388,9 +392,58 @@ static BPTreeNode *find_sibling(BPTreeNode *parent, BPTreeNode *node) {
return parent->children->items[child_index - 1];
}
static void _bptree_delete(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key) {
static void _BPTree_delete(BPTreeNode *root, BPTreeNodeArray *parents, BPTreeNode *node, uint64_t key) {
BPTreeNode *parent = NULL;
if (parents->size > 0) {
parent = parents->items[parents->size - 1];
BPTreeNodeArray_delete_at_index(parents, parents->size - 1);
}
if (node->is_leaf) {
IntegerArray_delete_sorted(node->keys, key);
}
if (node != root && node->keys->size < node->order) {
int child_index = find_child_index(parent, node);
BPTreeNode *sibling = find_sibling(parent, node);
if (sibling->keys->size == sibling->order) {
bptree_merge(parent, node, sibling);
if (parent == root && parent->keys->size == 0) {
shrink(root);
parent = NULL;
}
} else {
if (node->is_leaf) {
steal_leaf(parent, node, child_index, sibling);
} else {
steal_internal(parent, node, child_index, sibling);
}
}
}
int index;
if (!node->is_leaf && node->children->size > 0 && IntegerArray_binary_search(node->keys, key, &index)) {
node->keys->items[index] = find_smallest_key(node->children->items[index + 1]);
}
if (parent != NULL) {
_BPTree_delete(root, parents, parent, key);
}
}
void BPTree_delete(BPTreeNode *root, uint64_t key) {
BPTreeNodeArray *parents;
BPTreeNode *leaf = find_leaf(root, key, &parents);
int index;
if (!IntegerArray_binary_search(leaf->keys, key, &index)) {
BPTreeNodeArray_destroy(&parents);
return;
}
_BPTree_delete(root, parents, leaf, key);
BPTreeNodeArray_destroy(&parents);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment