From a651082dcc67647f78a269df5395d124a585befd Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 18 Apr 2025 21:06:13 +1000 Subject: [PATCH] start work on hash table --- src/allocators.c | 24 ++++++-- src/allocators.h | 10 ++-- src/ds.c | 21 ++++++- src/ds.h | 86 ++++++++++++++++++++-------- src/entry_linux.c | 46 +-------------- src/platform/platform.h | 1 + src/platform/platform_linux_public.c | 16 +++++- 7 files changed, 127 insertions(+), 77 deletions(-) diff --git a/src/allocators.c b/src/allocators.c index 9973c9b..12736a8 100644 --- a/src/allocators.c +++ b/src/allocators.c @@ -1,6 +1,7 @@ // ::Allocator::Globals:: -Allocator g_alloc; +FLAlloc FL_ALLOC = {0}; +Allocator ALLOC = {0}; read_only FLNode FL_NIL_NODE = {0}; // ::Allocator::Util::Header:: @@ -131,9 +132,9 @@ static void InitAllocator(usize init_size, usize grow_size) static void DeinitAlloc() { - for (u8 i = g_alloc.buf_len-1; i >= 0; i--) + for (u8 i = ALLOC.buf_len-1; i >= 0; i--) { - MemFree(g_alloc.buffers[i].buf, g_alloc.buffers[i].size); + MemFree(ALLOC.buffers[i].buf, ALLOC.buffers[i].size); } } @@ -149,7 +150,7 @@ static void Free(rawptr ptr) static void AllocGrow() { - u8 *mem = (u8 *)MemAllocZeroed(g_alloc.grow_size); + u8 *mem = (u8 *)MemAllocZeroed(ALLOC.grow_size); } @@ -160,6 +161,21 @@ static void AllocGrow() // ::Allocator::FreeList::Start:: +static void GlobalFreeListInit(usize size) +{ + FreeListInit(&FL_ALLOC, size); +} + +static rawptr FLMemAlloc(usize size) +{ + return FreeListAlloc(&FL_ALLOC, size); +} + +static void FLFree(rawptr ptr) +{ + FreeListFree(&FL_ALLOC, ptr); +} + static void FreeListInit(FLAlloc *alloc, usize size) { alloc->lists = MemAllocZeroed(sizeof(FreeList *) * 16); diff --git a/src/allocators.h b/src/allocators.h index 23d30bd..26fec24 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -62,12 +62,10 @@ typedef struct FLAllocHeader usize padding; } FLAllocHeader; -typedef struct FLNode FLNode; - typedef struct FLNode { - FLNode *next; - usize size; + struct FLNode *next; + usize size; } FLNode; typedef struct FreeList @@ -89,6 +87,9 @@ typedef struct FLAlloc usize grow_size; } FLAlloc; +static void GlobalFreeListInit(usize size); +static rawptr FLMemAlloc(usize size); +static void FLFree(rawptr ptr); static void _FreeListInit(FreeList **alloc, usize size); static void FreeListInit(FLAlloc *alloc, usize size); static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, u32 alignment); @@ -102,3 +103,4 @@ static FLNode *FreeListSearch(FreeList *alloc, usize size, usize alignment, usiz static void FreeListCoalescence(FreeList *alloc, FLNode *prev_node, FLNode *free_node); static void FreeListRemove(FLNode **head, FLNode *prev_node, FLNode *del_node); static void FreeListInsert(FLNode **head, FLNode *prev_node, FLNode *new_node); + diff --git a/src/ds.c b/src/ds.c index ae565d7..f29479e 100644 --- a/src/ds.c +++ b/src/ds.c @@ -326,4 +326,23 @@ static void RBTreeRightRotate(RBTree *tree, RBNode *node) node->parent = left; } -// ::DataStructures::RedBlackTree::Functions::Start:: +// ::DataStructures::RedBlackTree::Functions::End:: + + + +// ::DataStructures::HashTable::Functions::Start:: + +static void InitHashTable(HashTable *table, u32 init_size) +{ + table->elem_count = init_size; + table->lists = FLMemAlloc(sizeof(HashList) * init_size); +} + +static void HashTableClear(HashTable *table) +{ + +} + +// ::DataStructures::HashTable::Functions::End:: + + diff --git a/src/ds.h b/src/ds.h index 73bbad4..7cc27f5 100644 --- a/src/ds.h +++ b/src/ds.h @@ -1,6 +1,10 @@ #pragma once -// ::DataStructures::Types::Header:: +// ::DataStructures::Macros::Header:: + +#define NodeDir(node) (node == node->parent->left ? RB_LEFT : RB_RIGHT) + +// ::DataStructures::RedBlackTree::Header:: typedef enum RBNodeColor_e { @@ -14,22 +18,20 @@ typedef enum RBNodeDir_e RB_RIGHT, } RBNodeDir; -typedef struct RBNode RBNode; - typedef struct RBNode { - RBNode *parent; union { struct { - RBNode *left; - RBNode *right; + struct RBNode *left; + struct RBNode *right; }; - RBNode *child[2]; + struct RBNode *child[2]; }; - i32 value; - rawptr data; + struct RBNode *parent; + i32 value; + rawptr data; RBNodeColor color; } RBNode; @@ -39,18 +41,56 @@ typedef struct RBTree RBNode *nil; } RBTree; -// ::DataStructures::Macros::Header:: - -#define NodeDir(node) (node == node->parent->left ? RB_LEFT : RB_RIGHT) - -// ::DataStructures::RedBlackTree::Functions::Header:: - -static void CreateRBTree(RBTree *tree); -static void RBTreeInsert(RBTree *tree, RBNode *node); -static b32 RBTreeSearch(RBTree *tree, i32 value, RBNode **node); -static void RBTreeDelete(RBTree *tree, i32 value); -static void RBTreeLeftRotate(RBTree *tree, RBNode *node); +static void CreateRBTree (RBTree *tree); +static void RBTreeInsert (RBTree *tree, RBNode *node); +static b32 RBTreeSearch (RBTree *tree, i32 value, RBNode **node); +static void RBTreeDelete (RBTree *tree, i32 value); +static void RBTreeLeftRotate (RBTree *tree, RBNode *node); static void RBTreeRightRotate(RBTree *tree, RBNode *node); -static void RBTreeRotate(RBTree *tree, RBNode *node, RBNodeDir dir); -static void RBTreeCorrect(RBTree *tree, RBNode *node); -static inline void RBTreeTransplant(RBTree *tree, RBNode *node, RBNode *placed_node); +static void RBTreeRotate (RBTree *tree, RBNode *node, RBNodeDir dir); +static void RBTreeCorrect (RBTree *tree, RBNode *node); +static void RBTreeTransplant (RBTree *tree, RBNode *node, RBNode *placed_node); + +// ::DataStructures::HashTable::Functions::Header:: + +typedef struct KeyValuePair +{ + union + { + u64 key_u64; + }; + union + { + Str8 value_string; + rawptr value_rawptr; + u32 value_u32; + u64 value_u64; + }; +} KeyValuePair; + +typedef struct HashNode +{ + struct HashNode *next; + KeyValuePair v; +} HashNode; + +typedef struct HashList +{ + HashNode *first; + HashNode *last; +} HashList; + +typedef struct HashTable +{ + HashElement *lists; + u32 elem_count; +} HashTable; + +static void InitHashTable(HashTable *table, u32 init_size); +static void HashTableClear(HashTable *table); +static HashNode *HashTablePush(HashTable *table, u64 hash, KeyValuePair value); +static HashNode *HashTablePushU32(HashTable *table, u64 key, u32 value); +static HashNode *HashTablePushU64(HashTable *table, u64 key, u64 value); +static HashNode *HashTablePushStr8(HashTable *table, u64 key, Str8 value); +static HashNode *HashTablePushRawptr(HashTable *table, u64 key, rawptr value); + diff --git a/src/entry_linux.c b/src/entry_linux.c index 1d49c2a..b5b8485 100644 --- a/src/entry_linux.c +++ b/src/entry_linux.c @@ -39,56 +39,14 @@ void Traverse(RBTree *tree) int main(int argc, char **argv) { + GlobalFreeListInit(MB(32)); + #ifdef BUILD_TEST RunTests(); return 0; #endif - RBTree tree; - CreateRBTree(&tree); - RBNode node1 = { .value = 4 }; - RBNode node2 = { .value = 7 }; - RBNode node3 = { .value = 33 }; - RBNode node4 = { .value = 53 }; - RBNode node5 = { .value = 25 }; - RBNode node6 = { .value = 22 }; - RBNode node7 = { .value = 6 }; - RBNode node8 = { .value = 1 }; - - RBTreeInsert(&tree, &node1); - RBTreeInsert(&tree, &node2); - RBTreeInsert(&tree, &node3); - RBTreeInsert(&tree, &node4); - RBTreeInsert(&tree, &node5); - RBTreeInsert(&tree, &node6); - RBTreeInsert(&tree, &node7); - RBTreeInsert(&tree, &node8); - - RBNode *search_node = NULL; - Assert(RBTreeSearch(&tree, 25, &search_node), "Unable to find node"); - Assert(search_node->value == 25, "Node has an invalid value"); - - RBTreeDelete(&tree, 25); - - RBNode node9 = { .value = 57 }; - RBTreeInsert(&tree, &node9); - - RBTreeDelete(&tree, 22); - - RBNode node10 = { .value = 59 }; - RBNode node11 = { .value = 60 }; - RBNode node12 = { .value = 58 }; - - RBTreeInsert(&tree, &node10); - RBTreeInsert(&tree, &node11); - RBTreeInsert(&tree, &node12); - - RBTreeDelete(&tree, 59); - RBTreeDelete(&tree, 33); - - Traverse(&tree); - u8 *mem = (u8 *)MemAllocZeroed(MB(64)); Arena *arena = CreateArenaDebug(mem, MB(64), __LINE__); diff --git a/src/platform/platform.h b/src/platform/platform.h index 58d7fad..f94a01d 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -44,6 +44,7 @@ b32 LoadFn(const char *name, Library *lib, Function *out_fn); rawptr MemAlloc(usize size); rawptr MemAllocZeroed(usize size); +rawptr MemRealloc(rawptr ptr, usize old_size, usize new_size); void MemFree(rawptr ptr, usize size); usize GetPageSize(); diff --git a/src/platform/platform_linux_public.c b/src/platform/platform_linux_public.c index f728171..3d7a4b0 100644 --- a/src/platform/platform_linux_public.c +++ b/src/platform/platform_linux_public.c @@ -44,7 +44,7 @@ b32 LoadFn(const char *name, Library *lib, Function *out_fn) rawptr MemAlloc(usize size) { - void *addr = mmap( + rawptr addr = mmap( NULL, size, PROT_READ | PROT_WRITE, @@ -65,6 +65,20 @@ rawptr MemAllocZeroed(usize size) return ptr; } +rawptr MemRealloc(rawptr ptr, usize old_size, usize new_size) +{ + rawptr addr = mremap( + ptr, + old_size, + new_size, + MAP_ANON | MAP_PRIVATE + ); + + if (CheckSyscallErr(addr)) addr = NULL; + + return addr; +} + void MemFree(rawptr ptr, usize size) { Assert(munmap(ptr, size) == 0, "munmap failed");