init core hash table
This commit is contained in:
@@ -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
103
src/core/core_hash_table.c
Normal 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;
|
||||||
|
}
|
||||||
@@ -44,4 +44,5 @@
|
|||||||
#include "core_log.c"
|
#include "core_log.c"
|
||||||
#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"
|
||||||
@@ -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");
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user