Skip to content

Commit

Permalink
fix(btree): index collision (with description)
Browse files Browse the repository at this point in the history
add checking index collision when finding values
remove additional inserting operations on index collision situation
  • Loading branch information
aloima committed Dec 7, 2024
1 parent 09f5063 commit ffa301a
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 35 deletions.
2 changes: 1 addition & 1 deletion headers/btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void move_kv(struct BTreeNode *node, const uint32_t at, const uint32_t to);
uint32_t find_node_of_index(struct BTreeNode **result, struct BTreeNode *search, const uint64_t index);

struct BTreeValue *insert_value_to_btree(struct BTree *tree, const uint64_t index, void *data);
struct BTreeValue *find_value_from_btree(struct BTree *tree, const uint64_t index);
struct BTreeValue *find_value_from_btree(struct BTree *tree, const uint64_t index, void *arg, bool (*check)(void *value, void *arg));
bool delete_value_from_btree(struct BTree *tree, const uint64_t index, void (*free_value)(void *value));

void free_btree(struct BTree *tree, void (*free_value)(void *value));
1 change: 1 addition & 0 deletions headers/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ void save_data(const uint64_t server_age);
bool bg_save(uint64_t server_age);

void set_kv(struct KVPair *kv, const string_t key, void *value, const enum TellyTypes type);
bool check_correct_kv(struct KVPair *kv, char *key);
void free_kv(struct KVPair *kv);
/* /DATABASE */

Expand Down
1 change: 1 addition & 0 deletions src/btree/delete.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ static void delete_from_leaf(struct BTree *tree, struct BTreeNode *node, const u
}
}

// TODO: deleting correct values for collised indexes on inserting values to b-tree
bool delete_value_from_btree(struct BTree *tree, const uint64_t index, void (*free_value)(void *value)) {
struct BTreeNode *node;
const uint32_t target_at = find_node_of_index(&node, tree->root, index);
Expand Down
44 changes: 33 additions & 11 deletions src/btree/find.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,49 @@

#include <stdint.h>
#include <string.h>
#include <stdbool.h>

static struct BTreeValue *find_value_from_node(struct BTreeNode *node, const uint64_t index) {
static struct BTreeValue *find_value_from_node(struct BTreeNode *node, const uint64_t index, void *arg, bool (*check)(void *value, void *arg)) {
if (node->children) {
for (uint32_t i = 0; i < node->size; ++i) {
struct BTreeValue *value = node->data[i];
if (index < value->index) return find_value_from_node(node->children[i], index);
else if (index == value->index) return value;
if (check) {
for (uint32_t i = 0; i < node->size; ++i) {
struct BTreeValue *value = node->data[i];
if (index < value->index) return find_value_from_node(node->children[i], index, arg, check);
else if (index == value->index) {
if (check(value->data, arg)) return value;
else {
struct BTreeValue *left = find_value_from_node(node->children[i], index, arg, check);
if (left) return left;
}
}
}
} else {
for (uint32_t i = 0; i < node->size; ++i) {
struct BTreeValue *value = node->data[i];
if (index < value->index) return find_value_from_node(node->children[i], index, arg, check);
else if (index == value->index) return value;
}
}

return find_value_from_node(node->children[node->size], index);
return find_value_from_node(node->children[node->size], index, arg, check);
} else {
for (uint32_t i = 0; i < node->size; ++i) {
struct BTreeValue *value = node->data[i];
if (index == value->index) return value;
if (check) {
for (uint32_t i = 0; i < node->size; ++i) {
struct BTreeValue *value = node->data[i];
if (index == value->index && check(value->data, arg)) return value;
}
} else {
for (uint32_t i = 0; i < node->size; ++i) {
struct BTreeValue *value = node->data[i];
if (index == value->index) return value;
}
}
}

return NULL;
}

struct BTreeValue *find_value_from_btree(struct BTree *tree, const uint64_t index) {
if (tree->root) return find_value_from_node(tree->root, index);
struct BTreeValue *find_value_from_btree(struct BTree *tree, const uint64_t index, void *arg, bool (*check)(void *value, void *arg)) {
if (tree->root) return find_value_from_node(tree->root, index, arg, check);
else return NULL;
}
16 changes: 4 additions & 12 deletions src/btree/insert.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <stdint.h>
#include <stdlib.h>

// TODO: invalid inserting on multiple same value indexes
static struct BTreeValue *insert_value_to_node(struct BTree *tree, struct BTreeNode *node, struct BTreeValue *value, const uint32_t value_at) {
tree->size += 1;
node->size += 1;
Expand Down Expand Up @@ -186,17 +185,10 @@ struct BTreeValue *insert_value_to_btree(struct BTree *tree, uint64_t index, voi

return value;
} else {
while (true) {
struct BTreeNode *node;
const uint32_t value_at = find_node_of_index(&node, tree->root, index);

if (value_at < node->size && node->data[value_at]->index == index) {
index += 1;
continue;
} else {
return insert_value_to_node(tree, node, value, value_at);
}
}
struct BTreeNode *node;
const uint32_t value_at = find_node_of_index(&node, tree->root, index);

return insert_value_to_node(tree, node, value, value_at);
}

return NULL;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/kv/rename.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ static void run(struct Client *client, commanddata_t *command, struct Password *
const string_t search = command->args[0];
const uint64_t index = hash(search.value, search.len);

struct BTreeValue *value = find_value_from_btree(get_cache(), index);
struct BTreeValue *value = find_value_from_btree(get_cache(), index, (char *) search.value, (bool (*)(void *, void *)) check_correct_kv);

if (value) {
struct KVPair *kv = value->data;
Expand Down
13 changes: 3 additions & 10 deletions src/database/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,10 @@ struct BTree *get_cache() {

struct KVPair *get_kv_from_cache(const char *key, const size_t length) {
uint64_t index = hash((char *) key, length);
struct BTreeValue *value = find_value_from_btree(cache, index, (char *) key, (bool (*)(void *, void *)) check_correct_kv);

while (true) {
struct BTreeValue *value = find_value_from_btree(cache, index);

if (value) {
struct KVPair *kv = value->data;

if (strncmp(kv->key.value, key, length) == 0) return kv;
else index += 1;
} else return NULL;
}
if (value) return value->data;
else return NULL;
}

bool delete_kv_from_cache(const char *key, const size_t length) {
Expand Down
4 changes: 4 additions & 0 deletions src/database/kv.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ void free_kv(struct KVPair *kv) {
free(kv->key.value);
free(kv);
}

bool check_correct_kv(struct KVPair *kv, char *key) {
return streq(kv->key.value, key);
}

0 comments on commit ffa301a

Please sign in to comment.