Rename bunch of variables.
[oota-llvm.git] / runtime / GCCLibraries / libc / qsort.c
1 //===-- qsort.c - The qsort function for the LLVM libc Library ----*- C -*-===//
2 // 
3 // This code is a modified form of the qsort() function from the GNU C
4 // library.
5 //
6 // Modifications:
7 //  2003/05/29 - Code disabled for compilation.  Line wrapping changed.
8 //
9 //===----------------------------------------------------------------------===//
10
11 /* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc.
12    This file is part of the GNU C Library.
13    Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
14
15    The GNU C Library is free software; you can redistribute it and/or
16    modify it under the terms of the GNU Lesser General Public
17    License as published by the Free Software Foundation; either
18    version 2.1 of the License, or (at your option) any later version.
19
20    The GNU C Library is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23    Lesser General Public License for more details.
24
25    You should have received a copy of the GNU Lesser General Public
26    License along with the GNU C Library; if not, write to the Free
27    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28    02111-1307 USA.  */
29
30 /* If you consider tuning this algorithm, you should consult first:
31    Engineering a sort function; Jon Bentley and M. Douglas McIlroy;
32    Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993.  */
33
34 #if 0
35
36 #include <limits.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 /* Byte-wise swap two items of size SIZE. */
41 #define SWAP(a, b, size)                        \
42   do                                            \
43     {                                           \
44       register size_t __size = (size);          \
45       register char *__a = (a), *__b = (b);     \
46       do                                        \
47         {                                       \
48           char __tmp = *__a;                    \
49           *__a++ = *__b;                        \
50           *__b++ = __tmp;                       \
51         } while (--__size > 0);                 \
52     } while (0)
53
54 /* Discontinue quicksort algorithm when partition gets below this size.
55    This particular magic number was chosen to work best on a Sun 4/260. */
56 #define MAX_THRESH 4
57
58 /* Stack node declarations used to store unfulfilled partition obligations. */
59 typedef struct
60   {
61     char *lo;
62     char *hi;
63   } stack_node;
64
65 /* The next 4 #defines implement a very fast in-line stack abstraction. */
66 /* The stack needs log (total_elements) entries (we could even subtract
67    log(MAX_THRESH)).  Since total_elements has type size_t, we get as
68    upper bound for log (total_elements):
69    bits per byte (CHAR_BIT) * sizeof(size_t).  */
70 #define STACK_SIZE      (CHAR_BIT * sizeof(size_t))
71 #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
72 #define POP(low, high)  ((void) (--top, (low = top->lo), (high = top->hi)))
73 #define STACK_NOT_EMPTY  (stack < top)
74
75
76 /* Order size using quicksort.  This implementation incorporates
77    four optimizations discussed in Sedgewick:
78
79    1. Non-recursive, using an explicit stack of pointer that store the
80       next array partition to sort.  To save time, this maximum amount
81       of space required to store an array of SIZE_MAX is allocated on the
82       stack.  Assuming a 32-bit (64 bit) integer for size_t, this needs
83       only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes).
84       Pretty cheap, actually.
85
86    2. Chose the pivot element using a median-of-three decision tree.
87       This reduces the probability of selecting a bad pivot value and
88       eliminates certain extraneous comparisons.
89
90    3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
91       insertion sort to order the MAX_THRESH items within each partition.
92       This is a big win, since insertion sort is faster for small, mostly
93       sorted array segments.
94
95    4. The larger of the two sub-partitions is always pushed onto the
96       stack first, with the algorithm then concentrating on the
97       smaller partition.  This *guarantees* no more than log (total_elems)
98       stack size is needed (actually O(1) in this case)!  */
99
100 typedef int(*__compar_fn_t)(const void *, const void *);
101 void
102 qsort (void *const pbase, size_t total_elems, size_t size,
103             __compar_fn_t cmp)
104 {
105   register char *base_ptr = (char *) pbase;
106
107   const size_t max_thresh = MAX_THRESH * size;
108
109   if (total_elems == 0)
110     /* Avoid lossage with unsigned arithmetic below.  */
111     return;
112
113   if (total_elems > MAX_THRESH)
114     {
115       char *lo = base_ptr;
116       char *hi = &lo[size * (total_elems - 1)];
117       stack_node stack[STACK_SIZE];
118       stack_node *top = stack + 1;
119
120       while (STACK_NOT_EMPTY)
121         {
122           char *left_ptr;
123           char *right_ptr;
124
125           /* Select median value from among LO, MID, and HI. Rearrange
126              LO and HI so the three values are sorted. This lowers the
127              probability of picking a pathological pivot value and
128              skips a comparison for both the LEFT_PTR and RIGHT_PTR in
129              the while loops. */
130
131           char *mid = lo + size * ((hi - lo) / size >> 1);
132
133           if ((*cmp) ((void *) mid, (void *) lo) < 0)
134             SWAP (mid, lo, size);
135           if ((*cmp) ((void *) hi, (void *) mid) < 0)
136             SWAP (mid, hi, size);
137           else
138             goto jump_over;
139           if ((*cmp) ((void *) mid, (void *) lo) < 0)
140             SWAP (mid, lo, size);
141         jump_over:;
142
143           left_ptr  = lo + size;
144           right_ptr = hi - size;
145
146           /* Here's the famous ``collapse the walls'' section of quicksort.
147              Gotta like those tight inner loops!  They are the main reason
148              that this algorithm runs much faster than others. */
149           do
150             {
151               while ((*cmp) ((void *) left_ptr, (void *) mid) < 0)
152                 left_ptr += size;
153
154               while ((*cmp) ((void *) mid, (void *) right_ptr) < 0)
155                 right_ptr -= size;
156
157               if (left_ptr < right_ptr)
158                 {
159                   SWAP (left_ptr, right_ptr, size);
160                   if (mid == left_ptr)
161                     mid = right_ptr;
162                   else if (mid == right_ptr)
163                     mid = left_ptr;
164                   left_ptr += size;
165                   right_ptr -= size;
166                 }
167               else if (left_ptr == right_ptr)
168                 {
169                   left_ptr += size;
170                   right_ptr -= size;
171                   break;
172                 }
173             }
174           while (left_ptr <= right_ptr);
175
176           /* Set up pointers for next iteration.  First determine whether
177              left and right partitions are below the threshold size.  If so,
178              ignore one or both.  Otherwise, push the larger partition's
179              bounds on the stack and continue sorting the smaller one. */
180
181           if ((size_t) (right_ptr - lo) <= max_thresh)
182             {
183               if ((size_t) (hi - left_ptr) <= max_thresh)
184                 /* Ignore both small partitions. */
185                 POP (lo, hi);
186               else
187                 /* Ignore small left partition. */
188                 lo = left_ptr;
189             }
190           else if ((size_t) (hi - left_ptr) <= max_thresh)
191             /* Ignore small right partition. */
192             hi = right_ptr;
193           else if ((right_ptr - lo) > (hi - left_ptr))
194             {
195               /* Push larger left partition indices. */
196               PUSH (lo, right_ptr);
197               lo = left_ptr;
198             }
199           else
200             {
201               /* Push larger right partition indices. */
202               PUSH (left_ptr, hi);
203               hi = right_ptr;
204             }
205         }
206     }
207
208   /* Once the BASE_PTR array is partially sorted by quicksort the rest
209      is completely sorted using insertion sort, since this is efficient
210      for partitions below MAX_THRESH size. BASE_PTR points to the beginning
211      of the array to sort, and END_PTR points at the very last element in
212      the array (*not* one beyond it!). */
213
214 #define min(x, y) ((x) < (y) ? (x) : (y))
215
216   {
217     char *const end_ptr = &base_ptr[size * (total_elems - 1)];
218     char *tmp_ptr = base_ptr;
219     char *thresh = min(end_ptr, base_ptr + max_thresh);
220     register char *run_ptr;
221
222     /* Find smallest element in first threshold and place it at the
223        array's beginning.  This is the smallest array element,
224        and the operation speeds up insertion sort's inner loop. */
225
226     for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
227       if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0)
228         tmp_ptr = run_ptr;
229
230     if (tmp_ptr != base_ptr)
231       SWAP (tmp_ptr, base_ptr, size);
232
233     /* Insertion sort, running from left-hand-side up to right-hand-side.  */
234
235     run_ptr = base_ptr + size;
236     while ((run_ptr += size) <= end_ptr)
237       {
238         tmp_ptr = run_ptr - size;
239         while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0)
240           tmp_ptr -= size;
241
242         tmp_ptr += size;
243         if (tmp_ptr != run_ptr)
244           {
245             char *trav;
246
247             trav = run_ptr + size;
248             while (--trav >= run_ptr)
249               {
250                 char c = *trav;
251                 char *hi, *lo;
252
253                 for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)
254                   *hi = *lo;
255                 *hi = c;
256               }
257           }
258       }
259   }
260 }
261 #endif