annotate yaffs_qsort.c @ 389:10fe81fa4682

Update yaffs docs
author charles <charles>
date Tue, 16 Mar 2010 03:30:45 +0000
parents c0dfae9e8073
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
1 /*
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
2 * Copyright (c) 1992, 1993
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
3 * The Regents of the University of California. All rights reserved.
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
4 *
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
5 * Redistribution and use in source and binary forms, with or without
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
6 * modification, are permitted provided that the following conditions
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
7 * are met:
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
8 * 1. Redistributions of source code must retain the above copyright
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
9 * notice, this list of conditions and the following disclaimer.
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
10 * 2. Redistributions in binary form must reproduce the above copyright
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
11 * notice, this list of conditions and the following disclaimer in the
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
12 * documentation and/or other materials provided with the distribution.
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
13 * 3. Neither the name of the University nor the names of its contributors
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
14 * may be used to endorse or promote products derived from this software
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
15 * without specific prior written permission.
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
16 *
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
27 * SUCH DAMAGE.
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
28 */
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
29
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
30 #include "yportenv.h"
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
31 /* #include <linux/string.h> */
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
32
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
33 /*
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
34 * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
35 */
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
36 #define swapcode(TYPE, parmi, parmj, n) do { \
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
37 long i = (n) / sizeof (TYPE); \
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
38 register TYPE *pi = (TYPE *) (parmi); \
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
39 register TYPE *pj = (TYPE *) (parmj); \
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
40 do { \
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
41 register TYPE t = *pi; \
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
42 *pi++ = *pj; \
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
43 *pj++ = t; \
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
44 } while (--i > 0); \
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
45 } while (0)
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
46
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
47 #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
48 es % sizeof(long) ? 2 : es == sizeof(long) ? 0 : 1;
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
49
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
50 static __inline void
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
51 swapfunc(char *a, char *b, int n, int swaptype)
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
52 {
198
b7f785925166 Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents: 179
diff changeset
53 if (swaptype <= 1)
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
54 swapcode(long, a, b, n);
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
55 else
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
56 swapcode(char, a, b, n);
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
57 }
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
58
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
59 #define yswap(a, b) do { \
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
60 if (swaptype == 0) { \
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
61 long t = *(long *)(a); \
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
62 *(long *)(a) = *(long *)(b); \
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
63 *(long *)(b) = t; \
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
64 } else \
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
65 swapfunc(a, b, es, swaptype); \
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
66 } while (0)
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
67
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
68 #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
69
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
70 static __inline char *
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
71 med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
72 {
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
73 return cmp(a, b) < 0 ?
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
74 (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a))
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
75 : (cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c));
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
76 }
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
77
179
2c3cea26b1ca Rolling in Ians and other changes
charles <charles>
parents: 130
diff changeset
78 #ifndef min
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
79 #define min(a, b) (((a) < (b)) ? (a) : (b))
179
2c3cea26b1ca Rolling in Ians and other changes
charles <charles>
parents: 130
diff changeset
80 #endif
2c3cea26b1ca Rolling in Ians and other changes
charles <charles>
parents: 130
diff changeset
81
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
82 void
179
2c3cea26b1ca Rolling in Ians and other changes
charles <charles>
parents: 130
diff changeset
83 yaffs_qsort(void *aa, size_t n, size_t es,
2c3cea26b1ca Rolling in Ians and other changes
charles <charles>
parents: 130
diff changeset
84 int (*cmp)(const void *, const void *))
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
85 {
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
86 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
87 int d, r, swaptype, swap_cnt;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
88 register char *a = aa;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
89
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
90 loop: SWAPINIT(a, es);
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
91 swap_cnt = 0;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
92 if (n < 7) {
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
93 for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
94 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
95 pl -= es)
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
96 yswap(pl, pl - es);
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
97 return;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
98 }
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
99 pm = (char *)a + (n / 2) * es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
100 if (n > 7) {
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
101 pl = (char *)a;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
102 pn = (char *)a + (n - 1) * es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
103 if (n > 40) {
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
104 d = (n / 8) * es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
105 pl = med3(pl, pl + d, pl + 2 * d, cmp);
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
106 pm = med3(pm - d, pm, pm + d, cmp);
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
107 pn = med3(pn - 2 * d, pn - d, pn, cmp);
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
108 }
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
109 pm = med3(pl, pm, pn, cmp);
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
110 }
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
111 yswap(a, pm);
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
112 pa = pb = (char *)a + es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
113
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
114 pc = pd = (char *)a + (n - 1) * es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
115 for (;;) {
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
116 while (pb <= pc && (r = cmp(pb, a)) <= 0) {
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
117 if (r == 0) {
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
118 swap_cnt = 1;
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
119 yswap(pa, pb);
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
120 pa += es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
121 }
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
122 pb += es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
123 }
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
124 while (pb <= pc && (r = cmp(pc, a)) >= 0) {
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
125 if (r == 0) {
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
126 swap_cnt = 1;
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
127 yswap(pc, pd);
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
128 pd -= es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
129 }
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
130 pc -= es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
131 }
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
132 if (pb > pc)
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
133 break;
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
134 yswap(pb, pc);
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
135 swap_cnt = 1;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
136 pb += es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
137 pc -= es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
138 }
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
139 if (swap_cnt == 0) { /* Switch to insertion sort */
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
140 for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
198
b7f785925166 Cleanup patch - Remove all trailing whitespace and fix a few typos.
wookey <wookey>
parents: 179
diff changeset
141 for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
142 pl -= es)
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
143 yswap(pl, pl - es);
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
144 return;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
145 }
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
146
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
147 pn = (char *)a + n * es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
148 r = min(pa - (char *)a, pb - pa);
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
149 vecswap(a, pb - r, r);
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
150 r = min((long)(pd - pc), (long)(pn - pd - es));
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
151 vecswap(pb, pn - r, r);
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
152 r = pb - pa;
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
153 if (r > es)
179
2c3cea26b1ca Rolling in Ians and other changes
charles <charles>
parents: 130
diff changeset
154 yaffs_qsort(a, r / es, es, cmp);
271
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
155 r = pd - pc;
c0dfae9e8073 Major whitespace/style changes to match Linux checkpatch.pl code style
wookey <wookey>
parents: 198
diff changeset
156 if (r > es) {
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
157 /* Iterate rather than recurse to save stack space */
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
158 a = pn - r;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
159 n = r / es;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
160 goto loop;
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
161 }
179
2c3cea26b1ca Rolling in Ians and other changes
charles <charles>
parents: 130
diff changeset
162 /* yaffs_qsort(pn - r, r / es, es, cmp);*/
130
2f8d5c914150 Add qsort
charles <charles>
parents:
diff changeset
163 }