summaryrefslogtreecommitdiff
path: root/source/b_tree_impl.h
diff options
context:
space:
mode:
authornasr <nsrddyn@gmail.com>2026-03-16 19:20:23 +0000
committernasr <nsrddyn@gmail.com>2026-03-16 19:20:23 +0000
commit180ccc84aac07c7bee2b09a6e07f7406908409b9 (patch)
treeefa39665e41c3132626f2c08b2f3ae0d18adc17a /source/b_tree_impl.h
parent2e258673171c2e4663a8b5d58e2ad174bb0ecd96 (diff)
feature(main): lots of stuff see description
1. increased compile time warnings to help with some optimizations. 2. impelmeented csv lexing helper functions that do stuff on tokenlists like appending and concatenating lists with each other 3. realiszed that btree design in faulty so disabled it and will refactor it in the next approach
Diffstat (limited to 'source/b_tree_impl.h')
-rw-r--r--source/b_tree_impl.h165
1 files changed, 165 insertions, 0 deletions
diff --git a/source/b_tree_impl.h b/source/b_tree_impl.h
new file mode 100644
index 0000000..8eb0723
--- /dev/null
+++ b/source/b_tree_impl.h
@@ -0,0 +1,165 @@
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#if 0
8global_variable read_only s16 B_TREE_ORDER = 4;
9#endif
10#define B_TREE_ORDER 4
11
12//- NOTE(nasr): defining a key to improve sorting
13// i think saying that a key is a combination of the column + row is a good way of appraoching this
14typedef struct key key;
15struct key
16{
17 string8 header;
18 s32 row;
19};
20
21typedef struct b_tree_node b_tree_node;
22struct b_tree_node
23{
24 // store the key values of the sub nodes? if they are leaves?
25 key keys[B_TREE_ORDER - 1];
26 // TODO(nasr): replace with something more generic?
27 // NOTE(nasr): cons of void * -> no type safety
28 // is there a way to still have some sort of that?
29 // size not variable
30 void *payload_per_key[B_TREE_ORDER - 1];
31 b_tree_node *parent;
32 // handle to store children faster than linked list
33 // because now we can iterate over the nodes instead of having cache misses
34 // when jumping through linked nodes
35 b_tree_node *children[B_TREE_ORDER];
36 // this shouldn't change things but could be a performance improvement on a bigger scale??
37 s32 *max_children;
38 // NOTE(nasr): reference count ::: check how many leaves are using this node
39 // also not needed for now because we don't free individual node because of arena allocator
40 // s32 *refc;
41 s32 key_count;
42 b32 leaf;
43
44
45 // NOTE(nasr): do we hold the reference to the arena? or do we pass is it as a reference?
46 // this could solve memory location issues?
47};
48
49typedef struct b_tree b_tree;
50struct b_tree
51{
52 // NOTE(nasr): make sure this always stays in memory
53 // so that initial fetch never requires a disk read
54 b_tree_node *root;
55};
56
57#ifdef B_TREE_IMPLEMENTATION
58///////////////////////////////////////////////////////////////////////////////
59//- b_tree.c
60
61// TODO(nasr): 1. splitting the tree when getting too big? (horizontally) 2. joining trees?
62
63internal b_tree_node *
64btree_node_alloc(mem_arena *arena)
65{
66 b_tree_node *node = PushStructZero(arena, b_tree_node);
67 node->leaf = 1;
68 return node;
69}
70
71// NOTE(nasr): @return the index of the found element
72internal s32
73btree_node_find_pos(string8 value, b_tree_node *node)
74{
75 unused(value);
76 unused(node);
77
78#if 0
79 s32 i = 0;
80 for (; i < node->key_count && string8_cmp(node->keys[i], value) < 0; ++i);
81 return i;
82#endif
83
84 return 0;
85
86}
87
88internal void
89b_tree_create(mem_arena *arena, b_tree *tree)
90{
91 tree->root = btree_node_alloc(arena);
92 tree->root->leaf = 1;
93 tree->root->key_count = 0;
94}
95
96
97// NOTE(nasr): nodes that get passed as parameters should've already been loaded into memory
98internal void *
99b_tree_search(b_tree_node *node, string8 key)
100{
101 unused(node);
102 unused(key);
103
104#if 0
105 s32 i = btree_node_find_pos(key, node);
106
107 if (i < node->key_count && string8_cmp(node->keys[i], key) == 0)
108 {
109 return node->payload_per_key[i];
110 }
111 if (node->leaf)
112 {
113 return NULL;
114 }
115 return b_tree_search(node->children[i], key);
116#endif
117
118 return NULL;
119}
120
121
122// TODO(nasr): split node when key_count == B_TREE_ORDER - 1 (node is full)
123internal void
124b_tree_insert(b_tree *tree, string8 key, void *payload)
125{
126 unused(tree);
127 unused(key);
128 unused(payload);
129#if 0
130 b_tree_node *current_node = tree->root;
131
132 if (current_node->leaf)
133 {
134 // find the insertion position and shift keys right to make room
135 s32 i = btree_node_find_pos(key, current_node);
136 for (s32 j = current_node->key_count; j > i; --j)
137 {
138 current_node->keys[j] = current_node->keys[j - 1];
139 current_node->payload_per_key[j] = current_node->payload_per_key[j - 1];
140 }
141 current_node->keys[i] = key;
142 current_node->payload_per_key[i] = payload;
143
144 if(current_node->key_count < (B_TREE_ORDER - 1))
145 {
146 current_node->key_count += 1;
147 }
148 else {
149 // TODO(nasr): creating a new branch / tree?
150 // make a seperate function for this
151 }
152 }
153 // TODO(nasr): internal node case walk down then split on the way back up
154#endif
155}
156
157internal void
158b_tree_write(b_tree *bt)
159{
160 // TODO(nasr): write the b_tree to disk
161 unused(bt);
162}
163
164#endif /* B_TREE_IMPLEMENTATION */
165#endif /* B_TREE_H */