inplace quicksort fixes - but thier_apply seems like not doing anything?
This commit is contained in:
parent
79b95bf905
commit
873c17f658
73
thiersort.h
73
thiersort.h
@ -421,17 +421,17 @@ static inline void thiersort_apply(
|
|||||||
TSU32 elemsize,
|
TSU32 elemsize,
|
||||||
void *tmp,
|
void *tmp,
|
||||||
void (*free)(void *ptr)) {
|
void (*free)(void *ptr)) {
|
||||||
// Replace all positions
|
/* Replace all positions */
|
||||||
for(TSU32 i = 0; i < length; ++i) {
|
for(TSU32 i = 0; i < length; ++i) {
|
||||||
// Replace the whole chain starting at i (j for chain index)
|
/* Replace the whole chain starting at i (j for chain index) */
|
||||||
// This works because we can easily check what does'nt need moves anymore.
|
/* This works because we can easily check what does'nt need moves anymore. */
|
||||||
TSU32 j = i;
|
TSU32 j = i;
|
||||||
TSU32 ni = sortres[j].i;
|
TSU32 ni = sortres[j].i;
|
||||||
|
|
||||||
// Until would move to its own position, chain
|
/* Until would move to its own position, chain */
|
||||||
// This also solves "already at right place" originals.
|
/* This also solves "already at right place" originals. */
|
||||||
while(ni != j) {
|
while(ni != j) {
|
||||||
// xchg j and ni
|
/* xchg j and ni */
|
||||||
memcpy(tmp, &((TSU8*)arr)[(size_t)j * elemsize], elemsize);
|
memcpy(tmp, &((TSU8*)arr)[(size_t)j * elemsize], elemsize);
|
||||||
memcpy(
|
memcpy(
|
||||||
&((TSU8*)arr)[(size_t)j * elemsize],
|
&((TSU8*)arr)[(size_t)j * elemsize],
|
||||||
@ -439,14 +439,14 @@ static inline void thiersort_apply(
|
|||||||
elemsize);
|
elemsize);
|
||||||
memcpy(&((TSU8*)arr)[(size_t)ni * elemsize], tmp, elemsize);
|
memcpy(&((TSU8*)arr)[(size_t)ni * elemsize], tmp, elemsize);
|
||||||
|
|
||||||
// Mark j index as done in sortres for outer loop.
|
/* Mark j index as done in sortres for outer loop. */
|
||||||
// This is necessary for inner loop stopping early
|
/* This is necessary for inner loop stopping early */
|
||||||
// and outer catch up on already processed location.
|
/* and outer catch up on already processed location. */
|
||||||
sortres[j].i = j;
|
sortres[j].i = j;
|
||||||
|
|
||||||
// Update j and ni
|
/* Update j and ni */
|
||||||
// Now we must find what should be at new location j
|
/* Now we must find what should be at new location j */
|
||||||
// instead of what we swap in there from old j loc.
|
/* instead of what we swap in there from old j loc. */
|
||||||
j = ni;
|
j = ni;
|
||||||
ni = sortres[j].i;
|
ni = sortres[j].i;
|
||||||
}
|
}
|
||||||
@ -518,7 +518,8 @@ static inline TSU8 ts_radixi(
|
|||||||
return ts_floatsigntrick((TSU8)k.u);
|
return ts_floatsigntrick((TSU8)k.u);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(false); // should never happen
|
/* Should never happen */
|
||||||
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Simple inplace quicksort for tselems */
|
/** Simple inplace quicksort for tselems */
|
||||||
@ -533,8 +534,10 @@ static inline void ts_quicksort_inplace(
|
|||||||
const TSU32 bi,
|
const TSU32 bi,
|
||||||
void *reent_data),
|
void *reent_data),
|
||||||
void *reent_data) {
|
void *reent_data) {
|
||||||
// Must do this early exit!
|
/* Must do this early exit! */
|
||||||
if(from >= to) return;
|
// TODO: TS_UNLIKELY
|
||||||
|
if(to == 0) return;
|
||||||
|
if(from >= to - 1) return;
|
||||||
|
|
||||||
TSU32 len = (to - from);
|
TSU32 len = (to - from);
|
||||||
TSU32 mid = from + len / 2;
|
TSU32 mid = from + len / 2;
|
||||||
@ -544,7 +547,7 @@ static inline void ts_quicksort_inplace(
|
|||||||
TSU32 left = from;
|
TSU32 left = from;
|
||||||
TSU32 right = to - 1;
|
TSU32 right = to - 1;
|
||||||
while(left < right) {
|
while(left < right) {
|
||||||
// Step over rightly positioned elems from left
|
/* Step over rightly positioned elems from left */
|
||||||
union tskey leftkey = arr[left].key;
|
union tskey leftkey = arr[left].key;
|
||||||
TSU32 lefti = arr[left].i;
|
TSU32 lefti = arr[left].i;
|
||||||
while((left < right) && lt(leftkey, pivotkey, lefti, pivoti, reent_data)) {
|
while((left < right) && lt(leftkey, pivotkey, lefti, pivoti, reent_data)) {
|
||||||
@ -553,16 +556,16 @@ static inline void ts_quicksort_inplace(
|
|||||||
lefti = arr[left].i;
|
lefti = arr[left].i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step over rightly positioned elems from right
|
/* Step over rightly positioned elems from right */
|
||||||
union tskey rightkey = arr[right].key;
|
union tskey rightkey = arr[right].key;
|
||||||
TSU32 righti = arr[right].i;
|
TSU32 righti = arr[right].i;
|
||||||
while((left < right) && lt(pivotkey, rightkey, pivoti, righti, reent_data)) {
|
while((left < right) && !lt(rightkey, pivotkey, righti, pivoti, reent_data)) {
|
||||||
--right;
|
--right;
|
||||||
rightkey = arr[right].key;
|
rightkey = arr[right].key;
|
||||||
righti = arr[right].i;
|
righti = arr[right].i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap wrongly positioned element
|
/* Swap wrongly positioned element */
|
||||||
if(left < right) {
|
if(left < right) {
|
||||||
const struct tselem tmp = arr[left];
|
const struct tselem tmp = arr[left];
|
||||||
arr[left] = arr[right];
|
arr[left] = arr[right];
|
||||||
@ -579,9 +582,31 @@ static inline void ts_quicksort_inplace(
|
|||||||
left += (lt(leftkey, pivotkey, lefti, pivoti, reent_data));
|
left += (lt(leftkey, pivotkey, lefti, pivoti, reent_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Just simple recursion for now */
|
/* Check edge-case when left got empty. */
|
||||||
ts_quicksort_inplace(arr, from, left, lt, reent_data);
|
/* Rem.: Right moves over the pivot invariably as left cannot pass over if! */
|
||||||
ts_quicksort_inplace(arr, left, to, lt, reent_data);
|
/* This means that right subset can never be empty, but left can! */
|
||||||
|
/* This also means that if left is empty, all invariants were just */
|
||||||
|
/* stepped over (from right) and not moved from its original position! */
|
||||||
|
// TODO: TS_UNLIKELY
|
||||||
|
if(from < left) {
|
||||||
|
/** Good case: Somewhere cutting the array in around half */
|
||||||
|
ts_quicksort_inplace(arr, from, left, lt, reent_data);
|
||||||
|
ts_quicksort_inplace(arr, left, to, lt, reent_data);
|
||||||
|
} else {
|
||||||
|
/* Left sub-array got to be empty - but to step with recursion */
|
||||||
|
/* we need to shrink sizes, which is possible by moving the pivot */
|
||||||
|
/* to the start of the right (because we know its a minimal elem!) */
|
||||||
|
/* XXX: If we collect up all pivots, we can move all here if want.. */
|
||||||
|
|
||||||
|
/* Swap */
|
||||||
|
const struct tselem tmp = arr[left];
|
||||||
|
arr[left] = arr[mid];
|
||||||
|
arr[mid] = tmp;
|
||||||
|
|
||||||
|
/* Bad case: could shrink the array by one element only */
|
||||||
|
ts_quicksort_inplace(arr, left + 1, to, lt, reent_data);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -601,7 +626,7 @@ static inline void ts_quicksort_fromto(
|
|||||||
const TSU32 bi,
|
const TSU32 bi,
|
||||||
void *reent_data),
|
void *reent_data),
|
||||||
void *reent_data) {
|
void *reent_data) {
|
||||||
// Must do this early exit!
|
// FIXME: Code is rotten here - see above variant pls!
|
||||||
if(from >= to) return;
|
if(from >= to) return;
|
||||||
|
|
||||||
TSU32 len = (to - from);
|
TSU32 len = (to - from);
|
||||||
@ -650,7 +675,7 @@ static inline void thiersort8_internal(
|
|||||||
|
|
||||||
/* Step 1) Bucketing */
|
/* Step 1) Bucketing */
|
||||||
#ifdef TS_SSE2
|
#ifdef TS_SSE2
|
||||||
// TODO: implement with SSE2
|
/* TODO: implement with SSE2 */
|
||||||
#else
|
#else
|
||||||
/* TODO: We can go both down and upwards here to increase ILP! */
|
/* TODO: We can go both down and upwards here to increase ILP! */
|
||||||
/* Occurence counting O(n) */
|
/* Occurence counting O(n) */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user