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
Branches
No related tags found
No related merge requests found
File moved
......@@ -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);
......
......@@ -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
......
......@@ -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");
......
......@@ -2,7 +2,7 @@
#define DIRECTORY_H
#include "DirectoryRecord.h"
#include "bptree.h"
#include "BPTree.h"
#define DEFAULT_ORDER 2
......
#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);
......
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment