diff --git a/headers/btree.h b/headers/btree.h index 447ae63..ad140da 100644 --- a/headers/btree.h +++ b/headers/btree.h @@ -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)); diff --git a/headers/database.h b/headers/database.h index e596b61..31951e0 100644 --- a/headers/database.h +++ b/headers/database.h @@ -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 */ diff --git a/src/btree/delete.c b/src/btree/delete.c index ee7ee26..c5a0958 100644 --- a/src/btree/delete.c +++ b/src/btree/delete.c @@ -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); diff --git a/src/btree/find.c b/src/btree/find.c index 777b56a..139500a 100644 --- a/src/btree/find.c +++ b/src/btree/find.c @@ -2,27 +2,49 @@ #include #include +#include -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; } diff --git a/src/btree/insert.c b/src/btree/insert.c index b409e19..3002a45 100644 --- a/src/btree/insert.c +++ b/src/btree/insert.c @@ -6,7 +6,6 @@ #include #include -// 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; @@ -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; diff --git a/src/commands/kv/rename.c b/src/commands/kv/rename.c index 862600a..fd235ff 100644 --- a/src/commands/kv/rename.c +++ b/src/commands/kv/rename.c @@ -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; diff --git a/src/database/cache.c b/src/database/cache.c index bbd0968..39af0fc 100644 --- a/src/database/cache.c +++ b/src/database/cache.c @@ -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) { diff --git a/src/database/kv.c b/src/database/kv.c index da3b263..97bbedc 100644 --- a/src/database/kv.c +++ b/src/database/kv.c @@ -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); +}