/*\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
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
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
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
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
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
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
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
\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
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
\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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
}\r
return 0;\r
}\r
-\r
-\r