summaryrefslogtreecommitdiff
path: root/source/b_tree.h
diff options
context:
space:
mode:
Diffstat (limited to 'source/b_tree.h')
-rw-r--r--source/b_tree.h124
1 files changed, 0 insertions, 124 deletions
diff --git a/source/b_tree.h b/source/b_tree.h
deleted file mode 100644
index 0c4b1e1..0000000
--- a/source/b_tree.h
+++ /dev/null
@@ -1,124 +0,0 @@
1/* single header b-tree implementation by Abdellah El Morabit */
2#ifndef B_TREE_H
3#define B_TREE_H
4
5// maximum height of the tree the lower the lower the lower amount
6// of disk reads which translates into faster?
7#define B_TREE_ORDER 4
8
9typedef struct b_tree_node b_tree_node;
10struct b_tree_node
11{
12 // store the values
13 string8 keys[B_TREE_ORDER - 1];
14 // TODO(nasr): replace with something more generic?
15 // NOTE(nasr): cons of void * -> no type safety
16 // is there a way to still have some sort of that?
17 void *payload_per_key[B_TREE_ORDER - 1];
18 b_tree_node *parent;
19 // handle to store children faster than linked list
20 // because now we can iterate over the nodes instead of having cache misses
21 // when jumping through linked nodes
22 b_tree_node *children[B_TREE_ORDER];
23 // this shouldn't change things but could be a performance improvement on a bigger scale??
24 s32 *max_children;
25 // NOTE(nasr): reference count ::: check how many leaves are using this node
26 // also not needed for now because we don't free individual node because of arena allocator
27 // s32 *refc;
28 s32 key_count;
29 b32 leaf;
30};
31
32typedef struct b_tree b_tree;
33struct b_tree
34{
35 // NOTE(nasr): make sure this always stays in memory
36 // so that initial fetch never requires a disk read
37 b_tree_node *root;
38};
39
40#ifdef B_TREE_IMPLEMENTATION
41///////////////////////////////////////////////////////////////////////////////
42//- b_tree.c
43
44// TODO(nasr): 1. splitting the tree when getting too big? (horizontally) 2. joining trees?
45
46internal b_tree_node *
47btree_node_alloc(mem_arena *arena)
48{
49 b_tree_node *node = PushStructZero(arena, b_tree_node);
50 node->leaf = 1;
51 return node;
52}
53
54// NOTE(nasr): @return the index of the found element
55internal s32
56btree_node_find_pos(string8 value, b_tree_node *node)
57{
58 s32 i = 0;
59 for (; i < node->key_count && string8_cmp(node->keys[i], value) < 0; ++i);
60 return i;
61}
62
63internal void
64b_tree_create(mem_arena *arena, b_tree *tree)
65{
66 tree->root = btree_node_alloc(arena);
67 tree->root->leaf = 1;
68 tree->root->key_count = 0;
69}
70
71// NOTE(nasr): nodes that get passed as parameters should've already been loaded into memory
72internal void *
73b_tree_search(b_tree_node *node, string8 key)
74{
75 s32 i = btree_node_find_pos(key, node);
76
77 if (i < node->key_count && string8_cmp(node->keys[i], key) == 0)
78 {
79 return node->payload_per_key[i];
80 }
81 if (node->leaf)
82 {
83 return NULL;
84 }
85 return b_tree_search(node->children[i], key);
86}
87
88// TODO(nasr): split node when key_count == B_TREE_ORDER - 1 (node is full)
89internal void
90b_tree_insert(mem_arena *arena, b_tree *tree, string8 key, void *payload)
91{
92 b_tree_node *current_node = tree->root;
93
94 if (current_node->leaf)
95 {
96 // find the insertion position and shift keys right to make room
97 s32 i = btree_node_find_pos(key, current_node);
98 for (s32 j = current_node->key_count; j > i; --j)
99 {
100 current_node->keys[j] = current_node->keys[j - 1];
101 current_node->payload_per_key[j] = current_node->payload_per_key[j - 1];
102 }
103 current_node->keys[i] = key;
104 current_node->payload_per_key[i] = payload;
105
106 if(current_node->key_count < (B_TREE_ORDER - 1))
107 {
108 current_node->key_count += 1;
109 }
110 else {
111 // TODO(nasr): creating a new branch / tree?
112 }
113 }
114 // TODO(nasr): internal node case walk down then split on the way back up
115}
116
117internal void
118b_tree_write(b_tree *bt)
119{
120 // TODO(nasr): write the b_tree to disk
121}
122
123#endif /* B_TREE_IMPLEMENTATION */
124#endif /* B_TREE_H */