Root/
Source at commit 418 created 13 years 10 months ago. By azimutz, Trunk it, revs 413 --> 416. | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.␊ |
3 | *␊ |
4 | * @APPLE_LICENSE_HEADER_START@␊ |
5 | * ␊ |
6 | * Portions Copyright (c) 1999-2003 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 2.0 (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 | * 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 | ␊ |
57 | ␊ |
58 | #include <sys/types.h>␊ |
59 | #include <stdlib.h>␊ |
60 | ␊ |
61 | static inline char␉*med3 __P((char *, char *, char *, int (*)()));␊ |
62 | static inline void␉ swapfunc __P((char *, char *, int, int));␊ |
63 | ␊ |
64 | #define min(a, b)␉(a) < (b) ? a : b␊ |
65 | ␊ |
66 | /*␊ |
67 | * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".␊ |
68 | */␊ |
69 | #define swapcode(TYPE, parmi, parmj, n) { ␉␉\␊ |
70 | ␉long i = (n) / sizeof (TYPE); ␉␉␉\␊ |
71 | ␉register TYPE *pi = (TYPE *) (parmi); ␉␉\␊ |
72 | ␉register TYPE *pj = (TYPE *) (parmj); ␉␉\␊ |
73 | ␉do { ␉␉␉␉␉␉\␊ |
74 | ␉␉register TYPE␉t = *pi;␉␉\␊ |
75 | ␉␉*pi++ = *pj;␉␉␉␉\␊ |
76 | ␉␉*pj++ = t;␉␉␉␉\␊ |
77 | } while (--i > 0);␉␉␉␉\␊ |
78 | }␊ |
79 | ␊ |
80 | #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \␊ |
81 | ␉es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;␊ |
82 | ␊ |
83 | static inline void␊ |
84 | swapfunc(a, b, n, swaptype)␊ |
85 | ␉char *a, *b;␊ |
86 | ␉int n, swaptype;␊ |
87 | {␊ |
88 | ␉if(swaptype <= 1) ␊ |
89 | ␉␉swapcode(long, a, b, n)␊ |
90 | ␉else␊ |
91 | ␉␉swapcode(char, a, b, n)␊ |
92 | }␊ |
93 | ␊ |
94 | #define swap(a, b)␉␉␉␉␉\␊ |
95 | ␉if (swaptype == 0) {␉␉␉␉\␊ |
96 | ␉␉long t = *(long *)(a);␉␉␉\␊ |
97 | ␉␉*(long *)(a) = *(long *)(b);␉␉\␊ |
98 | ␉␉*(long *)(b) = t;␉␉␉\␊ |
99 | ␉} else␉␉␉␉␉␉\␊ |
100 | ␉␉swapfunc(a, b, es, swaptype)␊ |
101 | ␊ |
102 | #define vecswap(a, b, n) ␉if ((n) > 0) swapfunc(a, b, n, swaptype)␊ |
103 | ␊ |
104 | static inline char *␊ |
105 | med3(a, b, c, cmp)␊ |
106 | ␉char *a, *b, *c;␊ |
107 | ␉int (*cmp)();␊ |
108 | {␊ |
109 | ␉return cmp(a, b) < 0 ?␊ |
110 | ␉ (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))␊ |
111 | :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));␊ |
112 | }␊ |
113 | ␊ |
114 | void␊ |
115 | qsort(a, n, es, cmp)␊ |
116 | ␉void *a;␊ |
117 | ␉size_t n, es;␊ |
118 | ␉int (*cmp)();␊ |
119 | {␊ |
120 | ␉char *pa, *pb, *pc, *pd, *pl, *pm, *pn;␊ |
121 | ␉int d, r, swaptype, swap_cnt;␊ |
122 | ␊ |
123 | loop:␉SWAPINIT(a, es);␊ |
124 | ␉swap_cnt = 0;␊ |
125 | ␉if (n < 7) {␊ |
126 | ␉␉for (pm = a + es; pm < (char *) a + n * es; pm += es)␊ |
127 | ␉␉␉for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;␊ |
128 | ␉␉␉ pl -= es)␊ |
129 | ␉␉␉␉swap(pl, pl - es);␊ |
130 | ␉␉return;␊ |
131 | ␉}␊ |
132 | ␉pm = a + (n / 2) * es;␊ |
133 | ␉if (n > 7) {␊ |
134 | ␉␉pl = a;␊ |
135 | ␉␉pn = a + (n - 1) * es;␊ |
136 | ␉␉if (n > 40) {␊ |
137 | ␉␉␉d = (n / 8) * es;␊ |
138 | ␉␉␉pl = med3(pl, pl + d, pl + 2 * d, cmp);␊ |
139 | ␉␉␉pm = med3(pm - d, pm, pm + d, cmp);␊ |
140 | ␉␉␉pn = med3(pn - 2 * d, pn - d, pn, cmp);␊ |
141 | ␉␉}␊ |
142 | ␉␉pm = med3(pl, pm, pn, cmp);␊ |
143 | ␉}␊ |
144 | ␉swap(a, pm);␊ |
145 | ␉pa = pb = a + es;␊ |
146 | ␊ |
147 | ␉pc = pd = a + (n - 1) * es;␊ |
148 | ␉for (;;) {␊ |
149 | ␉␉while (pb <= pc && (r = cmp(pb, a)) <= 0) {␊ |
150 | ␉␉␉if (r == 0) {␊ |
151 | ␉␉␉␉swap_cnt = 1;␊ |
152 | ␉␉␉␉swap(pa, pb);␊ |
153 | ␉␉␉␉pa += es;␊ |
154 | ␉␉␉}␊ |
155 | ␉␉␉pb += es;␊ |
156 | ␉␉}␊ |
157 | ␉␉while (pb <= pc && (r = cmp(pc, a)) >= 0) {␊ |
158 | ␉␉␉if (r == 0) {␊ |
159 | ␉␉␉␉swap_cnt = 1;␊ |
160 | ␉␉␉␉swap(pc, pd);␊ |
161 | ␉␉␉␉pd -= es;␊ |
162 | ␉␉␉}␊ |
163 | ␉␉␉pc -= es;␊ |
164 | ␉␉}␊ |
165 | ␉␉if (pb > pc)␊ |
166 | ␉␉␉break;␊ |
167 | ␉␉swap(pb, pc);␊ |
168 | ␉␉swap_cnt = 1;␊ |
169 | ␉␉pb += es;␊ |
170 | ␉␉pc -= es;␊ |
171 | ␉}␊ |
172 | ␉if (swap_cnt == 0) { /* Switch to insertion sort */␊ |
173 | ␉␉for (pm = a + es; pm < (char *) a + n * es; pm += es)␊ |
174 | ␉␉␉for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; ␊ |
175 | ␉␉␉ pl -= es)␊ |
176 | ␉␉␉␉swap(pl, pl - es);␊ |
177 | ␉␉return;␊ |
178 | ␉}␊ |
179 | ␊ |
180 | ␉pn = a + n * es;␊ |
181 | ␉r = min(pa - (char *)a, pb - pa);␊ |
182 | ␉vecswap(a, pb - r, r);␊ |
183 | ␉r = min(pd - pc, (pn - pd) - (int)es);␊ |
184 | ␉vecswap(pb, pn - r, r);␊ |
185 | ␉if ((r = pb - pa) > (int)es)␊ |
186 | ␉␉qsort(a, r / es, es, cmp);␊ |
187 | ␉if ((r = pd - pc) > (int)es) { ␊ |
188 | ␉␉/* Iterate rather than recurse to save stack space */␊ |
189 | ␉␉a = pn - r;␊ |
190 | ␉␉n = r / es;␊ |
191 | ␉␉goto loop;␊ |
192 | ␉}␊ |
193 | /*␉␉qsort(pn - r, r / es, es, cmp);*/␊ |
194 | }␊ |
195 |