diff --git a/a.c b/a.b similarity index 100% rename from a.c rename to a.b diff --git a/src/Array.c b/src/Array.c index 2d7daa5a88932e6de9a1326a2736cddd7d193e58..e9d75d65b206a61a886d7053dc694acec2d885b8 100644 --- a/src/Array.c +++ b/src/Array.c @@ -148,6 +148,18 @@ void BPTreeNodeArray_delete_at_index(BPTreeNodeArray *array, int index) { array->size--; } +void BPTreeNodeArray_clear(BPTreeNodeArray *array) { + array->size = 0; +} + +void BPTreeNodeArray_copy(BPTreeNodeArray *src, BPTreeNodeArray *dest) { + for (int i = 0; i < src->size; i++) { + dest->items[i] = src->items[i]; + } + + dest->size = src->size; +} + ByteArray *ByteArray_init(int capacity) { ByteArray *array = (ByteArray *)malloc(sizeof(ByteArray)); array->items = (uint8_t *)malloc(sizeof(uint8_t) * capacity); diff --git a/src/Array.h b/src/Array.h index ba8d3848961daf89dc37e3da99cbdc4f4000d2b5..e48817e428719ca779c474cea4e4b85818f086c6 100644 --- a/src/Array.h +++ b/src/Array.h @@ -40,6 +40,8 @@ void BPTreeNodeArray_destroy(BPTreeNodeArray **array); void BPTreeNodeArray_insert_at_index(BPTreeNodeArray *array, int index, BPTreeNode *item); void BPTreeNodeArray_append(BPTreeNodeArray *array, BPTreeNode *item); void BPTreeNodeArray_delete_at_index(BPTreeNodeArray *array, int index); +void BPTreeNodeArray_clear(BPTreeNodeArray *array); +void BPTreeNodeArray_copy(BPTreeNodeArray *src, BPTreeNodeArray *dest); // ByteArray diff --git a/src/Directory.c b/src/Directory.c index c861090b15d5bad4759e0f4fdff3d9793b7abb07..8c22e43da0e1fd78dadfc3b17836842afe2715de 100644 --- a/src/Directory.c +++ b/src/Directory.c @@ -11,7 +11,7 @@ #include "Array.h" #include "DirectoryRecord.h" -#include "bptree.h" +#include "BPTree.h" static uint64_t hash_string(char *str) { SHA256_CTX sha256; @@ -56,7 +56,7 @@ static void rebuild_index(Directory *directory) { char phone_number[PHONE_NUMBER_MAX_LENGTH]; phone_number[PHONE_NUMBER_MAX_LENGTH - 1] = '\0'; fread(phone_number, 1, PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER, fp); - bptree_insert(directory->index, hash_string(phone_number), data_ptr); + BPTree_insert(directory->index, hash_string(phone_number), data_ptr); fseek(fp, DirectoryRecord_size_on_disk() - 1 - PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER, SEEK_CUR); if (ftell(fp) == file_size) { @@ -70,14 +70,14 @@ static void rebuild_index(Directory *directory) { Directory *Directory_init(char database_filename[100]) { Directory *directory = (Directory *)malloc(sizeof(Directory)); strcpy(directory->database_filename, database_filename); - directory->index = bptree_init(DEFAULT_ORDER); + directory->index = BPTree_init(DEFAULT_ORDER); rebuild_index(directory); - bptree_print(directory->index, 0); + BPTree_print(directory->index, 0); return directory; } void Directory_destroy(Directory **directory) { - bptree_destroy(&(*directory)->index); + BPTree_destroy(&(*directory)->index); free(*directory); *directory = NULL; } @@ -118,7 +118,7 @@ void Directory_print(Directory *directory) { bool Directory_append(Directory *directory, DirectoryRecord *record) { uint64_t a; - if (bptree_search(directory->index, hash_string(record->phone_number), &a)) { + if (BPTree_search(directory->index, hash_string(record->phone_number), &a)) { return false; } @@ -137,13 +137,13 @@ bool Directory_append(Directory *directory, DirectoryRecord *record) { uint64_t data_ptr = (uint64_t)ftell(fp) - DirectoryRecord_size_on_disk(); fclose(fp); - bptree_insert(directory->index, hash_string(record->phone_number), data_ptr); + BPTree_insert(directory->index, hash_string(record->phone_number), data_ptr); return true; } DirectoryRecord *Directory_search(Directory *directory, char phone_number[11]) { uint64_t data_ptr; - if (bptree_search(directory->index, hash_string(phone_number), &data_ptr)) { + if (BPTree_search(directory->index, hash_string(phone_number), &data_ptr)) { FILE *fp; fp = fopen(directory->database_filename, "rb"); diff --git a/src/Directory.h b/src/Directory.h index 1d34825bad6f154b353dfa05a6cd7fc03836ef80..d6113b35c91493dfc419fc98c43b84211e2848a4 100644 --- a/src/Directory.h +++ b/src/Directory.h @@ -2,7 +2,7 @@ #define DIRECTORY_H #include "DirectoryRecord.h" -#include "bptree.h" +#include "BPTree.h" #define DEFAULT_ORDER 2 diff --git a/src/bptree.c b/src/bptree.c index ba5977c9e534e9590baa7ad0be94609401923af0..50a78b538bafb3de6230762e88961769acc8eae7 100644 --- a/src/bptree.c +++ b/src/bptree.c @@ -1,4 +1,4 @@ -#include "bptree.h" +#include "BPTree.h" #include <stdbool.h> #include <stdint.h> @@ -18,19 +18,20 @@ static bool has_maximum_keys(BPTreeNode *node) { return node->keys->size == 2 * node->order; } -BPTreeNode *bptree_init(int order) { +BPTreeNode *BPTree_init(int order) { BPTreeNode *root = (BPTreeNode *)malloc(sizeof(BPTreeNode)); root->order = order; root->is_leaf = true; root->keys = IntegerArray_init(2 * root->order); root->data = IntegerArray_init(2 * root->order); root->children = BPTreeNodeArray_init(2 * root->order + 1); + root->next = NULL; return root; } -void bptree_destroy(BPTreeNode **root) { +void BPTree_destroy(BPTreeNode **root) { for (int i = 0; i < (*root)->children->size; i++) { - bptree_destroy(&(*root)->children->items[i]); + BPTree_destroy(&(*root)->children->items[i]); } IntegerArray_destroy(&(*root)->keys); @@ -40,7 +41,7 @@ void bptree_destroy(BPTreeNode **root) { *root = NULL; } -void bptree_print(BPTreeNode *root, int depth) { +void BPTree_print(BPTreeNode *root, int depth) { for (int i = 0; i < depth; i++) { printf(" "); } @@ -48,11 +49,11 @@ void bptree_print(BPTreeNode *root, int depth) { IntegerArray_print(root->keys); for (int i = 0; i < root->children->size; i++) { - bptree_print(root->children->items[i], depth + 1); + BPTree_print(root->children->items[i], depth + 1); } } -bool bptree_search(BPTreeNode *root, uint64_t key, uint64_t *data) { +bool BPTree_search(BPTreeNode *root, uint64_t key, uint64_t *data) { if (root->is_leaf) { int index; bool found = IntegerArray_binary_search(root->keys, key, &index); @@ -70,7 +71,7 @@ bool bptree_search(BPTreeNode *root, uint64_t key, uint64_t *data) { child_index += 1; } - return bptree_search(root->children->items[child_index], key, data); + return BPTree_search(root->children->items[child_index], key, data); } // Insertion @@ -87,11 +88,17 @@ static void insert_non_full(BPTreeNode *node, uint64_t key, uint64_t data, BPTre 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->size; i++) { IntegerArray_append(right_node->keys, left_node->keys->items[i]); - IntegerArray_append(right_node->data, left_node->data->items[i]); + + if (left_node->is_leaf) { + IntegerArray_append(right_node->data, left_node->data->items[i]); + } } left_node->keys->size = left_index; - left_node->data->size = left_index; + + if (left_node->is_leaf) { + left_node->data->size = left_index; + } } static void redistribute_children(BPTreeNode *left_node, BPTreeNode *right_node, int left_index, int right_index) { @@ -106,7 +113,7 @@ static uint64_t split_internal(BPTreeNode *node, uint64_t key, BPTreeNode *right int virtual_insertion_index = lower_bound(node->keys, key); int median_index = node->keys->size / 2; uint64_t median_value; - *right_node = bptree_init(node->order); + *right_node = BPTree_init(node->order); (*right_node)->is_leaf = false; if (virtual_insertion_index < median_index) { @@ -135,7 +142,7 @@ static uint64_t split_leaf(BPTreeNode *node, uint64_t key, uint64_t data, BPTree int virtual_insertion_index = lower_bound(node->keys, key); int median_index = node->keys->size / 2; uint64_t median_value; - *right_node = bptree_init(node->order); + *right_node = BPTree_init(node->order); if (virtual_insertion_index < median_index) { median_value = node->keys->items[median_index - 1]; @@ -154,38 +161,28 @@ static uint64_t split_leaf(BPTreeNode *node, uint64_t key, uint64_t data, BPTree IntegerArray_insert_at_index((*right_node)->data, insertion_index, data); } - if (node->children->size == 0) { - BPTreeNodeArray_append(node->children, *right_node); - } else { - BPTreeNodeArray_append((*right_node)->children, node->children->items[0]); - node->children->items[0] = *right_node; + if (node->next != NULL) { + (*right_node)->next = node->next; } + node->next = *right_node; return median_value; } static void grow(BPTreeNode *root, uint64_t median_value, BPTreeNode *split_right_node) { - BPTreeNode *left_node = bptree_init(root->order); + BPTreeNode *left_node = BPTree_init(root->order); left_node->is_leaf = split_right_node->is_leaf; - - for (int i = 0; i < root->keys->size; i++) { - IntegerArray_append(left_node->keys, root->keys->items[i]); - - // if (root->is_leaf) { - if (left_node->is_leaf) { - IntegerArray_append(left_node->data, root->data->items[i]); - } - } - - for (int i = 0; i < root->children->size; i++) { - BPTreeNodeArray_append(left_node->children, root->children->items[i]); - } - root->is_leaf = false; - root->keys->size = 0; - root->children->size = 0; + IntegerArray_copy(root->keys, left_node->keys); + IntegerArray_clear(root->keys); IntegerArray_append(root->keys, median_value); + + IntegerArray_copy(root->data, left_node->data); + IntegerArray_clear(root->data); + + BPTreeNodeArray_copy(root->children, left_node->children); + BPTreeNodeArray_clear(root->children); BPTreeNodeArray_append(root->children, left_node); BPTreeNodeArray_append(root->children, split_right_node); } @@ -246,7 +243,7 @@ static void insert_non_full(BPTreeNode *node, uint64_t key, uint64_t data, BPTre } } -void bptree_insert(BPTreeNode *root, uint64_t key, uint64_t data) { +void BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data) { BPTreeNodeArray *parents; BPTreeNode *leaf = find_leaf(root, key, &parents); diff --git a/src/bptree.h b/src/bptree.h index 80b5e83569c686fab472844d868ff51bf37b887e..41962bf7fba8e3fb22e561e5ed0bd38ed85934b1 100644 --- a/src/bptree.h +++ b/src/bptree.h @@ -12,17 +12,18 @@ typedef struct BPTreeNode { IntegerArray *keys; IntegerArray *data; BPTreeNodeArray *children; + struct BPTreeNode *next; } BPTreeNode; -BPTreeNode *bptree_init(int order); -void bptree_destroy(BPTreeNode **root); +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); +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, uint64_t data); +void BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data); // Deletion