start work on hash table

This commit is contained in:
Matthew 2025-04-18 21:06:13 +10:00
parent 7602982c93
commit a651082dcc
7 changed files with 127 additions and 77 deletions

View File

@ -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);

View File

@ -62,11 +62,9 @@ typedef struct FLAllocHeader
usize padding;
} FLAllocHeader;
typedef struct FLNode FLNode;
typedef struct FLNode
{
FLNode *next;
struct FLNode *next;
usize size;
} FLNode;
@ -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);

View File

@ -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::

View File

@ -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,20 +18,18 @@ 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];
};
struct RBNode *parent;
i32 value;
rawptr data;
RBNodeColor color;
@ -39,12 +41,6 @@ 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);
@ -53,4 +49,48 @@ 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 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);

View File

@ -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__);

View File

@ -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();

View File

@ -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");