From f863f847dcf8c1c1891d704f274f19cdd77095b6 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Mon, 20 Jan 2025 10:24:03 +0100 Subject: [PATCH] revisit hash_table, add interning --- src/core/core_ctx.h | 2 + src/core/core_hash_table.c | 113 ++++++++++++++++++++++--------------- src/core/core_inc.h | 1 + src/core/core_test_entry.c | 30 +++++++--- src/meta/cgen.c | 2 +- src/ui/ui.c | 24 +------- todo.txt | 5 +- 7 files changed, 95 insertions(+), 82 deletions(-) diff --git a/src/core/core_ctx.h b/src/core/core_ctx.h index 257a2ad..edb55d2 100644 --- a/src/core/core_ctx.h +++ b/src/core/core_ctx.h @@ -16,6 +16,8 @@ struct thread_ctx_t { gb_thread thread_ctx_t tcx = { .log = { .break_on_fatal = true, + .break_on_error = true, + .break_on_warning = true, .log_proc = default_log_proc, } }; diff --git a/src/core/core_hash_table.c b/src/core/core_hash_table.c index f264bf5..42604c8 100644 --- a/src/core/core_hash_table.c +++ b/src/core/core_hash_table.c @@ -1,47 +1,12 @@ - -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; -}; - -ht_dict_t *ht_create(ma_arena_t *arena, i32 size) { - ht_dict_t *result = ma_push_type(arena, ht_dict_t); +fn ht_t *ht_create(ma_arena_t *arena, i32 size) { + ht_t *result = ma_push_type(arena, ht_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) { +fn ht_node_t *ht_insert_kv(ht_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; @@ -50,21 +15,26 @@ ht_node_t *ht_insert_kv(ht_dict_t *ht, u64 hash, ht_key_value_t kv) { return result; } -ht_node_t *ht_insert_u64_u64(ht_dict_t *ht, u64 key, u64 value) { +fn ht_node_t *ht_insert_u64(ht_t *ht, u64 key, u64 value) { u64 hash = hash_data(s8_struct(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); +fn ht_node_t *ht_insert_ptr(ht_t *ht, void *key, void *value) { + return ht_insert_u64(ht, (u64)key, (u64)value); } -ht_node_t *ht_insert_string(ht_dict_t *ht, s8_t key, s8_t value) { +fn ht_node_t *ht_insert_string(ht_t *ht, s8_t key, s8_t value) { u64 hash = hash_data(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) { +fn ht_node_t *ht_insert_string_ptr(ht_t *ht, s8_t key, void *value) { + u64 hash = hash_data(key); + return ht_insert_kv(ht, hash, (ht_key_value_t){.key_string = key, .value_ptr = value}); +} + +fn ht_node_t *ht_search_u64_ex(ht_t *ht, u64 key) { u64 hash = hash_data(s8_struct(key)); i64 idx = hash % ht->bucket_count; ht_bucket_t *bucket = ht->buckets + idx; @@ -76,11 +46,19 @@ ht_node_t *ht_search_u64(ht_dict_t *ht, u64 key) { return NULL; } -ht_node_t *ht_search_ptr(ht_dict_t *ht, void *key_ptr) { - return ht_search_u64(ht, (u64)key_ptr); +fn ht_node_t *ht_search_ptr_ex(ht_t *ht, void *key) { + u64 hash = hash_data(s8_struct(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_ptr == key) { + return it; + } + } + return NULL; } -ht_node_t *ht_search_string(ht_dict_t *ht, s8_t key) { +fn ht_node_t *ht_search_string_ex(ht_t *ht, s8_t key) { u64 hash = hash_data(key); i64 idx = hash % ht->bucket_count; ht_bucket_t *bucket = ht->buckets + idx; @@ -90,4 +68,45 @@ ht_node_t *ht_search_string(ht_dict_t *ht, s8_t key) { } } return NULL; -} \ No newline at end of file +} + +fn u64 *ht_search_u64(ht_t *ht, u64 key) { + ht_node_t *node = ht_search_u64_ex(ht, key); + if (node) return &node->kv.value_u64; + return NULL; +} + +fn void **ht_search_ptr(ht_t *ht, void *key) { + ht_node_t *node = ht_search_ptr_ex(ht, key); + if (node) return &node->kv.value_ptr; + return NULL; +} + +fn s8_t *ht_search_string(ht_t *ht, s8_t key) { + ht_node_t *node = ht_search_string_ex(ht, key); + if (node) return &node->kv.value_string; + return NULL; +} + +fn void **ht_search_string_ptr(ht_t *ht, s8_t key) { + ht_node_t *node = ht_search_string_ex(ht, key); + if (node) return &node->kv.value_ptr; + return NULL; +} + +/////////////////////////////// +// string interning +fn s8i_t *intern_string(ht_t *ht, s8_t string) { + s8_t *item = ht_search_string(ht, string); + if (!item) { + string = s8_copy(ht->arena, string); + ht_node_t *node = ht_insert_string(ht, string, string); + item = &node->kv.value_string; + } + return item; +} + +fn s8i_t *internf(ht_t *ht, char *str, ...) { + S8_FMT(ht->arena, str, string); + return intern_string(ht, string); +} diff --git a/src/core/core_inc.h b/src/core/core_inc.h index eabc8b8..65526e0 100644 --- a/src/core/core_inc.h +++ b/src/core/core_inc.h @@ -12,4 +12,5 @@ #include "core_type_info.h" #include "core_intrin.h" #include "core_platform.h" +#include "core_hash_table.h" #include "core_ctx.h" \ No newline at end of file diff --git a/src/core/core_test_entry.c b/src/core/core_test_entry.c index 7cd4250..8fae180 100644 --- a/src/core/core_test_entry.c +++ b/src/core/core_test_entry.c @@ -99,41 +99,54 @@ void test_s8(void) { void test_hash_table(void) { ma_temp_t scratch = ma_begin_scratch(); { - ht_dict_t *ht = ht_create(scratch.arena, 16); + ht_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); + ht_insert_u64(ht, i, i); + ht_node_t *node = ht_search_u64_ex(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); + ht_node_t *node = ht_search_u64_ex(ht, i); assert(node->kv.value_u64 == i); assert(node->kv.key_u64 == i); } - ht_node_t *node = ht_search_u64(ht, 1111); + ht_node_t *node = ht_search_u64_ex(ht, 1111); assert(node == NULL); } { - ht_dict_t *ht = ht_create(scratch.arena, 16); + ht_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); + ht_node_t *node = ht_search_string_ex(ht, s); assert(s8_are_equal(node->kv.value_string, s)); assert(s8_are_equal(node->kv.key_string, s)); } - ht_node_t *node = ht_search_string(ht, s8_lit("memes")); + ht_node_t *node = ht_search_string_ex(ht, s8_lit("memes")); assert(node == NULL); } ma_end_scratch(scratch); } +void test_intern_table(void) { + ma_temp_t scratch = ma_begin_scratch(); + ht_t *ht = ht_create(scratch.arena, 4); + assert(internf(ht, "asd") == internf(ht, "asd")); + assert(internf(ht, "asdf") != internf(ht, "asd")); + assert(internf(ht, "asdf") == internf(ht, "asdf")); + assert(internf(ht, "123asdf") == internf(ht, "123asdf")); + assert(internf(ht, "123asdf") != internf(ht, "133asdf")); + assert(internf(ht, "") == internf(ht, "")); + assert(internf(ht, "") != internf(ht, "a")); + ma_end_scratch(scratch); +} + #include int main(int argc, char **argv) { @@ -149,6 +162,7 @@ int main(int argc, char **argv) { test_s8(); test_hash_table(); + test_intern_table(); printf("all done!\n"); } \ No newline at end of file diff --git a/src/meta/cgen.c b/src/meta/cgen.c index 00b486f..f396031 100644 --- a/src/meta/cgen.c +++ b/src/meta/cgen.c @@ -118,7 +118,7 @@ fn s8_t cg_byte_array_from_data(ma_arena_t *arena, s8_t file, s8_t var_name) { #define cg_cpath(arena) cg_gen_filename(arena, s8_lit(__FILE__), s8_lit("c")) #define cg_hpath(arena) cg_gen_filename(arena, s8_lit(__FILE__), s8_lit("h")) -s8_t cg_gen_filename(ma_arena_t *arena, s8_t lit_file, s8_t ext) { +fn s8_t cg_gen_filename(ma_arena_t *arena, s8_t lit_file, s8_t ext) { s8_t file_noext = s8_chop_last_period(s8_chop_last_period(lit_file)); s8_t file = s8_printf(arena, "%S.gen.%S", file_noext, ext); return file; diff --git a/src/ui/ui.c b/src/ui/ui.c index cdd59f9..b824c9c 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -588,7 +588,7 @@ fn void ui_demo_update(app_frame_t *frame) { ui_set_rect(item_box, r2f32_cut_left(&ui->top->rect, ui_max)); static f32 scroller_value; - ui_set_text_align(ui_text_align_center) + ui_set_text_align(ui_text_align_left) ui_set_top(item_box) { for (i32 i = 0; i < lengthof(tweak_table); i += 1) { mt_tweak_t *tweak = tweak_table + i; @@ -610,29 +610,7 @@ fn void ui_demo_update(app_frame_t *frame) { } } else_is_invalid; } - ui_serial_subtype(&primary_color_global, type(v4f32_t), s8_lit("primary_color_global")); - ui_serial_subtype(&secondary_color_global, type(v4f32_t), s8_lit("secondary_color_global")); - ui_serial_subtype(&accent1_color_global, type(v4f32_t), s8_lit("accent1_color_global")); - ui_serial_subtype(&accent2_color_global, type(v4f32_t), s8_lit("accent2_color_global")); - ui_serial_subtype(&white_color_global, type(v4f32_t), s8_lit("white_color_global")); - ui_serial_subtype(&black_color_global, type(v4f32_t), s8_lit("black_color_global")); ui_serial_type(&ui_test_event, type(app_event_t)); - ui_expander("app_event_t") { - for (int i = 0; i < 2; i += 1) { - ui_label("kind: app_event_kind_t##a%d", i); - ui_label("ctrl: b8##ds%d", i); - ui_label("shift: b8##f%d", i); - ui_expander("pos: v3f32_t##gg%d", i) { - ui_label("x: f64 = value##hgt%d", i); - ui_label("y: f64 = value##r%d", i); - ui_label("z: f64 = value##yr%d", i); - } - ui_expander("mouse_pos: v2f32_t##i2%d", i) { - ui_label("x: f64 = value##i3%d", i); - ui_label("y: f64 = value##i4%d", i); - } - } - } } // @todo: fix scroller to match mouse diff --git a/todo.txt b/todo.txt index 1b7fc8c..f26aed8 100644 --- a/todo.txt +++ b/todo.txt @@ -23,10 +23,9 @@ [x] remove dates and time from core [ ] meta [x] search for python snippets and execute meta.py script on that file - [ ] simplify logging!!!! - [ ] somehow index properly the meta files and ignore generated files + [x] simplify logging!!!! + [x] somehow index properly the meta files and ignore generated files [x] extract declarations from c files meta(introspect) - [ ] extract all globals from c files [x] tweak variables and embeds declared in c code [ ] new simple format with tags [x] revisit api