feat(lsm): implement bt remove

This commit is contained in:
Jef Roosens 2023-10-13 11:56:50 +02:00
parent 13e42181a2
commit 96fc645034
Signed by: Jef Roosens
GPG key ID: B75D4F293C7052DB
7 changed files with 135 additions and 26 deletions

View file

@ -17,6 +17,20 @@ lsm_error lsm_bt_node_init(lsm_bt_node **ptr, const char key, void *data) {
return lsm_error_ok;
}
void lsm_bt_node_free(lsm_bt_node *node) { free(node); }
void lsm_bt_node_free_recursive(lsm_bt_node *node) {
if (node->left != NULL) {
lsm_bt_node_free_recursive(node->left);
}
if (node->right != NULL) {
lsm_bt_node_free_recursive(node->right);
}
lsm_bt_node_free(node);
}
lsm_error lsm_bt_init(lsm_bt **ptr) {
lsm_bt *bt = calloc(1, sizeof(lsm_bt));
@ -29,18 +43,26 @@ lsm_error lsm_bt_init(lsm_bt **ptr) {
return lsm_error_ok;
}
void lsm_bt_free(lsm_bt *bt) {
if (bt->root != NULL) {
lsm_bt_node_free_recursive(bt->root);
}
free(bt);
}
lsm_error lsm_bt_insert(lsm_bt *bt, char key, void *data) {
lsm_bt_node **dest = &bt->root;
// Traverse down the tree until we reach the new point to insert our node
while (*dest != NULL) {
if ((*dest)->key == key) {
return lsm_error_already_present;
}
while ((*dest != NULL) && ((*dest)->key != key)) {
dest = key < (*dest)->key ? &(*dest)->left : &(*dest)->right;
}
if (*dest != NULL) {
return lsm_error_already_present;
}
lsm_bt_node *node;
if (lsm_bt_node_init(&node, key, data) != lsm_error_ok) {
@ -56,15 +78,56 @@ lsm_error lsm_bt_insert(lsm_bt *bt, char key, void *data) {
lsm_error lsm_bt_search(void **out, lsm_bt *bt, char key) {
lsm_bt_node *node = bt->root;
while (node != NULL) {
if (node->key == key) {
*out = node->data;
return lsm_error_ok;
}
while ((node != NULL) && (node->key != key)) {
node = key < node->key ? node->left : node->right;
}
return lsm_error_not_found;
if (node == NULL) {
return lsm_error_not_found;
}
*out = node->data;
return lsm_error_ok;
}
lsm_error lsm_bt_remove(void **out, lsm_bt *bt, char key) {
if (bt->root == NULL) {
return lsm_error_not_found;
}
lsm_bt_node **dest = &bt->root;
while ((*dest != NULL) && ((*dest)->key != key)) {
dest = key < (*dest)->key ? &(*dest)->left : &(*dest)->right;
}
if (*dest == NULL) {
return lsm_error_not_found;
}
*out = (*dest)->data;
bt->size--;
if (((*dest)->left != NULL) && ((*dest)->right != NULL)) {
lsm_bt_node **succ = &(*dest)->right;
while ((*succ)->left != NULL) {
succ = &(*succ)->left;
}
(*dest)->key = (*succ)->key;
(*dest)->data = (*succ)->data;
lsm_bt_node *succ_replacement = (*succ)->right;
lsm_bt_node_free(*succ);
*succ = succ_replacement;
} else {
lsm_bt_node *replacement =
(*dest)->left != NULL ? (*dest)->left : (*dest)->right;
lsm_bt_node_free(*dest);
*dest = replacement;
}
return lsm_error_ok;
}

View file

@ -68,11 +68,13 @@ lsm_error lsm_bt_search(void **out, lsm_bt *bt, char key);
lsm_error lsm_bt_insert(lsm_bt *bt, char key, void *data);
/**
* Remove the given key from the binary tree.
* Remove the given key from the binary tree. Ownership of the data pointer is
* returned to the caller.
*
* @param out address to write data pointer to
* @param bt binary tree to remove from
* @param key key to remove
*/
lsm_error lsm_bt_remove(lsm_bt *bt, char key);
lsm_error lsm_bt_remove(void **out, lsm_bt *bt, char key);
#endif

View file

@ -6,7 +6,8 @@
/**
* Initialize a new lsm_store struct.
*
* @param lsm_store pointer to where to store the newly allocated object's pointer
* @param lsm_store pointer to where to store the newly allocated object's
* pointer
* @return success of the function
*/
lsm_error lsm_store_init(lsm_store **ptr) {

View file

@ -1,7 +1,7 @@
#include <stdlib.h>
#include "lsm_store_node.h"
#include "lsm.h"
#include "lsm_store_node.h"
lsm_error lsm_store_inode_init(lsm_store_inode **ptr, const char c) {
lsm_store_inode *node = calloc(1, sizeof(lsm_store_inode));
@ -28,7 +28,8 @@ lsm_error lsm_store_node_init(lsm_store_node **ptr) {
return lsm_error_ok;
}
lsm_error lsm_store_node_search(lsm_store_node **out_ptr, lsm_store_node *node, const char c) {
lsm_error lsm_store_node_search(lsm_store_node **out_ptr, lsm_store_node *node,
const char c) {
if (node->size == 0) {
return lsm_error_not_found;
}

View file

@ -37,6 +37,7 @@ lsm_error lsm_store_node_init(lsm_store_node **out);
/**
* Search for the next node following the given character, if present.
*/
lsm_error lsm_store_node_search(lsm_store_node **out, lsm_store_node *node, const char c);
lsm_error lsm_store_node_search(lsm_store_node **out, lsm_store_node *node,
const char c);
#endif