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