Changes in uspace/lib/c/generic/sort.c [c6c49de:549012c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/sort.c
rc6c49de r549012c 36 36 * 37 37 * This files contains functions implementing several sorting 38 * algorithms (e.g. quick sort and gnome sort).38 * algorithms (e.g. quick sort and bubble sort). 39 39 * 40 40 */ … … 44 44 #include <malloc.h> 45 45 46 /** Immediate buffer size.46 /** Bubble sort 47 47 * 48 * For small buffer sizes avoid doing malloc() 49 * and use the stack. 50 * 51 */ 52 #define IBUF_SIZE 32 53 54 /** Array accessor. 55 * 56 */ 57 #define INDEX(buf, i, elem_size) ((buf) + (i) * (elem_size)) 58 59 /** Gnome sort 60 * 61 * Apply generic gnome sort algorithm on supplied data, 48 * Apply generic bubble sort algorithm on supplied data, 62 49 * using pre-allocated buffer. 63 50 * … … 71 58 * 72 59 */ 73 static void _ gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,60 static void _bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, 74 61 void *arg, void *slot) 75 62 { 76 size_t i = 0; 63 bool done = false; 64 void *tmp; 77 65 78 while (i < cnt) { 79 if ((i != 0) && 80 (cmp(INDEX(data, i, elem_size), 81 INDEX(data, i - 1, elem_size), arg) == -1)) { 82 memcpy(slot, INDEX(data, i, elem_size), elem_size); 83 memcpy(INDEX(data, i, elem_size), INDEX(data, i - 1, elem_size), 84 elem_size); 85 memcpy(INDEX(data, i - 1, elem_size), slot, elem_size); 86 i--; 87 } else 88 i++; 66 while (!done) { 67 done = true; 68 69 for (tmp = data; tmp < data + elem_size * (cnt - 1); 70 tmp = tmp + elem_size) { 71 if (cmp(tmp, tmp + elem_size, arg) == 1) { 72 memcpy(slot, tmp, elem_size); 73 memcpy(tmp, tmp + elem_size, elem_size); 74 memcpy(tmp + elem_size, slot, elem_size); 75 done = false; 76 } 77 } 89 78 } 90 79 } … … 100 89 * @param cmp Comparator function. 101 90 * @param arg 3rd argument passed to cmp. 102 * @param slotPointer to scratch memory buffer91 * @param tmp Pointer to scratch memory buffer 103 92 * elem_size bytes long. 104 93 * @param pivot Pointer to scratch memory buffer … … 107 96 */ 108 97 static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, 109 void *arg, void * slot, void *pivot)98 void *arg, void *tmp, void *pivot) 110 99 { 111 100 if (cnt > 4) { … … 116 105 117 106 while (true) { 118 while ((cmp( INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt))107 while ((cmp(data + i * elem_size, pivot, arg) < 0) && (i < cnt)) 119 108 i++; 120 109 121 while ((cmp( INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0))110 while ((cmp(data + j * elem_size, pivot, arg) >= 0) && (j > 0)) 122 111 j--; 123 112 124 113 if (i < j) { 125 memcpy( slot, INDEX(data, i, elem_size), elem_size);126 memcpy( INDEX(data, i, elem_size), INDEX(data, j, elem_size),114 memcpy(tmp, data + i * elem_size, elem_size); 115 memcpy(data + i * elem_size, data + j * elem_size, 127 116 elem_size); 128 memcpy( INDEX(data, j, elem_size), slot, elem_size);117 memcpy(data + j * elem_size, tmp, elem_size); 129 118 } else 130 119 break; 131 120 } 132 121 133 _qsort(data, j + 1, elem_size, cmp, arg, slot, pivot);134 _qsort( INDEX(data, j + 1, elem_size), cnt - j - 1, elem_size,135 cmp, arg, slot, pivot);122 _qsort(data, j + 1, elem_size, cmp, arg, tmp, pivot); 123 _qsort(data + (j + 1) * elem_size, cnt - j - 1, elem_size, 124 cmp, arg, tmp, pivot); 136 125 } else 137 _ gsort(data, cnt, elem_size, cmp, arg, slot);126 _bsort(data, cnt, elem_size, cmp, arg, tmp); 138 127 } 139 128 140 /** Gnome sort wrapper129 /** Bubble sort wrapper 141 130 * 142 131 * This is only a wrapper that takes care of memory 143 132 * allocations for storing the slot element for generic 144 * gnome sort algorithm.133 * bubble sort algorithm. 145 134 * 146 135 * @param data Pointer to data to be sorted. … … 153 142 * 154 143 */ 155 bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg)144 bool bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg) 156 145 { 157 uint8_t ibuf_slot[IBUF_SIZE]; 158 void *slot; 146 void *slot = (void *) malloc(elem_size); 147 if (!slot) 148 return false; 159 149 160 if (elem_size > IBUF_SIZE) { 161 slot = (void *) malloc(elem_size); 162 if (!slot) 163 return false; 164 } else 165 slot = (void *) ibuf_slot; 150 _bsort(data, cnt, elem_size, cmp, arg, slot); 166 151 167 _gsort(data, cnt, elem_size, cmp, arg, slot); 168 169 if (elem_size > IBUF_SIZE) 170 free(slot); 152 free(slot); 171 153 172 154 return true; … … 190 172 bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg) 191 173 { 192 uint8_t ibuf_slot[IBUF_SIZE]; 193 uint8_t ibuf_pivot[IBUF_SIZE]; 194 void *slot; 195 void *pivot; 174 void *tmp = (void *) malloc(elem_size); 175 if (!tmp) 176 return false; 196 177 197 if (elem_size > IBUF_SIZE) { 198 slot = (void *) malloc(elem_size); 199 if (!slot) 200 return false; 201 202 pivot = (void *) malloc(elem_size); 203 if (!pivot) { 204 free(slot); 205 return false; 206 } 207 } else { 208 slot = (void *) ibuf_slot; 209 pivot = (void *) ibuf_pivot; 178 void *pivot = (void *) malloc(elem_size); 179 if (!pivot) { 180 free(tmp); 181 return false; 210 182 } 211 183 212 _qsort(data, cnt, elem_size, cmp, arg, slot, pivot);184 _qsort(data, cnt, elem_size, cmp, arg, tmp, pivot); 213 185 214 if (elem_size > IBUF_SIZE) { 215 free(pivot); 216 free(slot); 217 } 186 free(pivot); 187 free(tmp); 218 188 219 189 return true;
Note:
See TracChangeset
for help on using the changeset viewer.