* SUCH DAMAGE.
*/
-#include "c.h"
-
-
-static char *med3(char *a, char *b, char *c,
- qsort_arg_comparator cmp, void *arg);
-static void swapfunc(char *, char *, size_t, int);
-
/*
* Qsort routine based on J. L. Bentley and M. D. McIlroy,
* "Engineering a sort function",
* We have modified their original by adding a check for already-sorted input,
* which seems to be a win per discussions on pgsql-hackers around 2006-03-21.
*/
-#define swapcode(TYPE, parmi, parmj, n) \
-do { \
- size_t i = (n) / sizeof (TYPE); \
- TYPE *pi = (TYPE *)(void *)(parmi); \
- TYPE *pj = (TYPE *)(void *)(parmj); \
- do { \
- TYPE t = *pi; \
- *pi++ = *pj; \
- *pj++ = t; \
- } while (--i > 0); \
-} while (0)
-
-#define SWAPINIT(a, es) swaptype = ((char *)(a) - (char *)0) % sizeof(long) || \
- (es) % sizeof(long) ? 2 : (es) == sizeof(long)? 0 : 1;
static void
-swapfunc(char *a, char *b, size_t n, int swaptype)
+swapfunc(SortTuple *a, SortTuple *b, size_t n)
{
- if (swaptype <= 1)
- swapcode(long, a, b, n);
- else
- swapcode(char, a, b, n);
+ do
+ {
+ SortTuple t = *a;
+ *a++ = *b;
+ *b++ = t;
+ } while (--n > 0);
}
#define swap(a, b) \
- if (swaptype == 0) { \
- long t = *(long *)(void *)(a); \
- *(long *)(void *)(a) = *(long *)(void *)(b); \
- *(long *)(void *)(b) = t; \
- } else \
- swapfunc(a, b, es, swaptype)
+ do { \
+ SortTuple t = *(a); \
+ *(a) = *(b); \
+ *(b) = t; \
+ } while (0);
-#define vecswap(a, b, n) if ((n) > 0) swapfunc((a), (b), (size_t)(n), swaptype)
+#define vecswap(a, b, n) if ((n) > 0) swapfunc((a), (b), (size_t)(n))
-static char *
-med3(char *a, char *b, char *c, qsort_arg_comparator cmp, void *arg)
+static SortTuple *
+med3(SortTuple *a, SortTuple *b, SortTuple *c, qsort_arg_comparator cmp, void *arg)
{
return cmp(a, b, arg) < 0 ?
(cmp(b, c, arg) < 0 ? b : (cmp(a, c, arg) < 0 ? c : a))
}
static void
-qsort_tuple(void *a, size_t n, qsort_arg_comparator cmp, void *arg)
+qsort_tuple(SortTuple *a, size_t n, qsort_arg_comparator cmp, void *arg)
{
- char *pa,
+ SortTuple *pa,
*pb,
*pc,
*pd,
*pn;
int d,
r,
- swaptype,
presorted;
- size_t es = sizeof(SortTuple);
-loop:SWAPINIT(a, es);
+loop:
if (n < 7)
{
- for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
- for (pl = pm; pl > (char *) a && cmp(pl - es, pl, arg) > 0;
- pl -= es)
- swap(pl, pl - es);
+ for (pm = a + 1; pm < a + n; pm++)
+ for (pl = pm; pl > a && cmp(pl - 1, pl, arg) > 0; pl--)
+ swap(pl, pl - 1);
return;
}
presorted = 1;
- for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
+ for (pm = a + 1; pm < a + n; pm++)
{
- if (cmp(pm - es, pm, arg) > 0)
+ if (cmp(pm - 1, pm, arg) > 0)
{
presorted = 0;
break;
}
if (presorted)
return;
- pm = (char *) a + (n / 2) * es;
+ pm = a + (n / 2);
if (n > 7)
{
- pl = (char *) a;
- pn = (char *) a + (n - 1) * es;
+ pl = a;
+ pn = a + (n - 1);
if (n > 40)
{
- d = (n / 8) * es;
+ d = (n / 8);
pl = med3(pl, pl + d, pl + 2 * d, cmp, arg);
pm = med3(pm - d, pm, pm + d, cmp, arg);
pn = med3(pn - 2 * d, pn - d, pn, cmp, arg);
pm = med3(pl, pm, pn, cmp, arg);
}
swap(a, pm);
- pa = pb = (char *) a + es;
- pc = pd = (char *) a + (n - 1) * es;
+ pa = pb = a + 1;
+ pc = pd = a + (n - 1);
for (;;)
{
while (pb <= pc && (r = cmp(pb, a, arg)) <= 0)
if (r == 0)
{
swap(pa, pb);
- pa += es;
+ pa++;
}
- pb += es;
+ pb++;
}
while (pb <= pc && (r = cmp(pc, a, arg)) >= 0)
{
if (r == 0)
{
swap(pc, pd);
- pd -= es;
+ pd--;
}
- pc -= es;
+ pc--;
}
if (pb > pc)
break;
swap(pb, pc);
- pb += es;
- pc -= es;
+ pb++;
+ pc--;
}
- pn = (char *) a + n * es;
- r = Min(pa - (char *) a, pb - pa);
+ pn = a + n;
+ r = Min(pa - a, pb - pa);
vecswap(a, pb - r, r);
- r = Min(pd - pc, pn - pd - es);
+ r = Min(pd - pc, pn - pd - 1);
vecswap(pb, pn - r, r);
- if ((r = pb - pa) > es)
- qsort_tuple(a, r / es, cmp, arg);
- if ((r = pd - pc) > es)
+ if ((r = pb - pa) > 1)
+ qsort_tuple(a, r, cmp, arg);
+ if ((r = pd - pc) > 1)
{
/* Iterate rather than recurse to save stack space */
a = pn - r;
- n = r / es;
+ n = r;
goto loop;
}
-/* qsort_tuple(pn - r, r / es, es, cmp, arg);*/
+/* qsort_tuple(pn - r, r, cmp, arg);*/
}