X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..374ca955a76ecab1204ca8bfa63ff9238d998416:/icuSources/common/uarrsort.c diff --git a/icuSources/common/uarrsort.c b/icuSources/common/uarrsort.c new file mode 100644 index 00000000..8bc967ce --- /dev/null +++ b/icuSources/common/uarrsort.c @@ -0,0 +1,236 @@ +/* +******************************************************************************* +* +* Copyright (C) 2003, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: uarrsort.c +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2003aug04 +* created by: Markus W. Scherer +* +* Internal function for sorting arrays. +*/ + +#include "unicode/utypes.h" +#include "cmemory.h" +#include "uarrsort.h" + +enum { + MIN_QSORT=9, /* from Knuth */ + STACK_ITEM_SIZE=200 +}; + +/* UComparator convenience implementations ---------------------------------- */ + +U_CAPI int32_t U_EXPORT2 +uprv_uint16Comparator(const void *context, const void *left, const void *right) { + return (int32_t)*(const uint16_t *)left - (int32_t)*(const uint16_t *)right; +} + +U_CAPI int32_t U_EXPORT2 +uprv_int32Comparator(const void *context, const void *left, const void *right) { + return *(const int32_t *)left - *(const int32_t *)right; +} + +U_CAPI int32_t U_EXPORT2 +uprv_uint32Comparator(const void *context, const void *left, const void *right) { + uint32_t l=*(const uint32_t *)left, r=*(const uint32_t *)right; + + /* compare directly because (l-r) would overflow the int32_t result */ + if(lr */ { + return 1; + } +} + +/* Straight insertion sort from Knuth vol. III, pg. 81 ---------------------- */ + +static void +doInsertionSort(char *array, int32_t start, int32_t limit, int32_t itemSize, + UComparator *cmp, const void *context, void *pv) { + int32_t i, j; + + for(j=start+1; jstart; --i) { + if(/* v>=array[i-1] */ cmp(context, pv, array+(i-1)*itemSize)>=0) { + break; + } + + /* array[i]=array[i-1]; */ + uprv_memcpy(array+i*itemSize, array+(i-1)*itemSize, itemSize); + } + + if(i!=j) { + /* array[i]=v; */ + uprv_memcpy(array+i*itemSize, pv, itemSize); + } + } +} + +static void +insertionSort(char *array, int32_t length, int32_t itemSize, + UComparator *cmp, const void *context, UErrorCode *pErrorCode) { + UAlignedMemory v[STACK_ITEM_SIZE/sizeof(UAlignedMemory)+1]; + void *pv; + + /* allocate an intermediate item variable (v) */ + if(itemSize<=STACK_ITEM_SIZE) { + pv=v; + } else { + pv=uprv_malloc(itemSize); + if(pv==NULL) { + *pErrorCode=U_MEMORY_ALLOCATION_ERROR; + return; + } + } + + doInsertionSort(array, 0, length, itemSize, cmp, context, pv); + + if(pv!=v) { + uprv_free(pv); + } +} + +/* QuickSort ---------------------------------------------------------------- */ + +/* + * This implementation is semi-recursive: + * It recurses for the smaller sub-array to shorten the recursion depth, + * and loops for the larger sub-array. + * + * Loosely after QuickSort algorithms in + * Niklaus Wirth + * Algorithmen und Datenstrukturen mit Modula-2 + * B.G. Teubner Stuttgart + * 4. Auflage 1986 + * ISBN 3-519-02260-5 + */ +static void +subQuickSort(char *array, int32_t start, int32_t limit, int32_t itemSize, + UComparator *cmp, const void *context, + void *px, void *pw) { + int32_t left, right; + + /* start and left are inclusive, limit and right are exclusive */ + do { + if((start+MIN_QSORT)>=limit) { + doInsertionSort(array, start, limit, itemSize, cmp, context, px); + break; + } + + left=start; + right=limit; + + /* x=array[middle] */ + uprv_memcpy(px, array+((start+limit)/2)*itemSize, itemSize); + + do { + while(/* array[left]0 && array==NULL) || length<0 || itemSize<=0 || cmp==NULL) { + *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; + return; + } + + if(length<=1) { + return; + } else if(length