Skip to content
Snippets Groups Projects
Commit 4bc67884 authored by Florian Burgener's avatar Florian Burgener
Browse files

Refactoring + correction of a bug related to the data array in the BPTree

parent bce6f1f9
No related branches found
No related tags found
No related merge requests found
File moved
...@@ -148,6 +148,18 @@ void BPTreeNodeArray_delete_at_index(BPTreeNodeArray *array, int index) { ...@@ -148,6 +148,18 @@ void BPTreeNodeArray_delete_at_index(BPTreeNodeArray *array, int index) {
array->size--; 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 *ByteArray_init(int capacity) {
ByteArray *array = (ByteArray *)malloc(sizeof(ByteArray)); ByteArray *array = (ByteArray *)malloc(sizeof(ByteArray));
array->items = (uint8_t *)malloc(sizeof(uint8_t) * capacity); array->items = (uint8_t *)malloc(sizeof(uint8_t) * capacity);
......
...@@ -40,6 +40,8 @@ void BPTreeNodeArray_destroy(BPTreeNodeArray **array); ...@@ -40,6 +40,8 @@ void BPTreeNodeArray_destroy(BPTreeNodeArray **array);
void BPTreeNodeArray_insert_at_index(BPTreeNodeArray *array, int index, BPTreeNode *item); void BPTreeNodeArray_insert_at_index(BPTreeNodeArray *array, int index, BPTreeNode *item);
void BPTreeNodeArray_append(BPTreeNodeArray *array, BPTreeNode *item); void BPTreeNodeArray_append(BPTreeNodeArray *array, BPTreeNode *item);
void BPTreeNodeArray_delete_at_index(BPTreeNodeArray *array, int index); void BPTreeNodeArray_delete_at_index(BPTreeNodeArray *array, int index);
void BPTreeNodeArray_clear(BPTreeNodeArray *array);
void BPTreeNodeArray_copy(BPTreeNodeArray *src, BPTreeNodeArray *dest);
// ByteArray // ByteArray
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "Array.h" #include "Array.h"
#include "DirectoryRecord.h" #include "DirectoryRecord.h"
#include "bptree.h" #include "BPTree.h"
static uint64_t hash_string(char *str) { static uint64_t hash_string(char *str) {
SHA256_CTX sha256; SHA256_CTX sha256;
...@@ -56,7 +56,7 @@ static void rebuild_index(Directory *directory) { ...@@ -56,7 +56,7 @@ static void rebuild_index(Directory *directory) {
char phone_number[PHONE_NUMBER_MAX_LENGTH]; char phone_number[PHONE_NUMBER_MAX_LENGTH];
phone_number[PHONE_NUMBER_MAX_LENGTH - 1] = '\0'; phone_number[PHONE_NUMBER_MAX_LENGTH - 1] = '\0';
fread(phone_number, 1, PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER, fp); 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); fseek(fp, DirectoryRecord_size_on_disk() - 1 - PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER, SEEK_CUR);
if (ftell(fp) == file_size) { if (ftell(fp) == file_size) {
...@@ -70,14 +70,14 @@ static void rebuild_index(Directory *directory) { ...@@ -70,14 +70,14 @@ static void rebuild_index(Directory *directory) {
Directory *Directory_init(char database_filename[100]) { Directory *Directory_init(char database_filename[100]) {
Directory *directory = (Directory *)malloc(sizeof(Directory)); Directory *directory = (Directory *)malloc(sizeof(Directory));
strcpy(directory->database_filename, database_filename); strcpy(directory->database_filename, database_filename);
directory->index = bptree_init(DEFAULT_ORDER); directory->index = BPTree_init(DEFAULT_ORDER);
rebuild_index(directory); rebuild_index(directory);
bptree_print(directory->index, 0); BPTree_print(directory->index, 0);
return directory; return directory;
} }
void Directory_destroy(Directory **directory) { void Directory_destroy(Directory **directory) {
bptree_destroy(&(*directory)->index); BPTree_destroy(&(*directory)->index);
free(*directory); free(*directory);
*directory = NULL; *directory = NULL;
} }
...@@ -118,7 +118,7 @@ void Directory_print(Directory *directory) { ...@@ -118,7 +118,7 @@ void Directory_print(Directory *directory) {
bool Directory_append(Directory *directory, DirectoryRecord *record) { bool Directory_append(Directory *directory, DirectoryRecord *record) {
uint64_t a; 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; return false;
} }
...@@ -137,13 +137,13 @@ bool Directory_append(Directory *directory, DirectoryRecord *record) { ...@@ -137,13 +137,13 @@ bool Directory_append(Directory *directory, DirectoryRecord *record) {
uint64_t data_ptr = (uint64_t)ftell(fp) - DirectoryRecord_size_on_disk(); uint64_t data_ptr = (uint64_t)ftell(fp) - DirectoryRecord_size_on_disk();
fclose(fp); 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; return true;
} }
DirectoryRecord *Directory_search(Directory *directory, char phone_number[11]) { DirectoryRecord *Directory_search(Directory *directory, char phone_number[11]) {
uint64_t data_ptr; 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; FILE *fp;
fp = fopen(directory->database_filename, "rb"); fp = fopen(directory->database_filename, "rb");
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define DIRECTORY_H #define DIRECTORY_H
#include "DirectoryRecord.h" #include "DirectoryRecord.h"
#include "bptree.h" #include "BPTree.h"
#define DEFAULT_ORDER 2 #define DEFAULT_ORDER 2
......
#include "bptree.h" #include "BPTree.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
...@@ -18,19 +18,20 @@ static bool has_maximum_keys(BPTreeNode *node) { ...@@ -18,19 +18,20 @@ static bool has_maximum_keys(BPTreeNode *node) {
return node->keys->size == 2 * node->order; return node->keys->size == 2 * node->order;
} }
BPTreeNode *bptree_init(int order) { BPTreeNode *BPTree_init(int order) {
BPTreeNode *root = (BPTreeNode *)malloc(sizeof(BPTreeNode)); BPTreeNode *root = (BPTreeNode *)malloc(sizeof(BPTreeNode));
root->order = order; root->order = order;
root->is_leaf = true; root->is_leaf = true;
root->keys = IntegerArray_init(2 * root->order); root->keys = IntegerArray_init(2 * root->order);
root->data = IntegerArray_init(2 * root->order); root->data = IntegerArray_init(2 * root->order);
root->children = BPTreeNodeArray_init(2 * root->order + 1); root->children = BPTreeNodeArray_init(2 * root->order + 1);
root->next = NULL;
return root; return root;
} }
void bptree_destroy(BPTreeNode **root) { void BPTree_destroy(BPTreeNode **root) {
for (int i = 0; i < (*root)->children->size; i++) { 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); IntegerArray_destroy(&(*root)->keys);
...@@ -40,7 +41,7 @@ void bptree_destroy(BPTreeNode **root) { ...@@ -40,7 +41,7 @@ void bptree_destroy(BPTreeNode **root) {
*root = NULL; *root = NULL;
} }
void bptree_print(BPTreeNode *root, int depth) { void BPTree_print(BPTreeNode *root, int depth) {
for (int i = 0; i < depth; i++) { for (int i = 0; i < depth; i++) {
printf(" "); printf(" ");
} }
...@@ -48,11 +49,11 @@ void bptree_print(BPTreeNode *root, int depth) { ...@@ -48,11 +49,11 @@ void bptree_print(BPTreeNode *root, int depth) {
IntegerArray_print(root->keys); IntegerArray_print(root->keys);
for (int i = 0; i < root->children->size; i++) { 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) { if (root->is_leaf) {
int index; int index;
bool found = IntegerArray_binary_search(root->keys, key, &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) { ...@@ -70,7 +71,7 @@ bool bptree_search(BPTreeNode *root, uint64_t key, uint64_t *data) {
child_index += 1; child_index += 1;
} }
return bptree_search(root->children->items[child_index], key, data); return BPTree_search(root->children->items[child_index], key, data);
} }
// Insertion // Insertion
...@@ -87,11 +88,17 @@ static void insert_non_full(BPTreeNode *node, uint64_t key, uint64_t data, BPTre ...@@ -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) { 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++) { 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->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->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) { 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 ...@@ -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 virtual_insertion_index = lower_bound(node->keys, key);
int median_index = node->keys->size / 2; int median_index = node->keys->size / 2;
uint64_t median_value; uint64_t median_value;
*right_node = bptree_init(node->order); *right_node = BPTree_init(node->order);
(*right_node)->is_leaf = false; (*right_node)->is_leaf = false;
if (virtual_insertion_index < median_index) { if (virtual_insertion_index < median_index) {
...@@ -135,7 +142,7 @@ static uint64_t split_leaf(BPTreeNode *node, uint64_t key, uint64_t data, BPTree ...@@ -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 virtual_insertion_index = lower_bound(node->keys, key);
int median_index = node->keys->size / 2; int median_index = node->keys->size / 2;
uint64_t median_value; uint64_t median_value;
*right_node = bptree_init(node->order); *right_node = BPTree_init(node->order);
if (virtual_insertion_index < median_index) { if (virtual_insertion_index < median_index) {
median_value = node->keys->items[median_index - 1]; 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 ...@@ -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); IntegerArray_insert_at_index((*right_node)->data, insertion_index, data);
} }
if (node->children->size == 0) { if (node->next != NULL) {
BPTreeNodeArray_append(node->children, *right_node); (*right_node)->next = node->next;
} else {
BPTreeNodeArray_append((*right_node)->children, node->children->items[0]);
node->children->items[0] = *right_node;
} }
node->next = *right_node;
return median_value; return median_value;
} }
static void grow(BPTreeNode *root, uint64_t median_value, BPTreeNode *split_right_node) { 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; 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->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_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, left_node);
BPTreeNodeArray_append(root->children, split_right_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 ...@@ -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; BPTreeNodeArray *parents;
BPTreeNode *leaf = find_leaf(root, key, &parents); BPTreeNode *leaf = find_leaf(root, key, &parents);
......
...@@ -12,17 +12,18 @@ typedef struct BPTreeNode { ...@@ -12,17 +12,18 @@ typedef struct BPTreeNode {
IntegerArray *keys; IntegerArray *keys;
IntegerArray *data; IntegerArray *data;
BPTreeNodeArray *children; BPTreeNodeArray *children;
struct BPTreeNode *next;
} BPTreeNode; } BPTreeNode;
BPTreeNode *bptree_init(int order); BPTreeNode *BPTree_init(int order);
void bptree_destroy(BPTreeNode **root); void BPTree_destroy(BPTreeNode **root);
void bptree_print(BPTreeNode *root, int depth); void BPTree_print(BPTreeNode *root, int depth);
bool bptree_search(BPTreeNode *root, uint64_t key, uint64_t *data); bool BPTree_search(BPTreeNode *root, uint64_t key, uint64_t *data);
// Insertion // Insertion
void bptree_insert(BPTreeNode *root, uint64_t key, uint64_t data); void BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data);
// Deletion // Deletion
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment