diff --git a/src/bptree.c b/src/bptree.c index b55102442933cb3b9f4bd017bf19e6734fda4d6b..330dc1147eaae5da29790b40e2041499d19d7dd9 100644 --- a/src/bptree.c +++ b/src/bptree.c @@ -1,29 +1,29 @@ #include "bptree.h" #include <stdbool.h> +#include <stdint.h> +#include <stdio.h> #include <stdlib.h> -/// +#include "sorted_array.h" -static bool has_minimum_keys(BPTreeNode *root); -static bool has_maximum_keys(BPTreeNode *root); +// static bool has_minimum_keys(BPTreeNode *node); +static bool has_maximum_keys(BPTreeNode *node); -static bool has_minimum_keys(BPTreeNode *root) { - return root->keys_length == root->order; -} +// static bool has_minimum_keys(BPTreeNode *node) { +// return node->keys_length == node->order; +// } -static bool has_maximum_keys(BPTreeNode *root) { - return root->keys_length == 2 * root->order; +static bool has_maximum_keys(BPTreeNode *node) { + return node->keys_length == 2 * node->order; } -/// - BPTreeNode *bptree_init(int order) { BPTreeNode *root = (BPTreeNode *)malloc(sizeof(BPTreeNode)); root->order = order; root->is_leaf = true; root->keys_length = 0; - root->keys = (int *)malloc(sizeof(int) * (2 * order)); + root->keys = (uint64_t *)malloc(sizeof(uint64_t) * (2 * order)); root->children_length = 0; root->children = (BPTreeNode **)malloc(sizeof(BPTreeNode *) * (2 * order + 1)); return root; @@ -31,7 +31,7 @@ BPTreeNode *bptree_init(int order) { void bptree_destroy(BPTreeNode **root) { for (int i = 0; i < (*root)->children_length; i++) { - bptree_destroy((*root)->children[i]); + bptree_destroy(&(*root)->children[i]); } free((*root)->keys); @@ -40,6 +40,131 @@ void bptree_destroy(BPTreeNode **root) { *root = NULL; } +// ... + // Insertion +static void redistribute_keys(BPTreeNode *left_node, BPTreeNode *right_node, int left_index, int right_index) { + for (int i = right_index; i < left_node->keys_length; i++) { + array_append(&right_node->keys_length, right_node->keys, left_node->keys[i]); + } + + left_node->keys_length = left_index; +} + +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; + *right_node = bptree_init(node->order); + + if (virtual_insertion_index < median_index) { + median_value = node->keys[median_index - 1]; + redistribute_keys(node, *right_node, median_index - 1, median_index - 1); + sorted_array_insert(&node->keys_length, node->keys, key); + } else if (virtual_insertion_index > median_index) { + median_value = node->keys[median_index]; + redistribute_keys(node, *right_node, median_index, median_index); + sorted_array_insert(&(*right_node)->keys_length, (*right_node)->keys, key); + } else { + median_value = key; + redistribute_keys(node, *right_node, median_index, median_index); + sorted_array_insert(&(*right_node)->keys_length, (*right_node)->keys, key); + } + + // TODO : Linked List + + 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]); +// } + +// left_node->children_length = left_index; +// } + +static void grow(BPTreeNode *root, uint64_t median_value, BPTreeNode *split_right_node) { + BPTreeNode *left_node = bptree_init(root->order); + left_node->is_leaf = split_right_node->is_leaf; + + for (int i = 0; i < root->keys_length; i++) { + array_append(&left_node->keys_length, left_node->keys, root->keys[i]); + } + + for (int i = 0; i < root->children_length; i++) { + array_append_BPTreeNode(&left_node->children_length, left_node->children, root->children[i]); + } + + root->is_leaf = false; + root->keys_length = 0; + root->children_length = 0; + + array_append(&root->keys_length, root->keys, median_value); + array_append_BPTreeNode(&root->children_length, root->children, left_node); + array_append_BPTreeNode(&root->children_length, root->children, 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; + + if (node->is_leaf) { + median_value = split_leaf(node, key, &split_right_node); + } else { + // TODO + printf("TODO\n"); + } + + if (node == root) { + grow(root, median_value, split_right_node); + } else { + // TODO + printf("TODO\n"); + } +} + +static void insert_non_full(BPTreeNode *node, uint64_t key, BPTreeNode *previous_split_right_node) { + int insertion_index = sorted_array_insert(&node->keys_length, node->keys, key); + + if (previous_split_right_node != NULL) { + array_insert_at_index_BPTreeNode(&node->children_length, node->children, insertion_index + 1, previous_split_right_node); + } +} + +static BPTreeNode *find_leaf(BPTreeNode *root, uint64_t key, int *parents_length, BPTreeNode ***parents) { + BPTreeNode *current = root; + *parents_length = 0; + // TODO : 10 is not enough. + *parents = (BPTreeNode **)malloc(sizeof(BPTreeNode *) * 10); + + while (!current->is_leaf) { + array_append_BPTreeNode(parents_length, *parents, current); + int child_index = lower_bound(current->keys_length, current->keys, key); + + if (child_index < current->keys_length && current->keys[child_index] == key) { + child_index += 1; + } + + current = current->children[child_index]; + } + + return current; +} + +void bptree_insert(BPTreeNode *root, uint64_t key) { + int parents_length; + BPTreeNode **parents; + BPTreeNode *leaf = find_leaf(root, key, &parents_length, &parents); + + if (has_maximum_keys(leaf)) { + insert_full(root, &parents_length, parents, leaf, key, NULL); + } else { + insert_non_full(leaf, key, NULL); + } + + free(parents); +} + // Deletion diff --git a/src/bptree.h b/src/bptree.h index 559ccfeac5e18d51e9e48f602afaa93e90bdfc5b..d5bc03a34c4e075847f56ece5be8a420dcc05a52 100644 --- a/src/bptree.h +++ b/src/bptree.h @@ -1,13 +1,14 @@ #ifndef BPTREE_H #define BPTREE_h -#include "stdbool.h" +#include <stdbool.h> +#include <stdint.h> typedef struct BPTreeNode { int order; bool is_leaf; int keys_length; - int *keys; + uint64_t *keys; int children_length; struct BPTreeNode **children; } BPTreeNode; @@ -15,4 +16,12 @@ typedef struct BPTreeNode { BPTreeNode *bptree_init(int order); void bptree_destroy(BPTreeNode **root); +// ... + +// Insertion + +void bptree_insert(BPTreeNode *root, uint64_t key); + +// Deletion + #endif diff --git a/src/bptree.o b/src/bptree.o new file mode 100644 index 0000000000000000000000000000000000000000..1c3356f81150672ea30605e2d69c077b43918883 Binary files /dev/null and b/src/bptree.o differ diff --git a/src/main.c b/src/main.c index 3da830eaa6c695c46fe8f7194759adcb75c41e20..656890d2ee849a1f0eec45b9b955377a69807054 100644 --- a/src/main.c +++ b/src/main.c @@ -2,28 +2,19 @@ #include <stdlib.h> #include "sorted_array.h" +#include "bptree.h" int main() { - int *array = (int *)malloc(sizeof(int) * 10); - int array_length = 0; - - sorted_array_insert(array, &array_length, 3); - sorted_array_insert(array, &array_length, 11); - sorted_array_insert(array, &array_length, 5); - sorted_array_insert(array, &array_length, 1); - sorted_array_insert(array, &array_length, 15); - sorted_array_insert(array, &array_length, 12); - sorted_array_insert(array, &array_length, 8); - sorted_array_print(array, array_length); - - sorted_array_delete(array, &array_length, 12); - sorted_array_delete(array, &array_length, 1); - sorted_array_delete(array, &array_length, 15); - sorted_array_delete(array, &array_length, 5); - sorted_array_delete(array, &array_length, 8); - sorted_array_delete(array, &array_length, 11); - sorted_array_delete(array, &array_length, 3); - sorted_array_print(array, array_length); + 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); return EXIT_SUCCESS; } diff --git a/src/main.o b/src/main.o index 430793ffa0d07259fdf13973a75857418dc744d3..7cead98a5619bbb3096b135d6cd99d66c5f6d86c 100644 Binary files a/src/main.o and b/src/main.o differ diff --git a/src/program b/src/program index d77345c41e98d225093d0a372100bb75b4155945..b11cbd80e7c3c03fd3956742bc7631c4cbbb3342 100644 Binary files a/src/program and b/src/program differ diff --git a/src/sorted_array.c b/src/sorted_array.c index 0bbf3a06e28b0a7653ea4fc93c45f5c08f5f6486..50834dcd1a75503e8a406e4c8a139e46e7f9d093 100644 --- a/src/sorted_array.c +++ b/src/sorted_array.c @@ -1,10 +1,11 @@ #include "sorted_array.h" #include <stdbool.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> -int lower_bound(int *array, int array_length, int value) { +int lower_bound(int array_length, uint64_t *array, uint64_t value) { int low = 0; int high = array_length - 1; @@ -23,7 +24,7 @@ int lower_bound(int *array, int array_length, int value) { return low; } -int sorted_array_find_index(int *array, int array_length, int value) { +int sorted_array_find_index(int array_length, uint64_t *array, uint64_t value) { int low = 0; int high = array_length - 1; @@ -42,8 +43,8 @@ int sorted_array_find_index(int *array, int array_length, int value) { return -1; } -bool sorted_array_search(int *array, int array_length, int value, int *index) { - int i = sorted_array_find_index(array, array_length, value); +bool sorted_array_search(int array_length, uint64_t *array, uint64_t value, int *index) { + int i = sorted_array_find_index(array_length, array, value); if (index != NULL) { *index = i; @@ -52,16 +53,8 @@ bool sorted_array_search(int *array, int array_length, int value, int *index) { return i != -1; } -void sorted_array_print(int *array, int array_length) { - for (int i = 0; i < array_length; i++) { - printf("%d ", array[i]); - } - - printf("\n"); -} - -int sorted_array_insert(int *array, int *array_length, int value) { - int insertion_index = lower_bound(array, *array_length, value); +int sorted_array_insert(int *array_length, uint64_t *array, uint64_t value) { + int insertion_index = lower_bound(*array_length, array, value); for (int i = *array_length - 1; i >= insertion_index; i--) { array[i + 1] = array[i]; @@ -72,8 +65,8 @@ int sorted_array_insert(int *array, int *array_length, int value) { return insertion_index; } -void sorted_array_delete(int *array, int *array_length, int value) { - int index = sorted_array_find_index(array, *array_length, value); +void sorted_array_delete(int *array_length, uint64_t *array, uint64_t value) { + int index = sorted_array_find_index(*array_length, array, value); for (int i = index; i < *array_length; i++) { array[i] = array[i + 1]; @@ -81,3 +74,30 @@ void sorted_array_delete(int *array, int *array_length, int value) { *array_length -= 1; } + +void array_append(int *array_length, uint64_t *array, uint64_t value) { + array[*array_length] = value; + *array_length += 1; +} + +void array_print(int array_length, uint64_t *array) { + for (int i = 0; i < array_length; i++) { + printf("%ld ", array[i]); + } + + printf("\n"); +} + +void array_insert_at_index_BPTreeNode(int *array_length, BPTreeNode **array, int insertion_index, BPTreeNode *value) { + for (int i = *array_length - 1; i >= insertion_index; i--) { + array[i + 1] = array[i]; + } + + array[insertion_index] = value; + *array_length += 1; +} + +void array_append_BPTreeNode(int *array_length, BPTreeNode **array, BPTreeNode *value) { + array[*array_length] = value; + *array_length += 1; +} diff --git a/src/sorted_array.h b/src/sorted_array.h index e1088323b25e7064aaa6617138c602bb3da527e8..5192d0fa57e1f7c04232b7f99539066cce16985d 100644 --- a/src/sorted_array.h +++ b/src/sorted_array.h @@ -2,14 +2,23 @@ #define SORTED_ARRAY_H #include <stdbool.h> +#include <stdint.h> -int lower_bound(int *array, int array_length, int value); +int lower_bound(int array_length, uint64_t *array, uint64_t value); -int sorted_array_find_index(int *array, int array_length, int value); -bool sorted_array_search(int *array, int array_length, int value, int *index); -void sorted_array_print(int *array, int array_length); +int sorted_array_find_index(int array_length, uint64_t *array, uint64_t value); +bool sorted_array_search(int array_length, uint64_t *array, uint64_t value, int *index); -int sorted_array_insert(int *array, int *array_length, int value); -void sorted_array_delete(int *array, int *array_length, int value); +int sorted_array_insert(int *array_length, uint64_t *array, uint64_t value); +void sorted_array_delete(int *array_length, uint64_t *array, uint64_t value); + +void array_print(int array_length, uint64_t *array); +void array_append(int *array_length, uint64_t *array, uint64_t value); + +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); #endif diff --git a/src/sorted_array.o b/src/sorted_array.o index b5cdc315a1c1cef35f42c2424ca12b6288091a13..4d28f285dc92c82c19a672638a679bb237d9a952 100644 Binary files a/src/sorted_array.o and b/src/sorted_array.o differ