mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-10 19:08:39 +00:00
76 lines
2.3 KiB
C
Executable File
76 lines
2.3 KiB
C
Executable File
#ifndef COMS_SORT_EYTZINGER_SEARCH_H
|
|
#define COMS_SORT_EYTZINGER_SEARCH_H
|
|
|
|
#include "../stdlib/Types.h"
|
|
#include "../memory/RingMemory.h"
|
|
|
|
// @performance We could optimize eytzinger by using 1 based index
|
|
// Consider this https://en.algorithmica.org/hpc/data-structures/binary-search/
|
|
|
|
static
|
|
void eytzinger_rearrange(byte* arr, byte* temp, size_t start, size_t* index, size_t num, size_t size) noexcept {
|
|
if (start >= num) {
|
|
return;
|
|
}
|
|
|
|
// Fill the left child
|
|
eytzinger_rearrange(arr, temp, 2 * start + 1, index, num, size);
|
|
|
|
// Assign the current element
|
|
memcpy(temp + start * size, arr + (*index) * size, size);
|
|
++(*index);
|
|
|
|
// Fill the right child
|
|
eytzinger_rearrange(arr, temp, 2 * start + 2, index, num, size);
|
|
}
|
|
|
|
// @performance Instead of expecting a sorted array maybe we can improve it by immediately create the eytzinger array and thus avoid one "sort"
|
|
// arr MUST be sorted by a sorting algorithm of your choice
|
|
void eytzinger_create(byte* arr, size_t num, size_t size, RingMemory* ring) {
|
|
byte* temp = ring_get_memory(ring, size * num);
|
|
|
|
size_t index = 0;
|
|
eytzinger_rearrange(arr, temp, 0, &index, num, size);
|
|
|
|
// Copy the rearranged array back to the original array
|
|
for (size_t i = 0; i < size; ++i) {
|
|
memcpy(arr + i * size, temp + i * size, size);
|
|
}
|
|
}
|
|
|
|
// Example search for structs with an int id
|
|
// WARNING: the prefetching is usually only useful, if we go into 256KB array size
|
|
/*
|
|
void* search_eytzinger(MyStruct* arr, size_t num, int32 target_id) {
|
|
int32 index = 0;
|
|
while (index < num) {
|
|
// Prefetch the left and right children
|
|
int32 left_child = 2 * index + 1;
|
|
int32 right_child = 2 * index + 2;
|
|
|
|
if (left_child < num) {
|
|
// Prefetch left child
|
|
intrin_prefetch(&arr[left_child]);
|
|
}
|
|
if (right_child < num) {
|
|
// Prefetch right child
|
|
intrin_prefetch(&arr[right_child]);
|
|
}
|
|
|
|
// Check the current node
|
|
if (arr[index].id == target_id) {
|
|
return &arr[index];
|
|
} else if (arr[index].id < target_id) {
|
|
// Move to the right child
|
|
index = right_child;
|
|
} else {
|
|
// Move to the left child
|
|
index = left_child;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
*/
|
|
|
|
#endif |