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 run_server = false;
|
||||
|
||||
bool core_test_target = false;
|
||||
bool core_test_target = true;
|
||||
bool win32_target = false;
|
||||
bool wasm_target = true;
|
||||
bool wasm_target = false;
|
||||
|
||||
if (execute_python_snippets) {
|
||||
sb8_t *sb = sb8_serial_begin(arena);
|
||||
@@ -75,13 +75,14 @@ int main(int argc, char **argv) {
|
||||
ok = os_systemf(
|
||||
"cl ../src/core/core_test_entry.c -Fe:core_test.exe -Fd:core_test.pdb"
|
||||
" -I ../src"
|
||||
" /Zi /FC /nologo /Oi /O2"
|
||||
" /Zi /FC /nologo /Oi"
|
||||
" /WX /W3 /wd4200 /diagnostics:column"
|
||||
" /link /incremental:no"
|
||||
);
|
||||
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;
|
||||
}
|
||||
@@ -45,3 +45,4 @@
|
||||
#include "core_lexer.c"
|
||||
#include "core_type_info.c"
|
||||
#include "core_random.c"
|
||||
#include "core_hash_table.c"
|
||||
@@ -96,6 +96,44 @@ void test_s8(void) {
|
||||
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>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
@@ -110,6 +148,7 @@ int main(int argc, char **argv) {
|
||||
printf("PLATFORM_TCC = %d\n", PLATFORM_TCC);
|
||||
|
||||
test_s8();
|
||||
test_hash_table();
|
||||
|
||||
printf("all done!\n");
|
||||
}
|
||||
Reference in New Issue
Block a user