apply and prepare operations - first version

This commit is contained in:
Richard Thier 2023-04-29 19:14:03 +02:00
parent 8784773800
commit 8dd103ca54

View File

@ -364,28 +364,6 @@ static inline void thiersort8_floatkey(
TSTRUE);
}
/**
* Create [key, index] pairs from your raw input data sequence. O(n) runtime.
*
* Useful if you have an seq/arr of elements to sort and what them prepared to be
* properly thiersorted as key, index pairs. Then you can apply that reordering
* later using thiersort_apply(..). Also useful for online data stream sources.
*
* BEWARE: The returned array must be freed by you - with a corresponding free.
* An alternative is to do a thiersort_apply(..) call (for the array case).
*
* @param askey The sequence that generates input. Gives the ith elem as key.
* @param length The length of input sequence.
* @param malloc The function to use for allocating the key-index array.
* @returns The array of keys and indices for that key to sort.
*/
static inline struct tselem *thiersort_prepare(
union tskey (askey)(TSU32 i),
TSU32 length,
void* (*malloc)(size_t size)) {
// TODO
}
/**
* Create [key, index] pairs from your raw input data array. O(n) runtime.
*
@ -396,30 +374,82 @@ static inline struct tselem *thiersort_prepare(
* BEWARE: The returned array must be freed by you - with a corresponding free.
* An alternative is to do a thiersort_apply(..) call (for the array case).
*
* @param arr The input array.
* @param askey The sequence that generates input. Gives the ith elem as key.
* @param length The length of input sequence.
* @param elemlen The size of a single elem,
* @param length The length of input sequence. Number of elements.
* @param malloc The function to use for allocating the key-index array.
* @returns The array of keys and indices for that key to sort.
* @returns Created array of keys+indices for that key to sort.
*/
static inline struct tselem *thiersort_prepare_array(
void *arr,
union tskey (askey)(void *elem),
TSU32 length,
TSU32 elemlen,
TSU32 length,
void* (*malloc)(size_t size)) {
// TODO
/* Allocate */
tselem *out = malloc(length * sizeof(tselem));
/* Fill */
TSU32 j = 0;
for(size_t i = 0; i < (length * elemlen); i += elemlen, ++j) {
out[j].key = askey((void *)((TSU8 *)arr + i));
out[j].i = j;
}
/* Return */
return out;
}
/**
* Apply the given [key,index] sort result back to an array.
*
* Rem.: Also frees the sort result array!
*
* @param sortres A thiersort result on previously prepared arr.
* @param arr The original array which was prepared for sort and was sorted.
* @param length The number of element (both in sortres and arr)
* @param elemlen Size of a single element
* @param tmp An array of elemlen bytes to store values for swap!
* @param free The operation used for freeing the sort res array.
*/
static inline void thiersort_apply(
struct tselem *sortres,
void *arr,
TSU32 length,
TSU32 elemlen,
void (*free)(void *ptr)) {
// TODO
struct tselem *sortres,
void *arr,
TSU32 length,
TSU32 elemsize,
void *tmp,
void (*free)(void *ptr)) {
// Replace all positions
for(TSU32 i = 0; i < length; ++i) {
// Replace the whole chain starting at i (j for chain index)
// This works because we can easily check what does'nt need moves anymore.
TSU32 j = i;
TSU32 ni = sortres[j].i;
// Until would move to its own position, chain
// This also solves "already at right place" originals.
while(ni != j) {
// xchg j and ni
memcpy(tmp, arr[(size_t)j * elemsize], elemsize);
memcpy(
arr[(size_t)j * elemsize],
arr[(size_t)ni * elemsize],
elemsize);
memcpy(arr[(size_t)ni * elemsize], tmp, elemsize);
// Mark j index as done in sortres for outer loop.
// This is necessary for inner loop stopping early
// and outer catch up on already processed location.
sortres[j].i = j;
// Update j and ni
// Now we must find what should be at new location j
// instead of what we swap in there from old j loc.
TSU32 j = ni;
TSU32 ni = sortres[j].i;
}
}
}
/**