mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 17:28:07 +00:00
lock free hash trie
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
internal B32
|
||||
lfht_insert(Arena *arena,
|
||||
LFHT_NodeChunkList *node_chunks,
|
||||
LFHT_Node **root_ptr,
|
||||
U64 hash,
|
||||
void *data,
|
||||
LFHT_IsKeyEqualFunc *is_key_equal,
|
||||
void *is_key_equal_ud)
|
||||
{
|
||||
B32 was_inserted = 0;
|
||||
LFHT_Node **curr_ptr = root_ptr;
|
||||
for (U64 h = hash; ; h <<= 2) {
|
||||
LFHT_Node *curr = ins_atomic_ptr_eval(curr_ptr);
|
||||
|
||||
if (curr == 0) {
|
||||
if (node_chunks->last == 0 || node_chunks->last->count >= node_chunks->last->max) {
|
||||
LFHT_NodeChunk *c = push_array(arena, LFHT_NodeChunk, 1);
|
||||
c->max = 1024;
|
||||
c->count = 0;
|
||||
c->v = push_array_no_zero(arena, LFHT_Node, 1024);
|
||||
|
||||
SLLQueuePush(node_chunks->first, node_chunks->last, c);
|
||||
node_chunks->chunk_count += 1;
|
||||
}
|
||||
|
||||
LFHT_Node *n = &node_chunks->last->v[node_chunks->last->count];
|
||||
MemoryZeroStruct(n);
|
||||
n->data = data;
|
||||
|
||||
LFHT_Node *cmp = ins_atomic_ptr_eval_cond_assign(curr_ptr, n, curr);
|
||||
if (cmp == curr) {
|
||||
node_chunks->last->count += 1;
|
||||
node_chunks->total_count += 1;
|
||||
was_inserted = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// was the key already inserted?
|
||||
if (is_key_equal(is_key_equal_ud, curr->data, data)) { break; }
|
||||
|
||||
// descend
|
||||
curr_ptr = &curr->children[h >> 62];
|
||||
}
|
||||
return was_inserted;
|
||||
}
|
||||
|
||||
internal void *
|
||||
lfht_search(LFHT_Node *root, U64 hash, void *data, LFHT_IsKeyEqualFunc *is_key_equal, void *is_key_equal_ud)
|
||||
{
|
||||
LFHT_Node *curr = root;
|
||||
for (U64 h = hash; ; h <<= 2) {
|
||||
if (curr == 0) { break; }
|
||||
if (is_key_equal(is_key_equal_ud, curr->data, data)) { break; }
|
||||
curr = curr->children[h >> 62];
|
||||
}
|
||||
return curr ? curr->data : 0;
|
||||
}
|
||||
|
||||
internal U64
|
||||
lfht_total_count_from_node_chunk_lists(U64 list_count, LFHT_NodeChunkList *lists)
|
||||
{
|
||||
U64 total_count = 0;
|
||||
for EachIndex(i, list_count) { total_count += lists[i].total_count; }
|
||||
return total_count;
|
||||
}
|
||||
|
||||
internal void **
|
||||
lfht_data_from_node_chunk_lists(Arena *arena, U64 total_count, U64 list_count, LFHT_NodeChunkList *lists)
|
||||
{
|
||||
U64 result_count = 0;
|
||||
void **result = push_array(arena, void *, total_count);
|
||||
for EachIndex(list_idx, list_count) {
|
||||
LFHT_NodeChunkList l = lists[list_idx];
|
||||
for EachNode(c, LFHT_NodeChunk, l.first) {
|
||||
Assert(result_count + c->count <= total_count);
|
||||
for EachIndex(item_idx, c->count) {
|
||||
result[result_count++] = c->v[item_idx].data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) Epic Games Tools
|
||||
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
||||
|
||||
#ifndef LF_HASH_TABLE_H
|
||||
#define LF_HAHS_TABLE_H
|
||||
|
||||
typedef struct LFHT_Node
|
||||
{
|
||||
void *data;
|
||||
struct LFHT_Node *children[4];
|
||||
} LFHT_Node;
|
||||
|
||||
typedef struct LFHT_NodeChunk
|
||||
{
|
||||
struct LFHT_NodeChunk *next;
|
||||
U64 max;
|
||||
U64 count;
|
||||
LFHT_Node *v;
|
||||
} LFHT_NodeChunk;
|
||||
|
||||
typedef struct LFHT_NodeChunkList
|
||||
{
|
||||
U64 chunk_count;
|
||||
U64 total_count;
|
||||
LFHT_NodeChunk *first;
|
||||
LFHT_NodeChunk *last;
|
||||
} LFHT_NodeChunkList;
|
||||
|
||||
#define LFHT_IS_KEY_EQUAL_FUNC(name) B32 name(void *ud, void *a, void *b)
|
||||
typedef LFHT_IS_KEY_EQUAL_FUNC(LFHT_IsKeyEqualFunc);
|
||||
|
||||
internal B32 lfht_insert(Arena *arena, LFHT_NodeChunkList *node_chunks, LFHT_Node **root_ptr, U64 hash, void *data, LFHT_IsKeyEqualFunc *is_key_equal, void *is_key_equal_ud);
|
||||
|
||||
internal void ** lfht_data_from_node_chunk_lists(Arena *arena, U64 total_count, U64 list_count, LFHT_NodeChunkList *lists);
|
||||
|
||||
#endif // LF_HASH_TABLE_H
|
||||
Reference in New Issue
Block a user