23 #include "mysys_priv.h"
29 #ifdef QSORT_EXTRA_CMP_ARGUMENT
30 #define CMP(A,B) ((*cmp)(cmp_argument,(A),(B)))
32 #define CMP(A,B) ((*cmp)((A),(B)))
35 #define SWAP(A, B, size,swap_ptrs) \
39 reg1 char **a = (char**) (A), **b = (char**) (B); \
40 char *tmp = *a; *a++ = *b; *b++ = tmp; \
44 reg1 char *a = (A), *b = (B); \
45 reg3 char *end= a+size; \
48 char tmp = *a; *a++ = *b; *b++ = tmp; \
54 #define MEDIAN(low, mid, high) \
56 if (CMP(high,low) < 0) \
57 SWAP(high, low, size, ptr_cmp); \
58 if (CMP(mid, low) < 0) \
59 SWAP(mid, low, size, ptr_cmp); \
60 else if (CMP(high, mid) < 0) \
61 SWAP(mid, high, size, ptr_cmp); \
71 #define PUSH(LOW,HIGH) {stack_ptr->low = LOW; stack_ptr++->high = HIGH;}
72 #define POP(LOW,HIGH) {LOW = (--stack_ptr)->low; HIGH = stack_ptr->high;}
75 #define STACK_SIZE (8 * sizeof(unsigned long int))
76 #define THRESHOLD_FOR_INSERT_SORT 10
77 #if defined(QSORT_TYPE_IS_VOID)
78 #define SORT_RETURN return
80 #define SORT_RETURN return 0
93 #ifdef QSORT_EXTRA_CMP_ARGUMENT
94 qsort_t my_qsort2(
void *base_ptr,
size_t count,
size_t size, qsort2_cmp cmp,
95 const void *cmp_argument)
97 qsort_t my_qsort(
void *base_ptr,
size_t count,
size_t size, qsort_cmp cmp)
100 char *low, *high, *pivot;
108 low = (
char*) base_ptr;
109 high = low+ size * (count - 1);
110 stack_ptr = stack + 1;
113 stack[0].low=stack[0].high=0;
115 pivot = (
char *) my_alloca((
int)
size);
116 ptr_cmp= size ==
sizeof(
char*) && !((low - (
char*) 0)& (
sizeof(
char*)-1));
121 char *low_ptr, *high_ptr, *mid;
123 count=((size_t) (high - low) /
size)+1;
125 if (count < THRESHOLD_FOR_INSERT_SORT)
127 for (low_ptr = low + size; low_ptr <= high; low_ptr +=
size)
130 for (ptr = low_ptr; ptr > low && CMP(ptr - size, ptr) > 0;
132 SWAP(ptr, ptr - size, size, ptr_cmp);
139 mid= low + size * (count >> 1);
142 size_t step = size* (count / 8);
143 MEDIAN(low, low + step, low+step*2);
144 MEDIAN(mid - step, mid, mid+step);
145 MEDIAN(high - 2 * step, high-step, high);
147 MEDIAN(low+step, mid, high-step);
153 MEDIAN(low, mid, high);
155 low_ptr = low +
size;
156 high_ptr = high -
size;
158 memcpy(pivot, mid, size);
162 while (CMP(low_ptr, pivot) < 0)
164 while (CMP(pivot, high_ptr) < 0)
167 if (low_ptr < high_ptr)
169 SWAP(low_ptr, high_ptr, size, ptr_cmp);
175 if (low_ptr == high_ptr)
183 while (low_ptr <= high_ptr);
192 if ((
int) (high_ptr - low) <= 0)
194 if ((
int) (high - low_ptr) <= 0)
201 else if ((
int) (high - low_ptr) <= 0)
203 else if ((high_ptr - low) > (high - low_ptr))
213 }
while (stack_ptr > stack);