2 **********************************************************************
3 * Copyright (c) 2013-2014, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 **********************************************************************
9 #include "unicode/localpointer.h"
10 #include "unicode/uperf.h"
11 #include "unicode/ucol.h"
12 #include "unicode/coll.h"
13 #include "unicode/uiter.h"
14 #include "unicode/ustring.h"
15 #include "unicode/sortkey.h"
20 #define COMPACT_ARRAY(CompactArrays, UNIT) \
21 struct CompactArrays{\
22 CompactArrays(const CompactArrays & );\
23 CompactArrays & operator=(const CompactArrays & );\
24 int32_t count;/*total number of the strings*/ \
25 int32_t * index;/*relative offset in data*/ \
26 UNIT * data; /*the real space to hold strings*/ \
28 ~CompactArrays(){free(index);free(data);} \
29 CompactArrays() : count(0), index(NULL), data(NULL) { \
30 index = (int32_t *) realloc(index, sizeof(int32_t)); \
33 void append_one(int32_t theLen){ /*include terminal NULL*/ \
35 index = (int32_t *) realloc(index, sizeof(int32_t) * (count + 1)); \
36 index[count] = index[count - 1] + theLen; \
37 data = (UNIT *) realloc(data, sizeof(UNIT) * index[count]); \
39 UNIT * last(){return data + index[count - 1];} \
40 const UNIT * dataOf(int32_t i) const {return data + index[i];} \
41 int32_t lengthOf(int i) const {return index[i+1] - index[i] - 1; } /*exclude terminating NULL*/ \
44 COMPACT_ARRAY(CA_uchar
, UChar
)
45 COMPACT_ARRAY(CA_char
, char)
47 #define MAX_TEST_STRINGS_FOR_PERMUTING 1000
52 // Test case taking a single test data array, calling ucol_strcoll by permuting the test data
54 class Strcoll
: public UPerfFunction
57 Strcoll(const UCollator
* coll
, const CA_uchar
* source
, UBool useLen
);
59 virtual void call(UErrorCode
* status
);
60 virtual long getOperationsPerIteration();
63 const UCollator
*coll
;
64 const CA_uchar
*source
;
66 int32_t maxTestStrings
;
69 Strcoll::Strcoll(const UCollator
* coll
, const CA_uchar
* source
, UBool useLen
)
74 maxTestStrings
= source
->count
> MAX_TEST_STRINGS_FOR_PERMUTING
? MAX_TEST_STRINGS_FOR_PERMUTING
: source
->count
;
81 void Strcoll::call(UErrorCode
* status
)
83 if (U_FAILURE(*status
)) return;
85 // call strcoll for permutation
86 int32_t divisor
= source
->count
/ maxTestStrings
;
87 int32_t srcLen
, tgtLen
;
89 for (int32_t i
= 0, numTestStringsI
= 0; i
< source
->count
&& numTestStringsI
< maxTestStrings
; i
++) {
90 if (i
% divisor
) continue;
92 srcLen
= useLen
? source
->lengthOf(i
) : -1;
93 for (int32_t j
= 0, numTestStringsJ
= 0; j
< source
->count
&& numTestStringsJ
< maxTestStrings
; j
++) {
94 if (j
% divisor
) continue;
96 tgtLen
= useLen
? source
->lengthOf(j
) : -1;
97 cmp
+= ucol_strcoll(coll
, source
->dataOf(i
), srcLen
, source
->dataOf(j
), tgtLen
);
100 // At the end, cmp must be 0
102 *status
= U_INTERNAL_PROGRAM_ERROR
;
106 long Strcoll::getOperationsPerIteration()
108 return maxTestStrings
* maxTestStrings
;
112 // Test case taking two test data arrays, calling ucol_strcoll for strings at a same index
114 class Strcoll_2
: public UPerfFunction
117 Strcoll_2(const UCollator
* coll
, const CA_uchar
* source
, const CA_uchar
* target
, UBool useLen
);
119 virtual void call(UErrorCode
* status
);
120 virtual long getOperationsPerIteration();
123 const UCollator
*coll
;
124 const CA_uchar
*source
;
125 const CA_uchar
*target
;
129 Strcoll_2::Strcoll_2(const UCollator
* coll
, const CA_uchar
* source
, const CA_uchar
* target
, UBool useLen
)
137 Strcoll_2::~Strcoll_2()
141 void Strcoll_2::call(UErrorCode
* status
)
143 if (U_FAILURE(*status
)) return;
145 // call strcoll for two strings at the same index
146 if (source
->count
< target
->count
) {
147 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
149 for (int32_t i
= 0; i
< source
->count
; i
++) {
150 int32_t srcLen
= useLen
? source
->lengthOf(i
) : -1;
151 int32_t tgtLen
= useLen
? target
->lengthOf(i
) : -1;
152 ucol_strcoll(coll
, source
->dataOf(i
), srcLen
, target
->dataOf(i
), tgtLen
);
157 long Strcoll_2::getOperationsPerIteration()
159 return source
->count
;
164 // Test case taking a single test data array, calling ucol_strcollUTF8 by permuting the test data
166 class StrcollUTF8
: public UPerfFunction
169 StrcollUTF8(const UCollator
* coll
, const CA_char
* source
, UBool useLen
);
171 virtual void call(UErrorCode
* status
);
172 virtual long getOperationsPerIteration();
175 const UCollator
*coll
;
176 const CA_char
*source
;
178 int32_t maxTestStrings
;
181 StrcollUTF8::StrcollUTF8(const UCollator
* coll
, const CA_char
* source
, UBool useLen
)
186 maxTestStrings
= source
->count
> MAX_TEST_STRINGS_FOR_PERMUTING
? MAX_TEST_STRINGS_FOR_PERMUTING
: source
->count
;
189 StrcollUTF8::~StrcollUTF8()
193 void StrcollUTF8::call(UErrorCode
* status
)
195 if (U_FAILURE(*status
)) return;
197 // call strcollUTF8 for permutation
198 int32_t divisor
= source
->count
/ maxTestStrings
;
199 int32_t srcLen
, tgtLen
;
201 for (int32_t i
= 0, numTestStringsI
= 0; U_SUCCESS(*status
) && i
< source
->count
&& numTestStringsI
< maxTestStrings
; i
++) {
202 if (i
% divisor
) continue;
204 srcLen
= useLen
? source
->lengthOf(i
) : -1;
205 for (int32_t j
= 0, numTestStringsJ
= 0; U_SUCCESS(*status
) && j
< source
->count
&& numTestStringsJ
< maxTestStrings
; j
++) {
206 if (j
% divisor
) continue;
208 tgtLen
= useLen
? source
->lengthOf(j
) : -1;
209 cmp
+= ucol_strcollUTF8(coll
, source
->dataOf(i
), srcLen
, source
->dataOf(j
), tgtLen
, status
);
212 // At the end, cmp must be 0
214 *status
= U_INTERNAL_PROGRAM_ERROR
;
218 long StrcollUTF8::getOperationsPerIteration()
220 return maxTestStrings
* maxTestStrings
;
224 // Test case taking two test data arrays, calling ucol_strcoll for strings at a same index
226 class StrcollUTF8_2
: public UPerfFunction
229 StrcollUTF8_2(const UCollator
* coll
, const CA_char
* source
, const CA_char
* target
, UBool useLen
);
231 virtual void call(UErrorCode
* status
);
232 virtual long getOperationsPerIteration();
235 const UCollator
*coll
;
236 const CA_char
*source
;
237 const CA_char
*target
;
241 StrcollUTF8_2::StrcollUTF8_2(const UCollator
* coll
, const CA_char
* source
, const CA_char
* target
, UBool useLen
)
249 StrcollUTF8_2::~StrcollUTF8_2()
253 void StrcollUTF8_2::call(UErrorCode
* status
)
255 if (U_FAILURE(*status
)) return;
257 // call strcoll for two strings at the same index
258 if (source
->count
< target
->count
) {
259 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
261 for (int32_t i
= 0; U_SUCCESS(*status
) && i
< source
->count
; i
++) {
262 int32_t srcLen
= useLen
? source
->lengthOf(i
) : -1;
263 int32_t tgtLen
= useLen
? target
->lengthOf(i
) : -1;
264 ucol_strcollUTF8(coll
, source
->dataOf(i
), srcLen
, target
->dataOf(i
), tgtLen
, status
);
269 long StrcollUTF8_2::getOperationsPerIteration()
271 return source
->count
;
275 // Test case taking a single test data array, calling ucol_getSortKey for each
277 class GetSortKey
: public UPerfFunction
280 GetSortKey(const UCollator
* coll
, const CA_uchar
* source
, UBool useLen
);
282 virtual void call(UErrorCode
* status
);
283 virtual long getOperationsPerIteration();
286 const UCollator
*coll
;
287 const CA_uchar
*source
;
291 GetSortKey::GetSortKey(const UCollator
* coll
, const CA_uchar
* source
, UBool useLen
)
298 GetSortKey::~GetSortKey()
302 #define KEY_BUF_SIZE 512
304 void GetSortKey::call(UErrorCode
* status
)
306 if (U_FAILURE(*status
)) return;
308 uint8_t key
[KEY_BUF_SIZE
];
312 for (int32_t i
= 0; i
< source
->count
; i
++) {
313 len
= ucol_getSortKey(coll
, source
->dataOf(i
), source
->lengthOf(i
), key
, KEY_BUF_SIZE
);
316 for (int32_t i
= 0; i
< source
->count
; i
++) {
317 len
= ucol_getSortKey(coll
, source
->dataOf(i
), -1, key
, KEY_BUF_SIZE
);
322 long GetSortKey::getOperationsPerIteration()
324 return source
->count
;
328 // Test case taking a single test data array in UTF-16, calling ucol_nextSortKeyPart for each for the
331 class NextSortKeyPart
: public UPerfFunction
334 NextSortKeyPart(const UCollator
* coll
, const CA_uchar
* source
, int32_t bufSize
, int32_t maxIteration
= -1);
336 virtual void call(UErrorCode
* status
);
337 virtual long getOperationsPerIteration();
338 virtual long getEventsPerIteration();
341 const UCollator
*coll
;
342 const CA_uchar
*source
;
344 int32_t maxIteration
;
348 // Note: maxIteration = -1 -> repeat until the end of collation key
349 NextSortKeyPart::NextSortKeyPart(const UCollator
* coll
, const CA_uchar
* source
, int32_t bufSize
, int32_t maxIteration
/* = -1 */)
353 maxIteration(maxIteration
),
358 NextSortKeyPart::~NextSortKeyPart()
362 void NextSortKeyPart::call(UErrorCode
* status
)
364 if (U_FAILURE(*status
)) return;
366 uint8_t *part
= (uint8_t *)malloc(bufSize
);
371 for (int i
= 0; i
< source
->count
&& U_SUCCESS(*status
); i
++) {
372 uiter_setString(&iter
, source
->dataOf(i
), source
->lengthOf(i
));
375 int32_t partLen
= bufSize
;
376 for (int32_t n
= 0; U_SUCCESS(*status
) && partLen
== bufSize
&& (maxIteration
< 0 || n
< maxIteration
); n
++) {
377 partLen
= ucol_nextSortKeyPart(coll
, &iter
, state
, part
, bufSize
, status
);
384 long NextSortKeyPart::getOperationsPerIteration()
386 return source
->count
;
389 long NextSortKeyPart::getEventsPerIteration()
395 // Test case taking a single test data array in UTF-8, calling ucol_nextSortKeyPart for each for the
398 class NextSortKeyPartUTF8
: public UPerfFunction
401 NextSortKeyPartUTF8(const UCollator
* coll
, const CA_char
* source
, int32_t bufSize
, int32_t maxIteration
= -1);
402 ~NextSortKeyPartUTF8();
403 virtual void call(UErrorCode
* status
);
404 virtual long getOperationsPerIteration();
405 virtual long getEventsPerIteration();
408 const UCollator
*coll
;
409 const CA_char
*source
;
411 int32_t maxIteration
;
415 // Note: maxIteration = -1 -> repeat until the end of collation key
416 NextSortKeyPartUTF8::NextSortKeyPartUTF8(const UCollator
* coll
, const CA_char
* source
, int32_t bufSize
, int32_t maxIteration
/* = -1 */)
420 maxIteration(maxIteration
),
425 NextSortKeyPartUTF8::~NextSortKeyPartUTF8()
429 void NextSortKeyPartUTF8::call(UErrorCode
* status
)
431 if (U_FAILURE(*status
)) return;
433 uint8_t *part
= (uint8_t *)malloc(bufSize
);
438 for (int i
= 0; i
< source
->count
&& U_SUCCESS(*status
); i
++) {
439 uiter_setUTF8(&iter
, source
->dataOf(i
), source
->lengthOf(i
));
442 int32_t partLen
= bufSize
;
443 for (int32_t n
= 0; U_SUCCESS(*status
) && partLen
== bufSize
&& (maxIteration
< 0 || n
< maxIteration
); n
++) {
444 partLen
= ucol_nextSortKeyPart(coll
, &iter
, state
, part
, bufSize
, status
);
451 long NextSortKeyPartUTF8::getOperationsPerIteration()
453 return source
->count
;
456 long NextSortKeyPartUTF8::getEventsPerIteration()
461 // CPP API test cases
464 // Test case taking a single test data array, calling Collator::compare by permuting the test data
466 class CppCompare
: public UPerfFunction
469 CppCompare(const Collator
* coll
, const CA_uchar
* source
, UBool useLen
);
471 virtual void call(UErrorCode
* status
);
472 virtual long getOperationsPerIteration();
475 const Collator
*coll
;
476 const CA_uchar
*source
;
478 int32_t maxTestStrings
;
481 CppCompare::CppCompare(const Collator
* coll
, const CA_uchar
* source
, UBool useLen
)
486 maxTestStrings
= source
->count
> MAX_TEST_STRINGS_FOR_PERMUTING
? MAX_TEST_STRINGS_FOR_PERMUTING
: source
->count
;
489 CppCompare::~CppCompare()
493 void CppCompare::call(UErrorCode
* status
) {
494 if (U_FAILURE(*status
)) return;
496 // call compare for permutation of test data
497 int32_t divisor
= source
->count
/ maxTestStrings
;
498 int32_t srcLen
, tgtLen
;
500 for (int32_t i
= 0, numTestStringsI
= 0; i
< source
->count
&& numTestStringsI
< maxTestStrings
; i
++) {
501 if (i
% divisor
) continue;
503 srcLen
= useLen
? source
->lengthOf(i
) : -1;
504 for (int32_t j
= 0, numTestStringsJ
= 0; j
< source
->count
&& numTestStringsJ
< maxTestStrings
; j
++) {
505 if (j
% divisor
) continue;
507 tgtLen
= useLen
? source
->lengthOf(j
) : -1;
508 cmp
+= coll
->compare(source
->dataOf(i
), srcLen
, source
->dataOf(j
), tgtLen
);
511 // At the end, cmp must be 0
513 *status
= U_INTERNAL_PROGRAM_ERROR
;
517 long CppCompare::getOperationsPerIteration()
519 return maxTestStrings
* maxTestStrings
;
523 // Test case taking two test data arrays, calling Collator::compare for strings at a same index
525 class CppCompare_2
: public UPerfFunction
528 CppCompare_2(const Collator
* coll
, const CA_uchar
* source
, const CA_uchar
* target
, UBool useLen
);
530 virtual void call(UErrorCode
* status
);
531 virtual long getOperationsPerIteration();
534 const Collator
*coll
;
535 const CA_uchar
*source
;
536 const CA_uchar
*target
;
540 CppCompare_2::CppCompare_2(const Collator
* coll
, const CA_uchar
* source
, const CA_uchar
* target
, UBool useLen
)
548 CppCompare_2::~CppCompare_2()
552 void CppCompare_2::call(UErrorCode
* status
) {
553 if (U_FAILURE(*status
)) return;
555 // call strcoll for two strings at the same index
556 if (source
->count
< target
->count
) {
557 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
559 for (int32_t i
= 0; i
< source
->count
; i
++) {
560 int32_t srcLen
= useLen
? source
->lengthOf(i
) : -1;
561 int32_t tgtLen
= useLen
? target
->lengthOf(i
) : -1;
562 coll
->compare(source
->dataOf(i
), srcLen
, target
->dataOf(i
), tgtLen
);
567 long CppCompare_2::getOperationsPerIteration()
569 return source
->count
;
574 // Test case taking a single test data array, calling Collator::compareUTF8 by permuting the test data
576 class CppCompareUTF8
: public UPerfFunction
579 CppCompareUTF8(const Collator
* coll
, const CA_char
* source
, UBool useLen
);
581 virtual void call(UErrorCode
* status
);
582 virtual long getOperationsPerIteration();
585 const Collator
*coll
;
586 const CA_char
*source
;
588 int32_t maxTestStrings
;
591 CppCompareUTF8::CppCompareUTF8(const Collator
* coll
, const CA_char
* source
, UBool useLen
)
596 maxTestStrings
= source
->count
> MAX_TEST_STRINGS_FOR_PERMUTING
? MAX_TEST_STRINGS_FOR_PERMUTING
: source
->count
;
599 CppCompareUTF8::~CppCompareUTF8()
603 void CppCompareUTF8::call(UErrorCode
* status
) {
604 if (U_FAILURE(*status
)) return;
606 // call compareUTF8 for all permutations
607 int32_t divisor
= source
->count
/ maxTestStrings
;
608 StringPiece src
, tgt
;
610 for (int32_t i
= 0, numTestStringsI
= 0; U_SUCCESS(*status
) && i
< source
->count
&& numTestStringsI
< maxTestStrings
; i
++) {
611 if (i
% divisor
) continue;
615 src
.set(source
->dataOf(i
), source
->lengthOf(i
));
617 src
.set(source
->dataOf(i
));
619 for (int32_t j
= 0, numTestStringsJ
= 0; U_SUCCESS(*status
) && j
< source
->count
&& numTestStringsJ
< maxTestStrings
; j
++) {
620 if (j
% divisor
) continue;
624 tgt
.set(source
->dataOf(i
), source
->lengthOf(i
));
626 tgt
.set(source
->dataOf(i
));
628 cmp
+= coll
->compareUTF8(src
, tgt
, *status
);
631 // At the end, cmp must be 0
633 *status
= U_INTERNAL_PROGRAM_ERROR
;
637 long CppCompareUTF8::getOperationsPerIteration()
639 return maxTestStrings
* maxTestStrings
;
644 // Test case taking two test data arrays, calling Collator::compareUTF8 for strings at a same index
646 class CppCompareUTF8_2
: public UPerfFunction
649 CppCompareUTF8_2(const Collator
* coll
, const CA_char
* source
, const CA_char
* target
, UBool useLen
);
651 virtual void call(UErrorCode
* status
);
652 virtual long getOperationsPerIteration();
655 const Collator
*coll
;
656 const CA_char
*source
;
657 const CA_char
*target
;
661 CppCompareUTF8_2::CppCompareUTF8_2(const Collator
* coll
, const CA_char
* source
, const CA_char
* target
, UBool useLen
)
669 CppCompareUTF8_2::~CppCompareUTF8_2()
673 void CppCompareUTF8_2::call(UErrorCode
* status
) {
674 if (U_FAILURE(*status
)) return;
676 // call strcoll for two strings at the same index
677 StringPiece src
, tgt
;
678 if (source
->count
< target
->count
) {
679 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
681 for (int32_t i
= 0; U_SUCCESS(*status
) && i
< source
->count
; i
++) {
683 src
.set(source
->dataOf(i
), source
->lengthOf(i
));
684 tgt
.set(target
->dataOf(i
), target
->lengthOf(i
));
686 src
.set(source
->dataOf(i
));
687 tgt
.set(target
->dataOf(i
));
689 coll
->compareUTF8(src
, tgt
, *status
);
694 long CppCompareUTF8_2::getOperationsPerIteration()
696 return source
->count
;
701 // Test case taking a single test data array, calling Collator::getCollationKey for each
703 class CppGetCollationKey
: public UPerfFunction
706 CppGetCollationKey(const Collator
* coll
, const CA_uchar
* source
, UBool useLen
);
707 ~CppGetCollationKey();
708 virtual void call(UErrorCode
* status
);
709 virtual long getOperationsPerIteration();
712 const Collator
*coll
;
713 const CA_uchar
*source
;
717 CppGetCollationKey::CppGetCollationKey(const Collator
* coll
, const CA_uchar
* source
, UBool useLen
)
724 CppGetCollationKey::~CppGetCollationKey()
728 void CppGetCollationKey::call(UErrorCode
* status
)
730 if (U_FAILURE(*status
)) return;
733 for (int32_t i
= 0; U_SUCCESS(*status
) && i
< source
->count
; i
++) {
734 coll
->getCollationKey(source
->dataOf(i
), source
->lengthOf(i
), key
, *status
);
738 long CppGetCollationKey::getOperationsPerIteration() {
739 return source
->count
;
744 struct CollatorAndCounter
{
745 CollatorAndCounter(const Collator
& coll
) : coll(coll
), ucoll(NULL
), counter(0) {}
746 CollatorAndCounter(const Collator
& coll
, const UCollator
*ucoll
)
747 : coll(coll
), ucoll(ucoll
), counter(0) {}
748 const Collator
& coll
;
749 const UCollator
*ucoll
;
754 UniStrCollatorComparator(const void* context
, const void* left
, const void* right
) {
755 CollatorAndCounter
& cc
= *(CollatorAndCounter
*)context
;
756 const UnicodeString
& leftString
= **(const UnicodeString
**)left
;
757 const UnicodeString
& rightString
= **(const UnicodeString
**)right
;
758 UErrorCode errorCode
= U_ZERO_ERROR
;
760 return cc
.coll
.compare(leftString
, rightString
, errorCode
);
765 class CollPerfFunction
: public UPerfFunction
{
767 CollPerfFunction(const Collator
& coll
, const UCollator
*ucoll
)
768 : coll(coll
), ucoll(ucoll
), ops(0) {}
769 virtual ~CollPerfFunction();
770 /** Calls call() to set the ops field, and returns that. */
771 virtual long getOperationsPerIteration();
774 const Collator
& coll
;
775 const UCollator
*ucoll
;
779 CollPerfFunction::~CollPerfFunction() {}
781 long CollPerfFunction::getOperationsPerIteration() {
782 UErrorCode errorCode
= U_ZERO_ERROR
;
784 return U_SUCCESS(errorCode
) ? ops
: 0;
787 class UniStrCollPerfFunction
: public CollPerfFunction
{
789 UniStrCollPerfFunction(const Collator
& coll
, const UCollator
*ucoll
, const CA_uchar
* data16
)
790 : CollPerfFunction(coll
, ucoll
), d16(data16
),
791 source(new UnicodeString
*[d16
->count
]) {
792 for (int32_t i
= 0; i
< d16
->count
; ++i
) {
793 source
[i
] = new UnicodeString(TRUE
, d16
->dataOf(i
), d16
->lengthOf(i
));
796 virtual ~UniStrCollPerfFunction();
800 UnicodeString
** source
;
803 UniStrCollPerfFunction::~UniStrCollPerfFunction() {
804 for (int32_t i
= 0; i
< d16
->count
; ++i
) {
811 // Test case sorting an array of UnicodeString pointers.
813 class UniStrSort
: public UniStrCollPerfFunction
{
815 UniStrSort(const Collator
& coll
, const UCollator
*ucoll
, const CA_uchar
* data16
)
816 : UniStrCollPerfFunction(coll
, ucoll
, data16
),
817 dest(new UnicodeString
*[d16
->count
]) {}
818 virtual ~UniStrSort();
819 virtual void call(UErrorCode
* status
);
822 UnicodeString
** dest
; // aliases only
825 UniStrSort::~UniStrSort() {
829 void UniStrSort::call(UErrorCode
* status
) {
830 if (U_FAILURE(*status
)) return;
832 CollatorAndCounter
cc(coll
);
833 int32_t count
= d16
->count
;
834 memcpy(dest
, source
, count
* sizeof(UnicodeString
*));
835 uprv_sortArray(dest
, count
, (int32_t)sizeof(UnicodeString
*),
836 UniStrCollatorComparator
, &cc
, TRUE
, status
);
843 StringPieceCollatorComparator(const void* context
, const void* left
, const void* right
) {
844 CollatorAndCounter
& cc
= *(CollatorAndCounter
*)context
;
845 const StringPiece
& leftString
= *(const StringPiece
*)left
;
846 const StringPiece
& rightString
= *(const StringPiece
*)right
;
847 UErrorCode errorCode
= U_ZERO_ERROR
;
849 return cc
.coll
.compareUTF8(leftString
, rightString
, errorCode
);
853 StringPieceUCollatorComparator(const void* context
, const void* left
, const void* right
) {
854 CollatorAndCounter
& cc
= *(CollatorAndCounter
*)context
;
855 const StringPiece
& leftString
= *(const StringPiece
*)left
;
856 const StringPiece
& rightString
= *(const StringPiece
*)right
;
857 UErrorCode errorCode
= U_ZERO_ERROR
;
859 return ucol_strcollUTF8(cc
.ucoll
,
860 leftString
.data(), leftString
.length(),
861 rightString
.data(), rightString
.length(), &errorCode
);
866 class StringPieceCollPerfFunction
: public CollPerfFunction
{
868 StringPieceCollPerfFunction(const Collator
& coll
, const UCollator
*ucoll
, const CA_char
* data8
)
869 : CollPerfFunction(coll
, ucoll
), d8(data8
),
870 source(new StringPiece
[d8
->count
]) {
871 for (int32_t i
= 0; i
< d8
->count
; ++i
) {
872 source
[i
].set(d8
->dataOf(i
), d8
->lengthOf(i
));
875 virtual ~StringPieceCollPerfFunction();
882 StringPieceCollPerfFunction::~StringPieceCollPerfFunction() {
886 class StringPieceSort
: public StringPieceCollPerfFunction
{
888 StringPieceSort(const Collator
& coll
, const UCollator
*ucoll
, const CA_char
* data8
)
889 : StringPieceCollPerfFunction(coll
, ucoll
, data8
),
890 dest(new StringPiece
[d8
->count
]) {}
891 virtual ~StringPieceSort();
897 StringPieceSort::~StringPieceSort() {
902 // Test case sorting an array of UTF-8 StringPiece's with Collator::compareUTF8().
904 class StringPieceSortCpp
: public StringPieceSort
{
906 StringPieceSortCpp(const Collator
& coll
, const UCollator
*ucoll
, const CA_char
* data8
)
907 : StringPieceSort(coll
, ucoll
, data8
) {}
908 virtual ~StringPieceSortCpp();
909 virtual void call(UErrorCode
* status
);
912 StringPieceSortCpp::~StringPieceSortCpp() {}
914 void StringPieceSortCpp::call(UErrorCode
* status
) {
915 if (U_FAILURE(*status
)) return;
917 CollatorAndCounter
cc(coll
);
918 int32_t count
= d8
->count
;
919 memcpy(dest
, source
, count
* sizeof(StringPiece
));
920 uprv_sortArray(dest
, count
, (int32_t)sizeof(StringPiece
),
921 StringPieceCollatorComparator
, &cc
, TRUE
, status
);
926 // Test case sorting an array of UTF-8 StringPiece's with ucol_strcollUTF8().
928 class StringPieceSortC
: public StringPieceSort
{
930 StringPieceSortC(const Collator
& coll
, const UCollator
*ucoll
, const CA_char
* data8
)
931 : StringPieceSort(coll
, ucoll
, data8
) {}
932 virtual ~StringPieceSortC();
933 virtual void call(UErrorCode
* status
);
936 StringPieceSortC::~StringPieceSortC() {}
938 void StringPieceSortC::call(UErrorCode
* status
) {
939 if (U_FAILURE(*status
)) return;
941 CollatorAndCounter
cc(coll
, ucoll
);
942 int32_t count
= d8
->count
;
943 memcpy(dest
, source
, count
* sizeof(StringPiece
));
944 uprv_sortArray(dest
, count
, (int32_t)sizeof(StringPiece
),
945 StringPieceUCollatorComparator
, &cc
, TRUE
, status
);
950 // Test case performing binary searches in a sorted array of UnicodeString pointers.
952 class UniStrBinSearch
: public UniStrCollPerfFunction
{
954 UniStrBinSearch(const Collator
& coll
, const UCollator
*ucoll
, const CA_uchar
* data16
)
955 : UniStrCollPerfFunction(coll
, ucoll
, data16
) {}
956 virtual ~UniStrBinSearch();
957 virtual void call(UErrorCode
* status
);
960 UniStrBinSearch::~UniStrBinSearch() {}
962 void UniStrBinSearch::call(UErrorCode
* status
) {
963 if (U_FAILURE(*status
)) return;
965 CollatorAndCounter
cc(coll
);
966 int32_t count
= d16
->count
;
967 for (int32_t i
= 0; i
< count
; ++i
) {
968 (void)uprv_stableBinarySearch((char *)source
, count
,
969 source
+ i
, (int32_t)sizeof(UnicodeString
*),
970 UniStrCollatorComparator
, &cc
);
975 class StringPieceBinSearch
: public StringPieceCollPerfFunction
{
977 StringPieceBinSearch(const Collator
& coll
, const UCollator
*ucoll
, const CA_char
* data8
)
978 : StringPieceCollPerfFunction(coll
, ucoll
, data8
) {}
979 virtual ~StringPieceBinSearch();
982 StringPieceBinSearch::~StringPieceBinSearch() {}
985 // Test case performing binary searches in a sorted array of UTF-8 StringPiece's
986 // with Collator::compareUTF8().
988 class StringPieceBinSearchCpp
: public StringPieceBinSearch
{
990 StringPieceBinSearchCpp(const Collator
& coll
, const UCollator
*ucoll
, const CA_char
* data8
)
991 : StringPieceBinSearch(coll
, ucoll
, data8
) {}
992 virtual ~StringPieceBinSearchCpp();
993 virtual void call(UErrorCode
* status
);
996 StringPieceBinSearchCpp::~StringPieceBinSearchCpp() {}
998 void StringPieceBinSearchCpp::call(UErrorCode
* status
) {
999 if (U_FAILURE(*status
)) return;
1001 CollatorAndCounter
cc(coll
);
1002 int32_t count
= d8
->count
;
1003 for (int32_t i
= 0; i
< count
; ++i
) {
1004 (void)uprv_stableBinarySearch((char *)source
, count
,
1005 source
+ i
, (int32_t)sizeof(StringPiece
),
1006 StringPieceCollatorComparator
, &cc
);
1012 // Test case performing binary searches in a sorted array of UTF-8 StringPiece's
1013 // with ucol_strcollUTF8().
1015 class StringPieceBinSearchC
: public StringPieceBinSearch
{
1017 StringPieceBinSearchC(const Collator
& coll
, const UCollator
*ucoll
, const CA_char
* data8
)
1018 : StringPieceBinSearch(coll
, ucoll
, data8
) {}
1019 virtual ~StringPieceBinSearchC();
1020 virtual void call(UErrorCode
* status
);
1023 StringPieceBinSearchC::~StringPieceBinSearchC() {}
1025 void StringPieceBinSearchC::call(UErrorCode
* status
) {
1026 if (U_FAILURE(*status
)) return;
1028 CollatorAndCounter
cc(coll
, ucoll
);
1029 int32_t count
= d8
->count
;
1030 for (int32_t i
= 0; i
< count
; ++i
) {
1031 (void)uprv_stableBinarySearch((char *)source
, count
,
1032 source
+ i
, (int32_t)sizeof(StringPiece
),
1033 StringPieceUCollatorComparator
, &cc
);
1039 class CollPerf2Test
: public UPerfTest
1042 CollPerf2Test(int32_t argc
, const char *argv
[], UErrorCode
&status
);
1044 virtual UPerfFunction
* runIndexedTest(
1045 int32_t index
, UBool exec
, const char *&name
, char *par
= NULL
);
1055 CA_uchar
* modData16
;
1058 CA_uchar
* sortedData16
;
1059 CA_char
* sortedData8
;
1061 CA_uchar
* randomData16
;
1062 CA_char
* randomData8
;
1064 const CA_uchar
* getData16(UErrorCode
&status
);
1065 const CA_char
* getData8(UErrorCode
&status
);
1067 const CA_uchar
* getModData16(UErrorCode
&status
);
1068 const CA_char
* getModData8(UErrorCode
&status
);
1070 const CA_uchar
* getSortedData16(UErrorCode
&status
);
1071 const CA_char
* getSortedData8(UErrorCode
&status
);
1073 const CA_uchar
* getRandomData16(UErrorCode
&status
);
1074 const CA_char
* getRandomData8(UErrorCode
&status
);
1076 static CA_uchar
* sortData16(
1077 const CA_uchar
* d16
,
1078 UComparator
*cmp
, const void *context
,
1079 UErrorCode
&status
);
1080 static CA_char
* getData8FromData16(const CA_uchar
* d16
, UErrorCode
&status
);
1082 UPerfFunction
* TestStrcoll();
1083 UPerfFunction
* TestStrcollNull();
1084 UPerfFunction
* TestStrcollSimilar();
1086 UPerfFunction
* TestStrcollUTF8();
1087 UPerfFunction
* TestStrcollUTF8Null();
1088 UPerfFunction
* TestStrcollUTF8Similar();
1090 UPerfFunction
* TestGetSortKey();
1091 UPerfFunction
* TestGetSortKeyNull();
1093 UPerfFunction
* TestNextSortKeyPart_4All();
1094 UPerfFunction
* TestNextSortKeyPart_4x2();
1095 UPerfFunction
* TestNextSortKeyPart_4x4();
1096 UPerfFunction
* TestNextSortKeyPart_4x8();
1097 UPerfFunction
* TestNextSortKeyPart_32All();
1098 UPerfFunction
* TestNextSortKeyPart_32x2();
1100 UPerfFunction
* TestNextSortKeyPartUTF8_4All();
1101 UPerfFunction
* TestNextSortKeyPartUTF8_4x2();
1102 UPerfFunction
* TestNextSortKeyPartUTF8_4x4();
1103 UPerfFunction
* TestNextSortKeyPartUTF8_4x8();
1104 UPerfFunction
* TestNextSortKeyPartUTF8_32All();
1105 UPerfFunction
* TestNextSortKeyPartUTF8_32x2();
1107 UPerfFunction
* TestCppCompare();
1108 UPerfFunction
* TestCppCompareNull();
1109 UPerfFunction
* TestCppCompareSimilar();
1111 UPerfFunction
* TestCppCompareUTF8();
1112 UPerfFunction
* TestCppCompareUTF8Null();
1113 UPerfFunction
* TestCppCompareUTF8Similar();
1115 UPerfFunction
* TestCppGetCollationKey();
1116 UPerfFunction
* TestCppGetCollationKeyNull();
1118 UPerfFunction
* TestUniStrSort();
1119 UPerfFunction
* TestStringPieceSortCpp();
1120 UPerfFunction
* TestStringPieceSortC();
1122 UPerfFunction
* TestUniStrBinSearch();
1123 UPerfFunction
* TestStringPieceBinSearchCpp();
1124 UPerfFunction
* TestStringPieceBinSearchC();
1127 CollPerf2Test::CollPerf2Test(int32_t argc
, const char *argv
[], UErrorCode
&status
) :
1128 UPerfTest(argc
, argv
, status
),
1141 if (U_FAILURE(status
)) {
1145 if (locale
== NULL
){
1146 locale
= "en_US"; // set default locale
1149 // Set up an ICU collator
1150 coll
= ucol_open(locale
, &status
);
1151 collObj
= Collator::createInstance(locale
, status
);
1153 // Keyword support should be actually a part of ICU collator, see ICU ticket #8260.
1154 char keyBuffer
[256];
1155 UColAttributeValue val
;
1156 if (uloc_getKeywordValue(locale
, "strength", keyBuffer
, sizeof(keyBuffer
)/sizeof(keyBuffer
[0]), &status
)) {
1157 if (strcmp(keyBuffer
, "primary") == 0) {
1159 } else if (strcmp(keyBuffer
, "secondary") == 0) {
1160 val
= UCOL_SECONDARY
;
1161 } else if (strcmp(keyBuffer
, "tertiary") == 0) {
1162 val
= UCOL_TERTIARY
;
1163 } else if (strcmp(keyBuffer
, "quaternary") == 0) {
1164 val
= UCOL_QUATERNARY
;
1165 } else if (strcmp(keyBuffer
, "identical") == 0) {
1166 val
= UCOL_IDENTICAL
;
1168 status
= U_ILLEGAL_ARGUMENT_ERROR
;
1170 if (U_SUCCESS(status
)) {
1171 ucol_setAttribute(coll
, UCOL_STRENGTH
, val
, &status
);
1172 collObj
->setAttribute(UCOL_STRENGTH
, val
, status
);
1175 if (uloc_getKeywordValue(locale
, "alternate", keyBuffer
, sizeof(keyBuffer
)/sizeof(keyBuffer
[0]), &status
)) {
1176 if (strcmp(keyBuffer
, "non-ignorable") == 0) {
1177 val
= UCOL_NON_IGNORABLE
;
1178 } else if (strcmp(keyBuffer
, "shifted") == 0) {
1181 status
= U_ILLEGAL_ARGUMENT_ERROR
;
1183 if (U_SUCCESS(status
)) {
1184 ucol_setAttribute(coll
, UCOL_ALTERNATE_HANDLING
, val
, &status
);
1185 collObj
->setAttribute(UCOL_ALTERNATE_HANDLING
, val
, status
);
1188 if (uloc_getKeywordValue(locale
, "backwards", keyBuffer
, sizeof(keyBuffer
)/sizeof(keyBuffer
[0]), &status
)) {
1189 if (strcmp(keyBuffer
, "on") == 0) {
1191 } else if (strcmp(keyBuffer
, "off") == 0) {
1194 status
= U_ILLEGAL_ARGUMENT_ERROR
;
1196 if (U_SUCCESS(status
)) {
1197 ucol_setAttribute(coll
, UCOL_FRENCH_COLLATION
, val
, &status
);
1198 collObj
->setAttribute(UCOL_FRENCH_COLLATION
, val
, status
);
1201 if (uloc_getKeywordValue(locale
, "normalization", keyBuffer
, sizeof(keyBuffer
)/sizeof(keyBuffer
[0]), &status
)) {
1202 if (strcmp(keyBuffer
, "on") == 0) {
1204 } else if (strcmp(keyBuffer
, "off") == 0) {
1207 status
= U_ILLEGAL_ARGUMENT_ERROR
;
1209 if (U_SUCCESS(status
)) {
1210 ucol_setAttribute(coll
, UCOL_NORMALIZATION_MODE
, val
, &status
);
1211 collObj
->setAttribute(UCOL_NORMALIZATION_MODE
, val
, status
);
1214 if (uloc_getKeywordValue(locale
, "caseLevel", keyBuffer
, sizeof(keyBuffer
)/sizeof(keyBuffer
[0]), &status
)) {
1215 if (strcmp(keyBuffer
, "on") == 0) {
1217 } else if (strcmp(keyBuffer
, "off") == 0) {
1220 status
= U_ILLEGAL_ARGUMENT_ERROR
;
1222 if (U_SUCCESS(status
)) {
1223 ucol_setAttribute(coll
, UCOL_CASE_LEVEL
, val
, &status
);
1224 collObj
->setAttribute(UCOL_CASE_LEVEL
, val
, status
);
1227 if (uloc_getKeywordValue(locale
, "caseFirst", keyBuffer
, sizeof(keyBuffer
)/sizeof(keyBuffer
[0]), &status
)) {
1228 if (strcmp(keyBuffer
, "upper") == 0) {
1229 val
= UCOL_UPPER_FIRST
;
1230 } else if (strcmp(keyBuffer
, "lower") == 0) {
1231 val
= UCOL_LOWER_FIRST
;
1232 } else if (strcmp(keyBuffer
, "off") == 0) {
1235 status
= U_ILLEGAL_ARGUMENT_ERROR
;
1237 if (U_SUCCESS(status
)) {
1238 ucol_setAttribute(coll
, UCOL_CASE_FIRST
, val
, &status
);
1239 collObj
->setAttribute(UCOL_CASE_FIRST
, val
, status
);
1242 if (uloc_getKeywordValue(locale
, "hiraganaQuaternary", keyBuffer
, sizeof(keyBuffer
)/sizeof(keyBuffer
[0]), &status
)) {
1243 if (strcmp(keyBuffer
, "on") == 0) {
1245 } else if (strcmp(keyBuffer
, "off") == 0) {
1248 status
= U_ILLEGAL_ARGUMENT_ERROR
;
1250 if (U_SUCCESS(status
)) {
1251 ucol_setAttribute(coll
, UCOL_HIRAGANA_QUATERNARY_MODE
, val
, &status
);
1252 collObj
->setAttribute(UCOL_HIRAGANA_QUATERNARY_MODE
, val
, status
);
1255 if (uloc_getKeywordValue(locale
, "numeric", keyBuffer
, sizeof(keyBuffer
)/sizeof(keyBuffer
[0]), &status
)) {
1256 if (strcmp(keyBuffer
, "on") == 0) {
1258 } else if (strcmp(keyBuffer
, "off") == 0) {
1261 status
= U_ILLEGAL_ARGUMENT_ERROR
;
1263 if (U_SUCCESS(status
)) {
1264 ucol_setAttribute(coll
, UCOL_NUMERIC_COLLATION
, val
, &status
);
1265 collObj
->setAttribute(UCOL_NUMERIC_COLLATION
, val
, status
);
1268 if (uloc_getKeywordValue(locale
, "variableTop", keyBuffer
, sizeof(keyBuffer
)/sizeof(keyBuffer
[0]), &status
)) {
1269 // no support for now
1270 status
= U_UNSUPPORTED_ERROR
;
1272 if (uloc_getKeywordValue(locale
, "reorder", keyBuffer
, sizeof(keyBuffer
)/sizeof(keyBuffer
[0]), &status
)) {
1273 // no support for now
1274 status
= U_UNSUPPORTED_ERROR
;
1278 CollPerf2Test::~CollPerf2Test()
1287 delete sortedData16
;
1289 delete randomData16
;
1293 #define MAX_NUM_DATA 10000
1295 const CA_uchar
* CollPerf2Test::getData16(UErrorCode
&status
)
1297 if (U_FAILURE(status
)) return NULL
;
1298 if (data16
) return data16
;
1300 CA_uchar
* d16
= new CA_uchar();
1301 const UChar
*line
= NULL
;
1303 int32_t numData
= 0;
1306 line
= ucbuf_readline(ucharBuf
, &len
, &status
);
1307 if (line
== NULL
|| U_FAILURE(status
)) break;
1309 // Refer to the source code of ucbuf_readline()
1310 // 1. 'len' includes the line terminal symbols
1311 // 2. The length of the line terminal symbols is only one character
1312 // 3. The Windows CR LF line terminal symbols will be converted to CR
1314 if (len
== 1 || line
[0] == 0x23 /* '#' */) {
1315 continue; // skip empty/comment line
1317 d16
->append_one(len
);
1318 u_memcpy(d16
->last(), line
, len
);
1321 if (numData
>= MAX_NUM_DATA
) break;
1325 if (U_SUCCESS(status
)) {
1334 const CA_char
* CollPerf2Test::getData8(UErrorCode
&status
)
1336 if (U_FAILURE(status
)) return NULL
;
1337 if (data8
) return data8
;
1338 return data8
= getData8FromData16(getData16(status
), status
);
1341 const CA_uchar
* CollPerf2Test::getModData16(UErrorCode
&status
)
1343 if (U_FAILURE(status
)) return NULL
;
1344 if (modData16
) return modData16
;
1346 const CA_uchar
* d16
= getData16(status
);
1347 if (U_FAILURE(status
)) return NULL
;
1349 CA_uchar
* modData16
= new CA_uchar();
1351 for (int32_t i
= 0; i
< d16
->count
; i
++) {
1352 const UChar
*s
= d16
->dataOf(i
);
1353 int32_t len
= d16
->lengthOf(i
) + 1; // including NULL terminator
1355 modData16
->append_one(len
);
1356 u_memcpy(modData16
->last(), s
, len
);
1358 // replacing the last character with a different character
1359 UChar
*lastChar
= &modData16
->last()[len
-2];
1360 for (int32_t j
= i
+ 1; j
!= i
; j
++) {
1361 if (j
>= d16
->count
) {
1364 const UChar
*s1
= d16
->dataOf(j
);
1365 UChar lastChar1
= s1
[d16
->lengthOf(j
) - 1];
1366 if (*lastChar
!= lastChar1
) {
1367 *lastChar
= lastChar1
;
1376 const CA_char
* CollPerf2Test::getModData8(UErrorCode
&status
)
1378 if (U_FAILURE(status
)) return NULL
;
1379 if (modData8
) return modData8
;
1380 return modData8
= getData8FromData16(getModData16(status
), status
);
1385 struct ArrayAndColl
{
1386 ArrayAndColl(const CA_uchar
* a
, const Collator
& c
) : d16(a
), coll(c
) {}
1387 const CA_uchar
* d16
;
1388 const Collator
& coll
;
1392 U16CollatorComparator(const void* context
, const void* left
, const void* right
) {
1393 const ArrayAndColl
& ac
= *(const ArrayAndColl
*)context
;
1394 const CA_uchar
* d16
= ac
.d16
;
1395 int32_t leftIndex
= *(const int32_t*)left
;
1396 int32_t rightIndex
= *(const int32_t*)right
;
1397 UErrorCode errorCode
= U_ZERO_ERROR
;
1398 return ac
.coll
.compare(d16
->dataOf(leftIndex
), d16
->lengthOf(leftIndex
),
1399 d16
->dataOf(rightIndex
), d16
->lengthOf(rightIndex
),
1404 U16HashComparator(const void* context
, const void* left
, const void* right
) {
1405 const CA_uchar
* d16
= (const CA_uchar
*)context
;
1406 int32_t leftIndex
= *(const int32_t*)left
;
1407 int32_t rightIndex
= *(const int32_t*)right
;
1408 int32_t leftHash
= ustr_hashUCharsN(d16
->dataOf(leftIndex
), d16
->lengthOf(leftIndex
));
1409 int32_t rightHash
= ustr_hashUCharsN(d16
->dataOf(rightIndex
), d16
->lengthOf(rightIndex
));
1410 return leftHash
< rightHash
? -1 : leftHash
== rightHash
? 0 : 1;
1415 const CA_uchar
* CollPerf2Test::getSortedData16(UErrorCode
&status
) {
1416 if (U_FAILURE(status
)) return NULL
;
1417 if (sortedData16
) return sortedData16
;
1419 ArrayAndColl
ac(getData16(status
), *collObj
);
1420 return sortedData16
= sortData16(ac
.d16
, U16CollatorComparator
, &ac
, status
);
1423 const CA_char
* CollPerf2Test::getSortedData8(UErrorCode
&status
) {
1424 if (U_FAILURE(status
)) return NULL
;
1425 if (sortedData8
) return sortedData8
;
1426 return sortedData8
= getData8FromData16(getSortedData16(status
), status
);
1429 const CA_uchar
* CollPerf2Test::getRandomData16(UErrorCode
&status
) {
1430 if (U_FAILURE(status
)) return NULL
;
1431 if (randomData16
) return randomData16
;
1433 // Sort the strings by their hash codes, which should be a reasonably pseudo-random order.
1434 const CA_uchar
* d16
= getData16(status
);
1435 return randomData16
= sortData16(d16
, U16HashComparator
, d16
, status
);
1438 const CA_char
* CollPerf2Test::getRandomData8(UErrorCode
&status
) {
1439 if (U_FAILURE(status
)) return NULL
;
1440 if (randomData8
) return randomData8
;
1441 return randomData8
= getData8FromData16(getRandomData16(status
), status
);
1444 CA_uchar
* CollPerf2Test::sortData16(const CA_uchar
* d16
,
1445 UComparator
*cmp
, const void *context
,
1446 UErrorCode
&status
) {
1447 if (U_FAILURE(status
)) return NULL
;
1449 LocalArray
<int32_t> indexes(new int32_t[d16
->count
]);
1450 for (int32_t i
= 0; i
< d16
->count
; ++i
) {
1453 uprv_sortArray(indexes
.getAlias(), d16
->count
, 4, cmp
, context
, TRUE
, &status
);
1454 if (U_FAILURE(status
)) return NULL
;
1456 // Copy the strings in sorted order into a new array.
1457 LocalPointer
<CA_uchar
> newD16(new CA_uchar());
1458 for (int32_t i
= 0; i
< d16
->count
; i
++) {
1459 const UChar
* s
= d16
->dataOf(i
);
1460 int32_t len
= d16
->lengthOf(i
);
1461 int32_t capacity
= len
+ 1; // including NULL terminator
1462 newD16
->append_one(capacity
);
1463 u_memcpy(newD16
->last(), s
, capacity
);
1466 if (U_SUCCESS(status
)) {
1467 return newD16
.orphan();
1473 CA_char
* CollPerf2Test::getData8FromData16(const CA_uchar
* d16
, UErrorCode
&status
) {
1474 if (U_FAILURE(status
)) return NULL
;
1476 // UTF-16 -> UTF-8 conversion
1477 LocalPointer
<CA_char
> d8(new CA_char());
1478 for (int32_t i
= 0; i
< d16
->count
; i
++) {
1479 const UChar
*s16
= d16
->dataOf(i
);
1480 int32_t length16
= d16
->lengthOf(i
);
1482 // get length in UTF-8
1484 u_strToUTF8(NULL
, 0, &length8
, s16
, length16
, &status
);
1485 if (status
== U_BUFFER_OVERFLOW_ERROR
|| status
== U_ZERO_ERROR
){
1486 status
= U_ZERO_ERROR
;
1490 int32_t capacity8
= length8
+ 1; // plus terminal NULL
1491 d8
->append_one(capacity8
);
1494 u_strToUTF8(d8
->last(), capacity8
, NULL
, s16
, length16
, &status
);
1495 if (U_FAILURE(status
)) break;
1498 if (U_SUCCESS(status
)) {
1506 CollPerf2Test::runIndexedTest(int32_t index
, UBool exec
, const char *&name
, char *par
/*= NULL*/)
1509 TESTCASE_AUTO_BEGIN
;
1511 TESTCASE_AUTO(TestStrcoll
);
1512 TESTCASE_AUTO(TestStrcollNull
);
1513 TESTCASE_AUTO(TestStrcollSimilar
);
1515 TESTCASE_AUTO(TestStrcollUTF8
);
1516 TESTCASE_AUTO(TestStrcollUTF8Null
);
1517 TESTCASE_AUTO(TestStrcollUTF8Similar
);
1519 TESTCASE_AUTO(TestGetSortKey
);
1520 TESTCASE_AUTO(TestGetSortKeyNull
);
1522 TESTCASE_AUTO(TestNextSortKeyPart_4All
);
1523 TESTCASE_AUTO(TestNextSortKeyPart_4x4
);
1524 TESTCASE_AUTO(TestNextSortKeyPart_4x8
);
1525 TESTCASE_AUTO(TestNextSortKeyPart_32All
);
1526 TESTCASE_AUTO(TestNextSortKeyPart_32x2
);
1528 TESTCASE_AUTO(TestNextSortKeyPartUTF8_4All
);
1529 TESTCASE_AUTO(TestNextSortKeyPartUTF8_4x4
);
1530 TESTCASE_AUTO(TestNextSortKeyPartUTF8_4x8
);
1531 TESTCASE_AUTO(TestNextSortKeyPartUTF8_32All
);
1532 TESTCASE_AUTO(TestNextSortKeyPartUTF8_32x2
);
1534 TESTCASE_AUTO(TestCppCompare
);
1535 TESTCASE_AUTO(TestCppCompareNull
);
1536 TESTCASE_AUTO(TestCppCompareSimilar
);
1538 TESTCASE_AUTO(TestCppCompareUTF8
);
1539 TESTCASE_AUTO(TestCppCompareUTF8Null
);
1540 TESTCASE_AUTO(TestCppCompareUTF8Similar
);
1542 TESTCASE_AUTO(TestCppGetCollationKey
);
1543 TESTCASE_AUTO(TestCppGetCollationKeyNull
);
1545 TESTCASE_AUTO(TestUniStrSort
);
1546 TESTCASE_AUTO(TestStringPieceSortCpp
);
1547 TESTCASE_AUTO(TestStringPieceSortC
);
1549 TESTCASE_AUTO(TestUniStrBinSearch
);
1550 TESTCASE_AUTO(TestStringPieceBinSearchCpp
);
1551 TESTCASE_AUTO(TestStringPieceBinSearchC
);
1559 UPerfFunction
* CollPerf2Test::TestStrcoll()
1561 UErrorCode status
= U_ZERO_ERROR
;
1562 Strcoll
*testCase
= new Strcoll(coll
, getData16(status
), TRUE
/* useLen */);
1563 if (U_FAILURE(status
)) {
1570 UPerfFunction
* CollPerf2Test::TestStrcollNull()
1572 UErrorCode status
= U_ZERO_ERROR
;
1573 Strcoll
*testCase
= new Strcoll(coll
, getData16(status
), FALSE
/* useLen */);
1574 if (U_FAILURE(status
)) {
1581 UPerfFunction
* CollPerf2Test::TestStrcollSimilar()
1583 UErrorCode status
= U_ZERO_ERROR
;
1584 Strcoll_2
*testCase
= new Strcoll_2(coll
, getData16(status
), getModData16(status
), TRUE
/* useLen */);
1585 if (U_FAILURE(status
)) {
1592 UPerfFunction
* CollPerf2Test::TestStrcollUTF8()
1594 UErrorCode status
= U_ZERO_ERROR
;
1595 StrcollUTF8
*testCase
= new StrcollUTF8(coll
, getData8(status
), TRUE
/* useLen */);
1596 if (U_FAILURE(status
)) {
1603 UPerfFunction
* CollPerf2Test::TestStrcollUTF8Null()
1605 UErrorCode status
= U_ZERO_ERROR
;
1606 StrcollUTF8
*testCase
= new StrcollUTF8(coll
, getData8(status
),FALSE
/* useLen */);
1607 if (U_FAILURE(status
)) {
1614 UPerfFunction
* CollPerf2Test::TestStrcollUTF8Similar()
1616 UErrorCode status
= U_ZERO_ERROR
;
1617 StrcollUTF8_2
*testCase
= new StrcollUTF8_2(coll
, getData8(status
), getModData8(status
), TRUE
/* useLen */);
1618 if (U_FAILURE(status
)) {
1625 UPerfFunction
* CollPerf2Test::TestGetSortKey()
1627 UErrorCode status
= U_ZERO_ERROR
;
1628 GetSortKey
*testCase
= new GetSortKey(coll
, getData16(status
), TRUE
/* useLen */);
1629 if (U_FAILURE(status
)) {
1636 UPerfFunction
* CollPerf2Test::TestGetSortKeyNull()
1638 UErrorCode status
= U_ZERO_ERROR
;
1639 GetSortKey
*testCase
= new GetSortKey(coll
, getData16(status
), FALSE
/* useLen */);
1640 if (U_FAILURE(status
)) {
1647 UPerfFunction
* CollPerf2Test::TestNextSortKeyPart_4All()
1649 UErrorCode status
= U_ZERO_ERROR
;
1650 NextSortKeyPart
*testCase
= new NextSortKeyPart(coll
, getData16(status
), 4 /* bufSize */);
1651 if (U_FAILURE(status
)) {
1658 UPerfFunction
* CollPerf2Test::TestNextSortKeyPart_4x4()
1660 UErrorCode status
= U_ZERO_ERROR
;
1661 NextSortKeyPart
*testCase
= new NextSortKeyPart(coll
, getData16(status
), 4 /* bufSize */, 4 /* maxIteration */);
1662 if (U_FAILURE(status
)) {
1669 UPerfFunction
* CollPerf2Test::TestNextSortKeyPart_4x8()
1671 UErrorCode status
= U_ZERO_ERROR
;
1672 NextSortKeyPart
*testCase
= new NextSortKeyPart(coll
, getData16(status
), 4 /* bufSize */, 8 /* maxIteration */);
1673 if (U_FAILURE(status
)) {
1680 UPerfFunction
* CollPerf2Test::TestNextSortKeyPart_32All()
1682 UErrorCode status
= U_ZERO_ERROR
;
1683 NextSortKeyPart
*testCase
= new NextSortKeyPart(coll
, getData16(status
), 32 /* bufSize */);
1684 if (U_FAILURE(status
)) {
1691 UPerfFunction
* CollPerf2Test::TestNextSortKeyPart_32x2()
1693 UErrorCode status
= U_ZERO_ERROR
;
1694 NextSortKeyPart
*testCase
= new NextSortKeyPart(coll
, getData16(status
), 32 /* bufSize */, 2 /* maxIteration */);
1695 if (U_FAILURE(status
)) {
1702 UPerfFunction
* CollPerf2Test::TestNextSortKeyPartUTF8_4All()
1704 UErrorCode status
= U_ZERO_ERROR
;
1705 NextSortKeyPartUTF8
*testCase
= new NextSortKeyPartUTF8(coll
, getData8(status
), 4 /* bufSize */);
1706 if (U_FAILURE(status
)) {
1713 UPerfFunction
* CollPerf2Test::TestNextSortKeyPartUTF8_4x4()
1715 UErrorCode status
= U_ZERO_ERROR
;
1716 NextSortKeyPartUTF8
*testCase
= new NextSortKeyPartUTF8(coll
, getData8(status
), 4 /* bufSize */, 4 /* maxIteration */);
1717 if (U_FAILURE(status
)) {
1724 UPerfFunction
* CollPerf2Test::TestNextSortKeyPartUTF8_4x8()
1726 UErrorCode status
= U_ZERO_ERROR
;
1727 NextSortKeyPartUTF8
*testCase
= new NextSortKeyPartUTF8(coll
, getData8(status
), 4 /* bufSize */, 8 /* maxIteration */);
1728 if (U_FAILURE(status
)) {
1735 UPerfFunction
* CollPerf2Test::TestNextSortKeyPartUTF8_32All()
1737 UErrorCode status
= U_ZERO_ERROR
;
1738 NextSortKeyPartUTF8
*testCase
= new NextSortKeyPartUTF8(coll
, getData8(status
), 32 /* bufSize */);
1739 if (U_FAILURE(status
)) {
1746 UPerfFunction
* CollPerf2Test::TestNextSortKeyPartUTF8_32x2()
1748 UErrorCode status
= U_ZERO_ERROR
;
1749 NextSortKeyPartUTF8
*testCase
= new NextSortKeyPartUTF8(coll
, getData8(status
), 32 /* bufSize */, 2 /* maxIteration */);
1750 if (U_FAILURE(status
)) {
1757 UPerfFunction
* CollPerf2Test::TestCppCompare()
1759 UErrorCode status
= U_ZERO_ERROR
;
1760 CppCompare
*testCase
= new CppCompare(collObj
, getData16(status
), TRUE
/* useLen */);
1761 if (U_FAILURE(status
)) {
1768 UPerfFunction
* CollPerf2Test::TestCppCompareNull()
1770 UErrorCode status
= U_ZERO_ERROR
;
1771 CppCompare
*testCase
= new CppCompare(collObj
, getData16(status
), FALSE
/* useLen */);
1772 if (U_FAILURE(status
)) {
1779 UPerfFunction
* CollPerf2Test::TestCppCompareSimilar()
1781 UErrorCode status
= U_ZERO_ERROR
;
1782 CppCompare_2
*testCase
= new CppCompare_2(collObj
, getData16(status
), getModData16(status
), TRUE
/* useLen */);
1783 if (U_FAILURE(status
)) {
1790 UPerfFunction
* CollPerf2Test::TestCppCompareUTF8()
1792 UErrorCode status
= U_ZERO_ERROR
;
1793 CppCompareUTF8
*testCase
= new CppCompareUTF8(collObj
, getData8(status
), TRUE
/* useLen */);
1794 if (U_FAILURE(status
)) {
1801 UPerfFunction
* CollPerf2Test::TestCppCompareUTF8Null()
1803 UErrorCode status
= U_ZERO_ERROR
;
1804 CppCompareUTF8
*testCase
= new CppCompareUTF8(collObj
, getData8(status
), FALSE
/* useLen */);
1805 if (U_FAILURE(status
)) {
1812 UPerfFunction
* CollPerf2Test::TestCppCompareUTF8Similar()
1814 UErrorCode status
= U_ZERO_ERROR
;
1815 CppCompareUTF8_2
*testCase
= new CppCompareUTF8_2(collObj
, getData8(status
), getModData8(status
), TRUE
/* useLen */);
1816 if (U_FAILURE(status
)) {
1823 UPerfFunction
* CollPerf2Test::TestCppGetCollationKey()
1825 UErrorCode status
= U_ZERO_ERROR
;
1826 CppGetCollationKey
*testCase
= new CppGetCollationKey(collObj
, getData16(status
), TRUE
/* useLen */);
1827 if (U_FAILURE(status
)) {
1834 UPerfFunction
* CollPerf2Test::TestCppGetCollationKeyNull()
1836 UErrorCode status
= U_ZERO_ERROR
;
1837 CppGetCollationKey
*testCase
= new CppGetCollationKey(collObj
, getData16(status
), FALSE
/* useLen */);
1838 if (U_FAILURE(status
)) {
1845 UPerfFunction
* CollPerf2Test::TestUniStrSort() {
1846 UErrorCode status
= U_ZERO_ERROR
;
1847 UPerfFunction
*testCase
= new UniStrSort(*collObj
, coll
, getRandomData16(status
));
1848 if (U_FAILURE(status
)) {
1855 UPerfFunction
* CollPerf2Test::TestStringPieceSortCpp() {
1856 UErrorCode status
= U_ZERO_ERROR
;
1857 UPerfFunction
*testCase
= new StringPieceSortCpp(*collObj
, coll
, getRandomData8(status
));
1858 if (U_FAILURE(status
)) {
1865 UPerfFunction
* CollPerf2Test::TestStringPieceSortC() {
1866 UErrorCode status
= U_ZERO_ERROR
;
1867 UPerfFunction
*testCase
= new StringPieceSortC(*collObj
, coll
, getRandomData8(status
));
1868 if (U_FAILURE(status
)) {
1875 UPerfFunction
* CollPerf2Test::TestUniStrBinSearch() {
1876 UErrorCode status
= U_ZERO_ERROR
;
1877 UPerfFunction
*testCase
= new UniStrBinSearch(*collObj
, coll
, getSortedData16(status
));
1878 if (U_FAILURE(status
)) {
1885 UPerfFunction
* CollPerf2Test::TestStringPieceBinSearchCpp() {
1886 UErrorCode status
= U_ZERO_ERROR
;
1887 UPerfFunction
*testCase
= new StringPieceBinSearchCpp(*collObj
, coll
, getSortedData8(status
));
1888 if (U_FAILURE(status
)) {
1895 UPerfFunction
* CollPerf2Test::TestStringPieceBinSearchC() {
1896 UErrorCode status
= U_ZERO_ERROR
;
1897 UPerfFunction
*testCase
= new StringPieceBinSearchC(*collObj
, coll
, getSortedData8(status
));
1898 if (U_FAILURE(status
)) {
1906 int main(int argc
, const char *argv
[])
1908 UErrorCode status
= U_ZERO_ERROR
;
1909 CollPerf2Test
test(argc
, argv
, status
);
1911 if (U_FAILURE(status
)){
1912 printf("The error is %s\n", u_errorName(status
));
1913 //TODO: print usage here
1917 if (test
.run() == FALSE
){
1918 fprintf(stderr
, "FAILED: Tests could not be run please check the arguments.\n");