Annotation of researchv10no/libc/gen/qsort.c, revision 1.1.1.1

1.1       root        1: /* qsort -- qsort interface implemented by faster quicksort */
                      2: 
                      3: #define SWAPINIT(a, es) swaptype =         \
                      4:     (a-(char*)0 | es) % sizeof(long) ? 2 : es > sizeof(long) ? 1 : 0;
                      5: #define swapcode(TYPE, parmi, parmj, n) {  \
                      6:     register TYPE *pi = (TYPE *) (parmi);  \
                      7:     register TYPE *pj = (TYPE *) (parmj);  \
                      8:     do {                                   \
                      9:         register TYPE t = *pi;             \
                     10:         *pi++ = *pj;                       \
                     11:         *pj++ = t;                         \
                     12:     } while ((n -= sizeof(TYPE)) > 0);     \
                     13: }
                     14: #include <stddef.h>
                     15: static void swapfunc(char *a, char *b, size_t n, int swaptype)
                     16: {   if (swaptype <= 1) swapcode(long, a, b, n)
                     17:     else swapcode(char, a, b, n)
                     18: }
                     19: #define swap(a, b)                         \
                     20:     if (swaptype == 0) {                   \
                     21:         t = *(long*)(a);                   \
                     22:         *(long*)(a) = *(long*)(b);         \
                     23:         *(long*)(b) = t;                   \
                     24:     } else                                 \
                     25:         swapfunc(a, b, es, swaptype)
                     26: 
                     27: #define PVINIT(pv, pm)                                \
                     28:     if (swaptype != 0) { pv = a; swap(pv, pm); }      \
                     29:     else { pv = (char*)&v; *(long*)pv = *(long*)pm; }
                     30: 
                     31: #define vecswap(a, b, n) if (n > 0) swapfunc(a, b, n, swaptype)
                     32: 
                     33: #define min(x, y) ((x)<=(y) ? (x) : (y))
                     34: 
                     35: static char *med3(char *a, char *b, char *c, int (*cmp)())
                     36: {      return cmp(a, b) < 0 ?
                     37:                  (cmp(b, c) < 0 ? b : cmp(a, c) < 0 ? c : a)
                     38:                : (cmp(b, c) > 0 ? b : cmp(a, c) > 0 ? c : a);
                     39: }
                     40: 
                     41: void qsort(char *a, size_t n, size_t es, int (*cmp)())
                     42: {
                     43:        char *pa, *pb, *pc, *pd, *pl, *pm, *pn, *pv;
                     44:        int r, swaptype;
                     45:        long s, t, v;
                     46: 
                     47:        SWAPINIT(a, es);
                     48:        if (n < 7) {     /* Insertion sort on smallest arrays */
                     49:                for (pm = a + es; pm < a + n*es; pm += es)
                     50:                        for (pl = pm; pl > a && cmp(pl-es, pl) > 0; pl -= es)
                     51:                                swap(pl, pl-es);
                     52:                return;
                     53:        }
                     54:        pm = a + (n/2)*es;    /* Small arrays, middle element */
                     55:        if (n > 7) {
                     56:                pl = a;
                     57:                pn = a + (n-1)*es;
                     58:                if (n > 40) {    /* Big arrays, pseudomedian of 9 */
                     59:                        s = (n/8)*es;
                     60:                        pl = med3(pl, pl+s, pl+2*s, cmp);
                     61:                        pm = med3(pm-s, pm, pm+s, cmp);
                     62:                        pn = med3(pn-2*s, pn-s, pn, cmp);
                     63:                }
                     64:                pm = med3(pl, pm, pn, cmp); /* Mid-size, med of 3 */
                     65:        }
                     66:        PVINIT(pv, pm);
                     67:        pa = pb = a;
                     68:        pc = pd = a + (n-1)*es;
                     69:        for (;;) {
                     70:                while (pb <= pc && (r = cmp(pb, pv)) <= 0) {
                     71:                        if (r == 0) { swap(pa, pb); pa += es; }
                     72:                        pb += es;
                     73:                }
                     74:                while (pb <= pc && (r = cmp(pc, pv)) >= 0) {
                     75:                        if (r == 0) { swap(pc, pd); pd -= es; }
                     76:                        pc -= es;
                     77:                }
                     78:                if (pb > pc) break;
                     79:                swap(pb, pc);
                     80:                pb += es;
                     81:                pc -= es;
                     82:        }
                     83:        pn = a + n*es;
                     84:        s = min(pa-a,  pb-pa   ); vecswap(a,  pb-s, s);
                     85:        s = min(pd-pc, pn-pd-es); vecswap(pb, pn-s, s);
                     86:        if ((s = pb-pa) > es) qsort(a,    s/es, es, cmp);
                     87:        if ((s = pd-pc) > es) qsort(pn-s, s/es, es, cmp);
                     88: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.