start work on hash table
This commit is contained in:
parent
7602982c93
commit
a651082dcc
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
21
src/ds.c
21
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::
|
||||
|
||||
|
||||
|
||||
68
src/ds.h
68
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,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);
|
||||
|
||||
|
||||
@ -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__);
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user