00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025 #include "libiberty.h"
00026 #include "sort.h"
00027 #ifdef HAVE_LIMITS_H
00028 #include <limits.h>
00029 #endif
00030 #ifdef HAVE_SYS_PARAM_H
00031 #include <sys/param.h>
00032 #endif
00033 #ifdef HAVE_STDLIB_H
00034 #include <stdlib.h>
00035 #endif
00036 #ifdef HAVE_STRING_H
00037 #include <string.h>
00038 #endif
00039
00040 #ifndef UCHAR_MAX
00041 #define UCHAR_MAX ((unsigned char)(-1))
00042 #endif
00043
00044
00045
00046
00047 void sort_pointers (n, pointers, work)
00048 size_t n;
00049 void **pointers;
00050 void **work;
00051 {
00052
00053
00054
00055 typedef unsigned char digit_t;
00056
00057
00058 #define DIGIT_MAX (UCHAR_MAX + 1)
00059
00060
00061
00062 unsigned int count[DIGIT_MAX];
00063
00064 int big_endian_p;
00065 size_t i;
00066 size_t j;
00067
00068
00069
00070
00071
00072
00073 if ((sizeof (void *) / sizeof (digit_t)) % 2 != 0)
00074 abort ();
00075
00076
00077 for (i = 0, j = 0; i < sizeof (size_t); ++i)
00078 {
00079 j *= (UCHAR_MAX + 1);
00080 j += i;
00081 }
00082 big_endian_p = (((char *)&j)[0] == 0);
00083
00084
00085
00086 for (i = 0; i < sizeof (void *) / sizeof (digit_t); ++i)
00087 {
00088 digit_t *digit;
00089 digit_t *bias;
00090 digit_t *top;
00091 unsigned int *countp;
00092 void **pointerp;
00093
00094
00095
00096 if (big_endian_p)
00097 j = sizeof (void *) / sizeof (digit_t) - i;
00098 else
00099 j = i;
00100
00101
00102
00103 memset (count, 0, DIGIT_MAX * sizeof (unsigned int));
00104
00105
00106
00107
00108 bias = ((digit_t *) pointers) + j;
00109 top = ((digit_t *) (pointers + n)) + j;
00110
00111
00112
00113
00114 for (digit = bias;
00115 digit < top;
00116 digit += sizeof (void *) / sizeof (digit_t))
00117 ++count[*digit];
00118
00119
00120
00121 for (countp = count + 1; countp < count + DIGIT_MAX; ++countp)
00122 *countp += countp[-1];
00123
00124
00125 for (pointerp = pointers + n - 1; pointerp >= pointers; --pointerp)
00126 work[--count[((digit_t *) pointerp)[j]]] = *pointerp;
00127
00128
00129
00130 pointerp = pointers;
00131 pointers = work;
00132 work = pointerp;
00133 }
00134 }
00135
00136
00137
00138
00139 #ifdef UNIT_TEST
00140
00141 #include <stdio.h>
00142
00143 void *xmalloc (n)
00144 size_t n;
00145 {
00146 return malloc (n);
00147 }
00148
00149 int main (int argc, char **argv)
00150 {
00151 int k;
00152 int result;
00153 size_t i;
00154 void **pointers;
00155 void **work;
00156
00157 if (argc > 1)
00158 k = atoi (argv[1]);
00159 else
00160 k = 10;
00161
00162 pointers = xmalloc (k * sizeof (void *));
00163 work = xmalloc (k * sizeof (void *));
00164
00165 for (i = 0; i < k; ++i)
00166 {
00167 pointers[i] = (void *) random ();
00168 printf ("%x\n", pointers[i]);
00169 }
00170
00171 sort_pointers (k, pointers, work);
00172
00173 printf ("\nSorted\n\n");
00174
00175 result = 0;
00176
00177 for (i = 0; i < k; ++i)
00178 {
00179 printf ("%x\n", pointers[i]);
00180 if (i > 0 && (char*) pointers[i] < (char*) pointers[i - 1])
00181 result = 1;
00182 }
00183
00184 free (pointers);
00185 free (work);
00186
00187 return result;
00188 }
00189
00190 #endif