From d16be0ea7fee16c7d8dd9aa9ceab49ffdff5a252 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Mon, 4 Aug 2003 20:37:54 +0000 Subject: [PATCH] ICU-3138 add internal sort function to replace qsort X-SVN-Rev: 12753 --- icu4c/source/common/Makefile.in | 2 +- icu4c/source/common/common.dsp | 8 ++ icu4c/source/common/common.vcproj | 6 + icu4c/source/common/uarrsort.c | 216 ++++++++++++++++++++++++++++++ icu4c/source/common/uarrsort.h | 82 ++++++++++++ 5 files changed, 313 insertions(+), 1 deletion(-) create mode 100644 icu4c/source/common/uarrsort.c create mode 100644 icu4c/source/common/uarrsort.h diff --git a/icu4c/source/common/Makefile.in b/icu4c/source/common/Makefile.in index 0769f11d292..cdba0f0f628 100644 --- a/icu4c/source/common/Makefile.in +++ b/icu4c/source/common/Makefile.in @@ -66,7 +66,7 @@ uchar.o uprops.o propname.o ubidi.o ubidiwrt.o ubidiln.o ushape.o unames.o \ ucln_cmn.o uscript.o usc_impl.o umemstrm.o ucmp8.o uvector.o uvectr32.o digitlst.o \ brkiter.o brkdict.o ubrk.o dbbi.o dbbi_tbl.o \ rbbi.o rbbidata.o rbbinode.o rbbirb.o rbbiscan.o rbbisetb.o rbbistbl.o rbbitblb.o \ -utrie.o uset.o cmemory.o caniter.o \ +uarrsort.o utrie.o uset.o cmemory.o caniter.o \ unifilt.o unifunct.o uniset.o usetiter.o util.o uenum.o \ icuserv.o iculserv.o icunotif.o ustrenum.o \ uidna.o usprep.o punycode.o ucat.o diff --git a/icu4c/source/common/common.dsp b/icu4c/source/common/common.dsp index b4e368764a8..580e9d1184c 100644 --- a/icu4c/source/common/common.dsp +++ b/icu4c/source/common/common.dsp @@ -600,6 +600,14 @@ InputPath=.\unicode\strenum.h # End Source File # Begin Source File +SOURCE=.\uarrsort.c +# End Source File +# Begin Source File + +SOURCE=.\uarrsort.h +# End Source File +# Begin Source File + SOURCE=.\ucmp8.c # End Source File # Begin Source File diff --git a/icu4c/source/common/common.vcproj b/icu4c/source/common/common.vcproj index 9112ac04e2b..f1067b23509 100644 --- a/icu4c/source/common/common.vcproj +++ b/icu4c/source/common/common.vcproj @@ -363,6 +363,12 @@ Outputs="..\..\include\unicode\strenum.h"/> + + + + diff --git a/icu4c/source/common/uarrsort.c b/icu4c/source/common/uarrsort.c new file mode 100644 index 00000000000..9ec8f428432 --- /dev/null +++ b/icu4c/source/common/uarrsort.c @@ -0,0 +1,216 @@ +/* +******************************************************************************* +* +* 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 { + 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 +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; + int32_t i, j; + + /* 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; + } + } + + for(j=1; j0; --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); + } + } + + 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. + */ +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 { + 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<=10 || sortStable) { + insertionSort((char *)array, length, itemSize, cmp, context, pErrorCode); + } else { + /* quickSort */ + quickSort((char *)array, length, itemSize, cmp, context, pErrorCode); + } +} diff --git a/icu4c/source/common/uarrsort.h b/icu4c/source/common/uarrsort.h new file mode 100644 index 00000000000..3cb4c3d214c --- /dev/null +++ b/icu4c/source/common/uarrsort.h @@ -0,0 +1,82 @@ +/* +******************************************************************************* +* +* Copyright (C) 2003, International Business Machines +* Corporation and others. All Rights Reserved. +* +******************************************************************************* +* file name: uarrsort.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 2003aug04 +* created by: Markus W. Scherer +* +* Internal function for sorting arrays. +*/ + +#ifndef __UARRSORT_H__ +#define __UARRSORT_H__ + +#include "unicode/utypes.h" + +/** + * Function type for comparing two items as part of sorting an array or similar. + * Callback function for uprv_sortArray(). + * + * @param context Application-specific pointer, passed through by uprv_sortArray(). + * @param left Pointer to the "left" item. + * @param right Pointer to the "right" item. + * @return 32-bit signed integer comparison result: + * <0 if left0 if left>right + * + * @internal + */ +typedef int32_t U_CALLCONV +UComparator(const void *context, const void *left, const void *right); + +/** + * Array sorting function. + * Uses a UComparator for comparing array items to each other, and simple + * memory copying to move items. + * + * @param array The array to be sorted. + * @param length The number of items in the array. + * @param itemSize The size in bytes of each array item. + * @param cmp UComparator function used to compare two items each. + * @param context Application-specific pointer, passed through to the UComparator. + * @param sortStable If true, a stable sorting algorithm must be used. + * @param pErrorCode ICU in/out UErrorCode parameter. + * + * @internal + */ +U_CAPI void U_EXPORT2 +uprv_sortArray(void *array, int32_t length, int32_t itemSize, + UComparator *cmp, const void *context, + UBool sortStable, UErrorCode *pErrorCode); + +/** + * Convenience UComparator implementation for uint16_t arrays. + * @internal + */ +U_CAPI int32_t U_EXPORT2 +uprv_uint16Comparator(const void *context, const void *left, const void *right); + +/** + * Convenience UComparator implementation for int32_t arrays. + * @internal + */ +U_CAPI int32_t U_EXPORT2 +uprv_int32Comparator(const void *context, const void *left, const void *right); + +/** + * Convenience UComparator implementation for uint32_t arrays. + * @internal + */ +U_CAPI int32_t U_EXPORT2 +uprv_uint32Comparator(const void *context, const void *left, const void *right); + +#endif