diff --git a/src/Makefile b/src/Makefile index 2ab95ed890da7bf58a65f046688d633b0d6e5fb4..bc8383b49240801ba1809020bae83d1506fe0588 100644 --- a/src/Makefile +++ b/src/Makefile @@ -2,7 +2,7 @@ TARGET = program LIBS = -lm CC = gcc CFLAGS = -g -Wall -Wextra -pedantic -Ofast -# CFLAGS += -fsanitize=address -fsanitize=leak +CFLAGS += -fsanitize=address -fsanitize=leak .PHONY: default all clean @@ -18,7 +18,7 @@ HEADERS = $(wildcard *.h) .PRECIOUS: $(TARGET) $(OBJECTS) $(TARGET): $(OBJECTS) - $(CC) $(OBJECTS) ${CFLAGS} $(LIBS) -o $@ + $(CC) $(OBJECTS) $(CFLAGS) $(LIBS) -o $@ clean: rm -f *.o ${TARGET}* diff --git a/src/bptree.c b/src/bptree.c index 660fc9fa7e3cfe9be12d2d6e487b21525c181bd9..c9bf2b6cd98eb3788c5a78492578827dbcf01938 100644 --- a/src/bptree.c +++ b/src/bptree.c @@ -24,6 +24,8 @@ BPTreeNode *bptree_init(int order) { root->is_leaf = true; root->keys_length = 0; root->keys = (uint64_t *)malloc(sizeof(uint64_t) * (2 * order)); + root->data_length = 0; + root->data = (uint64_t *)malloc(sizeof(uint64_t) * (2 * order)); root->children_length = 0; root->children = (BPTreeNode **)malloc(sizeof(BPTreeNode *) * (2 * order + 1)); return root; @@ -35,6 +37,7 @@ void bptree_destroy(BPTreeNode **root) { } free((*root)->keys); + free((*root)->data); free((*root)->children); free(*root); *root = NULL; @@ -52,17 +55,40 @@ void bptree_print(BPTreeNode *root, int depth) { } } +bool bptree_search(BPTreeNode *root, uint64_t key, uint64_t *data) { + if (root->is_leaf) { + int index; + bool found = sorted_array_search(root->keys_length, root->keys, key, &index); + + if (found) { + *data = root->data[index]; + } + + return found; + } + + int child_index = lower_bound(root->keys_length, root->keys, key); + + if (child_index < root->keys_length && root->keys[child_index] == key) { + child_index += 1; + } + + return bptree_search(root->children[child_index], key, data); +} + // 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]); + array_append(&right_node->data_length, right_node->data, left_node->data[i]); } left_node->keys_length = left_index; + left_node->data_length = left_index; } -static uint64_t split_leaf(BPTreeNode *node, uint64_t key, BPTreeNode **right_node) { +static uint64_t split_leaf(BPTreeNode *node, uint64_t key, uint64_t data, 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; @@ -71,15 +97,18 @@ static uint64_t split_leaf(BPTreeNode *node, uint64_t key, BPTreeNode **right_no 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); + int insertion_index = sorted_array_insert(&node->keys_length, node->keys, key); + array_insert_at_index(&node->data_length, node->data, insertion_index, data); } 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); + int insertion_index = sorted_array_insert(&(*right_node)->keys_length, (*right_node)->keys, key); + array_insert_at_index(&(*right_node)->data_length, (*right_node)->data, insertion_index, data); } else { median_value = key; redistribute_keys(node, *right_node, median_index, median_index); - sorted_array_insert(&(*right_node)->keys_length, (*right_node)->keys, key); + int insertion_index = sorted_array_insert(&(*right_node)->keys_length, (*right_node)->keys, key); + array_insert_at_index(&(*right_node)->data_length, (*right_node)->data, insertion_index, data); } // TODO : Linked List @@ -130,6 +159,10 @@ static void grow(BPTreeNode *root, uint64_t median_value, BPTreeNode *split_righ for (int i = 0; i < root->keys_length; i++) { array_append(&left_node->keys_length, left_node->keys, root->keys[i]); + + if (root->is_leaf) { + array_append(&left_node->data_length, left_node->data, root->data[i]); + } } for (int i = 0; i < root->children_length; i++) { @@ -145,14 +178,14 @@ 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_non_full(BPTreeNode *node, uint64_t key, uint64_t data, 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) { +static void insert_full(BPTreeNode *root, int *parents_length, BPTreeNode **parents, BPTreeNode *node, uint64_t key, uint64_t data, 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); + median_value = split_leaf(node, key, data, &split_right_node); } else { median_value = split_internal(node, key, previous_split_right_node, &split_right_node); } @@ -164,16 +197,20 @@ static void insert_full(BPTreeNode *root, int *parents_length, BPTreeNode **pare 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); + insert_full(root, parents_length, parents, parent, median_value, 0, split_right_node); } else { - insert_non_full(parent, median_value, split_right_node); + insert_non_full(parent, median_value, data, split_right_node); } } } -static void insert_non_full(BPTreeNode *node, uint64_t key, BPTreeNode *previous_split_right_node) { +static void insert_non_full(BPTreeNode *node, uint64_t key, uint64_t data, BPTreeNode *previous_split_right_node) { int insertion_index = sorted_array_insert(&node->keys_length, node->keys, key); + if (node->is_leaf) { + array_insert_at_index(&node->data_length, node->data, insertion_index, data); + } + if (previous_split_right_node != NULL) { array_insert_at_index_BPTreeNode(&node->children_length, node->children, insertion_index + 1, previous_split_right_node); } @@ -199,7 +236,7 @@ static BPTreeNode *find_leaf(BPTreeNode *root, uint64_t key, int *parents_length return current; } -void bptree_insert(BPTreeNode *root, uint64_t key) { +void bptree_insert(BPTreeNode *root, uint64_t key, uint64_t data) { int parents_length; BPTreeNode **parents; BPTreeNode *leaf = find_leaf(root, key, &parents_length, &parents); @@ -207,9 +244,9 @@ void bptree_insert(BPTreeNode *root, uint64_t key) { // TODO : vérifier si la clé existe dans leaf. if (has_maximum_keys(leaf)) { - insert_full(root, &parents_length, parents, leaf, key, NULL); + insert_full(root, &parents_length, parents, leaf, key, data, NULL); } else { - insert_non_full(leaf, key, NULL); + insert_non_full(leaf, key, data, NULL); } free(parents); diff --git a/src/bptree.h b/src/bptree.h index 308dc0c871a501123d608c9c63387dad8bcc33e7..bff78b36d3a68d91ce42e204306ad613bec4949d 100644 --- a/src/bptree.h +++ b/src/bptree.h @@ -9,6 +9,8 @@ typedef struct BPTreeNode { bool is_leaf; int keys_length; uint64_t *keys; + int data_length; + uint64_t *data; int children_length; struct BPTreeNode **children; } BPTreeNode; @@ -17,12 +19,13 @@ BPTreeNode *bptree_init(int order); void bptree_destroy(BPTreeNode **root); void bptree_print(BPTreeNode *root, int depth); +bool bptree_search(BPTreeNode *root, uint64_t key, uint64_t *data); // ... // Insertion -void bptree_insert(BPTreeNode *root, uint64_t key); +void bptree_insert(BPTreeNode *root, uint64_t key, uint64_t data); // Deletion diff --git a/src/bptree.o b/src/bptree.o index 9add434408ea836f14fd8beda4e8ae16dd6dabf8..294a237e01ba5f0ef580c048fb095a908abe53f8 100644 Binary files a/src/bptree.o and b/src/bptree.o differ diff --git a/src/main.c b/src/main.c index 69cae45e1f7d723670f4623197744e22de8ae2a8..9f584fe03ae65a54f038697f87e7abcb108fd8c2 100644 --- a/src/main.c +++ b/src/main.c @@ -1,3 +1,6 @@ +#include <assert.h> +// Warning : stdbool +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> @@ -11,9 +14,19 @@ int main() { array_print(keys_length, keys); for (int i = 0; i < keys_length; i++) { - bptree_insert(root, keys[i]); + bptree_insert(root, keys[i], keys[i] * 1000); } bptree_print(root, 0); + + for (int i = 0; i < keys_length; i++) { + uint64_t data; + bool found = bptree_search(root, keys[i], &data); + + assert(found == true); + assert(data == keys[i] * 1000); + } + + bptree_destroy(&root); return EXIT_SUCCESS; } diff --git a/src/main.o b/src/main.o index d47a4d1ce4a6d1ed2ac727bdee6c2a822203f63d..48a3065119e6f7e4a258d9e3f7cababf73859fc3 100644 Binary files a/src/main.o and b/src/main.o differ diff --git a/src/program b/src/program index 5eaec8a64b736d8c9349cd161513078dee25a623..9e4a14ec81fca974afb54dcc39df11dba1aa35df 100644 Binary files a/src/program and b/src/program differ diff --git a/src/sorted_array.c b/src/sorted_array.c index 85ffd9d9b1df7465acdc6ba17350528a55af1044..3e75b04714892a35be6ac86f093eb56637e8c46a 100644 --- a/src/sorted_array.c +++ b/src/sorted_array.c @@ -75,6 +75,15 @@ void sorted_array_delete(int *array_length, uint64_t *array, uint64_t value) { *array_length -= 1; } +void array_insert_at_index(int *array_length, uint64_t *array, int insertion_index, uint64_t 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(int *array_length, uint64_t *array, uint64_t value) { array[*array_length] = value; *array_length += 1; diff --git a/src/sorted_array.h b/src/sorted_array.h index b8c330c7be3daaab9fdf15f85dff106a816dea26..02f12fdcd90d6cc122299379ab6d227a1b2db2ed 100644 --- a/src/sorted_array.h +++ b/src/sorted_array.h @@ -8,11 +8,11 @@ int lower_bound(int array_length, uint64_t *array, uint64_t value); 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_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_insert_at_index(int *array_length, uint64_t *array, int insertion_index, uint64_t value); void array_append(int *array_length, uint64_t *array, uint64_t value); typedef struct BPTreeNode BPTreeNode; diff --git a/src/sorted_array.o b/src/sorted_array.o index 2e7e50aa021f3738994c20557dcc6f90e9328abb..86c0e6abcb2b5fda3a3099c6ed01cd631b041225 100644 Binary files a/src/sorted_array.o and b/src/sorted_array.o differ