diff --git a/include/bplus_tree.h b/include/bplus_tree.h index 7bb3e1d..9fea3a7 100644 --- a/include/bplus_tree.h +++ b/include/bplus_tree.h @@ -8,17 +8,30 @@ #include #include +#include -#include +#ifdef USE_GLIB + #include +#else + #include + #define g_assert assert + #define gboolean int + #define TRUE 1 + #define FALSE 0 + #define g_slice_new(type) (type*)malloc(sizeof(type)) + #define g_slice_free(type,ptr) free(ptr) + #define g_return_if_fail(expr) if(!(expr))return; + #define g_return_val_if_fail(expr,ret) if(!(expr))return(ret); +#endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +#define KeyFmt PRIu64 typedef uint64_t BplusKey; typedef void* BplusValue; -typedef struct _BplusItem BplusItem; struct _BplusItem { @@ -26,6 +39,7 @@ struct _BplusItem BplusValue value; }; +typedef struct _BplusItem BplusItem; typedef struct _BplusTree BplusTree; typedef struct _BplusIterator BplusIterator; @@ -56,6 +70,8 @@ BplusIterator* bplus_iterator_to_key(BplusTree const* tree, BplusKey const key BplusIterator* bplus_iterator_for_key(BplusTree const* tree, BplusKey const key); BplusIterator* bplus_iterator_for_key_range(BplusTree const* tree, BplusKey const key_from, BplusKey const key_to); +int bplus_tree_print(BplusTree const* const tree, char const* format, ...); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..38257e4 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,29 @@ +CC = gcc +CFLAGS = -I../include -g +AR = ar + +TARGET=bplus_tree + +all: lib$(TARGET).a + +bplus_tree.o: bplus_tree.c +bplus_node.o: bplus_node.c +bplus_leaf.o: bplus_leaf.c + +bplus_insert.o: bplus_insert.c +bplus_remove.o: bplus_remove.c +bplus_search.o: bplus_search.c +bplus_foreach.o: bplus_foreach.c + +bplus_iterator.o: bplus_iterator.c +bplus_rebalance.o: bplus_rebalance.c + + +lib$(TARGET).a: bplus_tree.o bplus_node.o bplus_leaf.o \ + bplus_insert.o bplus_remove.o bplus_search.o \ + bplus_foreach.o bplus_iterator.o bplus_rebalance.o + $(AR) -cq $@ $+ + +clean: + rm -rf *.o lib$(TARGET).a + diff --git a/src/bplus_foreach.c b/src/bplus_foreach.c index e9184b7..8c8860c 100644 --- a/src/bplus_foreach.c +++ b/src/bplus_foreach.c @@ -9,12 +9,13 @@ void bplus_foreach_item_in_node(BplusTree* tree, BplusNode* node, BplusForeachItemFunc* foreach, void* argument) { + size_t i; if (!node->is_leaf) - for (size_t i = 0; i < node->length; ++i) + for (i = 0; i < node->length; ++i) bplus_foreach_item_in_node(tree, bplus_node_at(node, i), foreach, argument); else - for (size_t i = 0; i < node->length; ++i) + for (i = 0; i < node->length; ++i) foreach(tree, node->items + i, argument); } @@ -26,8 +27,9 @@ void bplus_foreach_item_in_tree(BplusTree* tree, BplusForeachItemFunc* foreach, void bplus_foreach_node_in_node(BplusTree* tree, BplusNode* node, BplusForeachNodeFunc* foreach, void* argument) { + size_t i; if (!node->is_leaf) - for (size_t i = 0; i < node->length; ++i) + for (i = 0; i < node->length; ++i) bplus_foreach_node_in_node(tree, bplus_node_at(node, i), foreach, argument); foreach(tree, node, argument); diff --git a/src/bplus_insert.c b/src/bplus_insert.c index 9cd3ea7..541e0b6 100644 --- a/src/bplus_insert.c +++ b/src/bplus_insert.c @@ -33,7 +33,8 @@ void bplus_node_insert_at(BplusTree const* tree, BplusNode* node, size_t const i if (node->is_leaf) return; - for (size_t i = index; i < index + length; ++i) + size_t i; + for (i = index; i < index + length; ++i) bplus_node_at(node, i)->parent = node; } diff --git a/src/bplus_rebalance.c b/src/bplus_rebalance.c index a3cf401..3c3aca0 100644 --- a/src/bplus_rebalance.c +++ b/src/bplus_rebalance.c @@ -16,7 +16,8 @@ void bplus_rebalance_propagate(BplusTree const* tree, BplusPath* path) g_return_if_fail(path != NULL); BplusNode* node = path->leaf; - for (size_t i = 1; i < path->length; ++i) + size_t i; + for (i = 1; i < path->length; ++i) { size_t const index = path->index[i]; BplusKey const key = bplus_key_first(node); @@ -208,11 +209,21 @@ static int bplus_rebalance_try_merge(BplusTree* tree, BplusNode* node, size_t co void bplus_rebalance_overfilled(BplusTree* tree, BplusPath const* path) { + size_t i; g_return_if_fail(tree != NULL); g_return_if_fail(path != NULL); BplusNode* node = (BplusNode*) path->leaf; - for (size_t i = 1; i < path->length; ++i) + +#if 1 + #include + fprintf(stderr, "rebalance overfilled %zu\n", node->length); + for (i = 1; i < path->length; ++i) + fprintf(stderr, " %zu", path->index[i]); + fprintf(stderr, "\n"); +#endif + + for (i = 1; i < path->length; ++i) { if (!bplus_node_overfilled(node)) break; @@ -224,6 +235,7 @@ void bplus_rebalance_overfilled(BplusTree* tree, BplusPath const* path) node = node->parent; } + g_assert(node != NULL); if (bplus_node_overfilled(node)) { bplus_rebalance_new_root(tree); @@ -260,7 +272,8 @@ void bplus_rebalance_underfilled(BplusTree* tree, BplusPath const* path) g_return_if_fail(path != NULL); BplusNode* node = (BplusNode*) path->leaf; - for (size_t i = 1; i < path->length; ++i) + size_t i; + for (i = 1; i < path->length; ++i) { if (!bplus_node_underfilled(node)) break; diff --git a/src/bplus_search.c b/src/bplus_search.c index a1e7c3b..bcab2da 100644 --- a/src/bplus_search.c +++ b/src/bplus_search.c @@ -52,11 +52,12 @@ static size_t bplus_node_get_key_index_before(BplusTree const* tree, BplusNode c \ BplusNode const* node = (tree_m)->root; \ size_t const length = (tree_m)->height; \ - for (size_t i = length; i > 0; --i) \ + size_t i, j; \ + for (i = length; i > 0; --i) \ { \ - for (int i = 0; i < BPLUS_TREE_ORDER * sizeof(*node->items) / 64; ++i) \ + for (j = 0; j < BPLUS_TREE_ORDER * sizeof(*node->items) / 64; ++j) \ { \ - __builtin_prefetch(node->items + i * 64 / sizeof(*node->items)); \ + __builtin_prefetch(node->items + j * 64 / sizeof(*node->items)); \ } \ \ size_t const index = operator_m((tree_m), node, (key_m)); \ diff --git a/src/bplus_tree.c b/src/bplus_tree.c index fc8bb8e..dd314bd 100644 --- a/src/bplus_tree.c +++ b/src/bplus_tree.c @@ -116,73 +116,76 @@ BplusValue bplus_tree_get_nth(BplusTree const* tree, size_t position) return NULL; } -void bplus_value_print(BplusNode* node, size_t const index, BplusKey key, BplusValue value, int depth) +void bplus_leaf_print(BplusNode* node) { static char const* indent = " "; - fprintf(stderr, "%*.s n%p_%zu[label=\"%lu\",fontcolor=\"#000099\"];", 0, indent, node, index, key); - fprintf(stderr, "%*.s n%p->n%p_%zu;", 0, indent, node, node, index); + fprintf(stdout, "%*.s n%p_vals[label=\"", 0, indent, node); + size_t i; + for(i = 0; i < node->length; ++i) + fprintf(stdout, "%" KeyFmt "\\n", bplus_key_at(node, i)); + fprintf(stdout, "\",fontcolor=\"#000099\"];\n"); + fprintf(stdout, "%*.s n%p->n%p_vals;\n", 0, indent, node, node); } -void bplus_node_print(BplusNode* parent, BplusKey key, BplusNode* node, int depth) +void bplus_node_print(BplusNode* parent, BplusKey key, BplusNode* node) { static char const* indent = " "; - fprintf(stderr, "%*.s n%p[label=\"%lu\"];", 0, indent, node, key); - fprintf(stderr, "%*.s n%p->n%p;", 0, indent, parent, node); + fprintf(stdout, "%*.s n%p[label=\"%" KeyFmt "\"];// node\n", 0, indent, node, key); + fprintf(stdout, "%*.s n%p->n%p;\n", 0, indent, parent, node); if (node->is_leaf) { if (((BplusLeaf*) node)->right != NULL) - fprintf(stderr, "n%p->n%p[constraint=false];", node, ((BplusLeaf*) node)->right); + fprintf(stdout, "n%p->n%p[constraint=false];// right\n", node, ((BplusLeaf*) node)->right); if (((BplusLeaf*) node)->left != NULL) - fprintf(stderr, "n%p->n%p[constraint=false];", node, ((BplusLeaf*) node)->left); + fprintf(stdout, "n%p->n%p[constraint=false];// left\n", node, ((BplusLeaf*) node)->left); } - for (size_t i = 0; i < node->length; ++i) - { - if (node->is_leaf) - bplus_value_print(node, i, bplus_key_at(node, i), bplus_value_at(node, i), 2); - else - bplus_node_print(node, bplus_key_at(node, i), bplus_node_at(node, i), depth + 2); - - } + size_t i; + if (node->is_leaf) + bplus_leaf_print(node); + else + for (i = 0; i < node->length; ++i) + bplus_node_print(node, bplus_key_at(node, i), bplus_node_at(node, i)); } int bplus_tree_print(BplusTree const* const tree, char const* format, ...) { static int count = 0; - fprintf(stderr, "echo 'digraph {"); - fprintf(stderr, "graph[ordering=\"out\"];\n"); - fprintf(stderr, "node[width=0.2,height=0.2,fixedsize=true,fontsize=6,fontcolor=\"#990000\",shape=plaintext];"); - fprintf(stderr, "edge[arrowsize=0.1,fontsize=6];"); + fprintf(stdout, "digraph {\n"); + fprintf(stdout, "graph[ordering=\"out\"];\n"); + fprintf(stdout, "node[fontcolor=\"#990000\",shape=plaintext];\n"); + fprintf(stdout, "edge[arrowsize=0.6,fontsize=6];\n"); BplusNode* node = tree->root; - fprintf(stderr, "n%p[label=\"0\"];", node); + fprintf(stdout, "n%p[label=\"root\"];\n", node); if (node->is_leaf) { if (((BplusLeaf*) node)->right != NULL) - fprintf(stderr, "n%p->n%p[constraint=false];", node, ((BplusLeaf*) node)->right); + fprintf(stdout, "n%p->n%p[constraint=false];\n", node, ((BplusLeaf*) node)->right); if (((BplusLeaf*) node)->left != NULL) - fprintf(stderr, "n%p->n%p[constraint=false];", node, ((BplusLeaf*) node)->left); + fprintf(stdout, "n%p->n%p[constraint=false];\n", node, ((BplusLeaf*) node)->left); } - for (size_t i = 0; i < node->length; ++i) + size_t i; + if (node->is_leaf) + bplus_leaf_print(node); + else { - if (node->is_leaf) - bplus_value_print(node, i, bplus_key_at(node, i), bplus_value_at(node, i), 2); - else - bplus_node_print(node, bplus_key_at(node, i), bplus_node_at(node, i), 2); - + for (i = 0; i < node->length; ++i) + bplus_node_print(node, bplus_key_at(node, i), bplus_node_at(node, i)); } va_list vargs; va_start(vargs, format); - vfprintf(stderr, format, vargs); + vfprintf(stdout, format, vargs); va_end(vargs); - fprintf(stderr, "}'| dot -T png -o tree-%d.png\n", count); + fprintf(stdout, "}\n"); + fprintf(stderr, "dot -T png -o tree-%d.png\n", count); count++; return 0; } diff --git a/src/bplus_tree_private.h b/src/bplus_tree_private.h index 97b873f..384d019 100644 --- a/src/bplus_tree_private.h +++ b/src/bplus_tree_private.h @@ -14,7 +14,7 @@ extern "C" #endif // ifdef __cplusplus #ifndef BPLUS_TREE_ORDER -# define BPLUS_TREE_ORDER 32 +# define BPLUS_TREE_ORDER 16 #endif /* ifndef BPLUS_TREE_ORDER */ typedef struct _BplusNode BplusNode; diff --git a/test_mine/Makefile b/test_mine/Makefile new file mode 100644 index 0000000..c187370 --- /dev/null +++ b/test_mine/Makefile @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -I../include -I../src -g +LIBS = ../src/libbplus_tree.a + +all: test1 + +test1.o: test1.c + +test1: test1.o + $(CC) $+ $(LIBS) -o $@ + +clean: + rm -rf *.o test1 + diff --git a/test_mine/test1.c b/test_mine/test1.c new file mode 100644 index 0000000..5189b7a --- /dev/null +++ b/test_mine/test1.c @@ -0,0 +1,20 @@ +#include "bplus_tree.h" +#include "bplus_tree_private.h" + +#define __NUM__ (BPLUS_TREE_ORDER) + +int main() +{ + BplusTree *tree; + tree = bplus_tree_new(); + + size_t i; + for(i = 0; i < __NUM__; ++i) + { + bplus_tree_insert(tree, i, NULL); + } + + bplus_tree_print(tree, ""); + bplus_tree_destroy(tree); + return 0; +}