diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..9339112b4f916c9a05275554589afc4b9f97854e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +src/program diff --git a/__main__.py b/__main__.py index b369571643756636ca86f40317669f015d10a616..66507d0ed76dbc31b5dc975b8649fcc3a647490b 100644 --- a/__main__.py +++ b/__main__.py @@ -444,14 +444,14 @@ def main(): random.seed(a) order = 2 - # root = Node(order) - # keys = generate_random_keys(40, 1, 99) - # print(keys) + root = Node(order) + keys = generate_random_keys(40, 1, 99) + print(keys) - # for key in keys: - # bptree_insert(root, key) + for key in keys: + bptree_insert(root, key) - # bptree_print(root) + bptree_print(root) # extracted_keys = bptree_extract_all_keys(root) # assert extracted_keys == sorted(keys) @@ -467,20 +467,20 @@ def main(): # assert not bptree_search(root, random_key) - root = Node(order) - keys = generate_random_keys(30, 1, 99) - print(keys) - print("=====") + # root = Node(order) + # keys = generate_random_keys(30, 1, 99) + # print(keys) + # print("=====") - for key in keys: - bptree_insert(root, key) + # for key in keys: + # bptree_insert(root, key) - bptree_delete(root, 65) - bptree_delete(root, 57) - bptree_delete(root, 47) # bptree_delete(root, 65) + # bptree_delete(root, 57) + # bptree_delete(root, 47) + # # bptree_delete(root, 65) - bptree_print(root) + # bptree_print(root) if __name__ == "__main__": diff --git a/src/bptree.c b/src/bptree.c index 330dc1147eaae5da29790b40e2041499d19d7dd9..660fc9fa7e3cfe9be12d2d6e487b21525c181bd9 100644 --- a/src/bptree.c +++ b/src/bptree.c @@ -40,7 +40,17 @@ void bptree_destroy(BPTreeNode **root) { *root = NULL; } -// ... +void bptree_print(BPTreeNode *root, int depth) { + for (int i = 0; i < depth; i++) { + printf(" "); + } + + array_print(root->keys_length, root->keys); + + for (int i = 0; i < root->children_length; i++) { + bptree_print(root->children[i], depth + 1); + } +} // Insertion @@ -52,7 +62,7 @@ static void redistribute_keys(BPTreeNode *left_node, BPTreeNode *right_node, int left_node->keys_length = left_index; } -uint64_t split_leaf(BPTreeNode *node, uint64_t key, BPTreeNode **right_node) { +static uint64_t split_leaf(BPTreeNode *node, uint64_t key, BPTreeNode **right_node) { int virtual_insertion_index = lower_bound(node->keys_length, node->keys, key); int median_index = node->keys_length / 2; uint64_t median_value; @@ -77,13 +87,42 @@ uint64_t split_leaf(BPTreeNode *node, uint64_t key, BPTreeNode **right_node) { return median_value; } -// static void redistribute_children(BPTreeNode *left_node, BPTreeNode *right_node, int left_index, int right_index) { -// for (int i = right_index; i < left_node->children_length; i++) { -// array_append_BPTreeNode(&right_node->children_length, right_node->children, left_node->children[i]); -// } +static void redistribute_children(BPTreeNode *left_node, BPTreeNode *right_node, int left_index, int right_index) { + for (int i = right_index; i < left_node->children_length; i++) { + array_append_BPTreeNode(&right_node->children_length, right_node->children, left_node->children[i]); + } -// left_node->children_length = left_index; -// } + left_node->children_length = left_index; +} + +static uint64_t split_internal(BPTreeNode *node, uint64_t key, BPTreeNode *right_child_node, BPTreeNode **right_node) { + int virtual_insertion_index = lower_bound(node->keys_length, node->keys, key); + int median_index = node->keys_length / 2; + uint64_t median_value; + *right_node = bptree_init(node->order); + (*right_node)->is_leaf = false; + + if (virtual_insertion_index < median_index) { + median_value = node->keys[median_index - 1]; + redistribute_keys(node, *right_node, median_index - 1, median_index); + redistribute_children(node, *right_node, median_index, median_index); + int insertion_index = sorted_array_insert(&node->keys_length, node->keys, key); + array_insert_at_index_BPTreeNode(&node->children_length, node->children, insertion_index + 1, right_child_node); + } else if (virtual_insertion_index > median_index) { + median_value = node->keys[median_index]; + redistribute_keys(node, *right_node, median_index, median_index + 1); + redistribute_children(node, *right_node, median_index + 1, median_index + 1); + int insertion_index = sorted_array_insert(&(*right_node)->keys_length, (*right_node)->keys, key); + array_insert_at_index_BPTreeNode(&(*right_node)->children_length, (*right_node)->children, insertion_index + 1, right_child_node); + } else { + median_value = key; + redistribute_keys(node, *right_node, median_index, median_index); + redistribute_children(node, *right_node, median_index + 1, median_index + 1); + array_insert_at_index_BPTreeNode(&(*right_node)->children_length, (*right_node)->children, 0, right_child_node); + } + + return median_value; +} static void grow(BPTreeNode *root, uint64_t median_value, BPTreeNode *split_right_node) { BPTreeNode *left_node = bptree_init(root->order); @@ -106,6 +145,8 @@ static void grow(BPTreeNode *root, uint64_t median_value, BPTreeNode *split_righ array_append_BPTreeNode(&root->children_length, root->children, split_right_node); } +static void insert_non_full(BPTreeNode *node, uint64_t key, BPTreeNode *previous_split_right_node); + static void insert_full(BPTreeNode *root, int *parents_length, BPTreeNode **parents, BPTreeNode *node, uint64_t key, BPTreeNode *previous_split_right_node) { uint64_t median_value; BPTreeNode *split_right_node; @@ -113,15 +154,20 @@ static void insert_full(BPTreeNode *root, int *parents_length, BPTreeNode **pare if (node->is_leaf) { median_value = split_leaf(node, key, &split_right_node); } else { - // TODO - printf("TODO\n"); + median_value = split_internal(node, key, previous_split_right_node, &split_right_node); } if (node == root) { grow(root, median_value, split_right_node); } else { - // TODO - printf("TODO\n"); + BPTreeNode *parent = parents[*parents_length - 1]; + array_delete_at_index_BPTreeNode(parents_length, parents, *parents_length - 1); + + if (has_maximum_keys(parent)) { + insert_full(root, parents_length, parents, parent, median_value, split_right_node); + } else { + insert_non_full(parent, median_value, split_right_node); + } } } @@ -158,6 +204,8 @@ void bptree_insert(BPTreeNode *root, uint64_t key) { BPTreeNode **parents; BPTreeNode *leaf = find_leaf(root, key, &parents_length, &parents); + // TODO : vérifier si la clé existe dans leaf. + if (has_maximum_keys(leaf)) { insert_full(root, &parents_length, parents, leaf, key, NULL); } else { diff --git a/src/bptree.h b/src/bptree.h index d5bc03a34c4e075847f56ece5be8a420dcc05a52..308dc0c871a501123d608c9c63387dad8bcc33e7 100644 --- a/src/bptree.h +++ b/src/bptree.h @@ -16,6 +16,8 @@ typedef struct BPTreeNode { BPTreeNode *bptree_init(int order); void bptree_destroy(BPTreeNode **root); +void bptree_print(BPTreeNode *root, int depth); + // ... // Insertion diff --git a/src/bptree.o b/src/bptree.o index 1c3356f81150672ea30605e2d69c077b43918883..9add434408ea836f14fd8beda4e8ae16dd6dabf8 100644 Binary files a/src/bptree.o and b/src/bptree.o differ diff --git a/src/main.c b/src/main.c index 656890d2ee849a1f0eec45b9b955377a69807054..69cae45e1f7d723670f4623197744e22de8ae2a8 100644 --- a/src/main.c +++ b/src/main.c @@ -1,20 +1,19 @@ #include <stdio.h> #include <stdlib.h> -#include "sorted_array.h" #include "bptree.h" +#include "sorted_array.h" int main() { BPTreeNode *root = bptree_init(2); - // [8, 12, 11, 47, 22, 95, 86, 40, 33, 78, 28, 5, 75, 88, 21, 56, 82, 51, 93, 66, 48, 70, 57, 65, 35, 4, 60, 41, 49, 55 - bptree_insert(root, 8); - bptree_insert(root, 12); - bptree_insert(root, 11); - bptree_insert(root, 47); - bptree_insert(root, 22); - array_print(root->keys_length, root->keys); - array_print(root->children[0]->keys_length, root->children[0]->keys); - array_print(root->children[1]->keys_length, root->children[1]->keys); + int keys_length = 40; + uint64_t keys[] = {8, 12, 11, 47, 22, 95, 86, 40, 33, 78, 28, 5, 75, 88, 21, 56, 82, 51, 93, 66, 48, 70, 57, 65, 35, 4, 60, 41, 49, 55, 68, 72, 23, 31, 30, 42, 18, 87, 24, 58}; + array_print(keys_length, keys); + + for (int i = 0; i < keys_length; i++) { + bptree_insert(root, keys[i]); + } + bptree_print(root, 0); return EXIT_SUCCESS; } diff --git a/src/main.o b/src/main.o index 7cead98a5619bbb3096b135d6cd99d66c5f6d86c..d47a4d1ce4a6d1ed2ac727bdee6c2a822203f63d 100644 Binary files a/src/main.o and b/src/main.o differ diff --git a/src/program b/src/program index b11cbd80e7c3c03fd3956742bc7631c4cbbb3342..5eaec8a64b736d8c9349cd161513078dee25a623 100644 Binary files a/src/program and b/src/program differ diff --git a/src/sorted_array.c b/src/sorted_array.c index 50834dcd1a75503e8a406e4c8a139e46e7f9d093..85ffd9d9b1df7465acdc6ba17350528a55af1044 100644 --- a/src/sorted_array.c +++ b/src/sorted_array.c @@ -81,11 +81,17 @@ void array_append(int *array_length, uint64_t *array, uint64_t value) { } void array_print(int array_length, uint64_t *array) { + printf("["); + for (int i = 0; i < array_length; i++) { - printf("%ld ", array[i]); + printf("%ld", array[i]); + + if (i < array_length - 1) { + printf(", "); + } } - printf("\n"); + printf("]\n"); } void array_insert_at_index_BPTreeNode(int *array_length, BPTreeNode **array, int insertion_index, BPTreeNode *value) { @@ -101,3 +107,11 @@ void array_append_BPTreeNode(int *array_length, BPTreeNode **array, BPTreeNode * array[*array_length] = value; *array_length += 1; } + +void array_delete_at_index_BPTreeNode(int *array_length, BPTreeNode **array, int deletion_index) { + for (int i = deletion_index; i < *array_length; i++) { + array[i] = array[i + 1]; + } + + *array_length -= 1; +} diff --git a/src/sorted_array.h b/src/sorted_array.h index 5192d0fa57e1f7c04232b7f99539066cce16985d..b8c330c7be3daaab9fdf15f85dff106a816dea26 100644 --- a/src/sorted_array.h +++ b/src/sorted_array.h @@ -19,6 +19,6 @@ typedef struct BPTreeNode BPTreeNode; void array_insert_at_index_BPTreeNode(int *array_length, BPTreeNode **array, int insertion_index, BPTreeNode *value); void array_append_BPTreeNode(int *array_length, BPTreeNode **array, BPTreeNode *value); -// void array_delete_at_index_BPTreeNode(BPTreeNode **array, int *array_length, int index); +void array_delete_at_index_BPTreeNode(int *array_length, BPTreeNode **array, int deletion_index); #endif diff --git a/src/sorted_array.o b/src/sorted_array.o index 4d28f285dc92c82c19a672638a679bb237d9a952..2e7e50aa021f3738994c20557dcc6f90e9328abb 100644 Binary files a/src/sorted_array.o and b/src/sorted_array.o differ