feat(lsm): binary tree iterators

This commit is contained in:
Jef Roosens 2023-12-22 22:07:09 +01:00
parent 8c2a7a640d
commit 5564e23ceb
Signed by: Jef Roosens
GPG key ID: B75D4F293C7052DB
5 changed files with 130 additions and 5 deletions

View file

@ -9,12 +9,13 @@
/**
* Node inside a binary tree
*/
typedef struct lsm_bt_node {
struct lsm_bt_node {
struct lsm_bt_node *left;
struct lsm_bt_node *right;
struct lsm_bt_node *parent;
void *data;
char key;
} lsm_bt_node;
};
/**
* Initialize a new binary tree node

View file

@ -1,5 +1,6 @@
#include <stdlib.h>
#include "lsm/bt.h"
#include "lsm/bt_internal.h"
lsm_error lsm_bt_node_init(lsm_bt_node **ptr, const char key, void *data) {
@ -60,10 +61,12 @@ void lsm_bt_free(lsm_bt *bt) {
uint64_t lsm_bt_size(const lsm_bt *bt) { return bt->size; }
lsm_error lsm_bt_insert(lsm_bt *bt, char key, void *data) {
lsm_bt_node *parent = NULL;
lsm_bt_node **dest = &bt->root;
// Traverse down the tree until we reach the new point to insert our node
while ((*dest != NULL) && ((*dest)->key != key)) {
parent = *dest;
dest = key < (*dest)->key ? &(*dest)->left : &(*dest)->right;
}
@ -71,9 +74,8 @@ lsm_error lsm_bt_insert(lsm_bt *bt, char key, void *data) {
return lsm_error_already_present;
}
if (lsm_bt_node_init(dest, key, data) != lsm_error_ok) {
return lsm_error_failed_alloc;
}
LSM_RES(lsm_bt_node_init(dest, key, data));
(*dest)->parent = parent;
bt->size++;
@ -125,13 +127,27 @@ lsm_error lsm_bt_remove(void **out, lsm_bt *bt, char key) {
(*dest)->data = (*succ)->data;
lsm_bt_node *succ_replacement = (*succ)->right;
lsm_bt_node *parent = (*succ)->parent;
lsm_bt_node_free(*succ);
*succ = succ_replacement;
if (*succ != NULL) {
(*succ)->parent = parent;
}
} else {
lsm_bt_node *replacement =
(*dest)->left != NULL ? (*dest)->left : (*dest)->right;
lsm_bt_node *parent = (*dest)->parent;
lsm_bt_node_free(*dest);
*dest = replacement;
if (*dest != NULL) {
(*dest)->parent = parent;
}
}
return lsm_error_ok;
@ -156,3 +172,45 @@ lsm_error lsm_bt_replace(void **out, lsm_bt *bt, char key, void *data) {
return lsm_error_ok;
}
void lsm_bt_iter(lsm_bt_iterator *out, const lsm_bt *bt) {
out->next = bt->root;
if (bt->root != NULL) {
// Initialize the iterator to the smallest element in the tree
while (out->next->left != NULL) {
out->next = out->next->left;
}
}
}
bool lsm_bt_iter_next(const void **out, char *key_out, lsm_bt_iterator *iter) {
if (iter->next == NULL) {
return false;
}
if (out != NULL) {
*out = iter->next->data;
}
if (key_out != NULL) {
*key_out = iter->next->key;
}
if (iter->next->right != NULL) {
iter->next = iter->next->right;
while (iter->next->left != NULL) {
iter->next = iter->next->left;
}
} else {
while ((iter->next->parent != NULL) &&
(iter->next->parent->right == iter->next)) {
iter->next = iter->next->parent;
}
iter->next = iter->next->parent;
}
return true;
}