Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Functions

qsort_arg.c File Reference

#include "c.h"
Include dependency graph for qsort_arg.c:

Go to the source code of this file.

Defines

#define swapcode(TYPE, parmi, parmj, n)
#define SWAPINIT(a, es)
#define swap(a, b)
#define vecswap(a, b, n)   if ((n) > 0) swapfunc((a), (b), (size_t)(n), swaptype)

Functions

static char * med3 (char *a, char *b, char *c, qsort_arg_comparator cmp, void *arg)
static void swapfunc (char *, char *, size_t, int)
void qsort_arg (void *a, size_t n, size_t es, qsort_arg_comparator cmp, void *arg)

Define Documentation

#define swap (   a,
  b 
)
Value:
if (swaptype == 0) {                    \
        long t = *(long *)(void *)(a);          \
        *(long *)(void *)(a) = *(long *)(void *)(b);    \
        *(long *)(void *)(b) = t;           \
    } else                          \
        swapfunc(a, b, es, swaptype)

Definition at line 84 of file qsort_arg.c.

Referenced by qsort_arg().

#define swapcode (   TYPE,
  parmi,
  parmj,
  n 
)
Value:
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)

Definition at line 60 of file qsort_arg.c.

Referenced by swapfunc().

#define SWAPINIT (   a,
  es 
)
Value:
swaptype = ((char *)(a) - (char *)0) % sizeof(long) || \
    (es) % sizeof(long) ? 2 : (es) == sizeof(long)? 0 : 1;

Definition at line 72 of file qsort_arg.c.

Referenced by qsort_arg().

#define vecswap (   a,
  b,
  n 
)    if ((n) > 0) swapfunc((a), (b), (size_t)(n), swaptype)

Definition at line 92 of file qsort_arg.c.

Referenced by qsort_arg().


Function Documentation

static char * med3 ( char *  a,
char *  b,
char *  c,
qsort_arg_comparator  cmp,
void *  arg 
) [static]

Definition at line 95 of file qsort_arg.c.

References cmp().

Referenced by qsort_arg().

{
    return cmp(a, b, arg) < 0 ?
        (cmp(b, c, arg) < 0 ? b : (cmp(a, c, arg) < 0 ? c : a))
        : (cmp(b, c, arg) > 0 ? b : (cmp(a, c, arg) < 0 ? a : c));
}

void qsort_arg ( void *  a,
size_t  n,
size_t  es,
qsort_arg_comparator  cmp,
void *  arg 
)

Definition at line 103 of file qsort_arg.c.

References cmp(), med3(), Min, qsort_arg(), swap, SWAPINIT, and vecswap.

Referenced by _bt_sort_array_elements(), compute_range_stats(), compute_scalar_stats(), gbt_var_picksplit(), ginExtractEntries(), mcelem_array_selec(), qsort_arg(), range_gist_double_sorting_split(), range_gist_single_sorting_split(), SortAndUniqItems(), spg_range_quad_picksplit(), tsvectorrecv(), and uniqueentry().

{
    char       *pa,
               *pb,
               *pc,
               *pd,
               *pl,
               *pm,
               *pn;
    int         d,
                r,
                swaptype,
                presorted;

loop:SWAPINIT(a, es);
    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);
        return;
    }
    presorted = 1;
    for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
    {
        if (cmp(pm - es, pm, arg) > 0)
        {
            presorted = 0;
            break;
        }
    }
    if (presorted)
        return;
    pm = (char *) a + (n / 2) * es;
    if (n > 7)
    {
        pl = (char *) a;
        pn = (char *) a + (n - 1) * es;
        if (n > 40)
        {
            d = (n / 8) * es;
            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;
    for (;;)
    {
        while (pb <= pc && (r = cmp(pb, a, arg)) <= 0)
        {
            if (r == 0)
            {
                swap(pa, pb);
                pa += es;
            }
            pb += es;
        }
        while (pb <= pc && (r = cmp(pc, a, arg)) >= 0)
        {
            if (r == 0)
            {
                swap(pc, pd);
                pd -= es;
            }
            pc -= es;
        }
        if (pb > pc)
            break;
        swap(pb, pc);
        pb += es;
        pc -= es;
    }
    pn = (char *) a + n * es;
    r = Min(pa - (char *) a, pb - pa);
    vecswap(a, pb - r, r);
    r = Min(pd - pc, pn - pd - es);
    vecswap(pb, pn - r, r);
    if ((r = pb - pa) > es)
        qsort_arg(a, r / es, es, cmp, arg);
    if ((r = pd - pc) > es)
    {
        /* Iterate rather than recurse to save stack space */
        a = pn - r;
        n = r / es;
        goto loop;
    }
/*      qsort_arg(pn - r, r / es, es, cmp, arg);*/
}

static void swapfunc ( char *  a,
char *  b,
size_t  n,
int  swaptype 
) [static]

Definition at line 76 of file qsort_arg.c.

References swapcode.

{
    if (swaptype <= 1)
        swapcode(long, a, b, n);
    else
        swapcode(char, a, b, n);
}