mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-09 11:01:37 -07:00
hash_store -> content
This commit is contained in:
@@ -56,8 +56,8 @@ main_thread_base_entry_point(int arguments_count, char **arguments)
|
||||
#if defined(ASYNC_H) && !defined(ASYNC_INIT_MANUAL)
|
||||
async_init(&cmdline);
|
||||
#endif
|
||||
#if defined(HASH_STORE_H) && !defined(HS_INIT_MANUAL)
|
||||
hs_init();
|
||||
#if defined(CONTENT_H) && !defined(C_INIT_MANUAL)
|
||||
c_init();
|
||||
#endif
|
||||
#if defined(FILE_STREAM_H) && !defined(FS_INIT_MANUAL)
|
||||
fs_init();
|
||||
@@ -191,8 +191,8 @@ async_thread_entry_point(void *params)
|
||||
for(;!ins_atomic_u32_eval(&global_async_exit);)
|
||||
{
|
||||
MutexScope(async_tick_start_mutex) cond_var_wait(async_tick_start_cond_var, async_tick_start_mutex, os_now_microseconds()+100000);
|
||||
#if defined(HASH_STORE_H)
|
||||
hs_tick();
|
||||
#if defined(CONTENT_H)
|
||||
c_tick();
|
||||
#endif
|
||||
#if defined(FILE_STREAM_H)
|
||||
fs_tick();
|
||||
|
||||
@@ -0,0 +1,593 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#undef LAYER_COLOR
|
||||
#define LAYER_COLOR 0x684123ff
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
#if !defined(XXH_IMPLEMENTATION)
|
||||
# define XXH_IMPLEMENTATION
|
||||
# define XXH_STATIC_LINKING_ONLY
|
||||
# include "third_party/xxHash/xxhash.h"
|
||||
#endif
|
||||
|
||||
internal U64
|
||||
c_little_hash_from_data(String8 data)
|
||||
{
|
||||
U64 result = XXH3_64bits(data.str, data.size);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U128
|
||||
c_hash_from_data(String8 data)
|
||||
{
|
||||
U128 u128 = {0};
|
||||
XXH128_hash_t hash = XXH3_128bits(data.str, data.size);
|
||||
MemoryCopy(&u128, &hash, sizeof(u128));
|
||||
return u128;
|
||||
}
|
||||
|
||||
internal C_ID
|
||||
c_id_make(U64 u64_0, U64 u64_1)
|
||||
{
|
||||
C_ID id;
|
||||
id.u128[0].u64[0] = u64_0;
|
||||
id.u128[0].u64[1] = u64_1;
|
||||
return id;
|
||||
}
|
||||
|
||||
internal B32
|
||||
c_id_match(C_ID a, C_ID b)
|
||||
{
|
||||
B32 result = MemoryMatchStruct(&a, &b);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal C_Key
|
||||
c_key_make(C_Root root, C_ID id)
|
||||
{
|
||||
C_Key key = {root, 0, id};
|
||||
return key;
|
||||
}
|
||||
|
||||
internal B32
|
||||
c_key_match(C_Key a, C_Key b)
|
||||
{
|
||||
return (MemoryMatchStruct(&a.root, &b.root) && c_id_match(a.id, b.id));
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Layer Initialization
|
||||
|
||||
internal void
|
||||
c_init(void)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
c_shared = push_array(arena, C_Shared, 1);
|
||||
c_shared->arena = arena;
|
||||
c_shared->slots_count = 4096;
|
||||
c_shared->stripes_count = Min(c_shared->slots_count, os_get_system_info()->logical_processor_count);
|
||||
c_shared->slots = push_array(arena, C_BlobSlot, c_shared->slots_count);
|
||||
c_shared->stripes = push_array(arena, C_Stripe, c_shared->stripes_count);
|
||||
c_shared->stripes_free_nodes = push_array(arena, C_BlobNode *, c_shared->stripes_count);
|
||||
for(U64 idx = 0; idx < c_shared->stripes_count; idx += 1)
|
||||
{
|
||||
C_Stripe *stripe = &c_shared->stripes[idx];
|
||||
stripe->arena = arena_alloc();
|
||||
stripe->rw_mutex = rw_mutex_alloc();
|
||||
stripe->cv = cond_var_alloc();
|
||||
}
|
||||
c_shared->key_slots_count = 4096;
|
||||
c_shared->key_stripes_count = Min(c_shared->key_slots_count, os_get_system_info()->logical_processor_count);
|
||||
c_shared->key_slots = push_array(arena, C_KeySlot, c_shared->key_slots_count);
|
||||
c_shared->key_stripes = push_array(arena, C_Stripe, c_shared->key_stripes_count);
|
||||
c_shared->key_stripes_free_nodes = push_array(arena, C_KeyNode *, c_shared->key_stripes_count);
|
||||
for(U64 idx = 0; idx < c_shared->key_stripes_count; idx += 1)
|
||||
{
|
||||
C_Stripe *stripe = &c_shared->key_stripes[idx];
|
||||
stripe->arena = arena_alloc();
|
||||
stripe->rw_mutex = rw_mutex_alloc();
|
||||
stripe->cv = cond_var_alloc();
|
||||
}
|
||||
c_shared->root_slots_count = 4096;
|
||||
c_shared->root_stripes_count = Min(c_shared->root_slots_count, os_get_system_info()->logical_processor_count);
|
||||
c_shared->root_slots = push_array(arena, C_RootSlot, c_shared->root_slots_count);
|
||||
c_shared->root_stripes = push_array(arena, C_Stripe, c_shared->root_stripes_count);
|
||||
c_shared->root_stripes_free_nodes = push_array(arena, C_RootNode *, c_shared->root_stripes_count);
|
||||
for(U64 idx = 0; idx < c_shared->root_stripes_count; idx += 1)
|
||||
{
|
||||
C_Stripe *stripe = &c_shared->root_stripes[idx];
|
||||
stripe->arena = arena_alloc();
|
||||
stripe->rw_mutex = rw_mutex_alloc();
|
||||
stripe->cv = cond_var_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Root Allocation/Deallocation
|
||||
|
||||
internal C_Root
|
||||
c_root_alloc(void)
|
||||
{
|
||||
C_Root root = {0};
|
||||
root.u64[0] = ins_atomic_u64_inc_eval(&c_shared->root_id_gen);
|
||||
U64 slot_idx = root.u64[0]%c_shared->root_slots_count;
|
||||
U64 stripe_idx = slot_idx%c_shared->root_stripes_count;
|
||||
C_RootSlot *slot = &c_shared->root_slots[slot_idx];
|
||||
C_Stripe *stripe = &c_shared->root_stripes[stripe_idx];
|
||||
MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
C_RootNode *node = c_shared->root_stripes_free_nodes[stripe_idx];
|
||||
if(node != 0)
|
||||
{
|
||||
SLLStackPop(c_shared->root_stripes_free_nodes[stripe_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = push_array(stripe->arena, C_RootNode, 1);
|
||||
}
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
node->root = root;
|
||||
node->arena = arena_alloc();
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
internal void
|
||||
c_root_release(C_Root root)
|
||||
{
|
||||
//- rjf: unpack root
|
||||
U64 slot_idx = root.u64[0]%c_shared->root_slots_count;
|
||||
U64 stripe_idx = slot_idx%c_shared->root_stripes_count;
|
||||
C_RootSlot *slot = &c_shared->root_slots[slot_idx];
|
||||
C_Stripe *stripe = &c_shared->root_stripes[stripe_idx];
|
||||
|
||||
//- rjf: release root node, grab its arena / ID list
|
||||
Arena *root_arena = 0;
|
||||
C_RootIDChunkList root_ids = {0};
|
||||
MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
for(C_RootNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(MemoryMatchStruct(&root, &n->root))
|
||||
{
|
||||
DLLRemove(slot->first, slot->last, n);
|
||||
root_arena = n->arena;
|
||||
root_ids = n->ids;
|
||||
SLLStackPush(c_shared->root_stripes_free_nodes[stripe_idx], n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: release all IDs
|
||||
for(C_RootIDChunkNode *id_chunk_n = root_ids.first; id_chunk_n != 0; id_chunk_n = id_chunk_n->next)
|
||||
{
|
||||
for EachIndex(chunk_idx, id_chunk_n->count)
|
||||
{
|
||||
C_ID id = id_chunk_n->v[chunk_idx];
|
||||
C_Key key = c_key_make(root, id);
|
||||
U64 key_hash = c_little_hash_from_data(str8_struct(&key));
|
||||
U64 key_slot_idx = key_hash%c_shared->key_slots_count;
|
||||
U64 key_stripe_idx = key_slot_idx%c_shared->key_stripes_count;
|
||||
C_KeySlot *key_slot = &c_shared->key_slots[key_slot_idx];
|
||||
C_Stripe *key_stripe = &c_shared->key_stripes[key_stripe_idx];
|
||||
MutexScopeW(key_stripe->rw_mutex)
|
||||
{
|
||||
for(C_KeyNode *n = key_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(c_key_match(n->key, key))
|
||||
{
|
||||
// rjf: release reference to all hashes
|
||||
for(U64 history_idx = 0; history_idx < C_KEY_HASH_HISTORY_STRONG_REF_COUNT && history_idx < n->hash_history_gen; history_idx += 1)
|
||||
{
|
||||
U128 hash = n->hash_history[(n->hash_history_gen+history_idx)%ArrayCount(n->hash_history)];
|
||||
U64 hash_slot_idx = hash.u64[1]%c_shared->slots_count;
|
||||
U64 hash_stripe_idx = hash_slot_idx%c_shared->stripes_count;
|
||||
C_BlobSlot *hash_slot = &c_shared->slots[hash_slot_idx];
|
||||
C_Stripe *hash_stripe = &c_shared->stripes[hash_stripe_idx];
|
||||
MutexScopeR(hash_stripe->rw_mutex)
|
||||
{
|
||||
for(C_BlobNode *n = hash_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->hash, hash))
|
||||
{
|
||||
ins_atomic_u64_dec_eval(&n->key_ref_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: release key node
|
||||
DLLRemove(key_slot->first, key_slot->last, n);
|
||||
SLLStackPush(c_shared->key_stripes_free_nodes[key_stripe_idx], n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Submission
|
||||
|
||||
internal U128
|
||||
c_submit_data(C_Key key, Arena **data_arena, String8 data)
|
||||
{
|
||||
U64 key_hash = c_little_hash_from_data(str8_struct(&key));
|
||||
U64 key_slot_idx = key_hash%c_shared->key_slots_count;
|
||||
U64 key_stripe_idx = key_slot_idx%c_shared->key_stripes_count;
|
||||
C_KeySlot *key_slot = &c_shared->key_slots[key_slot_idx];
|
||||
C_Stripe *key_stripe = &c_shared->key_stripes[key_stripe_idx];
|
||||
U128 hash = c_hash_from_data(data);
|
||||
U64 slot_idx = hash.u64[1]%c_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%c_shared->stripes_count;
|
||||
C_BlobSlot *slot = &c_shared->slots[slot_idx];
|
||||
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
|
||||
|
||||
//- rjf: commit data to cache - if already there, just bump key refcount
|
||||
ProfScope("commit data to cache - if already there, just bump key refcount") MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
C_BlobNode *existing_node = 0;
|
||||
for(C_BlobNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->hash, hash))
|
||||
{
|
||||
existing_node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(existing_node == 0)
|
||||
{
|
||||
C_BlobNode *node = c_shared->stripes_free_nodes[stripe_idx];
|
||||
if(node)
|
||||
{
|
||||
SLLStackPop(c_shared->stripes_free_nodes[stripe_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = push_array(stripe->arena, C_BlobNode, 1);
|
||||
}
|
||||
node->hash = hash;
|
||||
if(data_arena != 0)
|
||||
{
|
||||
node->arena = *data_arena;
|
||||
}
|
||||
node->data = data;
|
||||
node->scope_ref_count = 0;
|
||||
node->key_ref_count = 1;
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_node->key_ref_count += 1;
|
||||
if(data_arena != 0)
|
||||
{
|
||||
arena_release(*data_arena);
|
||||
}
|
||||
}
|
||||
if(data_arena != 0)
|
||||
{
|
||||
*data_arena = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: commit this hash to key cache
|
||||
U128 key_expired_hash = {0};
|
||||
ProfScope("commit this hash to key cache") MutexScopeW(key_stripe->rw_mutex)
|
||||
{
|
||||
// rjf: find existing key
|
||||
B32 key_is_new = 0;
|
||||
C_KeyNode *key_node = 0;
|
||||
for(C_KeyNode *n = key_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(c_key_match(n->key, key))
|
||||
{
|
||||
key_node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: create key node if it doesn't exist
|
||||
if(!key_node)
|
||||
{
|
||||
key_is_new = 1;
|
||||
key_node = c_shared->key_stripes_free_nodes[key_stripe_idx];
|
||||
if(key_node)
|
||||
{
|
||||
SLLStackPop(c_shared->key_stripes_free_nodes[key_stripe_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
key_node = push_array(key_stripe->arena, C_KeyNode, 1);
|
||||
}
|
||||
key_node->key = key;
|
||||
DLLPushBack(key_slot->first, key_slot->last, key_node);
|
||||
}
|
||||
|
||||
// rjf: push hash into key's history
|
||||
if(key_node)
|
||||
{
|
||||
if(key_node->hash_history_gen >= C_KEY_HASH_HISTORY_STRONG_REF_COUNT)
|
||||
{
|
||||
key_expired_hash = key_node->hash_history[(key_node->hash_history_gen-C_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: key is new -> add this key to the associated root
|
||||
if(key_is_new)
|
||||
{
|
||||
U64 root_hash = c_little_hash_from_data(str8_struct(&key.root));
|
||||
U64 root_slot_idx = root_hash%c_shared->root_slots_count;
|
||||
U64 root_stripe_idx = root_slot_idx%c_shared->root_stripes_count;
|
||||
C_RootSlot *root_slot = &c_shared->root_slots[root_slot_idx];
|
||||
C_Stripe *root_stripe = &c_shared->root_stripes[root_stripe_idx];
|
||||
MutexScopeW(root_stripe->rw_mutex)
|
||||
{
|
||||
for(C_RootNode *n = root_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(MemoryMatchStruct(&n->root, &key.root))
|
||||
{
|
||||
C_RootIDChunkNode *chunk = n->ids.last;
|
||||
if(chunk == 0 || chunk->count >= chunk->cap)
|
||||
{
|
||||
chunk = push_array(n->arena, C_RootIDChunkNode, 1);
|
||||
SLLQueuePush(n->ids.first, n->ids.last, chunk);
|
||||
n->ids.chunk_count += 1;
|
||||
chunk->cap = 1024;
|
||||
chunk->v = push_array_no_zero(n->arena, C_ID, chunk->cap);
|
||||
}
|
||||
chunk->v[chunk->count] = key.id;
|
||||
chunk->count += 1;
|
||||
n->ids.total_count += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- 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]%c_shared->slots_count;
|
||||
U64 old_hash_stripe_idx = old_hash_slot_idx%c_shared->stripes_count;
|
||||
C_BlobSlot *old_hash_slot = &c_shared->slots[old_hash_slot_idx];
|
||||
C_Stripe *old_hash_stripe = &c_shared->stripes[old_hash_stripe_idx];
|
||||
MutexScopeR(old_hash_stripe->rw_mutex)
|
||||
{
|
||||
for(C_BlobNode *n = old_hash_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->hash, key_expired_hash))
|
||||
{
|
||||
ins_atomic_u64_dec_eval(&n->key_ref_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scoped Access
|
||||
|
||||
internal C_Scope *
|
||||
c_scope_open(void)
|
||||
{
|
||||
if(c_tctx == 0)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
c_tctx = push_array(arena, C_TCTX, 1);
|
||||
c_tctx->arena = arena;
|
||||
}
|
||||
C_Scope *scope = c_tctx->free_scope;
|
||||
if(scope)
|
||||
{
|
||||
SLLStackPop(c_tctx->free_scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
scope = push_array_no_zero(c_tctx->arena, C_Scope, 1);
|
||||
}
|
||||
MemoryZeroStruct(scope);
|
||||
return scope;
|
||||
}
|
||||
|
||||
internal void
|
||||
c_scope_close(C_Scope *scope)
|
||||
{
|
||||
for(C_Touch *touch = scope->top_touch, *next = 0; touch != 0; touch = next)
|
||||
{
|
||||
U128 hash = touch->hash;
|
||||
next = touch->next;
|
||||
U64 slot_idx = hash.u64[1]%c_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%c_shared->stripes_count;
|
||||
C_BlobSlot *slot = &c_shared->slots[slot_idx];
|
||||
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
|
||||
MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(C_BlobNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(hash, n->hash))
|
||||
{
|
||||
ins_atomic_u64_dec_eval(&n->scope_ref_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SLLStackPush(c_tctx->free_touch, touch);
|
||||
}
|
||||
SLLStackPush(c_tctx->free_scope, scope);
|
||||
}
|
||||
|
||||
internal void
|
||||
c_scope_touch_node__stripe_r_guarded(C_Scope *scope, C_BlobNode *node)
|
||||
{
|
||||
C_Touch *touch = c_tctx->free_touch;
|
||||
ins_atomic_u64_inc_eval(&node->scope_ref_count);
|
||||
if(touch != 0)
|
||||
{
|
||||
SLLStackPop(c_tctx->free_touch);
|
||||
}
|
||||
else
|
||||
{
|
||||
touch = push_array_no_zero(c_tctx->arena, C_Touch, 1);
|
||||
}
|
||||
MemoryZeroStruct(touch);
|
||||
touch->hash = node->hash;
|
||||
SLLStackPush(scope->top_touch, touch);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Downstream Accesses
|
||||
|
||||
internal void
|
||||
c_hash_downstream_inc(U128 hash)
|
||||
{
|
||||
U64 slot_idx = hash.u64[1]%c_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%c_shared->stripes_count;
|
||||
C_BlobSlot *slot = &c_shared->slots[slot_idx];
|
||||
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
|
||||
MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(C_BlobNode *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
|
||||
c_hash_downstream_dec(U128 hash)
|
||||
{
|
||||
U64 slot_idx = hash.u64[1]%c_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%c_shared->stripes_count;
|
||||
C_BlobSlot *slot = &c_shared->slots[slot_idx];
|
||||
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
|
||||
MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(C_BlobNode *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
|
||||
|
||||
internal U128
|
||||
c_hash_from_key(C_Key key, U64 rewind_count)
|
||||
{
|
||||
U128 result = {0};
|
||||
U64 key_hash = c_little_hash_from_data(str8_struct(&key));
|
||||
U64 key_slot_idx = key_hash%c_shared->key_slots_count;
|
||||
U64 key_stripe_idx = key_slot_idx%c_shared->key_stripes_count;
|
||||
C_KeySlot *key_slot = &c_shared->key_slots[key_slot_idx];
|
||||
C_Stripe *key_stripe = &c_shared->key_stripes[key_stripe_idx];
|
||||
MutexScopeR(key_stripe->rw_mutex)
|
||||
{
|
||||
for(C_KeyNode *n = key_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(c_key_match(n->key, key) && n->hash_history_gen > 0 && n->hash_history_gen-1 >= rewind_count)
|
||||
{
|
||||
result = n->hash_history[(n->hash_history_gen-1-rewind_count)%ArrayCount(n->hash_history)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
c_data_from_hash(C_Scope *scope, U128 hash)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
String8 result = {0};
|
||||
U64 slot_idx = hash.u64[1]%c_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%c_shared->stripes_count;
|
||||
C_BlobSlot *slot = &c_shared->slots[slot_idx];
|
||||
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
|
||||
MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(C_BlobNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->hash, hash))
|
||||
{
|
||||
result = n->data;
|
||||
c_scope_touch_node__stripe_r_guarded(scope, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ProfEnd();
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Tick
|
||||
|
||||
internal void
|
||||
c_tick(void)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Rng1U64 range = lane_range(c_shared->slots_count);
|
||||
for EachInRange(slot_idx, range)
|
||||
{
|
||||
U64 stripe_idx = slot_idx%c_shared->stripes_count;
|
||||
C_BlobSlot *slot = &c_shared->slots[slot_idx];
|
||||
C_Stripe *stripe = &c_shared->stripes[stripe_idx];
|
||||
B32 slot_has_work = 0;
|
||||
MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(C_BlobNode *n = slot->first; n != 0; n = 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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(slot_has_work) MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
for(C_BlobNode *n = slot->first, *next = 0; n != 0; n = next)
|
||||
{
|
||||
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);
|
||||
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(c_shared->stripes_free_nodes[stripe_idx], n);
|
||||
if(n->arena != 0)
|
||||
{
|
||||
arena_release(n->arena);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ProfEnd();
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef HASH_STORE_H
|
||||
#define HASH_STORE_H
|
||||
#ifndef CONTENT_H
|
||||
#define CONTENT_H
|
||||
|
||||
////////////////////////////////
|
||||
//~ NOTE(rjf): Hash Store Notes (2025/05/18)
|
||||
@@ -43,95 +43,95 @@
|
||||
////////////////////////////////
|
||||
//~ rjf: Key Types
|
||||
|
||||
typedef struct HS_Root HS_Root;
|
||||
struct HS_Root
|
||||
typedef struct C_Root C_Root;
|
||||
struct C_Root
|
||||
{
|
||||
U64 u64[1];
|
||||
};
|
||||
|
||||
typedef struct HS_ID HS_ID;
|
||||
struct HS_ID
|
||||
typedef struct C_ID C_ID;
|
||||
struct C_ID
|
||||
{
|
||||
U128 u128[1];
|
||||
};
|
||||
|
||||
typedef struct HS_Key HS_Key;
|
||||
struct HS_Key
|
||||
typedef struct C_Key C_Key;
|
||||
struct C_Key
|
||||
{
|
||||
HS_Root root;
|
||||
C_Root root;
|
||||
U64 _padding_;
|
||||
HS_ID id;
|
||||
C_ID id;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Root Cache Types
|
||||
|
||||
typedef struct HS_RootIDChunkNode HS_RootIDChunkNode;
|
||||
struct HS_RootIDChunkNode
|
||||
typedef struct C_RootIDChunkNode C_RootIDChunkNode;
|
||||
struct C_RootIDChunkNode
|
||||
{
|
||||
HS_RootIDChunkNode *next;
|
||||
HS_ID *v;
|
||||
C_RootIDChunkNode *next;
|
||||
C_ID *v;
|
||||
U64 count;
|
||||
U64 cap;
|
||||
};
|
||||
|
||||
typedef struct HS_RootIDChunkList HS_RootIDChunkList;
|
||||
struct HS_RootIDChunkList
|
||||
typedef struct C_RootIDChunkList C_RootIDChunkList;
|
||||
struct C_RootIDChunkList
|
||||
{
|
||||
HS_RootIDChunkNode *first;
|
||||
HS_RootIDChunkNode *last;
|
||||
C_RootIDChunkNode *first;
|
||||
C_RootIDChunkNode *last;
|
||||
U64 chunk_count;
|
||||
U64 total_count;
|
||||
};
|
||||
|
||||
typedef struct HS_RootNode HS_RootNode;
|
||||
struct HS_RootNode
|
||||
typedef struct C_RootNode C_RootNode;
|
||||
struct C_RootNode
|
||||
{
|
||||
HS_RootNode *next;
|
||||
HS_RootNode *prev;
|
||||
C_RootNode *next;
|
||||
C_RootNode *prev;
|
||||
Arena *arena;
|
||||
HS_Root root;
|
||||
HS_RootIDChunkList ids;
|
||||
C_Root root;
|
||||
C_RootIDChunkList ids;
|
||||
};
|
||||
|
||||
typedef struct HS_RootSlot HS_RootSlot;
|
||||
struct HS_RootSlot
|
||||
typedef struct C_RootSlot C_RootSlot;
|
||||
struct C_RootSlot
|
||||
{
|
||||
HS_RootNode *first;
|
||||
HS_RootNode *last;
|
||||
C_RootNode *first;
|
||||
C_RootNode *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Key Cache Types
|
||||
|
||||
#define HS_KEY_HASH_HISTORY_COUNT 64
|
||||
#define HS_KEY_HASH_HISTORY_STRONG_REF_COUNT 2
|
||||
#define C_KEY_HASH_HISTORY_COUNT 64
|
||||
#define C_KEY_HASH_HISTORY_STRONG_REF_COUNT 2
|
||||
|
||||
typedef struct HS_KeyNode HS_KeyNode;
|
||||
struct HS_KeyNode
|
||||
typedef struct C_KeyNode C_KeyNode;
|
||||
struct C_KeyNode
|
||||
{
|
||||
HS_KeyNode *next;
|
||||
HS_KeyNode *prev;
|
||||
HS_Key key;
|
||||
U128 hash_history[HS_KEY_HASH_HISTORY_COUNT];
|
||||
C_KeyNode *next;
|
||||
C_KeyNode *prev;
|
||||
C_Key key;
|
||||
U128 hash_history[C_KEY_HASH_HISTORY_COUNT];
|
||||
U64 hash_history_gen;
|
||||
};
|
||||
|
||||
typedef struct HS_KeySlot HS_KeySlot;
|
||||
struct HS_KeySlot
|
||||
typedef struct C_KeySlot C_KeySlot;
|
||||
struct C_KeySlot
|
||||
{
|
||||
HS_KeyNode *first;
|
||||
HS_KeyNode *last;
|
||||
C_KeyNode *first;
|
||||
C_KeyNode *last;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Content Blob Cache Types
|
||||
|
||||
typedef struct HS_BlobNode HS_BlobNode;
|
||||
struct HS_BlobNode
|
||||
typedef struct C_BlobNode C_BlobNode;
|
||||
struct C_BlobNode
|
||||
{
|
||||
HS_BlobNode *next;
|
||||
HS_BlobNode *prev;
|
||||
C_BlobNode *next;
|
||||
C_BlobNode *prev;
|
||||
U128 hash;
|
||||
Arena *arena;
|
||||
String8 data;
|
||||
@@ -140,15 +140,15 @@ struct HS_BlobNode
|
||||
U64 downstream_ref_count;
|
||||
};
|
||||
|
||||
typedef struct HS_BlobSlot HS_BlobSlot;
|
||||
struct HS_BlobSlot
|
||||
typedef struct C_BlobSlot C_BlobSlot;
|
||||
struct C_BlobSlot
|
||||
{
|
||||
HS_BlobNode *first;
|
||||
HS_BlobNode *last;
|
||||
C_BlobNode *first;
|
||||
C_BlobNode *last;
|
||||
};
|
||||
|
||||
typedef struct HS_Stripe HS_Stripe;
|
||||
struct HS_Stripe
|
||||
typedef struct C_Stripe C_Stripe;
|
||||
struct C_Stripe
|
||||
{
|
||||
Arena *arena;
|
||||
RWMutex rw_mutex;
|
||||
@@ -158,116 +158,116 @@ struct HS_Stripe
|
||||
////////////////////////////////
|
||||
//~ rjf: Scoped Access
|
||||
|
||||
typedef struct HS_Touch HS_Touch;
|
||||
struct HS_Touch
|
||||
typedef struct C_Touch C_Touch;
|
||||
struct C_Touch
|
||||
{
|
||||
HS_Touch *next;
|
||||
C_Touch *next;
|
||||
U128 hash;
|
||||
};
|
||||
|
||||
typedef struct HS_Scope HS_Scope;
|
||||
struct HS_Scope
|
||||
typedef struct C_Scope C_Scope;
|
||||
struct C_Scope
|
||||
{
|
||||
HS_Scope *next;
|
||||
HS_Touch *top_touch;
|
||||
C_Scope *next;
|
||||
C_Touch *top_touch;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Thread Context
|
||||
|
||||
typedef struct HS_TCTX HS_TCTX;
|
||||
struct HS_TCTX
|
||||
typedef struct C_TCTX C_TCTX;
|
||||
struct C_TCTX
|
||||
{
|
||||
Arena *arena;
|
||||
HS_Scope *free_scope;
|
||||
HS_Touch *free_touch;
|
||||
C_Scope *free_scope;
|
||||
C_Touch *free_touch;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Shared State
|
||||
|
||||
typedef struct HS_Shared HS_Shared;
|
||||
struct HS_Shared
|
||||
typedef struct C_Shared C_Shared;
|
||||
struct C_Shared
|
||||
{
|
||||
Arena *arena;
|
||||
|
||||
// rjf: main data cache
|
||||
U64 slots_count;
|
||||
U64 stripes_count;
|
||||
HS_BlobSlot *slots;
|
||||
HS_Stripe *stripes;
|
||||
HS_BlobNode **stripes_free_nodes;
|
||||
C_BlobSlot *slots;
|
||||
C_Stripe *stripes;
|
||||
C_BlobNode **stripes_free_nodes;
|
||||
|
||||
// rjf: key cache
|
||||
U64 key_slots_count;
|
||||
U64 key_stripes_count;
|
||||
HS_KeySlot *key_slots;
|
||||
HS_Stripe *key_stripes;
|
||||
HS_KeyNode **key_stripes_free_nodes;
|
||||
C_KeySlot *key_slots;
|
||||
C_Stripe *key_stripes;
|
||||
C_KeyNode **key_stripes_free_nodes;
|
||||
|
||||
// rjf: root cache
|
||||
U64 root_slots_count;
|
||||
U64 root_stripes_count;
|
||||
HS_RootSlot *root_slots;
|
||||
HS_Stripe *root_stripes;
|
||||
HS_RootNode **root_stripes_free_nodes;
|
||||
C_RootSlot *root_slots;
|
||||
C_Stripe *root_stripes;
|
||||
C_RootNode **root_stripes_free_nodes;
|
||||
U64 root_id_gen;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
thread_static HS_TCTX *hs_tctx = 0;
|
||||
global HS_Shared *hs_shared = 0;
|
||||
thread_static C_TCTX *c_tctx = 0;
|
||||
global C_Shared *c_shared = 0;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
internal U64 hs_little_hash_from_data(String8 data);
|
||||
internal U128 hs_hash_from_data(String8 data);
|
||||
internal HS_ID hs_id_make(U64 u64_0, U64 u64_1);
|
||||
internal B32 hs_id_match(HS_ID a, HS_ID b);
|
||||
internal HS_Key hs_key_make(HS_Root root, HS_ID id);
|
||||
internal B32 hs_key_match(HS_Key a, HS_Key b);
|
||||
internal U64 c_little_hash_from_data(String8 data);
|
||||
internal U128 c_hash_from_data(String8 data);
|
||||
internal C_ID c_id_make(U64 u64_0, U64 u64_1);
|
||||
internal B32 c_id_match(C_ID a, C_ID b);
|
||||
internal C_Key c_key_make(C_Root root, C_ID id);
|
||||
internal B32 c_key_match(C_Key a, C_Key b);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Layer Initialization
|
||||
|
||||
internal void hs_init(void);
|
||||
internal void c_init(void);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Root Allocation/Deallocation
|
||||
|
||||
internal HS_Root hs_root_alloc(void);
|
||||
internal void hs_root_release(HS_Root root);
|
||||
internal C_Root c_root_alloc(void);
|
||||
internal void c_root_release(C_Root root);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Submission
|
||||
|
||||
internal U128 hs_submit_data(HS_Key key, Arena **data_arena, String8 data);
|
||||
internal U128 c_submit_data(C_Key key, Arena **data_arena, String8 data);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scoped Access
|
||||
|
||||
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_BlobNode *node);
|
||||
internal C_Scope *c_scope_open(void);
|
||||
internal void c_scope_close(C_Scope *scope);
|
||||
internal void c_scope_touch_node__stripe_r_guarded(C_Scope *scope, C_BlobNode *node);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Downstream Accesses
|
||||
|
||||
internal void hs_hash_downstream_inc(U128 hash);
|
||||
internal void hs_hash_downstream_dec(U128 hash);
|
||||
internal void c_hash_downstream_inc(U128 hash);
|
||||
internal void c_hash_downstream_dec(U128 hash);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Lookups
|
||||
|
||||
internal U128 hs_hash_from_key(HS_Key key, U64 rewind_count);
|
||||
internal String8 hs_data_from_hash(HS_Scope *scope, U128 hash);
|
||||
internal U128 c_hash_from_key(C_Key key, U64 rewind_count);
|
||||
internal String8 c_data_from_hash(C_Scope *scope, U128 hash);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Tick
|
||||
|
||||
internal void hs_tick(void);
|
||||
internal void c_tick(void);
|
||||
|
||||
#endif // HASH_STORE_H
|
||||
#endif // CONTENT_H
|
||||
+22
-22
@@ -1620,7 +1620,7 @@ ctrl_set_wakeup_hook(CTRL_WakeupFunctionType *wakeup_hook)
|
||||
|
||||
//- rjf: process memory cache key reading
|
||||
|
||||
internal HS_Key
|
||||
internal C_Key
|
||||
ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale)
|
||||
{
|
||||
CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache;
|
||||
@@ -1634,7 +1634,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32
|
||||
|
||||
//- rjf: get the hash store root for this process; construct process node if it
|
||||
// doesn't exist
|
||||
HS_Root root = {0};
|
||||
C_Root root = {0};
|
||||
{
|
||||
B32 node_found = 0;
|
||||
MutexScopeR(process_stripe->rw_mutex)
|
||||
@@ -1667,7 +1667,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32
|
||||
DLLPushBack(process_slot->first, process_slot->last, node);
|
||||
node->arena = node_arena;
|
||||
node->handle = process;
|
||||
node->root = hs_root_alloc();
|
||||
node->root = c_root_alloc();
|
||||
node->range_hash_slots_count = 1024;
|
||||
node->range_hash_slots = push_array(node_arena, CTRL_ProcessMemoryRangeHashSlot, node->range_hash_slots_count);
|
||||
root = node->root;
|
||||
@@ -1676,7 +1676,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32
|
||||
}
|
||||
|
||||
//- rjf: form ID for this process memory query
|
||||
HS_ID id = {0};
|
||||
C_ID id = {0};
|
||||
{
|
||||
id.u128[0].u64[0] = vaddr_range.min & 0x00ffffffffffffffull;
|
||||
id.u128[0].u64[1] = vaddr_range.max & 0x00ffffffffffffffull;
|
||||
@@ -1685,10 +1685,10 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32
|
||||
id.u128[0].u64[0] |= (1ull << 63);
|
||||
}
|
||||
}
|
||||
U64 range_hash = hs_little_hash_from_data(str8_struct(&id));
|
||||
U64 range_hash = c_little_hash_from_data(str8_struct(&id));
|
||||
|
||||
//- rjf: form full key
|
||||
HS_Key key = hs_key_make(root, id);
|
||||
C_Key key = c_key_make(root, id);
|
||||
|
||||
//- rjf: loop: try to look for current results, request if not there, wait if we can, repeat until we can't
|
||||
U64 mem_gen = ctrl_mem_gen();
|
||||
@@ -1709,7 +1709,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32
|
||||
CTRL_ProcessMemoryRangeHashSlot *range_slot = &process_n->range_hash_slots[range_slot_idx];
|
||||
for(CTRL_ProcessMemoryRangeHashNode *n = range_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(hs_id_match(n->id, id))
|
||||
if(c_id_match(n->id, id))
|
||||
{
|
||||
id_exists = 1;
|
||||
id_stale = (n->mem_gen < mem_gen);
|
||||
@@ -1758,7 +1758,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32
|
||||
CTRL_ProcessMemoryRangeHashNode *range_n = 0;
|
||||
for(CTRL_ProcessMemoryRangeHashNode *n = range_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(hs_id_match(n->id, id))
|
||||
if(c_id_match(n->id, id))
|
||||
{
|
||||
range_n = n;
|
||||
break;
|
||||
@@ -1807,7 +1807,7 @@ ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32
|
||||
CTRL_ProcessMemoryRangeHashNode *range_n = 0;
|
||||
for(CTRL_ProcessMemoryRangeHashNode *n = range_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(hs_id_match(n->id, id))
|
||||
if(c_id_match(n->id, id))
|
||||
{
|
||||
n->working_count -= 1;
|
||||
break;
|
||||
@@ -1851,7 +1851,7 @@ ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rn
|
||||
range.max <= 0x000FFFFFFFFFFFFFull)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
HS_Scope *scope = hs_scope_open();
|
||||
C_Scope *scope = c_scope_open();
|
||||
CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache;
|
||||
|
||||
//- rjf: unpack address range, prepare per-touched-page info
|
||||
@@ -1868,9 +1868,9 @@ ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rn
|
||||
{
|
||||
U64 page_base_vaddr = page_range.min + page_idx*page_size;
|
||||
B32 page_is_stale = 0;
|
||||
HS_Key page_key = ctrl_key_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0, endt_us, &page_is_stale);
|
||||
U128 page_hash = hs_hash_from_key(page_key, 0);
|
||||
U128 page_last_hash = hs_hash_from_key(page_key, 1);
|
||||
C_Key page_key = ctrl_key_from_process_vaddr_range(process, r1u64(page_base_vaddr, page_base_vaddr+page_size), 0, endt_us, &page_is_stale);
|
||||
U128 page_hash = c_hash_from_key(page_key, 0);
|
||||
U128 page_last_hash = c_hash_from_key(page_key, 1);
|
||||
result.stale = (result.stale || page_is_stale);
|
||||
page_hashes[page_idx] = page_hash;
|
||||
page_last_hashes[page_idx] = page_last_hash;
|
||||
@@ -1889,7 +1889,7 @@ ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rn
|
||||
for(U64 page_idx = 0; page_idx < page_count; page_idx += 1)
|
||||
{
|
||||
// rjf: read data for this page
|
||||
String8 data = hs_data_from_hash(scope, page_hashes[page_idx]);
|
||||
String8 data = c_data_from_hash(scope, page_hashes[page_idx]);
|
||||
Rng1U64 data_vaddr_range = r1u64(page_range.min + page_idx*page_size, page_range.min + page_idx*page_size+data.size);
|
||||
|
||||
// rjf: skip/chop bytes which are irrelevant for the actual requested read
|
||||
@@ -1925,7 +1925,7 @@ ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rn
|
||||
// fill out changed flags
|
||||
if(!u128_match(page_hashes[page_idx], page_last_hashes[page_idx])) ProfScope("hashes don't match; diff each byte")
|
||||
{
|
||||
String8 last_data = hs_data_from_hash(scope, page_last_hashes[page_idx]);
|
||||
String8 last_data = c_data_from_hash(scope, page_last_hashes[page_idx]);
|
||||
String8 in_range_last_data = last_data;
|
||||
if(page_idx == page_count-1 && data_vaddr_range.max > range.max)
|
||||
{
|
||||
@@ -1977,7 +1977,7 @@ ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rn
|
||||
}
|
||||
}
|
||||
|
||||
hs_scope_close(scope);
|
||||
c_scope_close(scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
ProfEnd();
|
||||
@@ -6866,7 +6866,7 @@ ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg)
|
||||
//- rjf: user -> memory stream communication
|
||||
|
||||
internal B32
|
||||
ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us)
|
||||
ctrl_u2ms_enqueue_req(C_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us)
|
||||
{
|
||||
B32 good = 0;
|
||||
MutexScope(ctrl_state->u2ms_ring_mutex) for(;;)
|
||||
@@ -6890,7 +6890,7 @@ ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32
|
||||
}
|
||||
|
||||
internal void
|
||||
ctrl_u2ms_dequeue_req(HS_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated)
|
||||
ctrl_u2ms_dequeue_req(C_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated)
|
||||
{
|
||||
MutexScope(ctrl_state->u2ms_ring_mutex) for(;;)
|
||||
{
|
||||
@@ -6917,7 +6917,7 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work)
|
||||
CTRL_ProcessMemoryCache *cache = &ctrl_state->process_memory_cache;
|
||||
|
||||
//- rjf: unpack next request
|
||||
HS_Key key = {0};
|
||||
C_Key key = {0};
|
||||
CTRL_Handle process = {0};
|
||||
Rng1U64 vaddr_range = {0};
|
||||
B32 zero_terminated = 0;
|
||||
@@ -6932,7 +6932,7 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work)
|
||||
CTRL_ProcessMemoryCacheStripe *process_stripe = &cache->stripes[process_stripe_idx];
|
||||
|
||||
//- rjf: unpack address range hash cache key
|
||||
U64 range_hash = hs_little_hash_from_data(str8_struct(&key.id));
|
||||
U64 range_hash = c_little_hash_from_data(str8_struct(&key.id));
|
||||
|
||||
//- rjf: clamp vaddr range
|
||||
Rng1U64 vaddr_range_clamped = vaddr_range;
|
||||
@@ -7037,7 +7037,7 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work)
|
||||
U128 hash = {0};
|
||||
if(range_base != 0 && pre_read_mem_gen == post_read_mem_gen)
|
||||
{
|
||||
hash = hs_submit_data(key, &range_arena, str8((U8*)range_base, zero_terminated_size));
|
||||
hash = c_submit_data(key, &range_arena, str8((U8*)range_base, zero_terminated_size));
|
||||
}
|
||||
else if(range_arena != 0)
|
||||
{
|
||||
@@ -7055,7 +7055,7 @@ ASYNC_WORK_DEF(ctrl_mem_stream_work)
|
||||
CTRL_ProcessMemoryRangeHashSlot *range_slot = &n->range_hash_slots[range_slot_idx];
|
||||
for(CTRL_ProcessMemoryRangeHashNode *range_n = range_slot->first; range_n != 0; range_n = range_n->next)
|
||||
{
|
||||
if(hs_id_match(range_n->id, key.id))
|
||||
if(c_id_match(range_n->id, key.id))
|
||||
{
|
||||
if(pre_read_mem_gen == post_read_mem_gen)
|
||||
{
|
||||
|
||||
@@ -545,7 +545,7 @@ struct CTRL_ProcessMemoryRangeHashNode
|
||||
// rjf: key
|
||||
Rng1U64 vaddr_range;
|
||||
B32 zero_terminated;
|
||||
HS_ID id;
|
||||
C_ID id;
|
||||
|
||||
// rjf: staleness info
|
||||
U64 mem_gen;
|
||||
@@ -570,7 +570,7 @@ struct CTRL_ProcessMemoryCacheNode
|
||||
CTRL_ProcessMemoryCacheNode *prev;
|
||||
Arena *arena;
|
||||
CTRL_Handle handle;
|
||||
HS_Root root;
|
||||
C_Root root;
|
||||
U64 range_hash_slots_count;
|
||||
CTRL_ProcessMemoryRangeHashSlot *range_hash_slots;
|
||||
};
|
||||
@@ -1076,7 +1076,7 @@ internal void ctrl_set_wakeup_hook(CTRL_WakeupFunctionType *wakeup_hook);
|
||||
//~ rjf: Process Memory Functions
|
||||
|
||||
//- rjf: process memory cache key reading
|
||||
internal HS_Key ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale);
|
||||
internal C_Key ctrl_key_from_process_vaddr_range(CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us, B32 *out_is_stale);
|
||||
|
||||
//- rjf: process memory cache reading helpers
|
||||
internal CTRL_ProcessMemorySlice ctrl_process_memory_slice_from_vaddr_range(Arena *arena, CTRL_Handle process, Rng1U64 range, U64 endt_us);
|
||||
@@ -1206,8 +1206,8 @@ internal void ctrl_thread__single_step(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg);
|
||||
//~ rjf: Asynchronous Memory Streaming Functions
|
||||
|
||||
//- rjf: user -> memory stream communication
|
||||
internal B32 ctrl_u2ms_enqueue_req(HS_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us);
|
||||
internal void ctrl_u2ms_dequeue_req(HS_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated);
|
||||
internal B32 ctrl_u2ms_enqueue_req(C_Key key, CTRL_Handle process, Rng1U64 vaddr_range, B32 zero_terminated, U64 endt_us);
|
||||
internal void ctrl_u2ms_dequeue_req(C_Key *out_key, CTRL_Handle *out_process, Rng1U64 *out_vaddr_range, B32 *out_zero_terminated);
|
||||
|
||||
//- rjf: entry point
|
||||
ASYNC_WORK_DEF(ctrl_mem_stream_work);
|
||||
|
||||
+12
-12
@@ -382,7 +382,7 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
node->hash = hash;
|
||||
MemoryCopyStruct(&node->params, params);
|
||||
node->root = hs_root_alloc();
|
||||
node->root = c_root_alloc();
|
||||
// TODO(rjf): need to make this releasable - currently all exe_paths just leak
|
||||
node->params.dbgi_key = di_key_copy(stripe->arena, &node->params.dbgi_key);
|
||||
ins_atomic_u64_inc_eval(&node->working_count);
|
||||
@@ -416,12 +416,12 @@ dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params)
|
||||
}
|
||||
|
||||
internal DASM_Info
|
||||
dasm_info_from_key_params(DASM_Scope *scope, HS_Key key, DASM_Params *params, U128 *hash_out)
|
||||
dasm_info_from_key_params(DASM_Scope *scope, C_Key key, DASM_Params *params, U128 *hash_out)
|
||||
{
|
||||
DASM_Info result = {0};
|
||||
for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
|
||||
for(U64 rewind_idx = 0; rewind_idx < C_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
|
||||
{
|
||||
U128 hash = hs_hash_from_key(key, rewind_idx);
|
||||
U128 hash = c_hash_from_key(key, rewind_idx);
|
||||
result = dasm_info_from_hash_params(scope, hash, params);
|
||||
if(result.lines.count != 0)
|
||||
{
|
||||
@@ -552,17 +552,17 @@ dasm_tick(void)
|
||||
break;
|
||||
}
|
||||
U64 req_idx = req_num-1;
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
DI_Scope *di_scope = di_scope_open();
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
|
||||
//- rjf: unpack
|
||||
B32 stale = 0;
|
||||
DASM_Request *r = &reqs[req_idx];
|
||||
HS_Root root = r->root;
|
||||
C_Root root = r->root;
|
||||
U128 hash = r->hash;
|
||||
DASM_Params params = r->params;
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
String8 data = c_data_from_hash(c_scope, hash);
|
||||
U64 change_gen = fs_change_gen();
|
||||
U64 slot_idx = hash.u64[1]%dasm_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%dasm_shared->stripes_count;
|
||||
@@ -647,7 +647,7 @@ dasm_tick(void)
|
||||
{
|
||||
// TODO(rjf): need redirection path - this may map to a different path on the local machine,
|
||||
// need frontend to communicate path remapping info to this layer
|
||||
HS_Key key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64), 0);
|
||||
C_Key key = fs_key_from_path_range(file_normalized_full_path, r1u64(0, max_U64), 0);
|
||||
TXT_LangKind lang_kind = txt_lang_kind_from_extension(file_normalized_full_path);
|
||||
U64 endt_us = max_U64;
|
||||
U128 hash = {0};
|
||||
@@ -655,7 +655,7 @@ dasm_tick(void)
|
||||
stale = (stale || u128_match(hash, u128_zero()));
|
||||
if(0 < line->line_num && line->line_num < text_info.lines_count)
|
||||
{
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
String8 data = c_data_from_hash(c_scope, hash);
|
||||
String8 line_text = str8_skip_chop_whitespace(str8_substr(data, text_info.lines_ranges[line->line_num-1]));
|
||||
if(line_text.size != 0)
|
||||
{
|
||||
@@ -738,10 +738,10 @@ dasm_tick(void)
|
||||
String8 text = str8_list_join(text_arena, &inst_strings, &text_join);
|
||||
|
||||
//- rjf: produce unique key for this disassembly's text
|
||||
HS_Key text_key = hs_key_make(root, hs_id_make(0, 0));
|
||||
C_Key text_key = c_key_make(root, c_id_make(0, 0));
|
||||
|
||||
//- rjf: submit text data to hash store
|
||||
U128 text_hash = hs_submit_data(text_key, &text_arena, text);
|
||||
U128 text_hash = c_submit_data(text_key, &text_arena, text);
|
||||
|
||||
//- rjf: produce value bundle
|
||||
info_arena = arena_alloc();
|
||||
@@ -786,7 +786,7 @@ dasm_tick(void)
|
||||
|
||||
txt_scope_close(txt_scope);
|
||||
di_scope_close(di_scope);
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
}
|
||||
lane_sync();
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ struct DASM_Params
|
||||
typedef struct DASM_Request DASM_Request;
|
||||
struct DASM_Request
|
||||
{
|
||||
HS_Root root;
|
||||
C_Root root;
|
||||
U128 hash;
|
||||
DASM_Params params;
|
||||
};
|
||||
@@ -167,7 +167,7 @@ struct DASM_LineArray
|
||||
typedef struct DASM_Info DASM_Info;
|
||||
struct DASM_Info
|
||||
{
|
||||
HS_Key text_key;
|
||||
C_Key text_key;
|
||||
DASM_LineArray lines;
|
||||
};
|
||||
|
||||
@@ -186,7 +186,7 @@ struct DASM_Node
|
||||
DASM_Params params;
|
||||
|
||||
// rjf: root
|
||||
HS_Root root;
|
||||
C_Root root;
|
||||
|
||||
// rjf: generations
|
||||
U64 change_gen;
|
||||
@@ -318,7 +318,7 @@ internal void dasm_scope_touch_node__stripe_r_guarded(DASM_Scope *scope, DASM_No
|
||||
//~ rjf: Cache Lookups
|
||||
|
||||
internal DASM_Info dasm_info_from_hash_params(DASM_Scope *scope, U128 hash, DASM_Params *params);
|
||||
internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, HS_Key key, DASM_Params *params, U128 *hash_out);
|
||||
internal DASM_Info dasm_info_from_key_params(DASM_Scope *scope, C_Key key, DASM_Params *params, U128 *hash_out);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Ticks
|
||||
|
||||
@@ -1421,8 +1421,8 @@ d_init(void)
|
||||
d_state = push_array(arena, D_State, 1);
|
||||
d_state->arena = arena;
|
||||
d_state->cmds_arena = arena_alloc();
|
||||
d_state->output_log_key = hs_key_make(hs_root_alloc(), hs_id_make(0, 0));
|
||||
hs_submit_data(d_state->output_log_key, 0, str8_zero());
|
||||
d_state->output_log_key = c_key_make(c_root_alloc(), c_id_make(0, 0));
|
||||
c_submit_data(d_state->output_log_key, 0, str8_zero());
|
||||
d_state->ctrl_entity_store = ctrl_entity_ctx_rw_store_alloc();
|
||||
d_state->ctrl_stop_arena = arena_alloc();
|
||||
d_state->ctrl_msg_arena = arena_alloc();
|
||||
|
||||
@@ -283,7 +283,7 @@ struct D_State
|
||||
D_CmdList cmds;
|
||||
|
||||
// rjf: output log key
|
||||
HS_Key output_log_key;
|
||||
C_Key output_log_key;
|
||||
|
||||
// rjf: per-run caches
|
||||
U64 tls_base_cache_reggen_idx;
|
||||
|
||||
@@ -27,7 +27,7 @@ fs_big_hash_from_string_range(String8 string, Rng1U64 range)
|
||||
MemoryCopy(buffer, string.str, string.size);
|
||||
MemoryCopy(buffer + string.size, &range.min, sizeof(range.min));
|
||||
MemoryCopy(buffer + string.size + sizeof(range.min), &range.max, sizeof(range.max));
|
||||
U128 hash = hs_hash_from_data(str8(buffer, buffer_size));
|
||||
U128 hash = c_hash_from_data(str8(buffer, buffer_size));
|
||||
scratch_end(scratch);
|
||||
return hash;
|
||||
}
|
||||
@@ -68,7 +68,7 @@ fs_change_gen(void)
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Interaction
|
||||
|
||||
internal HS_Key
|
||||
internal C_Key
|
||||
fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
@@ -82,7 +82,7 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
|
||||
FS_Stripe *path_stripe = &fs_shared->stripes[path_stripe_idx];
|
||||
|
||||
//- rjf: get root for this path - on 1st try (read mode), try to read, on 2nd try (write mode), create node
|
||||
HS_Root root = {0};
|
||||
C_Root root = {0};
|
||||
for(B32 write_mode = 0; write_mode <= 1; write_mode += 1)
|
||||
{
|
||||
B32 node_found = 0;
|
||||
@@ -102,7 +102,7 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
|
||||
FS_Node *node = push_array(path_stripe->arena, FS_Node, 1);
|
||||
SLLQueuePush(path_slot->first, path_slot->last, node);
|
||||
node->path = push_str8_copy(path_stripe->arena, path);
|
||||
node->root = hs_root_alloc();
|
||||
node->root = c_root_alloc();
|
||||
node->slots_count = 64;
|
||||
node->slots = push_array(path_stripe->arena, FS_RangeSlot, node->slots_count);
|
||||
root = node->root;
|
||||
@@ -115,11 +115,11 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
|
||||
}
|
||||
|
||||
//- rjf: build a key for this path/range combo
|
||||
HS_Key key = hs_key_make(root, hs_id_make(range.min, range.max));
|
||||
C_Key key = c_key_make(root, c_id_make(range.min, range.max));
|
||||
|
||||
//- rjf: if the most recent hash for this key is zero, then try to submit a new
|
||||
// request to pull it in.
|
||||
if(u128_match(hs_hash_from_key(key, 0), u128_zero()))
|
||||
if(u128_match(c_hash_from_key(key, 0), u128_zero()))
|
||||
{
|
||||
// rjf: loop: request, check for results, return until we can't
|
||||
RWMutexScope(path_stripe->rw_mutex, 1) for(;;)
|
||||
@@ -148,7 +148,7 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
|
||||
FS_RangeNode *range_node = 0;
|
||||
for(FS_RangeNode *n = range_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(hs_id_match(n->id, key.id))
|
||||
if(c_id_match(n->id, key.id))
|
||||
{
|
||||
range_node = n;
|
||||
break;
|
||||
@@ -180,7 +180,7 @@ fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
|
||||
}
|
||||
|
||||
// rjf: have time to wait? -> wait on this stripe; otherwise exit
|
||||
B32 have_results = !u128_match(hs_hash_from_key(key, 0), u128_zero());
|
||||
B32 have_results = !u128_match(c_hash_from_key(key, 0), u128_zero());
|
||||
if(!have_results && os_now_microseconds() < endt_us)
|
||||
{
|
||||
cond_var_wait_rw(path_stripe->cv, path_stripe->rw_mutex, 1, endt_us);
|
||||
@@ -201,10 +201,10 @@ fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us)
|
||||
{
|
||||
U128 hash = {0};
|
||||
{
|
||||
HS_Key key = fs_key_from_path_range(path, range, endt_us);
|
||||
for EachIndex(rewind_idx, HS_KEY_HASH_HISTORY_COUNT)
|
||||
C_Key key = fs_key_from_path_range(path, range, endt_us);
|
||||
for EachIndex(rewind_idx, C_KEY_HASH_HISTORY_COUNT)
|
||||
{
|
||||
hash = hs_hash_from_key(key, rewind_idx);
|
||||
hash = c_hash_from_key(key, rewind_idx);
|
||||
if(!u128_match(hash, u128_zero()))
|
||||
{
|
||||
break;
|
||||
@@ -271,7 +271,7 @@ fs_tick(void)
|
||||
range_n != 0;
|
||||
range_n = range_n->next)
|
||||
{
|
||||
HS_Key key = hs_key_make(n->root, range_n->id);
|
||||
C_Key key = c_key_make(n->root, range_n->id);
|
||||
if(ins_atomic_u64_eval(&range_n->working_count) == 0)
|
||||
{
|
||||
ins_atomic_u64_inc_eval(&range_n->working_count);
|
||||
@@ -325,7 +325,7 @@ fs_tick(void)
|
||||
}
|
||||
U64 req_idx = req_num-1;
|
||||
FS_Request *r = &reqs[req_idx];
|
||||
HS_Key key = r->key;
|
||||
C_Key key = r->key;
|
||||
String8 path = r->path;
|
||||
Rng1U64 range = r->range;
|
||||
U64 path_hash = fs_little_hash_from_string(path);
|
||||
@@ -373,7 +373,7 @@ fs_tick(void)
|
||||
{
|
||||
ProfScope("submit")
|
||||
{
|
||||
hs_submit_data(key, &data_arena, data);
|
||||
c_submit_data(key, &data_arena, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ typedef struct FS_RangeNode FS_RangeNode;
|
||||
struct FS_RangeNode
|
||||
{
|
||||
FS_RangeNode *next;
|
||||
HS_ID id;
|
||||
C_ID id;
|
||||
U64 working_count;
|
||||
};
|
||||
|
||||
@@ -32,7 +32,7 @@ struct FS_Node
|
||||
FileProperties props;
|
||||
|
||||
// rjf: hash store root
|
||||
HS_Root root;
|
||||
C_Root root;
|
||||
|
||||
// rjf: sub-table of per-requested-file-range info
|
||||
U64 slots_count;
|
||||
@@ -61,7 +61,7 @@ typedef struct FS_Request FS_Request;
|
||||
struct FS_Request
|
||||
{
|
||||
FS_Request *next;
|
||||
HS_Key key;
|
||||
C_Key key;
|
||||
String8 path;
|
||||
Rng1U64 range;
|
||||
};
|
||||
@@ -120,7 +120,7 @@ internal U64 fs_change_gen(void);
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Interaction
|
||||
|
||||
internal HS_Key fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us);
|
||||
internal C_Key fs_key_from_path_range(String8 path, Rng1U64 range, U64 endt_us);
|
||||
internal U128 fs_hash_from_path_range(String8 path, Rng1U64 range, U64 endt_us);
|
||||
internal FileProperties fs_properties_from_path(String8 path);
|
||||
|
||||
|
||||
@@ -181,12 +181,12 @@ geo_buffer_from_hash(GEO_Scope *scope, U128 hash)
|
||||
}
|
||||
|
||||
internal R_Handle
|
||||
geo_buffer_from_key(GEO_Scope *scope, HS_Key key)
|
||||
geo_buffer_from_key(GEO_Scope *scope, C_Key key)
|
||||
{
|
||||
R_Handle handle = {0};
|
||||
for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
|
||||
for(U64 rewind_idx = 0; rewind_idx < C_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
|
||||
{
|
||||
U128 hash = hs_hash_from_key(key, rewind_idx);
|
||||
U128 hash = c_hash_from_key(key, rewind_idx);
|
||||
handle = geo_buffer_from_hash(scope, hash);
|
||||
if(!r_handle_match(handle, r_handle_zero()))
|
||||
{
|
||||
@@ -245,7 +245,7 @@ geo_u2x_dequeue_req(U128 *hash_out)
|
||||
ASYNC_WORK_DEF(geo_xfer_work)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
HS_Scope *scope = hs_scope_open();
|
||||
C_Scope *scope = c_scope_open();
|
||||
|
||||
//- rjf: decode
|
||||
U128 hash = {0};
|
||||
@@ -275,7 +275,7 @@ ASYNC_WORK_DEF(geo_xfer_work)
|
||||
String8 data = {0};
|
||||
if(got_task)
|
||||
{
|
||||
data = hs_data_from_hash(scope, hash);
|
||||
data = c_data_from_hash(scope, hash);
|
||||
}
|
||||
|
||||
//- rjf: data -> buffer
|
||||
@@ -300,7 +300,7 @@ ASYNC_WORK_DEF(geo_xfer_work)
|
||||
}
|
||||
}
|
||||
|
||||
hs_scope_close(scope);
|
||||
c_scope_close(scope);
|
||||
ProfEnd();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ internal void geo_scope_touch_node__stripe_r_guarded(GEO_Scope *scope, GEO_Node
|
||||
//~ rjf: Cache Lookups
|
||||
|
||||
internal R_Handle geo_buffer_from_hash(GEO_Scope *scope, U128 hash);
|
||||
internal R_Handle geo_buffer_from_key(GEO_Scope *scope, HS_Key key);
|
||||
internal R_Handle geo_buffer_from_key(GEO_Scope *scope, C_Key key);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Transfer Threads
|
||||
|
||||
@@ -1,593 +0,0 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#undef LAYER_COLOR
|
||||
#define LAYER_COLOR 0x684123ff
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
#if !defined(XXH_IMPLEMENTATION)
|
||||
# define XXH_IMPLEMENTATION
|
||||
# define XXH_STATIC_LINKING_ONLY
|
||||
# include "third_party/xxHash/xxhash.h"
|
||||
#endif
|
||||
|
||||
internal U64
|
||||
hs_little_hash_from_data(String8 data)
|
||||
{
|
||||
U64 result = XXH3_64bits(data.str, data.size);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal U128
|
||||
hs_hash_from_data(String8 data)
|
||||
{
|
||||
U128 u128 = {0};
|
||||
XXH128_hash_t hash = XXH3_128bits(data.str, data.size);
|
||||
MemoryCopy(&u128, &hash, sizeof(u128));
|
||||
return u128;
|
||||
}
|
||||
|
||||
internal HS_ID
|
||||
hs_id_make(U64 u64_0, U64 u64_1)
|
||||
{
|
||||
HS_ID id;
|
||||
id.u128[0].u64[0] = u64_0;
|
||||
id.u128[0].u64[1] = u64_1;
|
||||
return id;
|
||||
}
|
||||
|
||||
internal B32
|
||||
hs_id_match(HS_ID a, HS_ID b)
|
||||
{
|
||||
B32 result = MemoryMatchStruct(&a, &b);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal HS_Key
|
||||
hs_key_make(HS_Root root, HS_ID id)
|
||||
{
|
||||
HS_Key key = {root, 0, id};
|
||||
return key;
|
||||
}
|
||||
|
||||
internal B32
|
||||
hs_key_match(HS_Key a, HS_Key b)
|
||||
{
|
||||
return (MemoryMatchStruct(&a.root, &b.root) && hs_id_match(a.id, b.id));
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Main Layer Initialization
|
||||
|
||||
internal void
|
||||
hs_init(void)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
hs_shared = push_array(arena, HS_Shared, 1);
|
||||
hs_shared->arena = arena;
|
||||
hs_shared->slots_count = 4096;
|
||||
hs_shared->stripes_count = Min(hs_shared->slots_count, os_get_system_info()->logical_processor_count);
|
||||
hs_shared->slots = push_array(arena, HS_BlobSlot, hs_shared->slots_count);
|
||||
hs_shared->stripes = push_array(arena, HS_Stripe, hs_shared->stripes_count);
|
||||
hs_shared->stripes_free_nodes = push_array(arena, HS_BlobNode *, hs_shared->stripes_count);
|
||||
for(U64 idx = 0; idx < hs_shared->stripes_count; idx += 1)
|
||||
{
|
||||
HS_Stripe *stripe = &hs_shared->stripes[idx];
|
||||
stripe->arena = arena_alloc();
|
||||
stripe->rw_mutex = rw_mutex_alloc();
|
||||
stripe->cv = cond_var_alloc();
|
||||
}
|
||||
hs_shared->key_slots_count = 4096;
|
||||
hs_shared->key_stripes_count = Min(hs_shared->key_slots_count, os_get_system_info()->logical_processor_count);
|
||||
hs_shared->key_slots = push_array(arena, HS_KeySlot, hs_shared->key_slots_count);
|
||||
hs_shared->key_stripes = push_array(arena, HS_Stripe, hs_shared->key_stripes_count);
|
||||
hs_shared->key_stripes_free_nodes = push_array(arena, HS_KeyNode *, hs_shared->key_stripes_count);
|
||||
for(U64 idx = 0; idx < hs_shared->key_stripes_count; idx += 1)
|
||||
{
|
||||
HS_Stripe *stripe = &hs_shared->key_stripes[idx];
|
||||
stripe->arena = arena_alloc();
|
||||
stripe->rw_mutex = rw_mutex_alloc();
|
||||
stripe->cv = cond_var_alloc();
|
||||
}
|
||||
hs_shared->root_slots_count = 4096;
|
||||
hs_shared->root_stripes_count = Min(hs_shared->root_slots_count, os_get_system_info()->logical_processor_count);
|
||||
hs_shared->root_slots = push_array(arena, HS_RootSlot, hs_shared->root_slots_count);
|
||||
hs_shared->root_stripes = push_array(arena, HS_Stripe, hs_shared->root_stripes_count);
|
||||
hs_shared->root_stripes_free_nodes = push_array(arena, HS_RootNode *, hs_shared->root_stripes_count);
|
||||
for(U64 idx = 0; idx < hs_shared->root_stripes_count; idx += 1)
|
||||
{
|
||||
HS_Stripe *stripe = &hs_shared->root_stripes[idx];
|
||||
stripe->arena = arena_alloc();
|
||||
stripe->rw_mutex = rw_mutex_alloc();
|
||||
stripe->cv = cond_var_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Root Allocation/Deallocation
|
||||
|
||||
internal HS_Root
|
||||
hs_root_alloc(void)
|
||||
{
|
||||
HS_Root root = {0};
|
||||
root.u64[0] = ins_atomic_u64_inc_eval(&hs_shared->root_id_gen);
|
||||
U64 slot_idx = root.u64[0]%hs_shared->root_slots_count;
|
||||
U64 stripe_idx = slot_idx%hs_shared->root_stripes_count;
|
||||
HS_RootSlot *slot = &hs_shared->root_slots[slot_idx];
|
||||
HS_Stripe *stripe = &hs_shared->root_stripes[stripe_idx];
|
||||
MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
HS_RootNode *node = hs_shared->root_stripes_free_nodes[stripe_idx];
|
||||
if(node != 0)
|
||||
{
|
||||
SLLStackPop(hs_shared->root_stripes_free_nodes[stripe_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = push_array(stripe->arena, HS_RootNode, 1);
|
||||
}
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
node->root = root;
|
||||
node->arena = arena_alloc();
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
internal void
|
||||
hs_root_release(HS_Root root)
|
||||
{
|
||||
//- rjf: unpack root
|
||||
U64 slot_idx = root.u64[0]%hs_shared->root_slots_count;
|
||||
U64 stripe_idx = slot_idx%hs_shared->root_stripes_count;
|
||||
HS_RootSlot *slot = &hs_shared->root_slots[slot_idx];
|
||||
HS_Stripe *stripe = &hs_shared->root_stripes[stripe_idx];
|
||||
|
||||
//- rjf: release root node, grab its arena / ID list
|
||||
Arena *root_arena = 0;
|
||||
HS_RootIDChunkList root_ids = {0};
|
||||
MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
for(HS_RootNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(MemoryMatchStruct(&root, &n->root))
|
||||
{
|
||||
DLLRemove(slot->first, slot->last, n);
|
||||
root_arena = n->arena;
|
||||
root_ids = n->ids;
|
||||
SLLStackPush(hs_shared->root_stripes_free_nodes[stripe_idx], n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: release all IDs
|
||||
for(HS_RootIDChunkNode *id_chunk_n = root_ids.first; id_chunk_n != 0; id_chunk_n = id_chunk_n->next)
|
||||
{
|
||||
for EachIndex(chunk_idx, id_chunk_n->count)
|
||||
{
|
||||
HS_ID id = id_chunk_n->v[chunk_idx];
|
||||
HS_Key key = hs_key_make(root, id);
|
||||
U64 key_hash = hs_little_hash_from_data(str8_struct(&key));
|
||||
U64 key_slot_idx = key_hash%hs_shared->key_slots_count;
|
||||
U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count;
|
||||
HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx];
|
||||
HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx];
|
||||
MutexScopeW(key_stripe->rw_mutex)
|
||||
{
|
||||
for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(hs_key_match(n->key, key))
|
||||
{
|
||||
// rjf: release reference to all hashes
|
||||
for(U64 history_idx = 0; history_idx < HS_KEY_HASH_HISTORY_STRONG_REF_COUNT && history_idx < n->hash_history_gen; history_idx += 1)
|
||||
{
|
||||
U128 hash = n->hash_history[(n->hash_history_gen+history_idx)%ArrayCount(n->hash_history)];
|
||||
U64 hash_slot_idx = hash.u64[1]%hs_shared->slots_count;
|
||||
U64 hash_stripe_idx = hash_slot_idx%hs_shared->stripes_count;
|
||||
HS_BlobSlot *hash_slot = &hs_shared->slots[hash_slot_idx];
|
||||
HS_Stripe *hash_stripe = &hs_shared->stripes[hash_stripe_idx];
|
||||
MutexScopeR(hash_stripe->rw_mutex)
|
||||
{
|
||||
for(HS_BlobNode *n = hash_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->hash, hash))
|
||||
{
|
||||
ins_atomic_u64_dec_eval(&n->key_ref_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: release key node
|
||||
DLLRemove(key_slot->first, key_slot->last, n);
|
||||
SLLStackPush(hs_shared->key_stripes_free_nodes[key_stripe_idx], n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Submission
|
||||
|
||||
internal U128
|
||||
hs_submit_data(HS_Key key, Arena **data_arena, String8 data)
|
||||
{
|
||||
U64 key_hash = hs_little_hash_from_data(str8_struct(&key));
|
||||
U64 key_slot_idx = key_hash%hs_shared->key_slots_count;
|
||||
U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count;
|
||||
HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx];
|
||||
HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx];
|
||||
U128 hash = hs_hash_from_data(data);
|
||||
U64 slot_idx = hash.u64[1]%hs_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%hs_shared->stripes_count;
|
||||
HS_BlobSlot *slot = &hs_shared->slots[slot_idx];
|
||||
HS_Stripe *stripe = &hs_shared->stripes[stripe_idx];
|
||||
|
||||
//- rjf: commit data to cache - if already there, just bump key refcount
|
||||
ProfScope("commit data to cache - if already there, just bump key refcount") MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
HS_BlobNode *existing_node = 0;
|
||||
for(HS_BlobNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->hash, hash))
|
||||
{
|
||||
existing_node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(existing_node == 0)
|
||||
{
|
||||
HS_BlobNode *node = hs_shared->stripes_free_nodes[stripe_idx];
|
||||
if(node)
|
||||
{
|
||||
SLLStackPop(hs_shared->stripes_free_nodes[stripe_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
node = push_array(stripe->arena, HS_BlobNode, 1);
|
||||
}
|
||||
node->hash = hash;
|
||||
if(data_arena != 0)
|
||||
{
|
||||
node->arena = *data_arena;
|
||||
}
|
||||
node->data = data;
|
||||
node->scope_ref_count = 0;
|
||||
node->key_ref_count = 1;
|
||||
DLLPushBack(slot->first, slot->last, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
existing_node->key_ref_count += 1;
|
||||
if(data_arena != 0)
|
||||
{
|
||||
arena_release(*data_arena);
|
||||
}
|
||||
}
|
||||
if(data_arena != 0)
|
||||
{
|
||||
*data_arena = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: commit this hash to key cache
|
||||
U128 key_expired_hash = {0};
|
||||
ProfScope("commit this hash to key cache") MutexScopeW(key_stripe->rw_mutex)
|
||||
{
|
||||
// rjf: find existing key
|
||||
B32 key_is_new = 0;
|
||||
HS_KeyNode *key_node = 0;
|
||||
for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(hs_key_match(n->key, key))
|
||||
{
|
||||
key_node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: create key node if it doesn't exist
|
||||
if(!key_node)
|
||||
{
|
||||
key_is_new = 1;
|
||||
key_node = hs_shared->key_stripes_free_nodes[key_stripe_idx];
|
||||
if(key_node)
|
||||
{
|
||||
SLLStackPop(hs_shared->key_stripes_free_nodes[key_stripe_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
key_node = push_array(key_stripe->arena, HS_KeyNode, 1);
|
||||
}
|
||||
key_node->key = key;
|
||||
DLLPushBack(key_slot->first, key_slot->last, key_node);
|
||||
}
|
||||
|
||||
// rjf: push hash into key's history
|
||||
if(key_node)
|
||||
{
|
||||
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-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: key is new -> add this key to the associated root
|
||||
if(key_is_new)
|
||||
{
|
||||
U64 root_hash = hs_little_hash_from_data(str8_struct(&key.root));
|
||||
U64 root_slot_idx = root_hash%hs_shared->root_slots_count;
|
||||
U64 root_stripe_idx = root_slot_idx%hs_shared->root_stripes_count;
|
||||
HS_RootSlot *root_slot = &hs_shared->root_slots[root_slot_idx];
|
||||
HS_Stripe *root_stripe = &hs_shared->root_stripes[root_stripe_idx];
|
||||
MutexScopeW(root_stripe->rw_mutex)
|
||||
{
|
||||
for(HS_RootNode *n = root_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(MemoryMatchStruct(&n->root, &key.root))
|
||||
{
|
||||
HS_RootIDChunkNode *chunk = n->ids.last;
|
||||
if(chunk == 0 || chunk->count >= chunk->cap)
|
||||
{
|
||||
chunk = push_array(n->arena, HS_RootIDChunkNode, 1);
|
||||
SLLQueuePush(n->ids.first, n->ids.last, chunk);
|
||||
n->ids.chunk_count += 1;
|
||||
chunk->cap = 1024;
|
||||
chunk->v = push_array_no_zero(n->arena, HS_ID, chunk->cap);
|
||||
}
|
||||
chunk->v[chunk->count] = key.id;
|
||||
chunk->count += 1;
|
||||
n->ids.total_count += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- 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;
|
||||
U64 old_hash_stripe_idx = old_hash_slot_idx%hs_shared->stripes_count;
|
||||
HS_BlobSlot *old_hash_slot = &hs_shared->slots[old_hash_slot_idx];
|
||||
HS_Stripe *old_hash_stripe = &hs_shared->stripes[old_hash_stripe_idx];
|
||||
MutexScopeR(old_hash_stripe->rw_mutex)
|
||||
{
|
||||
for(HS_BlobNode *n = old_hash_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->hash, key_expired_hash))
|
||||
{
|
||||
ins_atomic_u64_dec_eval(&n->key_ref_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Scoped Access
|
||||
|
||||
internal HS_Scope *
|
||||
hs_scope_open(void)
|
||||
{
|
||||
if(hs_tctx == 0)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
hs_tctx = push_array(arena, HS_TCTX, 1);
|
||||
hs_tctx->arena = arena;
|
||||
}
|
||||
HS_Scope *scope = hs_tctx->free_scope;
|
||||
if(scope)
|
||||
{
|
||||
SLLStackPop(hs_tctx->free_scope);
|
||||
}
|
||||
else
|
||||
{
|
||||
scope = push_array_no_zero(hs_tctx->arena, HS_Scope, 1);
|
||||
}
|
||||
MemoryZeroStruct(scope);
|
||||
return scope;
|
||||
}
|
||||
|
||||
internal void
|
||||
hs_scope_close(HS_Scope *scope)
|
||||
{
|
||||
for(HS_Touch *touch = scope->top_touch, *next = 0; touch != 0; touch = next)
|
||||
{
|
||||
U128 hash = touch->hash;
|
||||
next = touch->next;
|
||||
U64 slot_idx = hash.u64[1]%hs_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%hs_shared->stripes_count;
|
||||
HS_BlobSlot *slot = &hs_shared->slots[slot_idx];
|
||||
HS_Stripe *stripe = &hs_shared->stripes[stripe_idx];
|
||||
MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(HS_BlobNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(hash, n->hash))
|
||||
{
|
||||
ins_atomic_u64_dec_eval(&n->scope_ref_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SLLStackPush(hs_tctx->free_touch, touch);
|
||||
}
|
||||
SLLStackPush(hs_tctx->free_scope, scope);
|
||||
}
|
||||
|
||||
internal void
|
||||
hs_scope_touch_node__stripe_r_guarded(HS_Scope *scope, HS_BlobNode *node)
|
||||
{
|
||||
HS_Touch *touch = hs_tctx->free_touch;
|
||||
ins_atomic_u64_inc_eval(&node->scope_ref_count);
|
||||
if(touch != 0)
|
||||
{
|
||||
SLLStackPop(hs_tctx->free_touch);
|
||||
}
|
||||
else
|
||||
{
|
||||
touch = push_array_no_zero(hs_tctx->arena, HS_Touch, 1);
|
||||
}
|
||||
MemoryZeroStruct(touch);
|
||||
touch->hash = node->hash;
|
||||
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_BlobSlot *slot = &hs_shared->slots[slot_idx];
|
||||
HS_Stripe *stripe = &hs_shared->stripes[stripe_idx];
|
||||
MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(HS_BlobNode *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_BlobSlot *slot = &hs_shared->slots[slot_idx];
|
||||
HS_Stripe *stripe = &hs_shared->stripes[stripe_idx];
|
||||
MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(HS_BlobNode *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
|
||||
|
||||
internal U128
|
||||
hs_hash_from_key(HS_Key key, U64 rewind_count)
|
||||
{
|
||||
U128 result = {0};
|
||||
U64 key_hash = hs_little_hash_from_data(str8_struct(&key));
|
||||
U64 key_slot_idx = key_hash%hs_shared->key_slots_count;
|
||||
U64 key_stripe_idx = key_slot_idx%hs_shared->key_stripes_count;
|
||||
HS_KeySlot *key_slot = &hs_shared->key_slots[key_slot_idx];
|
||||
HS_Stripe *key_stripe = &hs_shared->key_stripes[key_stripe_idx];
|
||||
MutexScopeR(key_stripe->rw_mutex)
|
||||
{
|
||||
for(HS_KeyNode *n = key_slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(hs_key_match(n->key, key) && n->hash_history_gen > 0 && n->hash_history_gen-1 >= rewind_count)
|
||||
{
|
||||
result = n->hash_history[(n->hash_history_gen-1-rewind_count)%ArrayCount(n->hash_history)];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
hs_data_from_hash(HS_Scope *scope, U128 hash)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
String8 result = {0};
|
||||
U64 slot_idx = hash.u64[1]%hs_shared->slots_count;
|
||||
U64 stripe_idx = slot_idx%hs_shared->stripes_count;
|
||||
HS_BlobSlot *slot = &hs_shared->slots[slot_idx];
|
||||
HS_Stripe *stripe = &hs_shared->stripes[stripe_idx];
|
||||
MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(HS_BlobNode *n = slot->first; n != 0; n = n->next)
|
||||
{
|
||||
if(u128_match(n->hash, hash))
|
||||
{
|
||||
result = n->data;
|
||||
hs_scope_touch_node__stripe_r_guarded(scope, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ProfEnd();
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Tick
|
||||
|
||||
internal void
|
||||
hs_tick(void)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Rng1U64 range = lane_range(hs_shared->slots_count);
|
||||
for EachInRange(slot_idx, range)
|
||||
{
|
||||
U64 stripe_idx = slot_idx%hs_shared->stripes_count;
|
||||
HS_BlobSlot *slot = &hs_shared->slots[slot_idx];
|
||||
HS_Stripe *stripe = &hs_shared->stripes[stripe_idx];
|
||||
B32 slot_has_work = 0;
|
||||
MutexScopeR(stripe->rw_mutex)
|
||||
{
|
||||
for(HS_BlobNode *n = slot->first; n != 0; n = 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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(slot_has_work) MutexScopeW(stripe->rw_mutex)
|
||||
{
|
||||
for(HS_BlobNode *n = slot->first, *next = 0; n != 0; n = next)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
if(n->arena != 0)
|
||||
{
|
||||
arena_release(n->arena);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ProfEnd();
|
||||
}
|
||||
@@ -38,9 +38,9 @@ mtx_init(void)
|
||||
//~ rjf: Buffer Operations
|
||||
|
||||
internal void
|
||||
mtx_push_op(HS_Key buffer_key, MTX_Op op)
|
||||
mtx_push_op(C_Key buffer_key, MTX_Op op)
|
||||
{
|
||||
U64 hash = hs_little_hash_from_data(str8_struct(&buffer_key));
|
||||
U64 hash = c_little_hash_from_data(str8_struct(&buffer_key));
|
||||
MTX_MutThread *thread = &mtx_shared->mut_threads[hash%mtx_shared->mut_threads_count];
|
||||
mtx_enqueue_op(thread, buffer_key, op);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ mtx_push_op(HS_Key buffer_key, MTX_Op op)
|
||||
//~ rjf: Mutation Threads
|
||||
|
||||
internal void
|
||||
mtx_enqueue_op(MTX_MutThread *thread, HS_Key buffer_key, MTX_Op op)
|
||||
mtx_enqueue_op(MTX_MutThread *thread, C_Key buffer_key, MTX_Op op)
|
||||
{
|
||||
// TODO(rjf): if op.replace is too big, need to split into multiple edits
|
||||
MutexScope(thread->mutex) for(;;)
|
||||
@@ -71,7 +71,7 @@ mtx_enqueue_op(MTX_MutThread *thread, HS_Key buffer_key, MTX_Op op)
|
||||
}
|
||||
|
||||
internal void
|
||||
mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, HS_Key *buffer_key_out, MTX_Op *op_out)
|
||||
mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, C_Key *buffer_key_out, MTX_Op *op_out)
|
||||
{
|
||||
MutexScope(thread->mutex) for(;;)
|
||||
{
|
||||
@@ -98,16 +98,16 @@ mtx_mut_thread__entry_point(void *p)
|
||||
for(;;)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
|
||||
//- rjf: get next op
|
||||
HS_Key buffer_key = {0};
|
||||
C_Key buffer_key = {0};
|
||||
MTX_Op op = {0};
|
||||
mtx_dequeue_op(scratch.arena, mut_thread, &buffer_key, &op);
|
||||
|
||||
//- rjf: get buffer's current data
|
||||
U128 hash = hs_hash_from_key(buffer_key, 0);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
U128 hash = c_hash_from_key(buffer_key, 0);
|
||||
String8 data = c_data_from_hash(c_scope, hash);
|
||||
|
||||
//- rjf: clamp op by data
|
||||
op.range.min = Min(op.range.min, data.size);
|
||||
@@ -134,10 +134,10 @@ mtx_mut_thread__entry_point(void *p)
|
||||
MemoryCopy(new_data_base+pre_replace_data.size+op.replace.size, post_replace_data.str, post_replace_data.size);
|
||||
}
|
||||
String8 new_data = str8(new_data_base, new_data_size);
|
||||
hs_submit_data(buffer_key, &arena, new_data);
|
||||
c_submit_data(buffer_key, &arena, new_data);
|
||||
}
|
||||
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,13 +84,13 @@ internal void mtx_init(void);
|
||||
////////////////////////////////
|
||||
//~ rjf: Buffer Operations
|
||||
|
||||
internal void mtx_push_op(HS_Key buffer_key, MTX_Op op);
|
||||
internal void mtx_push_op(C_Key buffer_key, MTX_Op op);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Mutation Threads
|
||||
|
||||
internal void mtx_enqueue_op(MTX_MutThread *thread, HS_Key buffer_key, MTX_Op op);
|
||||
internal void mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, HS_Key *buffer_key_out, MTX_Op *op_out);
|
||||
internal void mtx_enqueue_op(MTX_MutThread *thread, C_Key buffer_key, MTX_Op op);
|
||||
internal void mtx_dequeue_op(Arena *arena, MTX_MutThread *thread, C_Key *buffer_key_out, MTX_Op *op_out);
|
||||
internal void mtx_mut_thread__entry_point(void *p);
|
||||
|
||||
#endif // MUTABLE_TEXT_H
|
||||
|
||||
@@ -166,7 +166,7 @@ ptg_builder_thread__entry_point(void *p)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
HS_Scope *scope = hs_scope_open();
|
||||
C_Scope *scope = c_scope_open();
|
||||
|
||||
//- rjf: get next key
|
||||
PTG_Key key = {0};
|
||||
@@ -214,7 +214,7 @@ ptg_builder_thread__entry_point(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
hs_scope_close(scope);
|
||||
c_scope_close(scope);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -517,7 +517,7 @@ Rng1U64 rd_reg_slot_range_table[47] =
|
||||
{OffsetOf(RD_Regs, file_path), OffsetOf(RD_Regs, file_path) + sizeof(String8)},
|
||||
{OffsetOf(RD_Regs, cursor), OffsetOf(RD_Regs, cursor) + sizeof(TxtPt)},
|
||||
{OffsetOf(RD_Regs, mark), OffsetOf(RD_Regs, mark) + sizeof(TxtPt)},
|
||||
{OffsetOf(RD_Regs, text_key), OffsetOf(RD_Regs, text_key) + sizeof(HS_Key)},
|
||||
{OffsetOf(RD_Regs, text_key), OffsetOf(RD_Regs, text_key) + sizeof(C_Key)},
|
||||
{OffsetOf(RD_Regs, lang_kind), OffsetOf(RD_Regs, lang_kind) + sizeof(TXT_LangKind)},
|
||||
{OffsetOf(RD_Regs, lines), OffsetOf(RD_Regs, lines) + sizeof(D_LineList)},
|
||||
{OffsetOf(RD_Regs, dbgi_key), OffsetOf(RD_Regs, dbgi_key) + sizeof(DI_Key)},
|
||||
|
||||
@@ -463,7 +463,7 @@ U64 inline_depth;
|
||||
String8 file_path;
|
||||
TxtPt cursor;
|
||||
TxtPt mark;
|
||||
HS_Key text_key;
|
||||
C_Key text_key;
|
||||
TXT_LangKind lang_kind;
|
||||
D_LineList lines;
|
||||
DI_Key dbgi_key;
|
||||
|
||||
@@ -733,7 +733,7 @@ RD_RegTable:
|
||||
{String8 file_path FilePath }
|
||||
{TxtPt cursor Cursor }
|
||||
{TxtPt mark Mark }
|
||||
{HS_Key text_key TextKey }
|
||||
{C_Key text_key TextKey }
|
||||
{TXT_LangKind lang_kind LangKind }
|
||||
{D_LineList lines Lines }
|
||||
{DI_Key dbgi_key DbgiKey }
|
||||
|
||||
+61
-61
@@ -1746,13 +1746,13 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
|
||||
//- rjf: reads from hash store key
|
||||
case E_SpaceKind_HashStoreKey:
|
||||
{
|
||||
HS_Root root = {space.u64_0};
|
||||
HS_ID id = {space.u128};
|
||||
HS_Key key = hs_key_make(root, id);
|
||||
U128 hash = hs_hash_from_key(key, 0);
|
||||
HS_Scope *scope = hs_scope_open();
|
||||
C_Root root = {space.u64_0};
|
||||
C_ID id = {space.u128};
|
||||
C_Key key = c_key_make(root, id);
|
||||
U128 hash = c_hash_from_key(key, 0);
|
||||
C_Scope *scope = c_scope_open();
|
||||
{
|
||||
String8 data = hs_data_from_hash(scope, hash);
|
||||
String8 data = c_data_from_hash(scope, hash);
|
||||
Rng1U64 legal_range = r1u64(0, data.size);
|
||||
Rng1U64 read_range = intersect_1u64(range, legal_range);
|
||||
if(read_range.min < read_range.max)
|
||||
@@ -1761,7 +1761,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
|
||||
MemoryCopy(out, data.str + read_range.min, dim_1u64(read_range));
|
||||
}
|
||||
}
|
||||
hs_scope_close(scope);
|
||||
c_scope_close(scope);
|
||||
}break;
|
||||
|
||||
//- rjf: file reads
|
||||
@@ -1779,13 +1779,13 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
|
||||
containing_range.max -= containing_range.max%chunk_size;
|
||||
|
||||
// rjf: map to hash
|
||||
HS_Key key = fs_key_from_path_range(file_path, containing_range, 0);
|
||||
U128 hash = hs_hash_from_key(key, 0);
|
||||
C_Key key = fs_key_from_path_range(file_path, containing_range, 0);
|
||||
U128 hash = c_hash_from_key(key, 0);
|
||||
|
||||
// rjf: look up from hash store
|
||||
HS_Scope *scope = hs_scope_open();
|
||||
C_Scope *scope = c_scope_open();
|
||||
{
|
||||
String8 data = hs_data_from_hash(scope, hash);
|
||||
String8 data = c_data_from_hash(scope, hash);
|
||||
Rng1U64 legal_range = r1u64(containing_range.min, containing_range.min + data.size);
|
||||
Rng1U64 read_range = intersect_1u64(range, legal_range);
|
||||
if(read_range.min < read_range.max)
|
||||
@@ -1794,7 +1794,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
|
||||
MemoryCopy(out, data.str + read_range.min - containing_range.min, dim_1u64(read_range));
|
||||
}
|
||||
}
|
||||
hs_scope_close(scope);
|
||||
c_scope_close(scope);
|
||||
}break;
|
||||
|
||||
//- rjf: interior control entity reads (inside process address space or thread register block)
|
||||
@@ -2137,17 +2137,17 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range)
|
||||
|
||||
//- rjf: asynchronous streamed reads -> hashes from spaces
|
||||
|
||||
internal HS_Key
|
||||
internal C_Key
|
||||
rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated)
|
||||
{
|
||||
HS_Key result = {0};
|
||||
C_Key result = {0};
|
||||
switch(space.kind)
|
||||
{
|
||||
case E_SpaceKind_HashStoreKey:
|
||||
{
|
||||
HS_Root root = {space.u64_0};
|
||||
HS_ID id = {space.u128};
|
||||
result = hs_key_make(root, id);
|
||||
C_Root root = {space.u64_0};
|
||||
C_ID id = {space.u128};
|
||||
result = c_key_make(root, id);
|
||||
}break;
|
||||
case E_SpaceKind_File:
|
||||
{
|
||||
@@ -2177,16 +2177,16 @@ rd_whole_range_from_eval_space(E_Space space)
|
||||
{
|
||||
case E_SpaceKind_HashStoreKey:
|
||||
{
|
||||
HS_Root root = {space.u64_0};
|
||||
HS_ID id = {space.u128};
|
||||
HS_Key key = hs_key_make(root, id);
|
||||
U128 hash = hs_hash_from_key(key, 0);
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Root root = {space.u64_0};
|
||||
C_ID id = {space.u128};
|
||||
C_Key key = c_key_make(root, id);
|
||||
U128 hash = c_hash_from_key(key, 0);
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
{
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
String8 data = c_data_from_hash(c_scope, hash);
|
||||
result = r1u64(0, data.size);
|
||||
}
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
}break;
|
||||
case E_SpaceKind_File:
|
||||
{
|
||||
@@ -2872,17 +2872,17 @@ rd_view_ui(Rng2F32 rect)
|
||||
// rjf: unpack view's target expression & hash
|
||||
E_Eval eval = e_eval_from_string(expr_string);
|
||||
Rng1U64 range = r1u64(0, 1024);
|
||||
HS_Key key = rd_key_from_eval_space_range(eval.space, range, 0);
|
||||
U128 hash = hs_hash_from_key(key, 0);
|
||||
C_Key key = rd_key_from_eval_space_range(eval.space, range, 0);
|
||||
U128 hash = c_hash_from_key(key, 0);
|
||||
|
||||
// rjf: determine if hash's blob is ready, and which viewer to use
|
||||
B32 data_is_ready = 0;
|
||||
String8 new_view_name = {0};
|
||||
{
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
if(!u128_match(hash, u128_zero()))
|
||||
{
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
String8 data = c_data_from_hash(c_scope, hash);
|
||||
U64 num_utf8_bytes = 0;
|
||||
U64 num_unknown_bytes = 0;
|
||||
for(U64 idx = 0; idx < data.size && idx < range.max;)
|
||||
@@ -2911,7 +2911,7 @@ rd_view_ui(Rng2F32 rect)
|
||||
new_view_name = str8_lit("memory");
|
||||
}
|
||||
}
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
}
|
||||
|
||||
// rjf: if we don't have a viewer, just use the memory viewer.
|
||||
@@ -5993,7 +5993,7 @@ rd_window_frame(void)
|
||||
//- rjf: @window_frame_part compute window's theme
|
||||
//
|
||||
{
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
|
||||
//- rjf: try to find theme settings from the project, then the user.
|
||||
RD_CfgList colors_cfgs = {0};
|
||||
@@ -6039,7 +6039,7 @@ rd_window_frame(void)
|
||||
}
|
||||
|
||||
//- rjf: map the theme config to the associated tree (either from a preset, or from a file)
|
||||
MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, hs_scope, theme_cfg->first->string);
|
||||
MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, c_scope, theme_cfg->first->string);
|
||||
if(colors_cfgs.count == 0 && theme_tree == &md_nil_node)
|
||||
{
|
||||
theme_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark];
|
||||
@@ -6110,7 +6110,7 @@ rd_window_frame(void)
|
||||
}
|
||||
}
|
||||
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@@ -10205,7 +10205,7 @@ rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs)
|
||||
//- rjf: colors
|
||||
|
||||
internal MD_Node *
|
||||
rd_theme_tree_from_name(Arena *arena, HS_Scope *scope, String8 theme_name)
|
||||
rd_theme_tree_from_name(Arena *arena, C_Scope *scope, String8 theme_name)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
MD_Node *theme_tree = &md_nil_node;
|
||||
@@ -10228,7 +10228,7 @@ rd_theme_tree_from_name(Arena *arena, HS_Scope *scope, String8 theme_name)
|
||||
endt_us = os_now_microseconds()+50000;
|
||||
}
|
||||
U128 hash = fs_hash_from_path_range(path, r1u64(0, max_U64), endt_us);
|
||||
String8 data = hs_data_from_hash(scope, hash);
|
||||
String8 data = c_data_from_hash(scope, hash);
|
||||
theme_tree = md_tree_from_string(arena, data);
|
||||
}
|
||||
}
|
||||
@@ -10864,10 +10864,10 @@ rd_init(CmdLine *cmdln)
|
||||
rd_state->user_path_arena = arena_alloc();
|
||||
rd_state->project_path_arena = arena_alloc();
|
||||
rd_state->theme_path_arena = arena_alloc();
|
||||
rd_state->user_cfg_string_key = hs_key_make(hs_root_alloc(), hs_id_make(0, 0));
|
||||
rd_state->project_cfg_string_key = hs_key_make(hs_root_alloc(), hs_id_make(0, 0));
|
||||
rd_state->cmdln_cfg_string_key = hs_key_make(hs_root_alloc(), hs_id_make(0, 0));
|
||||
rd_state->transient_cfg_string_key = hs_key_make(hs_root_alloc(), hs_id_make(0, 0));
|
||||
rd_state->user_cfg_string_key = c_key_make(c_root_alloc(), c_id_make(0, 0));
|
||||
rd_state->project_cfg_string_key = c_key_make(c_root_alloc(), c_id_make(0, 0));
|
||||
rd_state->cmdln_cfg_string_key = c_key_make(c_root_alloc(), c_id_make(0, 0));
|
||||
rd_state->transient_cfg_string_key = c_key_make(c_root_alloc(), c_id_make(0, 0));
|
||||
for(U64 idx = 0; idx < ArrayCount(rd_state->frame_arenas); idx += 1)
|
||||
{
|
||||
rd_state->frame_arenas[idx] = arena_alloc();
|
||||
@@ -11272,7 +11272,7 @@ rd_frame(void)
|
||||
{
|
||||
struct
|
||||
{
|
||||
HS_Key key;
|
||||
C_Key key;
|
||||
String8 name;
|
||||
}
|
||||
table[] =
|
||||
@@ -11288,7 +11288,7 @@ rd_frame(void)
|
||||
String8 data = rd_string_from_cfg_tree(arena,
|
||||
str8_zero(),
|
||||
rd_cfg_child_from_string(rd_state->root_cfg, table[idx].name));
|
||||
hs_submit_data(table[idx].key, &arena, data);
|
||||
c_submit_data(table[idx].key, &arena, data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -12459,10 +12459,10 @@ rd_frame(void)
|
||||
|
||||
//- rjf: add macro for output log
|
||||
{
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
HS_Key key = d_state->output_log_key;
|
||||
U128 hash = hs_hash_from_key(key, 0);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
C_Key key = d_state->output_log_key;
|
||||
U128 hash = c_hash_from_key(key, 0);
|
||||
String8 data = c_data_from_hash(c_scope, hash);
|
||||
E_Space space = e_space_make(E_SpaceKind_HashStoreKey);
|
||||
space.u64_0 = key.root.u64[0];
|
||||
space.u128 = key.id.u128[0];
|
||||
@@ -12471,7 +12471,7 @@ rd_frame(void)
|
||||
expr->mode = E_Mode_Offset;
|
||||
expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0);
|
||||
e_string2expr_map_insert(scratch.arena, macro_map, str8_lit("output"), expr);
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
}
|
||||
|
||||
//- rjf: (DEBUG) add macro for cfg strings
|
||||
@@ -12479,7 +12479,7 @@ rd_frame(void)
|
||||
{
|
||||
struct
|
||||
{
|
||||
HS_Key key;
|
||||
C_Key key;
|
||||
String8 name;
|
||||
}
|
||||
table[] =
|
||||
@@ -12491,10 +12491,10 @@ rd_frame(void)
|
||||
};
|
||||
for EachElement(idx, table)
|
||||
{
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
HS_Key key = table[idx].key;
|
||||
U128 hash = hs_hash_from_key(key, 0);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
C_Key key = table[idx].key;
|
||||
U128 hash = c_hash_from_key(key, 0);
|
||||
String8 data = c_data_from_hash(c_scope, hash);
|
||||
E_Space space = e_space_make(E_SpaceKind_HashStoreKey);
|
||||
E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, r1u64(0, 0));
|
||||
space.u64_0 = key.root.u64[0];
|
||||
@@ -12503,7 +12503,7 @@ rd_frame(void)
|
||||
expr->mode = E_Mode_Offset;
|
||||
expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), data.size, 0);
|
||||
e_string2expr_map_insert(scratch.arena, macro_map, table[idx].name, expr);
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -15936,10 +15936,10 @@ rd_frame(void)
|
||||
}break;
|
||||
case RD_CmdKind_AddThemeColor:
|
||||
{
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg);
|
||||
RD_Cfg *theme = rd_cfg_child_from_string_or_alloc(parent, str8_lit("theme"));
|
||||
MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, hs_scope, theme->first->string);
|
||||
MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, c_scope, theme->first->string);
|
||||
if(theme_tree == &md_nil_node)
|
||||
{
|
||||
rd_cfg_new_replace(theme, rd_theme_preset_display_string_table[RD_ThemePreset_DefaultDark]);
|
||||
@@ -15948,11 +15948,11 @@ rd_frame(void)
|
||||
rd_cfg_new(color, str8_lit("tags"));
|
||||
RD_Cfg *value = rd_cfg_new(color, str8_lit("value"));
|
||||
rd_cfg_new(value, str8_lit("0xffffffff"));
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
}break;
|
||||
case RD_CmdKind_ForkTheme:
|
||||
{
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
RD_Cfg *parent = rd_cfg_from_id(rd_regs()->cfg);
|
||||
RD_CfgList colors = rd_cfg_child_list_from_string(scratch.arena, parent, str8_lit("theme_color"));
|
||||
for(RD_CfgNode *n = colors.first; n != 0; n = n->next)
|
||||
@@ -15961,7 +15961,7 @@ rd_frame(void)
|
||||
}
|
||||
RD_Cfg *theme_cfg = rd_cfg_child_from_string(parent, str8_lit("theme"));
|
||||
String8 theme_name = theme_cfg->first->string;
|
||||
MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, hs_scope, theme_name);
|
||||
MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, c_scope, theme_name);
|
||||
if(theme_tree == &md_nil_node)
|
||||
{
|
||||
theme_tree = rd_state->theme_preset_trees[RD_ThemePreset_DefaultDark];
|
||||
@@ -15978,7 +15978,7 @@ rd_frame(void)
|
||||
}
|
||||
}
|
||||
rd_cfg_release(theme_cfg);
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
}break;
|
||||
case RD_CmdKind_SaveTheme:
|
||||
case RD_CmdKind_SaveAndSetTheme:
|
||||
@@ -16091,15 +16091,15 @@ rd_frame(void)
|
||||
case RD_CmdKind_GoToNameAtCursor:
|
||||
case RD_CmdKind_ToggleWatchExpressionAtCursor:
|
||||
{
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
RD_Regs *regs = rd_regs();
|
||||
HS_Key text_key = regs->text_key;
|
||||
C_Key text_key = regs->text_key;
|
||||
TXT_LangKind lang_kind = regs->lang_kind;
|
||||
TxtRng range = txt_rng(regs->cursor, regs->mark);
|
||||
U128 hash = {0};
|
||||
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, text_key, lang_kind, &hash);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
String8 data = c_data_from_hash(c_scope, hash);
|
||||
Rng1U64 expr_off_range = {0};
|
||||
if(range.min.column != range.max.column)
|
||||
{
|
||||
@@ -16115,7 +16115,7 @@ rd_frame(void)
|
||||
RD_CmdKind_GoToName),
|
||||
.string = expr);
|
||||
txt_scope_close(txt_scope);
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
}break;
|
||||
case RD_CmdKind_SetNextStatement:
|
||||
{
|
||||
|
||||
@@ -571,10 +571,10 @@ struct RD_State
|
||||
F32 tooltip_animation_rate;
|
||||
|
||||
// rjf: serialized config debug string keys
|
||||
HS_Key user_cfg_string_key;
|
||||
HS_Key project_cfg_string_key;
|
||||
HS_Key cmdln_cfg_string_key;
|
||||
HS_Key transient_cfg_string_key;
|
||||
C_Key user_cfg_string_key;
|
||||
C_Key project_cfg_string_key;
|
||||
C_Key cmdln_cfg_string_key;
|
||||
C_Key transient_cfg_string_key;
|
||||
|
||||
// rjf: schema table
|
||||
MD_NodePtrList *schemas;
|
||||
@@ -898,7 +898,7 @@ internal B32 rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range
|
||||
internal B32 rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range);
|
||||
|
||||
//- rjf: asynchronous streamed reads -> hashes from spaces
|
||||
internal HS_Key rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated);
|
||||
internal C_Key rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated);
|
||||
|
||||
//- rjf: space -> entire range
|
||||
internal Rng1U64 rd_whole_range_from_eval_space(E_Space space);
|
||||
@@ -988,7 +988,7 @@ internal void rd_set_autocomp_regs_(E_Eval dst_eval, RD_Regs *regs);
|
||||
//~ rjf: Colors, Fonts, Config
|
||||
|
||||
//- rjf: colors
|
||||
internal MD_Node *rd_theme_tree_from_name(Arena *arena, HS_Scope *scope, String8 theme_name);
|
||||
internal MD_Node *rd_theme_tree_from_name(Arena *arena, C_Scope *scope, String8 theme_name);
|
||||
internal Vec4F32 rd_rgba_from_code_color_slot(RD_CodeColorSlot slot);
|
||||
internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind(TXT_TokenKind kind);
|
||||
internal RD_CodeColorSlot rd_code_color_slot_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 string);
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
#include "rdi/rdi_local.h"
|
||||
#include "rdi_make/rdi_make_local.h"
|
||||
#include "mdesk/mdesk.h"
|
||||
#include "hash_store/hash_store.h"
|
||||
#include "content/content.h"
|
||||
#include "file_stream/file_stream.h"
|
||||
#include "text_cache/text_cache.h"
|
||||
#include "mutable_text/mutable_text.h"
|
||||
@@ -274,7 +274,7 @@
|
||||
#include "rdi/rdi_local.c"
|
||||
#include "rdi_make/rdi_make_local.c"
|
||||
#include "mdesk/mdesk.c"
|
||||
#include "hash_store/hash_store.c"
|
||||
#include "content/content.c"
|
||||
#include "file_stream/file_stream.c"
|
||||
#include "text_cache/text_cache.c"
|
||||
#include "mutable_text/mutable_text.c"
|
||||
|
||||
+16
-16
@@ -1944,8 +1944,8 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla
|
||||
dr_fstrs_push_new(arena, &fstrs, ¶ms, str8_lit(" "));
|
||||
dr_fstrs_push_new(arena, &fstrs, ¶ms, name);
|
||||
{
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, hs_scope, name);
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
MD_Node *theme_tree = rd_theme_tree_from_name(scratch.arena, c_scope, name);
|
||||
U64 color_idx = 0;
|
||||
for(MD_Node *n = theme_tree; color_idx < 4 && !md_node_is_nil(n); n = md_node_rec_depth_first_pre(n, theme_tree).next)
|
||||
{
|
||||
@@ -1973,7 +1973,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla
|
||||
}
|
||||
}
|
||||
}
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
}
|
||||
result.eval_fstrs = fstrs;
|
||||
}break;
|
||||
@@ -2025,7 +2025,7 @@ RD_VIEW_UI_FUNCTION_DEF(text)
|
||||
RD_CodeViewState *cv = rd_view_state(RD_CodeViewState);
|
||||
rd_code_view_init(cv);
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
|
||||
//////////////////////////////
|
||||
@@ -2091,7 +2091,7 @@ RD_VIEW_UI_FUNCTION_DEF(text)
|
||||
}
|
||||
U128 hash = {0};
|
||||
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, rd_regs()->text_key, rd_regs()->lang_kind, &hash);
|
||||
String8 data = hs_data_from_hash(hs_scope, hash);
|
||||
String8 data = c_data_from_hash(c_scope, hash);
|
||||
B32 file_is_missing = (rd_regs()->file_path.size != 0 && os_properties_from_file_path(rd_regs()->file_path).modified == 0);
|
||||
B32 key_has_data = !u128_match(hash, u128_zero()) && info.lines_count;
|
||||
ProfEnd();
|
||||
@@ -2251,7 +2251,7 @@ RD_VIEW_UI_FUNCTION_DEF(text)
|
||||
rd_store_view_param_s64(str8_lit("mark_column"), rd_regs()->mark.column);
|
||||
|
||||
txt_scope_close(txt_scope);
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
@@ -2291,7 +2291,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm)
|
||||
}
|
||||
RD_CodeViewState *cv = &dv->cv;
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
DASM_Scope *dasm_scope = dasm_scope_open();
|
||||
TXT_Scope *txt_scope = txt_scope_open();
|
||||
|
||||
@@ -2399,7 +2399,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm)
|
||||
syntax = DASM_Syntax_ATT;
|
||||
}
|
||||
}
|
||||
HS_Key dasm_key = rd_key_from_eval_space_range(space, range, 0);
|
||||
C_Key dasm_key = rd_key_from_eval_space_range(space, range, 0);
|
||||
U128 dasm_data_hash = {0};
|
||||
DASM_Params dasm_params = {0};
|
||||
{
|
||||
@@ -2415,7 +2415,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm)
|
||||
rd_regs()->lang_kind = txt_lang_kind_from_arch(arch);
|
||||
U128 dasm_text_hash = {0};
|
||||
TXT_TextInfo dasm_text_info = txt_text_info_from_key_lang(txt_scope, rd_regs()->text_key, rd_regs()->lang_kind, &dasm_text_hash);
|
||||
String8 dasm_text_data = hs_data_from_hash(hs_scope, dasm_text_hash);
|
||||
String8 dasm_text_data = c_data_from_hash(c_scope, dasm_text_hash);
|
||||
B32 has_disasm = (dasm_info.lines.count != 0 && dasm_text_info.lines_count != 0);
|
||||
B32 is_loading = (!has_disasm && dim_1u64(range) != 0 && eval.msgs.max_kind == E_MsgKind_Null && (space.kind != RD_EvalSpaceKind_CtrlEntity || space_entity != &ctrl_entity_nil));
|
||||
|
||||
@@ -2497,7 +2497,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm)
|
||||
|
||||
txt_scope_close(txt_scope);
|
||||
dasm_scope_close(dasm_scope);
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
@@ -3826,7 +3826,7 @@ EV_EXPAND_RULE_INFO_FUNCTION_DEF(bitmap)
|
||||
RD_VIEW_UI_FUNCTION_DEF(bitmap)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
HS_Scope *hs_scope = hs_scope_open();
|
||||
C_Scope *c_scope = c_scope_open();
|
||||
TEX_Scope *tex_scope = tex_scope_open();
|
||||
|
||||
//////////////////////////////
|
||||
@@ -3874,11 +3874,11 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap)
|
||||
//////////////////////////////
|
||||
//- rjf: map expression artifacts -> texture
|
||||
//
|
||||
HS_Key texture_key = rd_key_from_eval_space_range(eval.space, offset_range, 0);
|
||||
C_Key texture_key = rd_key_from_eval_space_range(eval.space, offset_range, 0);
|
||||
TEX_Topology topology = tex_topology_make(dim, fmt);
|
||||
U128 data_hash = {0};
|
||||
R_Handle texture = tex_texture_from_key_topology(tex_scope, texture_key, topology, &data_hash);
|
||||
String8 data = hs_data_from_hash(hs_scope, data_hash);
|
||||
String8 data = c_data_from_hash(c_scope, data_hash);
|
||||
|
||||
//////////////////////////////
|
||||
//- rjf: equip loading info
|
||||
@@ -4031,7 +4031,7 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap)
|
||||
rd_store_view_param_f32(str8_lit("x"), view_center_pos.x);
|
||||
rd_store_view_param_f32(str8_lit("y"), view_center_pos.y);
|
||||
|
||||
hs_scope_close(hs_scope);
|
||||
c_scope_close(c_scope);
|
||||
tex_scope_close(tex_scope);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
@@ -4364,8 +4364,8 @@ RD_VIEW_UI_FUNCTION_DEF(geo3d)
|
||||
U64 base_offset = eval_range.min;
|
||||
Rng1U64 idxs_range = r1u64(base_offset, base_offset+count*sizeof(U32));
|
||||
Rng1U64 vtxs_range = r1u64(vtx_base_off, vtx_base_off+vtx_size);
|
||||
HS_Key idxs_key = rd_key_from_eval_space_range(eval.space, idxs_range, 0);
|
||||
HS_Key vtxs_key = rd_key_from_eval_space_range(eval.space, vtxs_range, 0);
|
||||
C_Key idxs_key = rd_key_from_eval_space_range(eval.space, idxs_range, 0);
|
||||
C_Key vtxs_key = rd_key_from_eval_space_range(eval.space, vtxs_range, 0);
|
||||
R_Handle idxs_buffer = geo_buffer_from_key(geo_scope, idxs_key);
|
||||
R_Handle vtxs_buffer = geo_buffer_from_key(geo_scope, vtxs_key);
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
//- rjf: [h]
|
||||
#include "base/base_inc.h"
|
||||
#include "os/os_inc.h"
|
||||
#include "hash_store/hash_store.h"
|
||||
#include "content/content.h"
|
||||
#include "rdi_format/rdi_format_local.h"
|
||||
#include "regs/regs.h"
|
||||
#include "regs/rdi/regs_rdi.h"
|
||||
@@ -23,7 +23,7 @@
|
||||
//- rjf: [c]
|
||||
#include "base/base_inc.c"
|
||||
#include "os/os_inc.c"
|
||||
#include "hash_store/hash_store.c"
|
||||
#include "content/content.c"
|
||||
#include "rdi_format/rdi_format_local.c"
|
||||
#include "regs/regs.c"
|
||||
#include "regs/rdi/regs_rdi.c"
|
||||
@@ -148,7 +148,7 @@ for(Test *test = test_##name_identifier; test != 0; test = 0)
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 path = n->string;
|
||||
String8 data = os_data_from_file_path(scratch.arena, path);
|
||||
rdi_hashes[idx] = hs_hash_from_data(data);
|
||||
rdi_hashes[idx] = c_hash_from_data(data);
|
||||
rdi_paths_array[idx] = path;
|
||||
scratch_end(scratch);
|
||||
}
|
||||
@@ -160,7 +160,7 @@ for(Test *test = test_##name_identifier; test != 0; test = 0)
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 path = n->string;
|
||||
String8 data = os_data_from_file_path(scratch.arena, path);
|
||||
dump_hashes[idx] = hs_hash_from_data(data);
|
||||
dump_hashes[idx] = c_hash_from_data(data);
|
||||
dump_paths_array[idx] = path;
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
@@ -1771,12 +1771,12 @@ txt_text_info_from_hash_lang(TXT_Scope *scope, U128 hash, TXT_LangKind lang)
|
||||
}
|
||||
|
||||
internal TXT_TextInfo
|
||||
txt_text_info_from_key_lang(TXT_Scope *scope, HS_Key key, TXT_LangKind lang, U128 *hash_out)
|
||||
txt_text_info_from_key_lang(TXT_Scope *scope, C_Key key, TXT_LangKind lang, U128 *hash_out)
|
||||
{
|
||||
TXT_TextInfo result = {0};
|
||||
for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
|
||||
for(U64 rewind_idx = 0; rewind_idx < C_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
|
||||
{
|
||||
U128 hash = hs_hash_from_key(key, rewind_idx);
|
||||
U128 hash = c_hash_from_key(key, rewind_idx);
|
||||
result = txt_text_info_from_hash_lang(scope, hash, lang);
|
||||
if(result.lines_count != 0)
|
||||
{
|
||||
@@ -2206,7 +2206,7 @@ ASYNC_WORK_DEF(txt_parse_work)
|
||||
U128 hash = {0};
|
||||
TXT_LangKind lang = TXT_LangKind_Null;
|
||||
txt_u2p_dequeue_req(&hash, &lang);
|
||||
HS_Scope *scope = hs_scope_open();
|
||||
C_Scope *scope = c_scope_open();
|
||||
|
||||
//- rjf: unpack hash
|
||||
U64 slot_idx = hash.u64[1]%txt_shared->slots_count;
|
||||
@@ -2232,7 +2232,7 @@ ASYNC_WORK_DEF(txt_parse_work)
|
||||
String8 data = {0};
|
||||
if(got_task)
|
||||
{
|
||||
data = hs_data_from_hash(scope, hash);
|
||||
data = c_data_from_hash(scope, hash);
|
||||
}
|
||||
|
||||
//- rjf: data -> text info
|
||||
@@ -2488,7 +2488,7 @@ ASYNC_WORK_DEF(txt_parse_work)
|
||||
{
|
||||
if(u128_match(n->hash, hash) && n->lang == lang)
|
||||
{
|
||||
hs_hash_downstream_inc(n->hash);
|
||||
c_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;
|
||||
@@ -2500,7 +2500,7 @@ ASYNC_WORK_DEF(txt_parse_work)
|
||||
}
|
||||
}
|
||||
|
||||
hs_scope_close(scope);
|
||||
c_scope_close(scope);
|
||||
ProfEnd();
|
||||
return 0;
|
||||
}
|
||||
@@ -2551,7 +2551,7 @@ txt_evictor_thread__entry_point(void *p)
|
||||
n->is_working == 0)
|
||||
{
|
||||
DLLRemove(slot->first, slot->last, n);
|
||||
hs_hash_downstream_dec(n->hash);
|
||||
c_hash_downstream_dec(n->hash);
|
||||
if(n->arena != 0)
|
||||
{
|
||||
arena_release(n->arena);
|
||||
|
||||
@@ -308,7 +308,7 @@ internal void txt_scope_touch_node__stripe_r_guarded(TXT_Scope *scope, TXT_Node
|
||||
//~ rjf: Cache Lookups
|
||||
|
||||
internal TXT_TextInfo txt_text_info_from_hash_lang(TXT_Scope *scope, U128 hash, TXT_LangKind lang);
|
||||
internal TXT_TextInfo txt_text_info_from_key_lang(TXT_Scope *scope, HS_Key key, TXT_LangKind lang, U128 *hash_out);
|
||||
internal TXT_TextInfo txt_text_info_from_key_lang(TXT_Scope *scope, C_Key key, TXT_LangKind lang, U128 *hash_out);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Text Info Extractor Helpers
|
||||
|
||||
@@ -196,12 +196,12 @@ tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topolog
|
||||
}
|
||||
|
||||
internal R_Handle
|
||||
tex_texture_from_key_topology(TEX_Scope *scope, HS_Key key, TEX_Topology topology, U128 *hash_out)
|
||||
tex_texture_from_key_topology(TEX_Scope *scope, C_Key key, TEX_Topology topology, U128 *hash_out)
|
||||
{
|
||||
R_Handle handle = {0};
|
||||
for(U64 rewind_idx = 0; rewind_idx < HS_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
|
||||
for(U64 rewind_idx = 0; rewind_idx < C_KEY_HASH_HISTORY_COUNT; rewind_idx += 1)
|
||||
{
|
||||
U128 hash = hs_hash_from_key(key, rewind_idx);
|
||||
U128 hash = c_hash_from_key(key, rewind_idx);
|
||||
handle = tex_texture_from_hash_topology(scope, hash, topology);
|
||||
if(!r_handle_match(handle, r_handle_zero()))
|
||||
{
|
||||
@@ -266,7 +266,7 @@ tex_u2x_dequeue_req(U128 *hash_out, TEX_Topology *top_out)
|
||||
ASYNC_WORK_DEF(tex_xfer_work)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
HS_Scope *scope = hs_scope_open();
|
||||
C_Scope *scope = c_scope_open();
|
||||
|
||||
//- rjf: decode
|
||||
U128 hash = {0};
|
||||
@@ -297,7 +297,7 @@ ASYNC_WORK_DEF(tex_xfer_work)
|
||||
String8 data = {0};
|
||||
if(got_task)
|
||||
{
|
||||
data = hs_data_from_hash(scope, hash);
|
||||
data = c_data_from_hash(scope, hash);
|
||||
}
|
||||
|
||||
//- rjf: data * topology -> texture
|
||||
@@ -322,7 +322,7 @@ ASYNC_WORK_DEF(tex_xfer_work)
|
||||
}
|
||||
}
|
||||
|
||||
hs_scope_close(scope);
|
||||
c_scope_close(scope);
|
||||
ProfEnd();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ internal void tex_scope_touch_node__stripe_r_guarded(TEX_Scope *scope, TEX_Node
|
||||
//~ rjf: Cache Lookups
|
||||
|
||||
internal R_Handle tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topology);
|
||||
internal R_Handle tex_texture_from_key_topology(TEX_Scope *scope, HS_Key key, TEX_Topology topology, U128 *hash_out);
|
||||
internal R_Handle tex_texture_from_key_topology(TEX_Scope *scope, C_Key key, TEX_Topology topology, U128 *hash_out);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Transfer Threads
|
||||
|
||||
Reference in New Issue
Block a user