mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-17 06:41:27 -07:00
237 lines
5.1 KiB
C
237 lines
5.1 KiB
C
// Copyright (c) 2025 Epic Games Tools
|
|
// Licensed under the MIT license (https://opensource.org/license/mit/)
|
|
|
|
internal U64
|
|
void_list_count_nodes(VoidNode *head)
|
|
{
|
|
U64 node_count = 0;
|
|
for (VoidNode *curr = head; curr != 0; curr = curr->next) {
|
|
++node_count;
|
|
}
|
|
return node_count;
|
|
}
|
|
|
|
internal void
|
|
void_node_concat(VoidNode **head, VoidNode *node)
|
|
{
|
|
Assert(*head != node);
|
|
node->next = *head;
|
|
*head = node;
|
|
}
|
|
|
|
internal void
|
|
void_node_concat_atomic(VoidNode **head, VoidNode *node)
|
|
{
|
|
Assert(*head != node);
|
|
node->next = ins_atomic_ptr_eval_assign(head, node);
|
|
}
|
|
|
|
internal U64Node *
|
|
u64_list_push(Arena *arena, U64List *list, U64 data)
|
|
{
|
|
U64Node *n = push_array(arena, U64Node, 1);
|
|
n->next = 0;
|
|
n->data = data;
|
|
|
|
SLLQueuePush(list->first, list->last, n);
|
|
++list->count;
|
|
|
|
return n;
|
|
}
|
|
|
|
internal void
|
|
u64_list_concat_in_place(U64List *list, U64List *to_concat)
|
|
{
|
|
SLLConcatInPlace(list, to_concat);
|
|
}
|
|
|
|
internal U64Array
|
|
u64_array_from_list(Arena *arena, U64List *list)
|
|
{
|
|
U64Array result;
|
|
result.count = 0;
|
|
result.v = push_array(arena, U64, list->count);
|
|
for (U64Node *n = list->first; n != NULL; n = n->next) {
|
|
result.v[result.count++] = n->data;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal void
|
|
u32_array_sort(U64 count, U32 *v)
|
|
{
|
|
radsort(v, count, u32_is_before);
|
|
}
|
|
|
|
internal void
|
|
u64_array_sort(U64 count, U64 *v)
|
|
{
|
|
radsort(v, count, u64_is_before);
|
|
}
|
|
|
|
internal void
|
|
u32_pair_radix_sort(U64 count, PairU32 *arr)
|
|
{
|
|
Temp scratch = scratch_begin(0,0);
|
|
|
|
PairU32 *temp = push_array(scratch.arena, PairU32, count);
|
|
|
|
const U64 bit_count0 = 11;
|
|
const U64 bit_count1 = 11;
|
|
const U64 bit_count2 = 10;
|
|
|
|
U32 *count0 = push_array(scratch.arena, U32, (1 << bit_count0));
|
|
U32 *count1 = push_array(scratch.arena, U32, (1 << bit_count1));
|
|
U32 *count2 = push_array(scratch.arena, U32, (1 << bit_count2));
|
|
|
|
for (U64 i = 0; i < count; ++i) {
|
|
U32 digit0 = (arr[i].v0 >> 0 ) % (1 << bit_count0);
|
|
U32 digit1 = (arr[i].v0 >> bit_count0) % (1 << bit_count1);
|
|
U32 digit2 = (arr[i].v0 >> bit_count1) % (1 << bit_count2);
|
|
|
|
++count0[digit0];
|
|
++count1[digit1];
|
|
++count2[digit2];
|
|
}
|
|
|
|
counts_to_offsets_array_u32((1 << bit_count0), count0);
|
|
counts_to_offsets_array_u32((1 << bit_count1), count1);
|
|
counts_to_offsets_array_u32((1 << bit_count2), count2);
|
|
|
|
for (U64 i = 0; i < count; ++i) {
|
|
U32 digit0 = (arr[i].v0 >> 0) % (1 << bit_count0);
|
|
temp[count0[digit0]++] = arr[i];
|
|
}
|
|
|
|
for (U64 i = 0; i < count; ++i) {
|
|
U32 digit1 = (temp[i].v0 >> bit_count0) % (1 << bit_count1);
|
|
arr[count1[digit1]++] = temp[i];
|
|
}
|
|
|
|
for (U64 i = 0; i < count; ++i) {
|
|
U32 digit2 = (arr[i].v0 >> bit_count1) % (1 << bit_count2);
|
|
temp[count2[digit2]++] = arr[i];
|
|
}
|
|
|
|
MemoryCopyTyped(arr, temp, count);
|
|
|
|
scratch_end(scratch);
|
|
}
|
|
|
|
internal B32
|
|
u32_array_compare(U32Array a, U32Array b)
|
|
{
|
|
B32 are_equal = 0;
|
|
if (a.count == b.count) {
|
|
int cmp = MemoryCompare(a.v, b.v, sizeof(a.v[0]) * a.count);
|
|
are_equal = (cmp == 0);
|
|
}
|
|
return are_equal;
|
|
}
|
|
|
|
internal U64Array
|
|
u64_array_remove_duplicates(Arena *arena, U64Array in)
|
|
{
|
|
U64Array result;
|
|
result.count = 0;
|
|
result.v = push_array(arena, U64, in.count);
|
|
|
|
for (U64 i = 1; i < in.count; ++i) {
|
|
B32 is_unique = in.v[i - 1] != in.v[i];
|
|
if (is_unique) {
|
|
result.v[result.count++] = in.v[i - 1];
|
|
}
|
|
}
|
|
|
|
if (in.count > 0 && result.count > 0) {
|
|
B32 is_unique = result.v[result.count - 1] != in.v[in.count - 1];
|
|
if (is_unique) {
|
|
result.v[result.count++] = in.v[in.count - 1];
|
|
}
|
|
}
|
|
|
|
U64 slack_size = (in.count - result.count) * sizeof(result.v[0]);
|
|
arena_pop(arena, slack_size);
|
|
|
|
return result;
|
|
}
|
|
|
|
internal U64
|
|
sum_array_u64(U64 count, U64 *v)
|
|
{
|
|
U64 result = 0;
|
|
for (U64 i = 0; i < count; i += 1) {
|
|
result += v[i];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal U64
|
|
sum_matrix_u64(U64 rows, U64 cols, U64 **v)
|
|
{
|
|
U64 result = 0;
|
|
for (U64 i = 0; i < rows; ++i) {
|
|
result += sum_array_u64(cols, v[i]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal U64
|
|
max_array_u64(U64 count, U64 *v)
|
|
{
|
|
U64 result = 0;
|
|
for (U64 i = 0; i < count; i += 1) {
|
|
result = Max(v[i], result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal U64
|
|
min_array_u64(U64 count, U64 *v)
|
|
{
|
|
U64 result = max_U64;
|
|
for (U64 i = 0; i < count; i += 1) {
|
|
result = Min(v[i], result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
internal void
|
|
counts_to_offsets_array_u32(U64 count, U32 *arr)
|
|
{
|
|
U32 next_offset = 0;
|
|
for (U64 i = 0; i < count; i += 1) {
|
|
U32 current_offset = next_offset;
|
|
next_offset += arr[i];
|
|
arr[i] = current_offset;
|
|
}
|
|
}
|
|
|
|
internal void
|
|
counts_to_offsets_array_u64(U64 count, U64 *arr)
|
|
{
|
|
U64 next_offset = 0;
|
|
for (U64 i = 0; i < count; i += 1) {
|
|
U64 current_offset = next_offset;
|
|
next_offset += arr[i];
|
|
arr[i] = current_offset;
|
|
}
|
|
}
|
|
|
|
internal U32 *
|
|
offsets_from_counts_array_u32(Arena *arena, U32 *v, U64 count)
|
|
{
|
|
U32 *result = push_array_copy_u32(arena, v, count);
|
|
counts_to_offsets_array_u32(count, result);
|
|
return result;
|
|
}
|
|
|
|
internal U64 *
|
|
offsets_from_counts_array_u64(Arena *arena, U64 *v, U64 count)
|
|
{
|
|
U64 *result = push_array_copy_u64(arena, v, count);
|
|
counts_to_offsets_array_u64(count, result);
|
|
return result;
|
|
}
|
|
|