Working on removing keys from B+ trees
This commit is contained in:
5
.idea/vcs.xml
generated
5
.idea/vcs.xml
generated
@@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CommitMessageInspectionProfile">
|
||||
<profile version="1.0">
|
||||
<inspection_tool class="SubjectBodySeparation" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
|
||||
104
src/bplus_tree.c
104
src/bplus_tree.c
@@ -91,6 +91,28 @@ bool bplus_node_insert_kv(BPlusNode *node, BPlusKV *kv) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bplus_node_remove_kv(BPlusNode *node, BPlusKV *kv) {
|
||||
bool removed = false;
|
||||
//Find key
|
||||
for (size_t i = 0; i < node->keyCount; i++) {
|
||||
if (node->keys[i] == kv) {
|
||||
node->keys[i] = NULL;
|
||||
node->keyCount--;
|
||||
//Move keys down
|
||||
for (; i < node->keyCount; i++) {
|
||||
node->keys[i] = node->keys[i + 1];
|
||||
}
|
||||
removed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
bool bplus_node_merge(BPlusNode *left, BPlusNode *right) {
|
||||
|
||||
}
|
||||
|
||||
void print_bplus_node(BPlusNode *node, size_t indent) {
|
||||
char *indentStr = calloc(indent + 1, sizeof(char));
|
||||
memset(indentStr, ' ', sizeof(char) * indent);
|
||||
@@ -213,7 +235,7 @@ BPlusNode *bplus_tree_find_leaf(BPlusTree *tree, uint64_t key) {
|
||||
|
||||
bool bplus_tree_insert(BPlusTree *tree, uint64_t newKey, void *newValue) {
|
||||
BPlusNode *node = bplus_tree_find_leaf(tree, newKey);
|
||||
assert(node != NULL);
|
||||
assert(node != NULL && node->isInternal == false);
|
||||
|
||||
if (node->keyCount < node->order - 1) {
|
||||
//Can insert at this node
|
||||
@@ -294,6 +316,86 @@ bool bplus_tree_insert(BPlusTree *tree, uint64_t newKey, void *newValue) {
|
||||
|
||||
}
|
||||
|
||||
bool bplus_tree_delete(BPlusTree *tree, uint64_t key) {
|
||||
BPlusNode *node = bplus_tree_find_leaf(tree, key);
|
||||
assert(node != NULL && node->isInternal == false);
|
||||
|
||||
//Find and remove kv
|
||||
bool removed = false;
|
||||
for (size_t i = 0; i < node->keyCount; i++) {
|
||||
if (node->keys[i]->key == key) {
|
||||
BPlusKV *kv = node->keys[i];
|
||||
removed = bplus_node_remove_kv(node, node->keys[i]);
|
||||
assert(removed);
|
||||
free_bplus_kv(kv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!removed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node->keyCount >= tree->minFill || node->parent == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Try and borrow a key from a neighbour
|
||||
|
||||
//Check right leaf
|
||||
if (node->rightLeaf != NULL
|
||||
&& node->rightLeaf->parent == node->parent
|
||||
&& node->rightLeaf->keyCount > tree->minFill) {
|
||||
//Move first kv on leaf to this node
|
||||
BPlusKV *kv = node->rightLeaf->keys[0];
|
||||
assert(bplus_node_remove_kv(node->rightLeaf, kv));
|
||||
assert(bplus_node_insert_kv(node, kv));
|
||||
//Update the right leafs parent pointer
|
||||
for (size_t i = 0; i < node->parent->keyCount; i++) {
|
||||
if (node->parent->keys[i]->rightPointer == node->rightLeaf) {
|
||||
node->parent->keys[i]->key = node->rightLeaf->keys[0]->key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//Check left leaf
|
||||
if (node->leftLeaf != NULL
|
||||
&& node->leftLeaf->parent == node->parent
|
||||
&& node->leftLeaf->keyCount > tree->minFill) {
|
||||
//Borrow right most key from left leaf
|
||||
BPlusKV *kv = node->leftLeaf->keys[node->keyCount - 1];
|
||||
assert(bplus_node_remove_kv(node->leftLeaf, kv));
|
||||
assert(bplus_node_insert_kv(node, kv));
|
||||
//Update the key pointing to this node
|
||||
for (size_t i = 0; i < node->parent->keyCount; i++) {
|
||||
if (node->parent->keys[i]->rightPointer == node) {
|
||||
node->parent->keys[i]->key = node->keys[0]->key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//No key to borrow, merge with a sibling
|
||||
//Look right and left for leafs with same parent and where merging would result in keys < order
|
||||
|
||||
//Try right leaf
|
||||
if (node->rightLeaf != NULL
|
||||
&& node->parent == node->rightLeaf->parent
|
||||
&& node->keyCount + node->rightLeaf->keyCount < tree->order) {
|
||||
return bplus_node_merge(node, node->rightLeaf);
|
||||
}
|
||||
|
||||
//Try left leaf
|
||||
if (node->leftLeaf != NULL
|
||||
&& node->parent == node->leftLeaf->parent
|
||||
&& node->keyCount + node->leftLeaf->keyCount < tree->order) {
|
||||
return bplus_node_merge(node->leftLeaf, node);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BPlusKV *bplus_tree_find(BPlusTree *tree, uint64_t key) {
|
||||
BPlusNode *leaf = bplus_tree_find_leaf(tree, key);
|
||||
if (leaf == NULL) {
|
||||
|
||||
@@ -41,6 +41,10 @@ void free_bplus_node(BPlusNode *node);
|
||||
|
||||
bool bplus_node_insert_kv(BPlusNode *node, BPlusKV *kv);
|
||||
|
||||
bool bplus_node_remove_kv(BPlusNode *node, BPlusKV *kv);
|
||||
|
||||
bool bplus_node_merge(BPlusNode *left, BPlusNode *right);
|
||||
|
||||
void print_bplus_node(BPlusNode *node, size_t indent);
|
||||
|
||||
char *debug_bplus_node_str(BPlusNode *node, char *str, size_t *strSize);
|
||||
@@ -58,12 +62,15 @@ BPlusTree *new_bplus_tree(size_t order);
|
||||
void free_bplus_tree(BPlusTree *tree);
|
||||
|
||||
void print_bplus_tree(BPlusTree *tree);
|
||||
|
||||
char *debug_bplus_tree_str(BPlusTree *tree, char *str);
|
||||
|
||||
BPlusNode *bplus_tree_find_leaf(BPlusTree *tree, uint64_t key);
|
||||
|
||||
bool bplus_tree_insert(BPlusTree *tree, uint64_t key, void *value);
|
||||
|
||||
bool bplus_tree_delete(BPlusTree *tree, uint64_t key);
|
||||
|
||||
BPlusKV *bplus_tree_find(BPlusTree *tree, uint64_t key);
|
||||
|
||||
enum BPlusFindComp_t {
|
||||
@@ -73,6 +80,7 @@ enum BPlusFindComp_t {
|
||||
FIND_GT = 4
|
||||
};
|
||||
typedef enum BPlusFindComp_t BPlusFindComp;
|
||||
|
||||
BPlusKV *bplus_tree_find_closest(BPlusTree *tree, uint64_t key, BPlusFindComp dir);
|
||||
|
||||
#endif //SDB_BPLUS_TREE_H
|
||||
|
||||
Reference in New Issue
Block a user