diff options
| author | nasr <nsrddyn@gmail.com> | 2026-03-16 19:20:23 +0000 |
|---|---|---|
| committer | nasr <nsrddyn@gmail.com> | 2026-03-16 19:20:23 +0000 |
| commit | 180ccc84aac07c7bee2b09a6e07f7406908409b9 (patch) | |
| tree | efa39665e41c3132626f2c08b2f3ae0d18adc17a /source/b_tree.h | |
| parent | 2e258673171c2e4663a8b5d58e2ad174bb0ecd96 (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.h')
| -rw-r--r-- | source/b_tree.h | 124 |
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 | |||
| 9 | typedef struct b_tree_node b_tree_node; | ||
| 10 | struct 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 | |||
| 32 | typedef struct b_tree b_tree; | ||
| 33 | struct 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 | |||
| 46 | internal b_tree_node * | ||
| 47 | btree_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 | ||
| 55 | internal s32 | ||
| 56 | btree_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 | |||
| 63 | internal void | ||
| 64 | b_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 | ||
| 72 | internal void * | ||
| 73 | b_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) | ||
| 89 | internal void | ||
| 90 | b_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 | |||
| 117 | internal void | ||
| 118 | b_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 */ | ||
