mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-09-24 10:10:04 +00:00
90 lines
2.7 KiB
C
90 lines
2.7 KiB
C
// 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;
|
|
}
|
|
|
|
|