Changeset c6c49de in mainline
- Timestamp:
- 2010-06-30T20:17:27Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0c3e63f
- Parents:
- 4edd57fd
- Location:
- uspace/lib/c
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/sort.c
r4edd57fd rc6c49de 36 36 * 37 37 * This files contains functions implementing several sorting 38 * algorithms (e.g. quick sort and bubble sort).38 * algorithms (e.g. quick sort and gnome sort). 39 39 * 40 40 */ … … 44 44 #include <malloc.h> 45 45 46 /** Bubble sort 47 * 48 * Apply generic bubble sort algorithm on supplied data, 46 /** Immediate buffer size. 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, 49 62 * using pre-allocated buffer. 50 63 * … … 58 71 * 59 72 */ 60 static void _ bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp,73 static void _gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, 61 74 void *arg, void *slot) 62 75 { 63 bool done = false; 64 void *tmp; 65 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 } 76 size_t i = 0; 77 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++; 78 89 } 79 90 } … … 89 100 * @param cmp Comparator function. 90 101 * @param arg 3rd argument passed to cmp. 91 * @param tmpPointer to scratch memory buffer102 * @param slot Pointer to scratch memory buffer 92 103 * elem_size bytes long. 93 104 * @param pivot Pointer to scratch memory buffer … … 96 107 */ 97 108 static void _qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, 98 void *arg, void * tmp, void *pivot)109 void *arg, void *slot, void *pivot) 99 110 { 100 111 if (cnt > 4) { … … 105 116 106 117 while (true) { 107 while ((cmp( data + i * elem_size, pivot, arg) < 0) && (i < cnt))118 while ((cmp(INDEX(data, i, elem_size), pivot, arg) < 0) && (i < cnt)) 108 119 i++; 109 120 110 while ((cmp( data + j * elem_size, pivot, arg) >= 0) && (j > 0))121 while ((cmp(INDEX(data, j, elem_size), pivot, arg) >= 0) && (j > 0)) 111 122 j--; 112 123 113 124 if (i < j) { 114 memcpy( tmp, data + i * elem_size, elem_size);115 memcpy( data + i * elem_size, data + j * elem_size,125 memcpy(slot, INDEX(data, i, elem_size), elem_size); 126 memcpy(INDEX(data, i, elem_size), INDEX(data, j, elem_size), 116 127 elem_size); 117 memcpy( data + j * elem_size, tmp, elem_size);128 memcpy(INDEX(data, j, elem_size), slot, elem_size); 118 129 } else 119 130 break; 120 131 } 121 132 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);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); 125 136 } else 126 _ bsort(data, cnt, elem_size, cmp, arg, tmp);127 } 128 129 /** Bubble sort wrapper137 _gsort(data, cnt, elem_size, cmp, arg, slot); 138 } 139 140 /** Gnome sort wrapper 130 141 * 131 142 * This is only a wrapper that takes care of memory 132 143 * allocations for storing the slot element for generic 133 * bubble sort algorithm.144 * gnome sort algorithm. 134 145 * 135 146 * @param data Pointer to data to be sorted. … … 142 153 * 143 154 */ 144 bool bsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg) 145 { 146 void *slot = (void *) malloc(elem_size); 147 if (!slot) 148 return false; 149 150 _bsort(data, cnt, elem_size, cmp, arg, slot); 151 152 free(slot); 155 bool gsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg) 156 { 157 uint8_t ibuf_slot[IBUF_SIZE]; 158 void *slot; 159 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; 166 167 _gsort(data, cnt, elem_size, cmp, arg, slot); 168 169 if (elem_size > IBUF_SIZE) 170 free(slot); 153 171 154 172 return true; … … 172 190 bool qsort(void *data, size_t cnt, size_t elem_size, sort_cmp_t cmp, void *arg) 173 191 { 174 void *tmp = (void *) malloc(elem_size); 175 if (!tmp) 176 return false; 177 178 void *pivot = (void *) malloc(elem_size); 179 if (!pivot) { 180 free(tmp); 181 return false; 192 uint8_t ibuf_slot[IBUF_SIZE]; 193 uint8_t ibuf_pivot[IBUF_SIZE]; 194 void *slot; 195 void *pivot; 196 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; 182 210 } 183 211 184 _qsort(data, cnt, elem_size, cmp, arg, tmp, pivot); 185 186 free(pivot); 187 free(tmp); 212 _qsort(data, cnt, elem_size, cmp, arg, slot, pivot); 213 214 if (elem_size > IBUF_SIZE) { 215 free(pivot); 216 free(slot); 217 } 188 218 189 219 return true; -
uspace/lib/c/include/sort.h
r4edd57fd rc6c49de 41 41 typedef int (* sort_cmp_t)(void *, void *, void *); 42 42 43 extern bool bsort(void *, size_t, size_t, sort_cmp_t, void *);43 extern bool gsort(void *, size_t, size_t, sort_cmp_t, void *); 44 44 extern bool qsort(void *, size_t, size_t, sort_cmp_t, void *); 45 45
Note:
See TracChangeset
for help on using the changeset viewer.