00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00042 #include <sort.h>
00043 #include <mem.h>
00044 #include <malloc.h>
00045
00052 #define IBUF_SIZE 32
00053
00057 #define INDEX(buf, i, elem_size) ((buf) + (i) * (elem_size))
00058
00073 static void _gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
00074 void *arg, void *slot)
00075 {
00076 size_t i = 0;
00077
00078 while (i < cnt) {
00079 if ((i != 0) &&
00080 (cmp(INDEX(data, i, elem_size),
00081 INDEX(data, i - 1, elem_size), arg) == -1)) {
00082 memcpy(slot, INDEX(data, i, elem_size), elem_size);
00083 memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size),
00084 elem_size);
00085 memcpy(INDEX(data, i - 1, elem_size), slot, elem_size);
00086 i--;
00087 } else
00088 i++;
00089 }
00090 }
00091
00108 static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,
00109 void *arg, void *slot, void *pivot)
00110 {
00111 if (cnt > 4) {
00112 size_t i = 0;
00113 size_t j = cnt - 1;
00114
00115 memcpy(pivot, data, elem_size);
00116
00117 while (true) {
00118 while ((cmp(INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt))
00119 i++;
00120
00121 while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0))
00122 j--;
00123
00124 if (i < j) {
00125 memcpy(slot, INDEX(data, i, elem_size), elem_size);
00126 memcpy(INDEX(data, i, elem_size), INDEX(data, j, elem_size),
00127 elem_size);
00128 memcpy(INDEX(data, j, elem_size), slot, elem_size);
00129 } else
00130 break;
00131 }
00132
00133 _qsort(data, j + 1, elem_size, cmp, arg, slot, pivot);
00134 _qsort(INDEX(data, j + 1, elem_size), cnt - j - 1, elem_size,
00135 cmp, arg, slot, pivot);
00136 } else
00137 _gsort(data, cnt, elem_size, cmp, arg, slot);
00138 }
00139
00155 bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
00156 {
00157 uint8_t ibuf_slot[IBUF_SIZE];
00158 void *slot;
00159
00160 if (elem_size > IBUF_SIZE) {
00161 slot = (void *) malloc(elem_size);
00162 if (!slot)
00163 return false;
00164 } else
00165 slot = (void *) ibuf_slot;
00166
00167 _gsort(data, cnt, elem_size, cmp, arg, slot);
00168
00169 if (elem_size > IBUF_SIZE)
00170 free(slot);
00171
00172 return true;
00173 }
00174
00190 bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)
00191 {
00192 uint8_t ibuf_slot[IBUF_SIZE];
00193 uint8_t ibuf_pivot[IBUF_SIZE];
00194 void *slot;
00195 void *pivot;
00196
00197 if (elem_size > IBUF_SIZE) {
00198 slot = (void *) malloc(elem_size);
00199 if (!slot)
00200 return false;
00201
00202 pivot = (void *) malloc(elem_size);
00203 if (!pivot) {
00204 free(slot);
00205 return false;
00206 }
00207 } else {
00208 slot = (void *) ibuf_slot;
00209 pivot = (void *) ibuf_pivot;
00210 }
00211
00212 _qsort(data, cnt, elem_size, cmp, arg, slot, pivot);
00213
00214 if (elem_size > IBUF_SIZE) {
00215 free(pivot);
00216 free(slot);
00217 }
00218
00219 return true;
00220 }
00221