Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions include/bplus_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,38 @@

#include <stdint.h>
#include <stdlib.h>
#include <inttypes.h>

#include <glib.h>
#ifdef USE_GLIB
#include <glib.h>
#else
#include <assert.h>
#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
{
BplusKey key;
BplusValue value;
};

typedef struct _BplusItem BplusItem;
typedef struct _BplusTree BplusTree;
typedef struct _BplusIterator BplusIterator;

Expand Down Expand Up @@ -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 */
Expand Down
29 changes: 29 additions & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
@@ -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

8 changes: 5 additions & 3 deletions src/bplus_foreach.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

}
Expand All @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/bplus_insert.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
19 changes: 16 additions & 3 deletions src/bplus_rebalance.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 <stdio.h>
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;
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions src/bplus_search.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)); \
Expand Down
65 changes: 34 additions & 31 deletions src/bplus_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion src/bplus_tree_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions test_mine/Makefile
Original file line number Diff line number Diff line change
@@ -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

20 changes: 20 additions & 0 deletions test_mine/test1.c
Original file line number Diff line number Diff line change
@@ -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;
}