extend artifact cache with non-key-included generations, to allow gracefully decaying certain computations

This commit is contained in:
Ryan Fleury
2025-09-22 15:25:01 -07:00
parent 811e58c249
commit 8a1e6ab2e6
4 changed files with 27 additions and 87 deletions
+22 -6
View File
@@ -21,7 +21,7 @@ ac_init(void)
//~ rjf: Cache Lookups //~ rjf: Cache Lookups
internal void * internal void *
ac_artifact_from_key(Access *access, String8 key, AC_CreateFunctionType *create, AC_DestroyFunctionType *destroy, U64 slots_count) ac_artifact_from_key(Access *access, String8 key, U64 gen, AC_CreateFunctionType *create, AC_DestroyFunctionType *destroy, U64 slots_count)
{ {
//- rjf: create function -> cache //- rjf: create function -> cache
AC_Cache *cache = 0; AC_Cache *cache = 0;
@@ -69,8 +69,10 @@ ac_artifact_from_key(Access *access, String8 key, AC_CreateFunctionType *create,
for(B32 write_mode = 0; write_mode <= 1; write_mode += 1) for(B32 write_mode = 0; write_mode <= 1; write_mode += 1)
{ {
B32 found = 0; B32 found = 0;
B32 need_request = 0;
RWMutexScope(stripe->rw_mutex, write_mode) RWMutexScope(stripe->rw_mutex, write_mode)
{ {
// rjf: look up node
for(AC_Node *n = slot->first; n != 0; n = n->next) for(AC_Node *n = slot->first; n != 0; n = n->next)
{ {
if(str8_match(n->key, key, 0)) if(str8_match(n->key, key, 0))
@@ -78,11 +80,19 @@ ac_artifact_from_key(Access *access, String8 key, AC_CreateFunctionType *create,
found = 1; found = 1;
artifact = n->val; artifact = n->val;
access_touch(access, &n->access_pt, stripe->cv); access_touch(access, &n->access_pt, stripe->cv);
if(n->gen != gen)
{
B32 got_task = (ins_atomic_u64_eval_cond_assign(&n->working_count, 1, 0) == 0);
need_request = got_task;
}
break; break;
} }
} }
// rjf: no node? -> create
if(write_mode && !found) if(write_mode && !found)
{ {
need_request = 1;
AC_Node *node = stripe->free; AC_Node *node = stripe->free;
if(node) if(node)
{ {
@@ -99,11 +109,9 @@ ac_artifact_from_key(Access *access, String8 key, AC_CreateFunctionType *create,
node->working_count = 1; node->working_count = 1;
} }
} }
if(found)
{ // rjf: need request -> push
break; if(need_request)
}
else if(write_mode)
{ {
MutexScope(ac_shared->req_mutex) MutexScope(ac_shared->req_mutex)
{ {
@@ -111,10 +119,17 @@ ac_artifact_from_key(Access *access, String8 key, AC_CreateFunctionType *create,
SLLQueuePush(ac_shared->first_req, ac_shared->last_req, n); SLLQueuePush(ac_shared->first_req, ac_shared->last_req, n);
ac_shared->req_count += 1; ac_shared->req_count += 1;
n->v.key = str8_copy(ac_shared->req_arena, key); n->v.key = str8_copy(ac_shared->req_arena, key);
n->v.gen = gen;
n->v.create = create; n->v.create = create;
} }
cond_var_broadcast(async_tick_start_cond_var); cond_var_broadcast(async_tick_start_cond_var);
} }
// rjf: found node -> break
if(found)
{
break;
}
} }
} }
@@ -240,6 +255,7 @@ ac_tick(void)
{ {
if(str8_match(n->key, reqs[idx].key, 0)) if(str8_match(n->key, reqs[idx].key, 0))
{ {
n->gen = reqs[idx].gen;
n->val = val; n->val = val;
ins_atomic_u64_dec_eval(&n->working_count); ins_atomic_u64_dec_eval(&n->working_count);
} }
+4 -2
View File
@@ -17,6 +17,7 @@ typedef struct AC_Request AC_Request;
struct AC_Request struct AC_Request
{ {
String8 key; String8 key;
U64 gen;
AC_CreateFunctionType *create; AC_CreateFunctionType *create;
}; };
@@ -33,8 +34,9 @@ struct AC_Node
AC_Node *next; AC_Node *next;
AC_Node *prev; AC_Node *prev;
// rjf: key/value // rjf: key/gen/value
String8 key; String8 key;
U64 gen;
void *val; void *val;
// rjf: metadata // rjf: metadata
@@ -94,7 +96,7 @@ internal void ac_init(void);
//////////////////////////////// ////////////////////////////////
//~ rjf: Cache Lookups //~ rjf: Cache Lookups
internal void *ac_artifact_from_key(Access *access, String8 key, AC_CreateFunctionType *create, AC_DestroyFunctionType *destroy, U64 slots_count); internal void *ac_artifact_from_key(Access *access, String8 key, U64 gen, AC_CreateFunctionType *create, AC_DestroyFunctionType *destroy, U64 slots_count);
//////////////////////////////// ////////////////////////////////
//~ rjf: Tick //~ rjf: Tick
+1 -1
View File
@@ -2252,7 +2252,7 @@ txt_text_info_from_hash_lang(Access *access, U128 hash, TXT_LangKind lang)
TXT_LangKind lang; TXT_LangKind lang;
} key = {hash, lang}; } key = {hash, lang};
String8 key_string = str8_struct(&key); String8 key_string = str8_struct(&key);
TXT_Artifact *artifact = ac_artifact_from_key(access, key_string, txt_artifact_create, txt_artifact_destroy, 1024); TXT_Artifact *artifact = ac_artifact_from_key(access, key_string, 0, txt_artifact_create, txt_artifact_destroy, 1024);
TXT_TextInfo info = {0}; TXT_TextInfo info = {0};
if(artifact != 0) if(artifact != 0)
{ {
-78
View File
@@ -155,84 +155,6 @@ TXT_LangKind;
typedef TXT_TokenArray TXT_LangLexFunctionType(Arena *arena, U64 *bytes_processed_counter, String8 string); typedef TXT_TokenArray TXT_LangLexFunctionType(Arena *arena, U64 *bytes_processed_counter, String8 string);
////////////////////////////////
//~ rjf: Cache Types
typedef struct TXT_Request TXT_Request;
struct TXT_Request
{
U128 hash;
TXT_LangKind lang;
};
typedef struct TXT_RequestNode TXT_RequestNode;
struct TXT_RequestNode
{
TXT_RequestNode *next;
TXT_Request v;
};
typedef struct TXT_Node TXT_Node;
struct TXT_Node
{
// rjf: links
TXT_Node *next;
TXT_Node *prev;
// rjf: key
U128 hash;
TXT_LangKind lang;
// rjf: artifacts
Arena *arena;
TXT_TextInfo info;
// rjf: metadata
AccessPt access_pt;
B32 is_working;
U64 load_count;
};
typedef struct TXT_Slot TXT_Slot;
struct TXT_Slot
{
TXT_Node *first;
TXT_Node *last;
};
////////////////////////////////
//~ rjf: Shared State
typedef struct TXT_Shared TXT_Shared;
struct TXT_Shared
{
Arena *arena;
// rjf: cache
U64 slots_count;
TXT_Slot *slots;
StripeArray stripes;
TXT_Node **stripes_free_nodes;
// rjf: requests
Mutex req_mutex;
Arena *req_arena;
TXT_RequestNode *first_req;
TXT_RequestNode *last_req;
U64 req_count;
// rjf: user -> parse thread
U64 u2p_ring_size;
U8 *u2p_ring_base;
U64 u2p_ring_write_pos;
U64 u2p_ring_read_pos;
CondVar u2p_ring_cv;
Mutex u2p_ring_mutex;
// rjf: evictor thread
Thread evictor_thread;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Globals //~ rjf: Globals