deTABbed wxQsort()

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47745 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-07-27 13:48:20 +00:00
parent 3214311765
commit 11fe6505b8

View File

@@ -705,17 +705,17 @@ Thanks,
/* Byte-wise swap two items of size SIZE. */ /* Byte-wise swap two items of size SIZE. */
#define SWAP(a, b, size) \ #define SWAP(a, b, size) \
do \ do \
{ \ { \
register size_t __size = (size); \ register size_t __size = (size); \
register char *__a = (a), *__b = (b); \ register char *__a = (a), *__b = (b); \
do \ do \
{ \ { \
char __tmp = *__a; \ char __tmp = *__a; \
*__a++ = *__b; \ *__a++ = *__b; \
*__b++ = __tmp; \ *__b++ = __tmp; \
} while (--__size > 0); \ } while (--__size > 0); \
} while (0) } while (0)
/* Discontinue quicksort algorithm when partition gets below this size. /* Discontinue quicksort algorithm when partition gets below this size.
@@ -730,10 +730,10 @@ typedef struct
} stack_node; } stack_node;
/* The next 4 #defines implement a very fast in-line stack abstraction. */ /* The next 4 #defines implement a very fast in-line stack abstraction. */
#define STACK_SIZE (8 * sizeof(unsigned long int)) #define STACK_SIZE (8 * sizeof(unsigned long int))
#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
#define STACK_NOT_EMPTY (stack < top) #define STACK_NOT_EMPTY (stack < top)
/* Order size using quicksort. This implementation incorporates /* Order size using quicksort. This implementation incorporates
@@ -760,7 +760,7 @@ typedef struct
stack size is needed (actually O(1) in this case)! */ stack size is needed (actually O(1) in this case)! */
void wxQsort(void *const pbase, size_t total_elems, void wxQsort(void *const pbase, size_t total_elems,
size_t size, CMPFUNCDATA cmp, const void* user_data) size_t size, CMPFUNCDATA cmp, const void* user_data)
{ {
register char *base_ptr = (char *) pbase; register char *base_ptr = (char *) pbase;
const size_t max_thresh = MAX_THRESH * size; const size_t max_thresh = MAX_THRESH * size;
@@ -783,54 +783,54 @@ void wxQsort(void *const pbase, size_t total_elems,
char *left_ptr; char *left_ptr;
char *right_ptr; char *right_ptr;
/* Select median value from among LO, MID, and HI. Rearrange /* Select median value from among LO, MID, and HI. Rearrange
LO and HI so the three values are sorted. This lowers the LO and HI so the three values are sorted. This lowers the
probability of picking a pathological pivot value and probability of picking a pathological pivot value and
skips a comparison for both the LEFT_PTR and RIGHT_PTR. */ skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
char *mid = lo + size * ((hi - lo) / size >> 1); char *mid = lo + size * ((hi - lo) / size >> 1);
if ((*cmp) ((void *) mid, (void *) lo, user_data) < 0) if ((*cmp) ((void *) mid, (void *) lo, user_data) < 0)
SWAP (mid, lo, size); SWAP (mid, lo, size);
if ((*cmp) ((void *) hi, (void *) mid, user_data) < 0) if ((*cmp) ((void *) hi, (void *) mid, user_data) < 0)
SWAP (mid, hi, size); SWAP (mid, hi, size);
else else
goto jump_over; goto jump_over;
if ((*cmp) ((void *) mid, (void *) lo, user_data) < 0) if ((*cmp) ((void *) mid, (void *) lo, user_data) < 0)
SWAP (mid, lo, size); SWAP (mid, lo, size);
jump_over:; jump_over:;
left_ptr = lo + size; left_ptr = lo + size;
right_ptr = hi - size; right_ptr = hi - size;
/* Here's the famous ``collapse the walls'' section of quicksort. /* Here's the famous ``collapse the walls'' section of quicksort.
Gotta like those tight inner loops! They are the main reason Gotta like those tight inner loops! They are the main reason
that this algorithm runs much faster than others. */ that this algorithm runs much faster than others. */
do do
{ {
while ((*cmp) ((void *) left_ptr, (void *) mid, user_data) < 0) while ((*cmp) ((void *) left_ptr, (void *) mid, user_data) < 0)
left_ptr += size; left_ptr += size;
while ((*cmp) ((void *) mid, (void *) right_ptr, user_data) < 0) while ((*cmp) ((void *) mid, (void *) right_ptr, user_data) < 0)
right_ptr -= size; right_ptr -= size;
if (left_ptr < right_ptr) if (left_ptr < right_ptr)
{ {
SWAP (left_ptr, right_ptr, size); SWAP (left_ptr, right_ptr, size);
if (mid == left_ptr) if (mid == left_ptr)
mid = right_ptr; mid = right_ptr;
else if (mid == right_ptr) else if (mid == right_ptr)
mid = left_ptr; mid = left_ptr;
left_ptr += size; left_ptr += size;
right_ptr -= size; right_ptr -= size;
} }
else if (left_ptr == right_ptr) else if (left_ptr == right_ptr)
{ {
left_ptr += size; left_ptr += size;
right_ptr -= size; right_ptr -= size;
break; break;
} }
} }
while (left_ptr <= right_ptr); while (left_ptr <= right_ptr);
/* Set up pointers for next iteration. First determine whether /* Set up pointers for next iteration. First determine whether
left and right partitions are below the threshold size. If so, left and right partitions are below the threshold size. If so,
@@ -840,24 +840,24 @@ void wxQsort(void *const pbase, size_t total_elems,
if ((size_t) (right_ptr - lo) <= max_thresh) if ((size_t) (right_ptr - lo) <= max_thresh)
{ {
if ((size_t) (hi - left_ptr) <= max_thresh) if ((size_t) (hi - left_ptr) <= max_thresh)
/* Ignore both small partitions. */ /* Ignore both small partitions. */
POP (lo, hi); POP (lo, hi);
else else
/* Ignore small left partition. */ /* Ignore small left partition. */
lo = left_ptr; lo = left_ptr;
} }
else if ((size_t) (hi - left_ptr) <= max_thresh) else if ((size_t) (hi - left_ptr) <= max_thresh)
/* Ignore small right partition. */ /* Ignore small right partition. */
hi = right_ptr; hi = right_ptr;
else if ((right_ptr - lo) > (hi - left_ptr)) else if ((right_ptr - lo) > (hi - left_ptr))
{ {
/* Push larger left partition indices. */ /* Push larger left partition indices. */
PUSH (lo, right_ptr); PUSH (lo, right_ptr);
lo = left_ptr; lo = left_ptr;
} }
else else
{ {
/* Push larger right partition indices. */ /* Push larger right partition indices. */
PUSH (left_ptr, hi); PUSH (left_ptr, hi);
hi = right_ptr; hi = right_ptr;
} }
@@ -894,17 +894,17 @@ void wxQsort(void *const pbase, size_t total_elems,
run_ptr = base_ptr + size; run_ptr = base_ptr + size;
while ((run_ptr += size) <= end_ptr) while ((run_ptr += size) <= end_ptr)
{ {
tmp_ptr = run_ptr - size; tmp_ptr = run_ptr - size;
while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0) while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0)
tmp_ptr -= size; tmp_ptr -= size;
tmp_ptr += size; tmp_ptr += size;
if (tmp_ptr != run_ptr) if (tmp_ptr != run_ptr)
{ {
char *trav; char *trav;
trav = run_ptr + size; trav = run_ptr + size;
while (--trav >= run_ptr) while (--trav >= run_ptr)
{ {
char c = *trav; char c = *trav;
char *hi, *lo; char *hi, *lo;