sort.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Sergey Bondari
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 

Generated on Thu Jun 2 07:45:46 2011 for HelenOS/USB by  doxygen 1.4.7