init core hash table

This commit is contained in:
Krzosa Karol
2025-01-06 12:59:29 +01:00
parent a059eec8ea
commit 2e2b3ceafb
4 changed files with 149 additions and 5 deletions

View File

@@ -27,9 +27,9 @@ int main(int argc, char **argv) {
bool execute_python_snippets = true; // make sure to not abuse just for quick maths bool execute_python_snippets = true; // make sure to not abuse just for quick maths
bool run_server = false; bool run_server = false;
bool core_test_target = false; bool core_test_target = true;
bool win32_target = false; bool win32_target = false;
bool wasm_target = true; bool wasm_target = false;
if (execute_python_snippets) { if (execute_python_snippets) {
sb8_t *sb = sb8_serial_begin(arena); sb8_t *sb = sb8_serial_begin(arena);
@@ -75,13 +75,14 @@ int main(int argc, char **argv) {
ok = os_systemf( ok = os_systemf(
"cl ../src/core/core_test_entry.c -Fe:core_test.exe -Fd:core_test.pdb" "cl ../src/core/core_test_entry.c -Fe:core_test.exe -Fd:core_test.pdb"
" -I ../src" " -I ../src"
" /Zi /FC /nologo /Oi /O2" " /Zi /FC /nologo /Oi"
" /WX /W3 /wd4200 /diagnostics:column" " /WX /W3 /wd4200 /diagnostics:column"
" /link /incremental:no" " /link /incremental:no"
); );
if (ok != 0) return ok; if (ok != 0) return ok;
os_systemf("core_test.exe"); ok = os_systemf("core_test.exe");
return ok;
} }

103
src/core/core_hash_table.c Normal file
View File

@@ -0,0 +1,103 @@
typedef struct ht_key_value_t ht_key_value_t;
struct ht_key_value_t {
union {
s8_t key_string;
u64 key_u64;
void *key_ptr;
};
union {
s8_t value_string;
void *value_ptr;
u64 value_u64;
};
};
typedef struct ht_node_t ht_node_t;
struct ht_node_t {
ht_node_t *next;
ht_key_value_t kv;
};
typedef struct ht_bucket_t ht_bucket_t;
struct ht_bucket_t {
ht_node_t *first;
ht_node_t *last;
};
typedef struct ht_dict_t ht_dict_t;
struct ht_dict_t {
ma_arena_t *arena;
i32 item_count;
i32 bucket_count;
ht_bucket_t *buckets;
};
u64 ht_hash(s8_t string) {
u8 *data = string.str;
uint64_t hash = (u64)14695981039346656037ULL;
for (i64 i = 0; i < string.len; i++) {
hash = hash ^ (u64)(data[i]);
hash = hash * (u64)1099511628211ULL;
}
return hash;
}
ht_dict_t *ht_create(ma_arena_t *arena, i32 size) {
ht_dict_t *result = ma_push_type(arena, ht_dict_t);
result->buckets = ma_push_array(arena, ht_bucket_t, size);
result->bucket_count = size;
result->arena = arena;
return result;
}
ht_node_t *ht_insert_kv(ht_dict_t *ht, u64 hash, ht_key_value_t kv) {
ht_node_t *result = ma_push_type(ht->arena, ht_node_t);
result->kv = kv;
i64 idx = hash % ht->bucket_count;
SLLQ_APPEND(ht->buckets[idx].first, ht->buckets[idx].last, result);
ht->item_count += 1;
return result;
}
ht_node_t *ht_insert_u64_u64(ht_dict_t *ht, u64 key, u64 value) {
u64 hash = ht_hash(s8((char *)&key, sizeof(key)));
return ht_insert_kv(ht, hash, (ht_key_value_t){.key_u64 = key, .value_u64 = value});
}
ht_node_t *ht_insert_ptr(ht_dict_t *ht, void *key, void *value) {
return ht_insert_u64_u64(ht, (u64)key, (u64)value);
}
ht_node_t *ht_insert_string(ht_dict_t *ht, s8_t key, s8_t value) {
u64 hash = ht_hash(key);
return ht_insert_kv(ht, hash, (ht_key_value_t){.key_string = key, .value_string = value});
}
ht_node_t *ht_search_u64(ht_dict_t *ht, u64 key) {
u64 hash = ht_hash(s8((char *)&key, sizeof(key)));
i64 idx = hash % ht->bucket_count;
ht_bucket_t *bucket = ht->buckets + idx;
for (ht_node_t *it = bucket->first; it; it = it->next) {
if (it->kv.key_u64 == key) {
return it;
}
}
return NULL;
}
ht_node_t *ht_search_ptr(ht_dict_t *ht, void *key_ptr) {
return ht_search_u64(ht, (u64)key_ptr);
}
ht_node_t *ht_search_string(ht_dict_t *ht, s8_t key) {
u64 hash = ht_hash(key);
i64 idx = hash % ht->bucket_count;
ht_bucket_t *bucket = ht->buckets + idx;
for (ht_node_t *it = bucket->first; it; it = it->next) {
if (s8_equal(it->kv.key_string, key)) {
return it;
}
}
return NULL;
}

View File

@@ -45,3 +45,4 @@
#include "core_lexer.c" #include "core_lexer.c"
#include "core_type_info.c" #include "core_type_info.c"
#include "core_random.c" #include "core_random.c"
#include "core_hash_table.c"

View File

@@ -96,6 +96,44 @@ void test_s8(void) {
ma_destroy(arena); ma_destroy(arena);
} }
void test_hash_table(void) {
ma_temp_t scratch = ma_begin_scratch();
{
ht_dict_t *ht = ht_create(scratch.arena, 16);
for (u64 i = 0; i < 128; i += 1) {
ht_insert_u64_u64(ht, i, i);
ht_node_t *node = ht_search_u64(ht, i);
assert(node->kv.value_u64 == i);
assert(node->kv.key_u64 == i);
}
for (u64 i = 0; i < 128; i += 1) {
ht_node_t *node = ht_search_u64(ht, i);
assert(node->kv.value_u64 == i);
assert(node->kv.key_u64 == i);
}
ht_node_t *node = ht_search_u64(ht, 1111);
assert(node == NULL);
}
{
ht_dict_t *ht = ht_create(scratch.arena, 16);
for (i32 i = 0; i < 128; i += 1) {
s8_t s = s8_printf(scratch.arena, "%d", i);
ht_insert_string(ht, s, s);
ht_node_t *node = ht_search_string(ht, s);
assert(s8_equal(node->kv.value_string, s));
assert(s8_equal(node->kv.key_string, s));
}
ht_node_t *node = ht_search_string(ht, s8_lit("memes"));
assert(node == NULL);
}
ma_end_scratch(scratch);
}
#include <stdio.h> #include <stdio.h>
int main(int argc, char **argv) { int main(int argc, char **argv) {
@@ -110,6 +148,7 @@ int main(int argc, char **argv) {
printf("PLATFORM_TCC = %d\n", PLATFORM_TCC); printf("PLATFORM_TCC = %d\n", PLATFORM_TCC);
test_s8(); test_s8();
test_hash_table();
printf("all done!\n"); printf("all done!\n");
} }