|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved ! 27: * ! 28: * Copyright (c) 1992, 1993 ! 29: * The Regents of the University of California. All rights reserved. ! 30: * ! 31: * The NEXTSTEP Software License Agreement specifies the terms ! 32: * and conditions for redistribution. ! 33: * ! 34: * @(#)qsort.c 8.1 (Berkeley) 6/4/93 ! 35: */ ! 36: ! 37: ! 38: #include <sys/types.h> ! 39: #include <stdlib.h> ! 40: ! 41: static inline char *med3 __P((char *, char *, char *, int (*)())); ! 42: static inline void swapfunc __P((char *, char *, int, int)); ! 43: ! 44: #define min(a, b) (a) < (b) ? a : b ! 45: ! 46: /* ! 47: * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". ! 48: */ ! 49: #define swapcode(TYPE, parmi, parmj, n) { \ ! 50: long i = (n) / sizeof (TYPE); \ ! 51: register TYPE *pi = (TYPE *) (parmi); \ ! 52: register TYPE *pj = (TYPE *) (parmj); \ ! 53: do { \ ! 54: register TYPE t = *pi; \ ! 55: *pi++ = *pj; \ ! 56: *pj++ = t; \ ! 57: } while (--i > 0); \ ! 58: } ! 59: ! 60: #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ ! 61: es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; ! 62: ! 63: static inline void ! 64: swapfunc(a, b, n, swaptype) ! 65: char *a, *b; ! 66: int n, swaptype; ! 67: { ! 68: if(swaptype <= 1) ! 69: swapcode(long, a, b, n) ! 70: else ! 71: swapcode(char, a, b, n) ! 72: } ! 73: ! 74: #define swap(a, b) \ ! 75: if (swaptype == 0) { \ ! 76: long t = *(long *)(a); \ ! 77: *(long *)(a) = *(long *)(b); \ ! 78: *(long *)(b) = t; \ ! 79: } else \ ! 80: swapfunc(a, b, es, swaptype) ! 81: ! 82: #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) ! 83: ! 84: static inline char * ! 85: med3(a, b, c, cmp) ! 86: char *a, *b, *c; ! 87: int (*cmp)(); ! 88: { ! 89: return cmp(a, b) < 0 ? ! 90: (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) ! 91: :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c )); ! 92: } ! 93: ! 94: void ! 95: qsort(a, n, es, cmp) ! 96: void *a; ! 97: size_t n, es; ! 98: int (*cmp)(); ! 99: { ! 100: char *pa, *pb, *pc, *pd, *pl, *pm, *pn; ! 101: int d, r, swaptype, swap_cnt; ! 102: ! 103: loop: SWAPINIT(a, es); ! 104: swap_cnt = 0; ! 105: if (n < 7) { ! 106: for (pm = a + es; pm < (char *) a + n * es; pm += es) ! 107: for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; ! 108: pl -= es) ! 109: swap(pl, pl - es); ! 110: return; ! 111: } ! 112: pm = a + (n / 2) * es; ! 113: if (n > 7) { ! 114: pl = a; ! 115: pn = a + (n - 1) * es; ! 116: if (n > 40) { ! 117: d = (n / 8) * es; ! 118: pl = med3(pl, pl + d, pl + 2 * d, cmp); ! 119: pm = med3(pm - d, pm, pm + d, cmp); ! 120: pn = med3(pn - 2 * d, pn - d, pn, cmp); ! 121: } ! 122: pm = med3(pl, pm, pn, cmp); ! 123: } ! 124: swap(a, pm); ! 125: pa = pb = a + es; ! 126: ! 127: pc = pd = a + (n - 1) * es; ! 128: for (;;) { ! 129: while (pb <= pc && (r = cmp(pb, a)) <= 0) { ! 130: if (r == 0) { ! 131: swap_cnt = 1; ! 132: swap(pa, pb); ! 133: pa += es; ! 134: } ! 135: pb += es; ! 136: } ! 137: while (pb <= pc && (r = cmp(pc, a)) >= 0) { ! 138: if (r == 0) { ! 139: swap_cnt = 1; ! 140: swap(pc, pd); ! 141: pd -= es; ! 142: } ! 143: pc -= es; ! 144: } ! 145: if (pb > pc) ! 146: break; ! 147: swap(pb, pc); ! 148: swap_cnt = 1; ! 149: pb += es; ! 150: pc -= es; ! 151: } ! 152: if (swap_cnt == 0) { /* Switch to insertion sort */ ! 153: for (pm = a + es; pm < (char *) a + n * es; pm += es) ! 154: for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; ! 155: pl -= es) ! 156: swap(pl, pl - es); ! 157: return; ! 158: } ! 159: ! 160: pn = a + n * es; ! 161: r = min(pa - (char *)a, pb - pa); ! 162: vecswap(a, pb - r, r); ! 163: r = min(pd - pc, pn - pd - es); ! 164: vecswap(pb, pn - r, r); ! 165: if ((r = pb - pa) > es) ! 166: qsort(a, r / es, es, cmp); ! 167: if ((r = pd - pc) > es) { ! 168: /* Iterate rather than recurse to save stack space */ ! 169: a = pn - r; ! 170: n = r / es; ! 171: goto loop; ! 172: } ! 173: /* qsort(pn - r, r / es, es, cmp);*/ ! 174: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.