From c331133388e7e6e76f4838f39037d12fb42f63b2 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 13 Mar 2025 14:02:06 -0700 Subject: [PATCH] adjust hash store - first, don't keep strong refcounts for key history past the 2nd hash - this is prohibitively expensive. but, keep 'downstream' refcounts - this is a mechanism which downstream caches (e.g. text visualization info parsing etc.) can use to ensure a hash stays held in the hash store, given some other data's dependence on it - this stops the storing of unnecessary OutputDebugString log copies --- src/hash_store/hash_store.c | 57 +++++++++++++++++++++++++++++++++---- src/hash_store/hash_store.h | 8 ++++++ src/raddbg/raddbg_core.c | 18 +++++++++--- src/text_cache/text_cache.c | 7 +++-- 4 files changed, 77 insertions(+), 13 deletions(-) diff --git a/src/hash_store/hash_store.c b/src/hash_store/hash_store.c index 26dc64ba..587a45c0 100644 --- a/src/hash_store/hash_store.c +++ b/src/hash_store/hash_store.c @@ -152,17 +152,17 @@ hs_submit_data(U128 key, Arena **data_arena, String8 data) } if(key_node) { - if(key_node->hash_history_gen >= ArrayCount(key_node->hash_history)) + if(key_node->hash_history_gen >= HS_KEY_HASH_HISTORY_STRONG_REF_COUNT) { - key_expired_hash = key_node->hash_history[key_node->hash_history_gen%ArrayCount(key_node->hash_history)]; + key_expired_hash = key_node->hash_history[(key_node->hash_history_gen-HS_KEY_HASH_HISTORY_STRONG_REF_COUNT)%ArrayCount(key_node->hash_history)]; } key_node->hash_history[key_node->hash_history_gen%ArrayCount(key_node->hash_history)] = hash; key_node->hash_history_gen += 1; } } - //- rjf: if this key's history cache was full, dec key ref count of oldest hash - ProfScope("if this key's history cache was full, dec key ref count of oldest hash") + //- rjf: decrement key ref count of expired hash + ProfScope("decrement key ref count of expired hash") if(!u128_match(key_expired_hash, u128_zero())) { U64 old_hash_slot_idx = key_expired_hash.u64[1]%hs_shared->slots_count; @@ -250,6 +250,49 @@ hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node) SLLStackPush(scope->top_touch, touch); } +//////////////////////////////// +//~ rjf: Downstream Accesses + +internal void +hs_hash_downstream_inc(U128 hash) +{ + U64 slot_idx = hash.u64[1]%hs_shared->slots_count; + U64 stripe_idx = slot_idx%hs_shared->stripes_count; + HS_Slot *slot = &hs_shared->slots[slot_idx]; + HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; + OS_MutexScopeR(stripe->rw_mutex) + { + for(HS_Node *n = slot->first; n != 0; n = n->next) + { + if(u128_match(hash, n->hash)) + { + ins_atomic_u64_inc_eval(&n->downstream_ref_count); + break; + } + } + } +} + +internal void +hs_hash_downstream_dec(U128 hash) +{ + U64 slot_idx = hash.u64[1]%hs_shared->slots_count; + U64 stripe_idx = slot_idx%hs_shared->stripes_count; + HS_Slot *slot = &hs_shared->slots[slot_idx]; + HS_Stripe *stripe = &hs_shared->stripes[stripe_idx]; + OS_MutexScopeR(stripe->rw_mutex) + { + for(HS_Node *n = slot->first; n != 0; n = n->next) + { + if(u128_match(hash, n->hash)) + { + ins_atomic_u64_dec_eval(&n->downstream_ref_count); + break; + } + } + } +} + //////////////////////////////// //~ rjf: Cache Lookup @@ -321,7 +364,8 @@ hs_evictor_thread__entry_point(void *p) { U64 key_ref_count = ins_atomic_u64_eval(&n->key_ref_count); U64 scope_ref_count = ins_atomic_u64_eval(&n->scope_ref_count); - if(key_ref_count == 0 && scope_ref_count == 0) + U64 downstream_ref_count = ins_atomic_u64_eval(&n->downstream_ref_count); + if(key_ref_count == 0 && scope_ref_count == 0 && downstream_ref_count == 0) { slot_has_work = 1; break; @@ -335,7 +379,8 @@ hs_evictor_thread__entry_point(void *p) next = n->next; U64 key_ref_count = ins_atomic_u64_eval(&n->key_ref_count); U64 scope_ref_count = ins_atomic_u64_eval(&n->scope_ref_count); - if(key_ref_count == 0 && scope_ref_count == 0) + U64 downstream_ref_count = ins_atomic_u64_eval(&n->downstream_ref_count); + if(key_ref_count == 0 && scope_ref_count == 0 && downstream_ref_count == 0) { DLLRemove(slot->first, slot->last, n); SLLStackPush(hs_shared->stripes_free_nodes[stripe_idx], n); diff --git a/src/hash_store/hash_store.h b/src/hash_store/hash_store.h index ff886e79..784a9203 100644 --- a/src/hash_store/hash_store.h +++ b/src/hash_store/hash_store.h @@ -8,6 +8,7 @@ //~ rjf: Cache Types #define HS_KEY_HASH_HISTORY_COUNT 64 +#define HS_KEY_HASH_HISTORY_STRONG_REF_COUNT 2 typedef struct HS_KeyNode HS_KeyNode; struct HS_KeyNode @@ -35,6 +36,7 @@ struct HS_Node String8 data; U64 scope_ref_count; U64 key_ref_count; + U64 downstream_ref_count; }; typedef struct HS_Slot HS_Slot; @@ -138,6 +140,12 @@ internal HS_Scope *hs_scope_open(void); internal void hs_scope_close(HS_Scope *scope); internal void hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_Node *node); +//////////////////////////////// +//~ rjf: Downstream Accesses + +internal void hs_hash_downstream_inc(U128 hash); +internal void hs_hash_downstream_dec(U128 hash); + //////////////////////////////// //~ rjf: Cache Lookups diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index be5957f7..e40062b1 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5173,7 +5173,7 @@ rd_view_ui(Rng2F32 rect) } else { - rgba.w *= 0.15f; + rgba.w *= 0.05f; } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###cfg_hover_t_%p", cfg), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; @@ -5191,7 +5191,7 @@ rd_view_ui(Rng2F32 rect) } else { - rgba.w *= 0.15f; + rgba.w *= 0.05f; } rgba.w *= ui_anim(ui_key_from_stringf(ui_key_zero(), "###entity_hover_t_%p", entity), 1.f, .rate = entity_hover_t_rate); cell_background_color_override = rgba; @@ -7544,7 +7544,17 @@ rd_window_frame(void) content_rect_center.y - max_query_height_px/2.f, content_rect_center.x + query_width_px/2, content_rect_center.y - max_query_height_px/2.f + query_height_px*query_open_t); - + if(!ui_key_match(ui_key_zero(), ws->query_regs->ui_key)) + { + UI_Box *anchor_box = ui_box_from_key(ws->query_regs->ui_key); + if(anchor_box != &ui_nil_box) + { + query_rect.x0 = anchor_box->rect.x0; + query_rect.y0 = anchor_box->rect.y1; + query_rect.x1 = query_rect.x0 + ui_top_font_size()*40.f; + query_rect.y1 = query_rect.y0 + query_height_px; + } + } RD_Font(RD_FontSlot_Code) UI_FontSize(rd_font_size_from_slot(RD_FontSlot_Main)) UI_TagF("floating") @@ -16035,7 +16045,7 @@ Z(getting_started) // rjf: floating queries -> set up window to build immediate-mode top-level query RD_Cfg *view = &rd_nil_cfg; - if(cmd_kind_info->query.flags & RD_QueryFlag_Floating) + if(cmd_name.size == 0 || cmd_kind_info->query.flags & RD_QueryFlag_Floating) { RD_Cfg *window = rd_cfg_from_id(rd_regs()->window); RD_WindowState *ws = rd_window_state_from_cfg(window); diff --git a/src/text_cache/text_cache.c b/src/text_cache/text_cache.c index 377ee516..7a1fae94 100644 --- a/src/text_cache/text_cache.c +++ b/src/text_cache/text_cache.c @@ -2313,6 +2313,7 @@ ASYNC_WORK_DEF(txt_parse_work) { if(u128_match(n->hash, hash) && n->lang == lang) { + hs_hash_downstream_inc(n->hash); n->arena = info_arena; info.bytes_processed = n->info.bytes_processed; info.bytes_to_process = n->info.bytes_to_process; @@ -2340,7 +2341,7 @@ txt_evictor_thread__entry_point(void *p) { U64 check_time_us = os_now_microseconds(); U64 check_time_user_clocks = update_tick_idx(); - U64 evict_threshold_us = 10*1000000; + U64 evict_threshold_us = 2*1000000; U64 evict_threshold_user_clocks = 10; for(U64 slot_idx = 0; slot_idx < txt_shared->slots_count; slot_idx += 1) { @@ -2375,6 +2376,7 @@ txt_evictor_thread__entry_point(void *p) n->is_working == 0) { DLLRemove(slot->first, slot->last, n); + hs_hash_downstream_dec(n->hash); if(n->arena != 0) { arena_release(n->arena); @@ -2383,8 +2385,7 @@ txt_evictor_thread__entry_point(void *p) } } } - os_sleep_milliseconds(5); } - os_sleep_milliseconds(1000); + os_sleep_milliseconds(500); } }