|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved ! 24: * ! 25: * Copyright (c) 1992, 1993 ! 26: * The Regents of the University of California. All rights reserved. ! 27: * ! 28: * Redistribution and use in source and binary forms, with or without ! 29: * modification, are permitted provided that the following conditions ! 30: * are met: ! 31: * 1. Redistributions of source code must retain the above copyright ! 32: * notice, this list of conditions and the following disclaimer. ! 33: * 2. Redistributions in binary form must reproduce the above copyright ! 34: * notice, this list of conditions and the following disclaimer in the ! 35: * documentation and/or other materials provided with the distribution. ! 36: * 3. All advertising materials mentioning features or use of this software ! 37: * must display the following acknowledgement: ! 38: * This product includes software developed by the University of ! 39: * California, Berkeley and its contributors. ! 40: * 4. Neither the name of the University nor the names of its contributors ! 41: * may be used to endorse or promote products derived from this software ! 42: * without specific prior written permission. ! 43: * ! 44: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 45: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 46: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 47: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 48: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 49: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 50: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 51: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 52: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 53: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 54: * SUCH DAMAGE. ! 55: * ! 56: * @(#)qsort.c 8.1 (Berkeley) 6/4/93 ! 57: */ ! 58: ! 59: ! 60: #include <sys/types.h> ! 61: #include <stdlib.h> ! 62: ! 63: static inline char *med3 __P((char *, char *, char *, int (*)())); ! 64: static inline void swapfunc __P((char *, char *, int, int)); ! 65: ! 66: #define min(a, b) (a) < (b) ? a : b ! 67: ! 68: /* ! 69: * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". ! 70: */ ! 71: #define swapcode(TYPE, parmi, parmj, n) { \ ! 72: long i = (n) / sizeof (TYPE); \ ! 73: register TYPE *pi = (TYPE *) (parmi); \ ! 74: register TYPE *pj = (TYPE *) (parmj); \ ! 75: do { \ ! 76: register TYPE t = *pi; \ ! 77: *pi++ = *pj; \ ! 78: *pj++ = t; \ ! 79: } while (--i > 0); \ ! 80: } ! 81: ! 82: #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ ! 83: es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; ! 84: ! 85: static inline void ! 86: swapfunc(a, b, n, swaptype) ! 87: char *a, *b; ! 88: int n, swaptype; ! 89: { ! 90: if(swaptype <= 1) ! 91: swapcode(long, a, b, n) ! 92: else ! 93: swapcode(char, a, b, n) ! 94: } ! 95: ! 96: #define swap(a, b) \ ! 97: if (swaptype == 0) { \ ! 98: long t = *(long *)(a); \ ! 99: *(long *)(a) = *(long *)(b); \ ! 100: *(long *)(b) = t; \ ! 101: } else \ ! 102: swapfunc(a, b, es, swaptype) ! 103: ! 104: #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) ! 105: ! 106: static inline char * ! 107: med3(a, b, c, cmp) ! 108: char *a, *b, *c; ! 109: int (*cmp)(); ! 110: { ! 111: return cmp(a, b) < 0 ? ! 112: (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) ! 113: :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c )); ! 114: } ! 115: ! 116: void ! 117: qsort(a, n, es, cmp) ! 118: void *a; ! 119: size_t n, es; ! 120: int (*cmp)(); ! 121: { ! 122: char *pa, *pb, *pc, *pd, *pl, *pm, *pn; ! 123: int d, r, swaptype, swap_cnt; ! 124: ! 125: loop: SWAPINIT(a, es); ! 126: swap_cnt = 0; ! 127: if (n < 7) { ! 128: for (pm = a + es; pm < (char *) a + n * es; pm += es) ! 129: for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; ! 130: pl -= es) ! 131: swap(pl, pl - es); ! 132: return; ! 133: } ! 134: pm = a + (n / 2) * es; ! 135: if (n > 7) { ! 136: pl = a; ! 137: pn = a + (n - 1) * es; ! 138: if (n > 40) { ! 139: d = (n / 8) * es; ! 140: pl = med3(pl, pl + d, pl + 2 * d, cmp); ! 141: pm = med3(pm - d, pm, pm + d, cmp); ! 142: pn = med3(pn - 2 * d, pn - d, pn, cmp); ! 143: } ! 144: pm = med3(pl, pm, pn, cmp); ! 145: } ! 146: swap(a, pm); ! 147: pa = pb = a + es; ! 148: ! 149: pc = pd = a + (n - 1) * es; ! 150: for (;;) { ! 151: while (pb <= pc && (r = cmp(pb, a)) <= 0) { ! 152: if (r == 0) { ! 153: swap_cnt = 1; ! 154: swap(pa, pb); ! 155: pa += es; ! 156: } ! 157: pb += es; ! 158: } ! 159: while (pb <= pc && (r = cmp(pc, a)) >= 0) { ! 160: if (r == 0) { ! 161: swap_cnt = 1; ! 162: swap(pc, pd); ! 163: pd -= es; ! 164: } ! 165: pc -= es; ! 166: } ! 167: if (pb > pc) ! 168: break; ! 169: swap(pb, pc); ! 170: swap_cnt = 1; ! 171: pb += es; ! 172: pc -= es; ! 173: } ! 174: if (swap_cnt == 0) { /* Switch to insertion sort */ ! 175: for (pm = a + es; pm < (char *) a + n * es; pm += es) ! 176: for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; ! 177: pl -= es) ! 178: swap(pl, pl - es); ! 179: return; ! 180: } ! 181: ! 182: pn = a + n * es; ! 183: r = min(pa - (char *)a, pb - pa); ! 184: vecswap(a, pb - r, r); ! 185: r = min(pd - pc, pn - pd - es); ! 186: vecswap(pb, pn - r, r); ! 187: if ((r = pb - pa) > es) ! 188: qsort(a, r / es, es, cmp); ! 189: if ((r = pd - pc) > es) { ! 190: /* Iterate rather than recurse to save stack space */ ! 191: a = pn - r; ! 192: n = r / es; ! 193: goto loop; ! 194: } ! 195: /* qsort(pn - r, r / es, es, cmp);*/ ! 196: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.