]> granicus.if.org Git - icu/commitdiff
ICU-10549 collperf2 also test sorting & binary search
authorMarkus Scherer <markus.icu@gmail.com>
Wed, 8 Jan 2014 00:39:04 +0000 (00:39 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Wed, 8 Jan 2014 00:39:04 +0000 (00:39 +0000)
X-SVN-Rev: 34836

icu4c/source/test/perf/collperf2/CollPerf2_r.pl
icu4c/source/test/perf/collperf2/collperf2.cpp
icu4c/source/tools/ctestfw/unicode/uperf.h

index 58e8bbebb04fd30583e72ea37cd9e0b4871a8643..39d49bf5cf0cf32b26d02674719ab63f285ade14 100755 (executable)
@@ -1,10 +1,31 @@
 #!/usr/bin/perl
 # ********************************************************************
 #  COPYRIGHT:
-#  Copyright (c) 2013, International Business Machines Corporation and
+#  Copyright (c) 2013-2014, International Business Machines Corporation and
 #  others. All Rights Reserved.
 # ********************************************************************
 
+# Variables need to be set in ../perldriver/Common.pl for where ICU is on your machine.
+# Copy Common.pl.template to Common.pl and modify it.
+#
+# Sample Common.pl "Settings by user" for a Linux out-of-source build:
+#
+# $ICULatestVersion = "collv2";
+# $ICUPreviousVersion = "52";
+#
+# $PerformanceDataPath = "/home/mscherer/svn.icudata/trunk/src/test/perf";
+#
+# $ICULatest = "/home/mscherer/svn.icu/collv2/bld";
+# $ICUPrevious = "/home/mscherer/svn.icu/trunk/bld";
+#
+# The first time around, you also need to
+#   source/test/perf/collperf2$ mkdir ../results
+# Then invoke
+#   source/test/perf/collperf2$ ./CollPerf2_r.pl
+#
+# Sample debug invocation:
+#   ~/svn.icu/trunk/dbg/test/perf/collperf2$ LD_LIBRARY_PATH=../../../lib:../../../tools/ctestfw ./collperf2 -t 5 -p 1  -L "de" -f /home/mscherer/svn.icudata/trunk/src/test/perf/collation/TestNames_Latin.txt TestStringPieceSort
+
 #use strict;
 
 use lib '../perldriver';
@@ -18,7 +39,7 @@ my $options = {
     "headers"=>"ICU".$ICUPreviousVersion." ICU".$ICULatestVersion,
     "operationIs"=>"Collator",
     "passes"=>"1",
-    "time"=>"5",
+    "time"=>"2",
     #"outputType"=>"HTML",
     "dataDir"=>$CollationDataPath,
     "outputDir"=>"../results"
@@ -32,8 +53,8 @@ if ($OnWindows) {
     $p1 = "cd ".$ICUPrevious."/bin && ".$ICUPathPrevious."/collperf2/$WindowsPlatform/Release/collperf2.exe";
     $p2 = "cd ".$ICULatest."/bin && ".$ICUPathLatest."/collperf2/$WindowsPlatform/Release/collperf2.exe";
 } else {
-    $p1 = "LD_LIBRARY_PATH=".$ICUPrevious."/source/lib:".$ICUPrevious."/source/tools/ctestfw ".$ICUPathPrevious."/collperf2/collperf2";
-    $p2 = "LD_LIBRARY_PATH=".$ICULatest."/source/lib:".$ICULatest."/source/tools/ctestfw ".$ICUPathLatest."/collperf2/collperf2";
+    $p1 = "LD_LIBRARY_PATH=".$ICUPrevious."/lib:".$ICUPrevious."/tools/ctestfw ".$ICUPrevious."/test/perf/collperf2/collperf2";
+    $p2 = "LD_LIBRARY_PATH=".$ICULatest."/lib:".$ICULatest."/tools/ctestfw ".$ICULatest."/test/perf/collperf2/collperf2";
 }
 
 my $tests = {
@@ -70,6 +91,14 @@ my $tests = {
 
     "Collator::getCollationKey/len",        ["$p1,TestCppGetCollationKey", "$p2,TestCppGetCollationKey"],
     "Collator::getCollationKey/null",       ["$p1,TestCppGetCollationKeyNull", "$p2,TestCppGetCollationKeyNull"],
+
+    "sort UnicodeString*[]: compare()",         ["$p1,TestUniStrSort", "$p2,TestUniStrSort"],
+    "sort StringPiece[]: compareUTF8()",        ["$p1,TestStringPieceSortCpp", "$p2,TestStringPieceSortCpp"],
+    "sort StringPiece[]: ucol_strcollUTF8()",   ["$p1,TestStringPieceSortC", "$p2,TestStringPieceSortC"],
+
+    "binary search UnicodeString*[]: compare()",        ["$p1,TestUniStrBinSearch", "$p2,TestUniStrBinSearch"],
+    "binary search StringPiece[]: compareUTF8()",       ["$p1,TestStringPieceBinSearchCpp", "$p2,TestStringPieceBinSearchCpp"],
+    "binary search StringPiece[]: ucol_strcollUTF8()",  ["$p1,TestStringPieceBinSearchC", "$p2,TestStringPieceBinSearchC"],
 };
 
 my $dataFiles = {
index 3c3bdf1f07e0b70cb8cea425f1f971eea827f2f4..6145818369b97f1e4cd35e783d1daad92ca9996d 100644 (file)
@@ -1,19 +1,23 @@
 /*\r
 **********************************************************************\r
-* Copyright (c) 2013, International Business Machines\r
+* Copyright (c) 2013-2014, International Business Machines\r
 * Corporation and others.  All Rights Reserved.\r
 **********************************************************************\r
 */\r
 \r
 #include <string.h>\r
+#include "unicode/localpointer.h"\r
 #include "unicode/uperf.h"\r
 #include "unicode/ucol.h"\r
 #include "unicode/coll.h"\r
 #include "unicode/uiter.h"\r
+#include "unicode/ustring.h"\r
 #include "unicode/sortkey.h"\r
+#include "uarrsort.h"\r
 #include "uoptions.h"\r
+#include "ustr_imp.h"\r
 \r
-#define COMPATCT_ARRAY(CompactArrays, UNIT) \\r
+#define COMPACT_ARRAY(CompactArrays, UNIT) \\r
 struct CompactArrays{\\r
     CompactArrays(const CompactArrays & );\\r
     CompactArrays & operator=(const CompactArrays & );\\r
@@ -22,23 +26,23 @@ struct CompactArrays{\
     UNIT    * data; /*the real space to hold strings*/ \\r
     \\r
     ~CompactArrays(){free(index);free(data);} \\r
-    CompactArrays():data(NULL), index(NULL), count(0){ \\r
-    index = (int32_t *) realloc(index, sizeof(int32_t)); \\r
-    index[0] = 0; \\r
+    CompactArrays() : count(0), index(NULL), data(NULL) { \\r
+        index = (int32_t *) realloc(index, sizeof(int32_t)); \\r
+        index[0] = 0; \\r
     } \\r
     void append_one(int32_t theLen){ /*include terminal NULL*/ \\r
-    count++; \\r
-    index = (int32_t *) realloc(index, sizeof(int32_t) * (count + 1)); \\r
-    index[count] = index[count - 1] + theLen; \\r
-    data = (UNIT *) realloc(data, sizeof(UNIT) * index[count]); \\r
+        count++; \\r
+        index = (int32_t *) realloc(index, sizeof(int32_t) * (count + 1)); \\r
+        index[count] = index[count - 1] + theLen; \\r
+        data = (UNIT *) realloc(data, sizeof(UNIT) * index[count]); \\r
     } \\r
     UNIT * last(){return data + index[count - 1];} \\r
-    UNIT * dataOf(int32_t i){return data + index[i];} \\r
-    int32_t lengthOf(int i){return index[i+1] - index[i] - 1; } /*exclude terminating NULL*/  \\r
+    const UNIT * dataOf(int32_t i) const {return data + index[i];} \\r
+    int32_t lengthOf(int i) const {return index[i+1] - index[i] - 1; } /*exclude terminating NULL*/  \\r
 };\r
 \r
-COMPATCT_ARRAY(CA_uchar, UChar)\r
-COMPATCT_ARRAY(CA_char, char)\r
+COMPACT_ARRAY(CA_uchar, UChar)\r
+COMPACT_ARRAY(CA_char, char)\r
 \r
 #define MAX_TEST_STRINGS_FOR_PERMUTING 1000\r
 \r
@@ -50,19 +54,19 @@ COMPATCT_ARRAY(CA_char, char)
 class Strcoll : public UPerfFunction\r
 {\r
 public:\r
-    Strcoll(const UCollator* coll, CA_uchar* source, UBool useLen);\r
+    Strcoll(const UCollator* coll, const CA_uchar* source, UBool useLen);\r
     ~Strcoll();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
 \r
 private:\r
     const UCollator *coll;\r
-    CA_uchar *source;\r
+    const CA_uchar *source;\r
     UBool useLen;\r
     int32_t maxTestStrings;\r
 };\r
 \r
-Strcoll::Strcoll(const UCollator* coll, CA_uchar* source, UBool useLen)\r
+Strcoll::Strcoll(const UCollator* coll, const CA_uchar* source, UBool useLen)\r
     :   coll(coll),\r
         source(source),\r
         useLen(useLen)\r
@@ -110,19 +114,19 @@ long Strcoll::getOperationsPerIteration()
 class Strcoll_2 : public UPerfFunction\r
 {\r
 public:\r
-    Strcoll_2(const UCollator* coll, CA_uchar* source, CA_uchar* target, UBool useLen);\r
+    Strcoll_2(const UCollator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen);\r
     ~Strcoll_2();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
 \r
 private:\r
     const UCollator *coll;\r
-    CA_uchar *source;\r
-    CA_uchar *target;\r
+    const CA_uchar *source;\r
+    const CA_uchar *target;\r
     UBool useLen;\r
 };\r
 \r
-Strcoll_2::Strcoll_2(const UCollator* coll, CA_uchar* source, CA_uchar* target, UBool useLen)\r
+Strcoll_2::Strcoll_2(const UCollator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen)\r
     :   coll(coll),\r
         source(source),\r
         target(target),\r
@@ -162,19 +166,19 @@ long Strcoll_2::getOperationsPerIteration()
 class StrcollUTF8 : public UPerfFunction\r
 {\r
 public:\r
-    StrcollUTF8(const UCollator* coll, CA_char* source, UBool useLen);\r
+    StrcollUTF8(const UCollator* coll, const CA_char* source, UBool useLen);\r
     ~StrcollUTF8();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
 \r
 private:\r
     const UCollator *coll;\r
-    CA_char *source;\r
+    const CA_char *source;\r
     UBool useLen;\r
     int32_t maxTestStrings;\r
 };\r
 \r
-StrcollUTF8::StrcollUTF8(const UCollator* coll, CA_char* source, UBool useLen)\r
+StrcollUTF8::StrcollUTF8(const UCollator* coll, const CA_char* source, UBool useLen)\r
     :   coll(coll),\r
         source(source),\r
         useLen(useLen)\r
@@ -222,19 +226,19 @@ long StrcollUTF8::getOperationsPerIteration()
 class StrcollUTF8_2 : public UPerfFunction\r
 {\r
 public:\r
-    StrcollUTF8_2(const UCollator* coll, CA_char* source, CA_char* target, UBool useLen);\r
+    StrcollUTF8_2(const UCollator* coll, const CA_char* source, const CA_char* target, UBool useLen);\r
     ~StrcollUTF8_2();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
 \r
 private:\r
     const UCollator *coll;\r
-    CA_char *source;\r
-    CA_char *target;\r
+    const CA_char *source;\r
+    const CA_char *target;\r
     UBool useLen;\r
 };\r
 \r
-StrcollUTF8_2::StrcollUTF8_2(const UCollator* coll, CA_char* source, CA_char* target, UBool useLen)\r
+StrcollUTF8_2::StrcollUTF8_2(const UCollator* coll, const CA_char* source, const CA_char* target, UBool useLen)\r
     :   coll(coll),\r
         source(source),\r
         target(target),\r
@@ -273,18 +277,18 @@ long StrcollUTF8_2::getOperationsPerIteration()
 class GetSortKey : public UPerfFunction\r
 {\r
 public:\r
-    GetSortKey(const UCollator* coll, CA_uchar* source, UBool useLen);\r
+    GetSortKey(const UCollator* coll, const CA_uchar* source, UBool useLen);\r
     ~GetSortKey();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
 \r
 private:\r
     const UCollator *coll;\r
-    CA_uchar *source;\r
+    const CA_uchar *source;\r
     UBool useLen;\r
 };\r
 \r
-GetSortKey::GetSortKey(const UCollator* coll, CA_uchar* source, UBool useLen)\r
+GetSortKey::GetSortKey(const UCollator* coll, const CA_uchar* source, UBool useLen)\r
     :   coll(coll),\r
         source(source),\r
         useLen(useLen)\r
@@ -327,7 +331,7 @@ long GetSortKey::getOperationsPerIteration()
 class NextSortKeyPart : public UPerfFunction\r
 {\r
 public:\r
-    NextSortKeyPart(const UCollator* coll, CA_uchar* source, int32_t bufSize, int32_t maxIteration = -1);\r
+    NextSortKeyPart(const UCollator* coll, const CA_uchar* source, int32_t bufSize, int32_t maxIteration = -1);\r
     ~NextSortKeyPart();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
@@ -335,14 +339,14 @@ public:
 \r
 private:\r
     const UCollator *coll;\r
-    CA_uchar *source;\r
+    const CA_uchar *source;\r
     int32_t bufSize;\r
     int32_t maxIteration;\r
     long events;\r
 };\r
 \r
 // Note: maxIteration = -1 -> repeat until the end of collation key\r
-NextSortKeyPart::NextSortKeyPart(const UCollator* coll, CA_uchar* source, int32_t bufSize, int32_t maxIteration /* = -1 */)\r
+NextSortKeyPart::NextSortKeyPart(const UCollator* coll, const CA_uchar* source, int32_t bufSize, int32_t maxIteration /* = -1 */)\r
     :   coll(coll),\r
         source(source),\r
         bufSize(bufSize),\r
@@ -398,7 +402,7 @@ long NextSortKeyPart::getEventsPerIteration()
 class NextSortKeyPartUTF8 : public UPerfFunction\r
 {\r
 public:\r
-    NextSortKeyPartUTF8(const UCollator* coll, CA_char* source, int32_t bufSize, int32_t maxIteration = -1);\r
+    NextSortKeyPartUTF8(const UCollator* coll, const CA_char* source, int32_t bufSize, int32_t maxIteration = -1);\r
     ~NextSortKeyPartUTF8();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
@@ -406,14 +410,14 @@ public:
 \r
 private:\r
     const UCollator *coll;\r
-    CA_char *source;\r
+    const CA_char *source;\r
     int32_t bufSize;\r
     int32_t maxIteration;\r
     long events;\r
 };\r
 \r
 // Note: maxIteration = -1 -> repeat until the end of collation key\r
-NextSortKeyPartUTF8::NextSortKeyPartUTF8(const UCollator* coll, CA_char* source, int32_t bufSize, int32_t maxIteration /* = -1 */)\r
+NextSortKeyPartUTF8::NextSortKeyPartUTF8(const UCollator* coll, const CA_char* source, int32_t bufSize, int32_t maxIteration /* = -1 */)\r
     :   coll(coll),\r
         source(source),\r
         bufSize(bufSize),\r
@@ -470,19 +474,19 @@ long NextSortKeyPartUTF8::getEventsPerIteration()
 class CppCompare : public UPerfFunction\r
 {\r
 public:\r
-    CppCompare(const Collator* coll, CA_uchar* source, UBool useLen);\r
+    CppCompare(const Collator* coll, const CA_uchar* source, UBool useLen);\r
     ~CppCompare();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
 \r
 private:\r
     const Collator *coll;\r
-    CA_uchar *source;\r
+    const CA_uchar *source;\r
     UBool useLen;\r
     int32_t maxTestStrings;\r
 };\r
 \r
-CppCompare::CppCompare(const Collator* coll, CA_uchar* source, UBool useLen)\r
+CppCompare::CppCompare(const Collator* coll, const CA_uchar* source, UBool useLen)\r
     :   coll(coll),\r
         source(source),\r
         useLen(useLen)\r
@@ -529,19 +533,19 @@ long CppCompare::getOperationsPerIteration()
 class CppCompare_2 : public UPerfFunction\r
 {\r
 public:\r
-    CppCompare_2(const Collator* coll, CA_uchar* source, CA_uchar* target, UBool useLen);\r
+    CppCompare_2(const Collator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen);\r
     ~CppCompare_2();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
 \r
 private:\r
     const Collator *coll;\r
-    CA_uchar *source;\r
-    CA_uchar *target;\r
+    const CA_uchar *source;\r
+    const CA_uchar *target;\r
     UBool useLen;\r
 };\r
 \r
-CppCompare_2::CppCompare_2(const Collator* coll, CA_uchar* source, CA_uchar* target, UBool useLen)\r
+CppCompare_2::CppCompare_2(const Collator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen)\r
     :   coll(coll),\r
         source(source),\r
         target(target),\r
@@ -580,19 +584,19 @@ long CppCompare_2::getOperationsPerIteration()
 class CppCompareUTF8 : public UPerfFunction\r
 {\r
 public:\r
-    CppCompareUTF8(const Collator* coll, CA_char* source, UBool useLen);\r
+    CppCompareUTF8(const Collator* coll, const CA_char* source, UBool useLen);\r
     ~CppCompareUTF8();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
 \r
 private:\r
     const Collator *coll;\r
-    CA_char *source;\r
+    const CA_char *source;\r
     UBool useLen;\r
     int32_t maxTestStrings;\r
 };\r
 \r
-CppCompareUTF8::CppCompareUTF8(const Collator* coll, CA_char* source, UBool useLen)\r
+CppCompareUTF8::CppCompareUTF8(const Collator* coll, const CA_char* source, UBool useLen)\r
     :   coll(coll),\r
         source(source),\r
         useLen(useLen)\r
@@ -650,19 +654,19 @@ long CppCompareUTF8::getOperationsPerIteration()
 class CppCompareUTF8_2 : public UPerfFunction\r
 {\r
 public:\r
-    CppCompareUTF8_2(const Collator* coll, CA_char* source, CA_char* target, UBool useLen);\r
+    CppCompareUTF8_2(const Collator* coll, const CA_char* source, const CA_char* target, UBool useLen);\r
     ~CppCompareUTF8_2();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
 \r
 private:\r
     const Collator *coll;\r
-    CA_char *source;\r
-    CA_char *target;\r
+    const CA_char *source;\r
+    const CA_char *target;\r
     UBool useLen;\r
 };\r
 \r
-CppCompareUTF8_2::CppCompareUTF8_2(const Collator* coll, CA_char* source, CA_char* target, UBool useLen)\r
+CppCompareUTF8_2::CppCompareUTF8_2(const Collator* coll, const CA_char* source, const CA_char* target, UBool useLen)\r
     :   coll(coll),\r
         source(source),\r
         target(target),\r
@@ -707,18 +711,18 @@ long CppCompareUTF8_2::getOperationsPerIteration()
 class CppGetCollationKey : public UPerfFunction\r
 {\r
 public:\r
-    CppGetCollationKey(const Collator* coll, CA_uchar* source, UBool useLen);\r
+    CppGetCollationKey(const Collator* coll, const CA_uchar* source, UBool useLen);\r
     ~CppGetCollationKey();\r
     virtual void call(UErrorCode* status);\r
     virtual long getOperationsPerIteration();\r
 \r
 private:\r
     const Collator *coll;\r
-    CA_uchar *source;\r
+    const CA_uchar *source;\r
     UBool useLen;\r
 };\r
 \r
-CppGetCollationKey::CppGetCollationKey(const Collator* coll, CA_uchar* source, UBool useLen)\r
+CppGetCollationKey::CppGetCollationKey(const Collator* coll, const CA_uchar* source, UBool useLen)\r
     :   coll(coll),\r
         source(source),\r
         useLen(useLen)\r
@@ -743,6 +747,302 @@ long CppGetCollationKey::getOperationsPerIteration() {
     return source->count;\r
 }\r
 \r
+namespace {\r
+\r
+struct CollatorAndCounter {\r
+    CollatorAndCounter(const Collator& coll) : coll(coll), ucoll(NULL), counter(0) {}\r
+    CollatorAndCounter(const Collator& coll, const UCollator *ucoll)\r
+            : coll(coll), ucoll(ucoll), counter(0) {}\r
+    const Collator& coll;\r
+    const UCollator *ucoll;\r
+    int32_t counter;\r
+};\r
+\r
+int32_t U_CALLCONV\r
+UniStrCollatorComparator(const void* context, const void* left, const void* right) {\r
+    CollatorAndCounter& cc = *(CollatorAndCounter*)context;\r
+    const UnicodeString& leftString = **(const UnicodeString**)left;\r
+    const UnicodeString& rightString = **(const UnicodeString**)right;\r
+    UErrorCode errorCode = U_ZERO_ERROR;\r
+    ++cc.counter;\r
+    return cc.coll.compare(leftString, rightString, errorCode);\r
+}\r
+\r
+}  // namespace\r
+\r
+class CollPerfFunction : public UPerfFunction {\r
+public:\r
+    CollPerfFunction(const Collator& coll, const UCollator *ucoll)\r
+            : coll(coll), ucoll(ucoll), ops(0) {}\r
+    virtual ~CollPerfFunction();\r
+    /** Calls call() to set the ops field, and returns that. */\r
+    virtual long getOperationsPerIteration();\r
+\r
+protected:\r
+    const Collator& coll;\r
+    const UCollator *ucoll;\r
+    int32_t ops;\r
+};\r
+\r
+CollPerfFunction::~CollPerfFunction() {}\r
+\r
+long CollPerfFunction::getOperationsPerIteration() {\r
+    UErrorCode errorCode = U_ZERO_ERROR;\r
+    call(&errorCode);\r
+    return U_SUCCESS(errorCode) ? ops : 0;\r
+}\r
+\r
+class UniStrCollPerfFunction : public CollPerfFunction {\r
+public:\r
+    UniStrCollPerfFunction(const Collator& coll, const UCollator *ucoll, const CA_uchar* data16)\r
+            : CollPerfFunction(coll, ucoll), d16(data16),\r
+              source(new UnicodeString*[d16->count]) {\r
+        for (int32_t i = 0; i < d16->count; ++i) {\r
+            source[i] = new UnicodeString(TRUE, d16->dataOf(i), d16->lengthOf(i));\r
+        }\r
+    }\r
+    virtual ~UniStrCollPerfFunction();\r
+\r
+protected:\r
+    const CA_uchar* d16;\r
+    UnicodeString** source;\r
+};\r
+\r
+UniStrCollPerfFunction::~UniStrCollPerfFunction() {\r
+    for (int32_t i = 0; i < d16->count; ++i) {\r
+        delete source[i];\r
+    }\r
+    delete[] source;\r
+}\r
+\r
+//\r
+// Test case sorting an array of UnicodeString pointers.\r
+//\r
+class UniStrSort : public UniStrCollPerfFunction {\r
+public:\r
+    UniStrSort(const Collator& coll, const UCollator *ucoll, const CA_uchar* data16)\r
+            : UniStrCollPerfFunction(coll, ucoll, data16),\r
+              dest(new UnicodeString*[d16->count]) {}\r
+    virtual ~UniStrSort();\r
+    virtual void call(UErrorCode* status);\r
+\r
+private:\r
+    UnicodeString** dest;  // aliases only\r
+};\r
+\r
+UniStrSort::~UniStrSort() {\r
+    delete[] dest;\r
+}\r
+\r
+void UniStrSort::call(UErrorCode* status) {\r
+    if (U_FAILURE(*status)) return;\r
+\r
+    CollatorAndCounter cc(coll);\r
+    int32_t count = d16->count;\r
+    memcpy(dest, source, count * sizeof(UnicodeString *));\r
+    uprv_sortArray(dest, count, (int32_t)sizeof(UnicodeString *),\r
+                   UniStrCollatorComparator, &cc, TRUE, status);\r
+    ops = cc.counter;\r
+}\r
+\r
+namespace {\r
+\r
+int32_t U_CALLCONV\r
+StringPieceCollatorComparator(const void* context, const void* left, const void* right) {\r
+    CollatorAndCounter& cc = *(CollatorAndCounter*)context;\r
+    const StringPiece& leftString = *(const StringPiece*)left;\r
+    const StringPiece& rightString = *(const StringPiece*)right;\r
+    UErrorCode errorCode = U_ZERO_ERROR;\r
+    ++cc.counter;\r
+    return cc.coll.compareUTF8(leftString, rightString, errorCode);\r
+}\r
+\r
+int32_t U_CALLCONV\r
+StringPieceUCollatorComparator(const void* context, const void* left, const void* right) {\r
+    CollatorAndCounter& cc = *(CollatorAndCounter*)context;\r
+    const StringPiece& leftString = *(const StringPiece*)left;\r
+    const StringPiece& rightString = *(const StringPiece*)right;\r
+    UErrorCode errorCode = U_ZERO_ERROR;\r
+    ++cc.counter;\r
+    return ucol_strcollUTF8(cc.ucoll,\r
+                            leftString.data(), leftString.length(),\r
+                            rightString.data(), rightString.length(), &errorCode);\r
+}\r
+\r
+}  // namespace\r
+\r
+class StringPieceCollPerfFunction : public CollPerfFunction {\r
+public:\r
+    StringPieceCollPerfFunction(const Collator& coll, const UCollator *ucoll, const CA_char* data8)\r
+            : CollPerfFunction(coll, ucoll), d8(data8),\r
+              source(new StringPiece[d8->count]) {\r
+        for (int32_t i = 0; i < d8->count; ++i) {\r
+            source[i].set(d8->dataOf(i), d8->lengthOf(i));\r
+        }\r
+    }\r
+    virtual ~StringPieceCollPerfFunction();\r
+\r
+protected:\r
+    const CA_char* d8;\r
+    StringPiece* source;\r
+};\r
+\r
+StringPieceCollPerfFunction::~StringPieceCollPerfFunction() {\r
+    delete[] source;\r
+}\r
+\r
+class StringPieceSort : public StringPieceCollPerfFunction {\r
+public:\r
+    StringPieceSort(const Collator& coll, const UCollator *ucoll, const CA_char* data8)\r
+            : StringPieceCollPerfFunction(coll, ucoll, data8),\r
+              dest(new StringPiece[d8->count]) {}\r
+    virtual ~StringPieceSort();\r
+\r
+protected:\r
+    StringPiece* dest;\r
+};\r
+\r
+StringPieceSort::~StringPieceSort() {\r
+    delete[] dest;\r
+}\r
+\r
+//\r
+// Test case sorting an array of UTF-8 StringPiece's with Collator::compareUTF8().\r
+//\r
+class StringPieceSortCpp : public StringPieceSort {\r
+public:\r
+    StringPieceSortCpp(const Collator& coll, const UCollator *ucoll, const CA_char* data8)\r
+            : StringPieceSort(coll, ucoll, data8) {}\r
+    virtual ~StringPieceSortCpp();\r
+    virtual void call(UErrorCode* status);\r
+};\r
+\r
+StringPieceSortCpp::~StringPieceSortCpp() {}\r
+\r
+void StringPieceSortCpp::call(UErrorCode* status) {\r
+    if (U_FAILURE(*status)) return;\r
+\r
+    CollatorAndCounter cc(coll);\r
+    int32_t count = d8->count;\r
+    memcpy(dest, source, count * sizeof(StringPiece));\r
+    uprv_sortArray(dest, count, (int32_t)sizeof(StringPiece),\r
+                   StringPieceCollatorComparator, &cc, TRUE, status);\r
+    ops = cc.counter;\r
+}\r
+\r
+//\r
+// Test case sorting an array of UTF-8 StringPiece's with ucol_strcollUTF8().\r
+//\r
+class StringPieceSortC : public StringPieceSort {\r
+public:\r
+    StringPieceSortC(const Collator& coll, const UCollator *ucoll, const CA_char* data8)\r
+            : StringPieceSort(coll, ucoll, data8) {}\r
+    virtual ~StringPieceSortC();\r
+    virtual void call(UErrorCode* status);\r
+};\r
+\r
+StringPieceSortC::~StringPieceSortC() {}\r
+\r
+void StringPieceSortC::call(UErrorCode* status) {\r
+    if (U_FAILURE(*status)) return;\r
+\r
+    CollatorAndCounter cc(coll, ucoll);\r
+    int32_t count = d8->count;\r
+    memcpy(dest, source, count * sizeof(StringPiece));\r
+    uprv_sortArray(dest, count, (int32_t)sizeof(StringPiece),\r
+                   StringPieceUCollatorComparator, &cc, TRUE, status);\r
+    ops = cc.counter;\r
+}\r
+\r
+//\r
+// Test case performing binary searches in a sorted array of UnicodeString pointers.\r
+//\r
+class UniStrBinSearch : public UniStrCollPerfFunction {\r
+public:\r
+    UniStrBinSearch(const Collator& coll, const UCollator *ucoll, const CA_uchar* data16)\r
+            : UniStrCollPerfFunction(coll, ucoll, data16) {}\r
+    virtual ~UniStrBinSearch();\r
+    virtual void call(UErrorCode* status);\r
+};\r
+\r
+UniStrBinSearch::~UniStrBinSearch() {}\r
+\r
+void UniStrBinSearch::call(UErrorCode* status) {\r
+    if (U_FAILURE(*status)) return;\r
+\r
+    CollatorAndCounter cc(coll);\r
+    int32_t count = d16->count;\r
+    for (int32_t i = 0; i < count; ++i) {\r
+        (void)uprv_stableBinarySearch((char *)source, count,\r
+                                      source + i, (int32_t)sizeof(UnicodeString *),\r
+                                      UniStrCollatorComparator, &cc);\r
+    }\r
+    ops = cc.counter;\r
+}\r
+\r
+class StringPieceBinSearch : public StringPieceCollPerfFunction {\r
+public:\r
+    StringPieceBinSearch(const Collator& coll, const UCollator *ucoll, const CA_char* data8)\r
+            : StringPieceCollPerfFunction(coll, ucoll, data8) {}\r
+    virtual ~StringPieceBinSearch();\r
+};\r
+\r
+StringPieceBinSearch::~StringPieceBinSearch() {}\r
+\r
+//\r
+// Test case performing binary searches in a sorted array of UTF-8 StringPiece's\r
+// with Collator::compareUTF8().\r
+//\r
+class StringPieceBinSearchCpp : public StringPieceBinSearch {\r
+public:\r
+    StringPieceBinSearchCpp(const Collator& coll, const UCollator *ucoll, const CA_char* data8)\r
+            : StringPieceBinSearch(coll, ucoll, data8) {}\r
+    virtual ~StringPieceBinSearchCpp();\r
+    virtual void call(UErrorCode* status);\r
+};\r
+\r
+StringPieceBinSearchCpp::~StringPieceBinSearchCpp() {}\r
+\r
+void StringPieceBinSearchCpp::call(UErrorCode* status) {\r
+    if (U_FAILURE(*status)) return;\r
+\r
+    CollatorAndCounter cc(coll);\r
+    int32_t count = d8->count;\r
+    for (int32_t i = 0; i < count; ++i) {\r
+        (void)uprv_stableBinarySearch((char *)source, count,\r
+                                      source + i, (int32_t)sizeof(StringPiece),\r
+                                      StringPieceCollatorComparator, &cc);\r
+    }\r
+    ops = cc.counter;\r
+}\r
+\r
+//\r
+// Test case performing binary searches in a sorted array of UTF-8 StringPiece's\r
+// with ucol_strcollUTF8().\r
+//\r
+class StringPieceBinSearchC : public StringPieceBinSearch {\r
+public:\r
+    StringPieceBinSearchC(const Collator& coll, const UCollator *ucoll, const CA_char* data8)\r
+            : StringPieceBinSearch(coll, ucoll, data8) {}\r
+    virtual ~StringPieceBinSearchC();\r
+    virtual void call(UErrorCode* status);\r
+};\r
+\r
+StringPieceBinSearchC::~StringPieceBinSearchC() {}\r
+\r
+void StringPieceBinSearchC::call(UErrorCode* status) {\r
+    if (U_FAILURE(*status)) return;\r
+\r
+    CollatorAndCounter cc(coll, ucoll);\r
+    int32_t count = d8->count;\r
+    for (int32_t i = 0; i < count; ++i) {\r
+        (void)uprv_stableBinarySearch((char *)source, count,\r
+                                      source + i, (int32_t)sizeof(StringPiece),\r
+                                      StringPieceUCollatorComparator, &cc);\r
+    }\r
+    ops = cc.counter;\r
+}\r
+\r
 \r
 class CollPerf2Test : public UPerfTest\r
 {\r
@@ -763,11 +1063,29 @@ private:
     CA_uchar* modData16;\r
     CA_char* modData8;\r
 \r
-    CA_uchar* getData16(UErrorCode &status);\r
-    CA_char* getData8(UErrorCode &status);\r
+    CA_uchar* sortedData16;\r
+    CA_char* sortedData8;\r
+\r
+    CA_uchar* randomData16;\r
+    CA_char* randomData8;\r
+\r
+    const CA_uchar* getData16(UErrorCode &status);\r
+    const CA_char* getData8(UErrorCode &status);\r
+\r
+    const CA_uchar* getModData16(UErrorCode &status);\r
+    const CA_char* getModData8(UErrorCode &status);\r
+\r
+    const CA_uchar* getSortedData16(UErrorCode &status);\r
+    const CA_char* getSortedData8(UErrorCode &status);\r
 \r
-    CA_uchar* getModData16(UErrorCode &status);\r
-    CA_char* getModData8(UErrorCode &status);\r
+    const CA_uchar* getRandomData16(UErrorCode &status);\r
+    const CA_char* getRandomData8(UErrorCode &status);\r
+\r
+    static CA_uchar* sortData16(\r
+            const CA_uchar* d16,\r
+            UComparator *cmp, const void *context,\r
+            UErrorCode &status);\r
+    static CA_char* getData8FromData16(const CA_uchar* d16, UErrorCode &status);\r
 \r
     UPerfFunction* TestStrcoll();\r
     UPerfFunction* TestStrcollNull();\r
@@ -805,6 +1123,13 @@ private:
     UPerfFunction* TestCppGetCollationKey();\r
     UPerfFunction* TestCppGetCollationKeyNull();\r
 \r
+    UPerfFunction* TestUniStrSort();\r
+    UPerfFunction* TestStringPieceSortCpp();\r
+    UPerfFunction* TestStringPieceSortC();\r
+\r
+    UPerfFunction* TestUniStrBinSearch();\r
+    UPerfFunction* TestStringPieceBinSearchCpp();\r
+    UPerfFunction* TestStringPieceBinSearchC();\r
 };\r
 \r
 CollPerf2Test::CollPerf2Test(int32_t argc, const char *argv[], UErrorCode &status) :\r
@@ -815,7 +1140,11 @@ CollPerf2Test::CollPerf2Test(int32_t argc, const char *argv[], UErrorCode &statu
     data16(NULL),\r
     data8(NULL),\r
     modData16(NULL),\r
-    modData8(NULL)\r
+    modData8(NULL),\r
+    sortedData16(NULL),\r
+    sortedData8(NULL),\r
+    randomData16(NULL),\r
+    randomData8(NULL)\r
 {\r
     if (U_FAILURE(status)) {\r
         return;\r
@@ -829,7 +1158,7 @@ CollPerf2Test::CollPerf2Test(int32_t argc, const char *argv[], UErrorCode &statu
     coll = ucol_open(locale, &status);\r
     collObj = Collator::createInstance(locale, status);\r
 \r
-    // Keyword support should be actually a part of ICU collator\r
+    // Keyword support should be actually a part of ICU collator, see ICU ticket #8260.\r
     char keyBuffer[256];\r
     UColAttributeValue val;\r
     if (uloc_getKeywordValue(locale, "strength", keyBuffer, sizeof(keyBuffer)/sizeof(keyBuffer[0]), &status)) {\r
@@ -963,11 +1292,15 @@ CollPerf2Test::~CollPerf2Test()
     delete data8;\r
     delete modData16;\r
     delete modData8;\r
+    delete sortedData16;\r
+    delete sortedData8;\r
+    delete randomData16;\r
+    delete randomData8;\r
 }\r
 \r
 #define MAX_NUM_DATA 10000\r
 \r
-CA_uchar* CollPerf2Test::getData16(UErrorCode &status)\r
+const CA_uchar* CollPerf2Test::getData16(UErrorCode &status)\r
 {\r
     if (U_FAILURE(status)) return NULL;\r
     if (data16) return data16;\r
@@ -990,8 +1323,7 @@ CA_uchar* CollPerf2Test::getData16(UErrorCode &status)
             continue; // skip empty/comment line\r
         } else {\r
             d16->append_one(len);\r
-            memcpy(d16->last(), line, len * sizeof(UChar));\r
-            d16->last()[len - 1] = NULL;\r
+            u_memcpy(d16->last(), line, len);\r
 \r
             numData++;\r
             if (numData >= MAX_NUM_DATA) break;\r
@@ -1007,66 +1339,29 @@ CA_uchar* CollPerf2Test::getData16(UErrorCode &status)
     return data16;\r
 }\r
 \r
-CA_char* CollPerf2Test::getData8(UErrorCode &status)\r
+const CA_char* CollPerf2Test::getData8(UErrorCode &status)\r
 {\r
     if (U_FAILURE(status)) return NULL;\r
     if (data8) return data8;\r
-\r
-    // UTF-16 -> UTF-8 conversion\r
-    CA_uchar* d16 = getData16(status);\r
-    UConverter *conv = ucnv_open("utf-8", &status);\r
-    if (U_FAILURE(status)) return NULL;\r
-\r
-    CA_char* d8 = new CA_char();\r
-    for (int32_t i = 0; i < d16->count; i++) {\r
-        int32_t s, t;\r
-\r
-        // get length in UTF-8\r
-        s = ucnv_fromUChars(conv, NULL, 0, d16->dataOf(i), d16->lengthOf(i), &status);\r
-        if (status == U_BUFFER_OVERFLOW_ERROR || status == U_ZERO_ERROR){\r
-            status = U_ZERO_ERROR;\r
-        } else {\r
-            break;\r
-        }\r
-        d8->append_one(s + 1); // plus terminal NULL\r
-\r
-        // convert to UTF-8\r
-        t = ucnv_fromUChars(conv, d8->last(), s, d16->dataOf(i), d16->lengthOf(i), &status);\r
-        if (U_FAILURE(status)) break;\r
-        if (t != s) {\r
-            status = U_INVALID_FORMAT_ERROR;\r
-            break;\r
-        }\r
-        d8->last()[s] = 0;\r
-    }\r
-    ucnv_close(conv);\r
-\r
-    if (U_SUCCESS(status)) {\r
-        data8 = d8;\r
-    } else {\r
-        delete d8;\r
-    }\r
-\r
-    return data8;\r
+    return data8 = getData8FromData16(getData16(status), status);\r
 }\r
 \r
-CA_uchar* CollPerf2Test::getModData16(UErrorCode &status)\r
+const CA_uchar* CollPerf2Test::getModData16(UErrorCode &status)\r
 {\r
     if (U_FAILURE(status)) return NULL;\r
     if (modData16) return modData16;\r
 \r
-    CA_uchar* d16 = getData16(status);\r
+    const CA_uchar* d16 = getData16(status);\r
     if (U_FAILURE(status)) return NULL;\r
 \r
     CA_uchar* modData16 = new CA_uchar();\r
 \r
     for (int32_t i = 0; i < d16->count; i++) {\r
-        UChar *s = d16->dataOf(i);\r
+        const UChar *s = d16->dataOf(i);\r
         int32_t len = d16->lengthOf(i) + 1; // including NULL terminator\r
 \r
         modData16->append_one(len);\r
-        memcpy(modData16->last(), s, len * sizeof(UChar));\r
-        modData16->last()[len - 1] = NULL;\r
+        u_memcpy(modData16->last(), s, len);\r
 \r
         // replacing the last character with a different character\r
         UChar *lastChar = &modData16->last()[len -2];\r
@@ -1074,7 +1369,7 @@ CA_uchar* CollPerf2Test::getModData16(UErrorCode &status)
             if (j >= d16->count) {\r
                 j = 0;\r
             }\r
-            UChar *s1 = d16->dataOf(j);\r
+            const UChar *s1 = d16->dataOf(j);\r
             UChar lastChar1 = s1[d16->lengthOf(j) - 1];\r
             if (*lastChar != lastChar1) {\r
                 *lastChar = lastChar1;\r
@@ -1086,91 +1381,184 @@ CA_uchar* CollPerf2Test::getModData16(UErrorCode &status)
     return modData16;\r
 }\r
 \r
-CA_char* CollPerf2Test::getModData8(UErrorCode &status)\r
+const CA_char* CollPerf2Test::getModData8(UErrorCode &status)\r
 {\r
     if (U_FAILURE(status)) return NULL;\r
     if (modData8) return modData8;\r
+    return modData8 = getData8FromData16(getModData16(status), status);\r
+}\r
 \r
-    // UTF-16 -> UTF-8 conversion\r
-    CA_uchar* md16 = getModData16(status);\r
-    UConverter *conv = ucnv_open("utf-8", &status);\r
+namespace {\r
+\r
+struct ArrayAndColl {\r
+    ArrayAndColl(const CA_uchar* a, const Collator& c) : d16(a), coll(c) {}\r
+    const CA_uchar* d16;\r
+    const Collator& coll;\r
+};\r
+\r
+int32_t U_CALLCONV\r
+U16CollatorComparator(const void* context, const void* left, const void* right) {\r
+    const ArrayAndColl& ac = *(const ArrayAndColl*)context;\r
+    const CA_uchar* d16 = ac.d16;\r
+    int32_t leftIndex = *(const int32_t*)left;\r
+    int32_t rightIndex = *(const int32_t*)right;\r
+    UErrorCode errorCode = U_ZERO_ERROR;\r
+    return ac.coll.compare(d16->dataOf(leftIndex), d16->lengthOf(leftIndex),\r
+                           d16->dataOf(rightIndex), d16->lengthOf(rightIndex),\r
+                           errorCode);\r
+}\r
+\r
+int32_t U_CALLCONV\r
+U16HashComparator(const void* context, const void* left, const void* right) {\r
+    const CA_uchar* d16 = (const CA_uchar*)context;\r
+    int32_t leftIndex = *(const int32_t*)left;\r
+    int32_t rightIndex = *(const int32_t*)right;\r
+    int32_t leftHash = ustr_hashUCharsN(d16->dataOf(leftIndex), d16->lengthOf(leftIndex));\r
+    int32_t rightHash = ustr_hashUCharsN(d16->dataOf(rightIndex), d16->lengthOf(rightIndex));\r
+    return leftHash < rightHash ? -1 : leftHash == rightHash ? 0 : 1;\r
+}\r
+\r
+}  // namespace\r
+\r
+const CA_uchar* CollPerf2Test::getSortedData16(UErrorCode &status) {\r
+    if (U_FAILURE(status)) return NULL;\r
+    if (sortedData16) return sortedData16;\r
+\r
+    ArrayAndColl ac(getData16(status), *collObj);\r
+    return sortedData16 = sortData16(ac.d16, U16CollatorComparator, &ac, status);\r
+}\r
+\r
+const CA_char* CollPerf2Test::getSortedData8(UErrorCode &status) {\r
     if (U_FAILURE(status)) return NULL;\r
+    if (sortedData8) return sortedData8;\r
+    return sortedData8 = getData8FromData16(getSortedData16(status), status);\r
+}\r
+\r
+const CA_uchar* CollPerf2Test::getRandomData16(UErrorCode &status) {\r
+    if (U_FAILURE(status)) return NULL;\r
+    if (randomData16) return randomData16;\r
+\r
+    // Sort the strings by their hash codes, which should be a reasonably pseudo-random order.\r
+    const CA_uchar* d16 = getData16(status);\r
+    return randomData16 = sortData16(d16, U16HashComparator, d16, status);\r
+}\r
+\r
+const CA_char* CollPerf2Test::getRandomData8(UErrorCode &status) {\r
+    if (U_FAILURE(status)) return NULL;\r
+    if (randomData8) return randomData8;\r
+    return randomData8 = getData8FromData16(getRandomData16(status), status);\r
+}\r
 \r
-    CA_char* md8 = new CA_char();\r
-    for (int32_t i = 0; i < md16->count; i++) {\r
-        int32_t s, t;\r
+CA_uchar* CollPerf2Test::sortData16(const CA_uchar* d16,\r
+                                    UComparator *cmp, const void *context,\r
+                                    UErrorCode &status) {\r
+    if (U_FAILURE(status)) return NULL;\r
+\r
+    LocalArray<int32_t> indexes(new int32_t[d16->count]);\r
+    for (int32_t i = 0; i < d16->count; ++i) {\r
+        indexes[i] = i;\r
+    }\r
+    uprv_sortArray(indexes.getAlias(), d16->count, 4, cmp, context, TRUE, &status);\r
+    if (U_FAILURE(status)) return NULL;\r
+\r
+    // Copy the strings in sorted order into a new array.\r
+    LocalPointer<CA_uchar> newD16(new CA_uchar());\r
+    for (int32_t i = 0; i < d16->count; i++) {\r
+        const UChar* s = d16->dataOf(i);\r
+        int32_t len = d16->lengthOf(i);\r
+        int32_t capacity = len + 1;  // including NULL terminator\r
+        newD16->append_one(capacity);\r
+        u_memcpy(newD16->last(), s, capacity);\r
+    }\r
+\r
+    if (U_SUCCESS(status)) {\r
+        return newD16.orphan();\r
+    } else {\r
+        return NULL;\r
+    }\r
+}\r
+\r
+CA_char* CollPerf2Test::getData8FromData16(const CA_uchar* d16, UErrorCode &status) {\r
+    if (U_FAILURE(status)) return NULL;\r
+\r
+    // UTF-16 -> UTF-8 conversion\r
+    LocalPointer<CA_char> d8(new CA_char());\r
+    for (int32_t i = 0; i < d16->count; i++) {\r
+        const UChar *s16 = d16->dataOf(i);\r
+        int32_t length16 = d16->lengthOf(i);\r
 \r
         // get length in UTF-8\r
-        s = ucnv_fromUChars(conv, NULL, 0, md16->dataOf(i), md16->lengthOf(i), &status);\r
+        int32_t length8;\r
+        u_strToUTF8(NULL, 0, &length8, s16, length16, &status);\r
         if (status == U_BUFFER_OVERFLOW_ERROR || status == U_ZERO_ERROR){\r
             status = U_ZERO_ERROR;\r
         } else {\r
             break;\r
         }\r
-        md8->append_one(s + 1); // plus terminal NULL\r
+        int32_t capacity8 = length8 + 1;  // plus terminal NULL\r
+        d8->append_one(capacity8);\r
 \r
         // convert to UTF-8\r
-        t = ucnv_fromUChars(conv, md8->last(), s, md16->dataOf(i), md16->lengthOf(i), &status);\r
+        u_strToUTF8(d8->last(), capacity8, NULL, s16, length16, &status);\r
         if (U_FAILURE(status)) break;\r
-        if (t != s) {\r
-            status = U_INVALID_FORMAT_ERROR;\r
-            break;\r
-        }\r
-        md8->last()[s] = 0;\r
     }\r
-    ucnv_close(conv);\r
 \r
     if (U_SUCCESS(status)) {\r
-        modData8 = md8;\r
+        return d8.orphan();\r
     } else {\r
-        delete md8;\r
+        return NULL;\r
     }\r
-\r
-    return modData8;\r
 }\r
 \r
 UPerfFunction*\r
 CollPerf2Test::runIndexedTest(int32_t index, UBool exec, const char *&name, char *par /*= NULL*/)\r
 {\r
-    switch (index) {\r
-        TESTCASE(0, TestStrcoll);\r
-        TESTCASE(1, TestStrcollNull);\r
-        TESTCASE(2, TestStrcollSimilar);\r
+    (void)par;\r
+    TESTCASE_AUTO_BEGIN;\r
 \r
-        TESTCASE(3, TestStrcollUTF8);\r
-        TESTCASE(4, TestStrcollUTF8Null);\r
-        TESTCASE(5, TestStrcollUTF8Similar);\r
+    TESTCASE_AUTO(TestStrcoll);\r
+    TESTCASE_AUTO(TestStrcollNull);\r
+    TESTCASE_AUTO(TestStrcollSimilar);\r
 \r
-        TESTCASE(6, TestGetSortKey);\r
-        TESTCASE(7, TestGetSortKeyNull);\r
+    TESTCASE_AUTO(TestStrcollUTF8);\r
+    TESTCASE_AUTO(TestStrcollUTF8Null);\r
+    TESTCASE_AUTO(TestStrcollUTF8Similar);\r
 \r
-        TESTCASE(8, TestNextSortKeyPart_4All);\r
-        TESTCASE(9, TestNextSortKeyPart_4x4);\r
-        TESTCASE(10, TestNextSortKeyPart_4x8);\r
-        TESTCASE(11, TestNextSortKeyPart_32All);\r
-        TESTCASE(12, TestNextSortKeyPart_32x2);\r
+    TESTCASE_AUTO(TestGetSortKey);\r
+    TESTCASE_AUTO(TestGetSortKeyNull);\r
 \r
-        TESTCASE(13, TestNextSortKeyPartUTF8_4All);\r
-        TESTCASE(14, TestNextSortKeyPartUTF8_4x4);\r
-        TESTCASE(15, TestNextSortKeyPartUTF8_4x8);\r
-        TESTCASE(16, TestNextSortKeyPartUTF8_32All);\r
-        TESTCASE(17, TestNextSortKeyPartUTF8_32x2);\r
+    TESTCASE_AUTO(TestNextSortKeyPart_4All);\r
+    TESTCASE_AUTO(TestNextSortKeyPart_4x4);\r
+    TESTCASE_AUTO(TestNextSortKeyPart_4x8);\r
+    TESTCASE_AUTO(TestNextSortKeyPart_32All);\r
+    TESTCASE_AUTO(TestNextSortKeyPart_32x2);\r
 \r
-        TESTCASE(18, TestCppCompare);\r
-        TESTCASE(19, TestCppCompareNull);\r
-        TESTCASE(20, TestCppCompareSimilar);\r
+    TESTCASE_AUTO(TestNextSortKeyPartUTF8_4All);\r
+    TESTCASE_AUTO(TestNextSortKeyPartUTF8_4x4);\r
+    TESTCASE_AUTO(TestNextSortKeyPartUTF8_4x8);\r
+    TESTCASE_AUTO(TestNextSortKeyPartUTF8_32All);\r
+    TESTCASE_AUTO(TestNextSortKeyPartUTF8_32x2);\r
 \r
-        TESTCASE(21, TestCppCompareUTF8);\r
-        TESTCASE(22, TestCppCompareUTF8Null);\r
-        TESTCASE(23, TestCppCompareUTF8Similar);\r
+    TESTCASE_AUTO(TestCppCompare);\r
+    TESTCASE_AUTO(TestCppCompareNull);\r
+    TESTCASE_AUTO(TestCppCompareSimilar);\r
 \r
-        TESTCASE(24, TestCppGetCollationKey);\r
-        TESTCASE(25, TestCppGetCollationKeyNull);\r
+    TESTCASE_AUTO(TestCppCompareUTF8);\r
+    TESTCASE_AUTO(TestCppCompareUTF8Null);\r
+    TESTCASE_AUTO(TestCppCompareUTF8Similar);\r
 \r
-    default:\r
-            name = ""; \r
-            return NULL;\r
-    }\r
+    TESTCASE_AUTO(TestCppGetCollationKey);\r
+    TESTCASE_AUTO(TestCppGetCollationKeyNull);\r
+\r
+    TESTCASE_AUTO(TestUniStrSort);\r
+    TESTCASE_AUTO(TestStringPieceSortCpp);\r
+    TESTCASE_AUTO(TestStringPieceSortC);\r
+\r
+    TESTCASE_AUTO(TestUniStrBinSearch);\r
+    TESTCASE_AUTO(TestStringPieceBinSearchCpp);\r
+    TESTCASE_AUTO(TestStringPieceBinSearchC);\r
+\r
+    TESTCASE_AUTO_END;\r
     return NULL;\r
 }\r
 \r
@@ -1462,6 +1850,66 @@ UPerfFunction* CollPerf2Test::TestCppGetCollationKeyNull()
     return testCase;\r
 }\r
 \r
+UPerfFunction* CollPerf2Test::TestUniStrSort() {\r
+    UErrorCode status = U_ZERO_ERROR;\r
+    UPerfFunction *testCase = new UniStrSort(*collObj, coll, getRandomData16(status));\r
+    if (U_FAILURE(status)) {\r
+        delete testCase;\r
+        return NULL;\r
+    }\r
+    return testCase;\r
+}\r
+\r
+UPerfFunction* CollPerf2Test::TestStringPieceSortCpp() {\r
+    UErrorCode status = U_ZERO_ERROR;\r
+    UPerfFunction *testCase = new StringPieceSortCpp(*collObj, coll, getRandomData8(status));\r
+    if (U_FAILURE(status)) {\r
+        delete testCase;\r
+        return NULL;\r
+    }\r
+    return testCase;\r
+}\r
+\r
+UPerfFunction* CollPerf2Test::TestStringPieceSortC() {\r
+    UErrorCode status = U_ZERO_ERROR;\r
+    UPerfFunction *testCase = new StringPieceSortC(*collObj, coll, getRandomData8(status));\r
+    if (U_FAILURE(status)) {\r
+        delete testCase;\r
+        return NULL;\r
+    }\r
+    return testCase;\r
+}\r
+\r
+UPerfFunction* CollPerf2Test::TestUniStrBinSearch() {\r
+    UErrorCode status = U_ZERO_ERROR;\r
+    UPerfFunction *testCase = new UniStrBinSearch(*collObj, coll, getSortedData16(status));\r
+    if (U_FAILURE(status)) {\r
+        delete testCase;\r
+        return NULL;\r
+    }\r
+    return testCase;\r
+}\r
+\r
+UPerfFunction* CollPerf2Test::TestStringPieceBinSearchCpp() {\r
+    UErrorCode status = U_ZERO_ERROR;\r
+    UPerfFunction *testCase = new StringPieceBinSearchCpp(*collObj, coll, getSortedData8(status));\r
+    if (U_FAILURE(status)) {\r
+        delete testCase;\r
+        return NULL;\r
+    }\r
+    return testCase;\r
+}\r
+\r
+UPerfFunction* CollPerf2Test::TestStringPieceBinSearchC() {\r
+    UErrorCode status = U_ZERO_ERROR;\r
+    UPerfFunction *testCase = new StringPieceBinSearchC(*collObj, coll, getSortedData8(status));\r
+    if (U_FAILURE(status)) {\r
+        delete testCase;\r
+        return NULL;\r
+    }\r
+    return testCase;\r
+}\r
+\r
 \r
 int main(int argc, const char *argv[])\r
 {\r
@@ -1480,5 +1928,3 @@ int main(int argc, const char *argv[])
     }\r
     return 0;\r
 }\r
-\r
-\r
index a46ca2a740483896122abaa348f0e8d7d0918103..a5f7151ac78dc8abcbdc7674c08f5c60f611c0d5 100644 (file)
@@ -1,6 +1,6 @@
 /*
 **********************************************************************
-* Copyright (c) 2002-2011, International Business Machines
+* Copyright (c) 2002-2014, International Business Machines
 * Corporation and others.  All Rights Reserved.
 **********************************************************************
 */
@@ -22,7 +22,7 @@ typedef struct UOption UOption;
 #if !UCONFIG_NO_CONVERSION
 
 U_NAMESPACE_USE
-// Use the TESTCASE macro in subclasses of IntlTest.  Define the
+// Use the TESTCASE macro in subclasses of UPerfTest. Define the
 // runIndexedTest method in this fashion:
 //
 //| void MyTest::runIndexedTest(int32_t index, UBool exec,
@@ -32,29 +32,48 @@ U_NAMESPACE_USE
 //|         TESTCASE(1,TestSomethingElse);
 //|         TESTCASE(2,TestAnotherThing);
 //|         default: 
-//|             name = ""; 
-//|             return NULL;
+//|             name = "";
+//|             break;
 //|     }
+//|     return NULL;
 //| }
-#if 0
 #define TESTCASE(id,test)                       \
     case id:                                    \
         name = #test;                           \
         if (exec) {                             \
-            fprintf(stdout,#test "---");        \
-            fprintf(stdout,"\n");               \
             return test();                      \
         }                                       \
         break
 
-#endif
-#define TESTCASE(id,test)                       \
-    case id:                                    \
-        name = #test;                           \
-        if (exec) {                             \
-            return test();                      \
-        }                                       \
-        break
+// More convenient macros. These allow easy reordering of the test cases.
+// Copied from intltest.h, and adjusted to not logln() but return a UPerfFunction.
+//
+//| void MyTest::runIndexedTest(int32_t index, UBool exec,
+//|                             const char* &name, char* /*par*/) {
+//|     TESTCASE_AUTO_BEGIN;
+//|     TESTCASE_AUTO(TestSomething);
+//|     TESTCASE_AUTO(TestSomethingElse);
+//|     TESTCASE_AUTO(TestAnotherThing);
+//|     TESTCASE_AUTO_END;
+//|     return NULL;
+//| }
+#define TESTCASE_AUTO_BEGIN \
+    for(;;) { \
+        int32_t testCaseAutoNumber = 0
+
+#define TESTCASE_AUTO(test) \
+        if (index == testCaseAutoNumber++) { \
+            name = #test; \
+            if (exec) { \
+                return test(); \
+            } \
+            break; \
+        }
+
+#define TESTCASE_AUTO_END \
+        name = ""; \
+        break; \
+    }
 
 /**
  * Subclasses of PerfTest will need to create subclasses of