1/* 2********************************************************************** 3* Copyright (c) 2013-2014, International Business Machines 4* Corporation and others. All Rights Reserved. 5********************************************************************** 6*/ 7 8#include <string.h> 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" 16#include "uarrsort.h" 17#include "uoptions.h" 18#include "ustr_imp.h" 19 20#define COMPACT_ARRAY(CompactArrays, UNIT) \ 21struct 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*/ \ 27 \ 28 ~CompactArrays(){free(index);free(data);} \ 29 CompactArrays() : count(0), index(NULL), data(NULL) { \ 30 index = (int32_t *) realloc(index, sizeof(int32_t)); \ 31 index[0] = 0; \ 32 } \ 33 void append_one(int32_t theLen){ /*include terminal NULL*/ \ 34 count++; \ 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]); \ 38 } \ 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*/ \ 42}; 43 44COMPACT_ARRAY(CA_uchar, UChar) 45COMPACT_ARRAY(CA_char, char) 46 47#define MAX_TEST_STRINGS_FOR_PERMUTING 1000 48 49// C API test cases 50 51// 52// Test case taking a single test data array, calling ucol_strcoll by permuting the test data 53// 54class Strcoll : public UPerfFunction 55{ 56public: 57 Strcoll(const UCollator* coll, const CA_uchar* source, UBool useLen); 58 ~Strcoll(); 59 virtual void call(UErrorCode* status); 60 virtual long getOperationsPerIteration(); 61 62private: 63 const UCollator *coll; 64 const CA_uchar *source; 65 UBool useLen; 66 int32_t maxTestStrings; 67}; 68 69Strcoll::Strcoll(const UCollator* coll, const CA_uchar* source, UBool useLen) 70 : coll(coll), 71 source(source), 72 useLen(useLen) 73{ 74 maxTestStrings = source->count > MAX_TEST_STRINGS_FOR_PERMUTING ? MAX_TEST_STRINGS_FOR_PERMUTING : source->count; 75} 76 77Strcoll::~Strcoll() 78{ 79} 80 81void Strcoll::call(UErrorCode* status) 82{ 83 if (U_FAILURE(*status)) return; 84 85 // call strcoll for permutation 86 int32_t divisor = source->count / maxTestStrings; 87 int32_t srcLen, tgtLen; 88 int32_t cmp = 0; 89 for (int32_t i = 0, numTestStringsI = 0; i < source->count && numTestStringsI < maxTestStrings; i++) { 90 if (i % divisor) continue; 91 numTestStringsI++; 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; 95 numTestStringsJ++; 96 tgtLen = useLen ? source->lengthOf(j) : -1; 97 cmp += ucol_strcoll(coll, source->dataOf(i), srcLen, source->dataOf(j), tgtLen); 98 } 99 } 100 // At the end, cmp must be 0 101 if (cmp != 0) { 102 *status = U_INTERNAL_PROGRAM_ERROR; 103 } 104} 105 106long Strcoll::getOperationsPerIteration() 107{ 108 return maxTestStrings * maxTestStrings; 109} 110 111// 112// Test case taking two test data arrays, calling ucol_strcoll for strings at a same index 113// 114class Strcoll_2 : public UPerfFunction 115{ 116public: 117 Strcoll_2(const UCollator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen); 118 ~Strcoll_2(); 119 virtual void call(UErrorCode* status); 120 virtual long getOperationsPerIteration(); 121 122private: 123 const UCollator *coll; 124 const CA_uchar *source; 125 const CA_uchar *target; 126 UBool useLen; 127}; 128 129Strcoll_2::Strcoll_2(const UCollator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen) 130 : coll(coll), 131 source(source), 132 target(target), 133 useLen(useLen) 134{ 135} 136 137Strcoll_2::~Strcoll_2() 138{ 139} 140 141void Strcoll_2::call(UErrorCode* status) 142{ 143 if (U_FAILURE(*status)) return; 144 145 // call strcoll for two strings at the same index 146 if (source->count < target->count) { 147 *status = U_ILLEGAL_ARGUMENT_ERROR; 148 } else { 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); 153 } 154 } 155} 156 157long Strcoll_2::getOperationsPerIteration() 158{ 159 return source->count; 160} 161 162 163// 164// Test case taking a single test data array, calling ucol_strcollUTF8 by permuting the test data 165// 166class StrcollUTF8 : public UPerfFunction 167{ 168public: 169 StrcollUTF8(const UCollator* coll, const CA_char* source, UBool useLen); 170 ~StrcollUTF8(); 171 virtual void call(UErrorCode* status); 172 virtual long getOperationsPerIteration(); 173 174private: 175 const UCollator *coll; 176 const CA_char *source; 177 UBool useLen; 178 int32_t maxTestStrings; 179}; 180 181StrcollUTF8::StrcollUTF8(const UCollator* coll, const CA_char* source, UBool useLen) 182 : coll(coll), 183 source(source), 184 useLen(useLen) 185{ 186 maxTestStrings = source->count > MAX_TEST_STRINGS_FOR_PERMUTING ? MAX_TEST_STRINGS_FOR_PERMUTING : source->count; 187} 188 189StrcollUTF8::~StrcollUTF8() 190{ 191} 192 193void StrcollUTF8::call(UErrorCode* status) 194{ 195 if (U_FAILURE(*status)) return; 196 197 // call strcollUTF8 for permutation 198 int32_t divisor = source->count / maxTestStrings; 199 int32_t srcLen, tgtLen; 200 int32_t cmp = 0; 201 for (int32_t i = 0, numTestStringsI = 0; U_SUCCESS(*status) && i < source->count && numTestStringsI < maxTestStrings; i++) { 202 if (i % divisor) continue; 203 numTestStringsI++; 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; 207 numTestStringsJ++; 208 tgtLen = useLen ? source->lengthOf(j) : -1; 209 cmp += ucol_strcollUTF8(coll, source->dataOf(i), srcLen, source->dataOf(j), tgtLen, status); 210 } 211 } 212 // At the end, cmp must be 0 213 if (cmp != 0) { 214 *status = U_INTERNAL_PROGRAM_ERROR; 215 } 216} 217 218long StrcollUTF8::getOperationsPerIteration() 219{ 220 return maxTestStrings * maxTestStrings; 221} 222 223// 224// Test case taking two test data arrays, calling ucol_strcoll for strings at a same index 225// 226class StrcollUTF8_2 : public UPerfFunction 227{ 228public: 229 StrcollUTF8_2(const UCollator* coll, const CA_char* source, const CA_char* target, UBool useLen); 230 ~StrcollUTF8_2(); 231 virtual void call(UErrorCode* status); 232 virtual long getOperationsPerIteration(); 233 234private: 235 const UCollator *coll; 236 const CA_char *source; 237 const CA_char *target; 238 UBool useLen; 239}; 240 241StrcollUTF8_2::StrcollUTF8_2(const UCollator* coll, const CA_char* source, const CA_char* target, UBool useLen) 242 : coll(coll), 243 source(source), 244 target(target), 245 useLen(useLen) 246{ 247} 248 249StrcollUTF8_2::~StrcollUTF8_2() 250{ 251} 252 253void StrcollUTF8_2::call(UErrorCode* status) 254{ 255 if (U_FAILURE(*status)) return; 256 257 // call strcoll for two strings at the same index 258 if (source->count < target->count) { 259 *status = U_ILLEGAL_ARGUMENT_ERROR; 260 } else { 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); 265 } 266 } 267} 268 269long StrcollUTF8_2::getOperationsPerIteration() 270{ 271 return source->count; 272} 273 274// 275// Test case taking a single test data array, calling ucol_getSortKey for each 276// 277class GetSortKey : public UPerfFunction 278{ 279public: 280 GetSortKey(const UCollator* coll, const CA_uchar* source, UBool useLen); 281 ~GetSortKey(); 282 virtual void call(UErrorCode* status); 283 virtual long getOperationsPerIteration(); 284 285private: 286 const UCollator *coll; 287 const CA_uchar *source; 288 UBool useLen; 289}; 290 291GetSortKey::GetSortKey(const UCollator* coll, const CA_uchar* source, UBool useLen) 292 : coll(coll), 293 source(source), 294 useLen(useLen) 295{ 296} 297 298GetSortKey::~GetSortKey() 299{ 300} 301 302#define KEY_BUF_SIZE 512 303 304void GetSortKey::call(UErrorCode* status) 305{ 306 if (U_FAILURE(*status)) return; 307 308 uint8_t key[KEY_BUF_SIZE]; 309 int32_t len; 310 311 if (useLen) { 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); 314 } 315 } else { 316 for (int32_t i = 0; i < source->count; i++) { 317 len = ucol_getSortKey(coll, source->dataOf(i), -1, key, KEY_BUF_SIZE); 318 } 319 } 320} 321 322long GetSortKey::getOperationsPerIteration() 323{ 324 return source->count; 325} 326 327// 328// Test case taking a single test data array in UTF-16, calling ucol_nextSortKeyPart for each for the 329// given buffer size 330// 331class NextSortKeyPart : public UPerfFunction 332{ 333public: 334 NextSortKeyPart(const UCollator* coll, const CA_uchar* source, int32_t bufSize, int32_t maxIteration = -1); 335 ~NextSortKeyPart(); 336 virtual void call(UErrorCode* status); 337 virtual long getOperationsPerIteration(); 338 virtual long getEventsPerIteration(); 339 340private: 341 const UCollator *coll; 342 const CA_uchar *source; 343 int32_t bufSize; 344 int32_t maxIteration; 345 long events; 346}; 347 348// Note: maxIteration = -1 -> repeat until the end of collation key 349NextSortKeyPart::NextSortKeyPart(const UCollator* coll, const CA_uchar* source, int32_t bufSize, int32_t maxIteration /* = -1 */) 350 : coll(coll), 351 source(source), 352 bufSize(bufSize), 353 maxIteration(maxIteration), 354 events(0) 355{ 356} 357 358NextSortKeyPart::~NextSortKeyPart() 359{ 360} 361 362void NextSortKeyPart::call(UErrorCode* status) 363{ 364 if (U_FAILURE(*status)) return; 365 366 uint8_t *part = (uint8_t *)malloc(bufSize); 367 uint32_t state[2]; 368 UCharIterator iter; 369 370 events = 0; 371 for (int i = 0; i < source->count && U_SUCCESS(*status); i++) { 372 uiter_setString(&iter, source->dataOf(i), source->lengthOf(i)); 373 state[0] = 0; 374 state[1] = 0; 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); 378 events++; 379 } 380 } 381 free(part); 382} 383 384long NextSortKeyPart::getOperationsPerIteration() 385{ 386 return source->count; 387} 388 389long NextSortKeyPart::getEventsPerIteration() 390{ 391 return events; 392} 393 394// 395// Test case taking a single test data array in UTF-8, calling ucol_nextSortKeyPart for each for the 396// given buffer size 397// 398class NextSortKeyPartUTF8 : public UPerfFunction 399{ 400public: 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(); 406 407private: 408 const UCollator *coll; 409 const CA_char *source; 410 int32_t bufSize; 411 int32_t maxIteration; 412 long events; 413}; 414 415// Note: maxIteration = -1 -> repeat until the end of collation key 416NextSortKeyPartUTF8::NextSortKeyPartUTF8(const UCollator* coll, const CA_char* source, int32_t bufSize, int32_t maxIteration /* = -1 */) 417 : coll(coll), 418 source(source), 419 bufSize(bufSize), 420 maxIteration(maxIteration), 421 events(0) 422{ 423} 424 425NextSortKeyPartUTF8::~NextSortKeyPartUTF8() 426{ 427} 428 429void NextSortKeyPartUTF8::call(UErrorCode* status) 430{ 431 if (U_FAILURE(*status)) return; 432 433 uint8_t *part = (uint8_t *)malloc(bufSize); 434 uint32_t state[2]; 435 UCharIterator iter; 436 437 events = 0; 438 for (int i = 0; i < source->count && U_SUCCESS(*status); i++) { 439 uiter_setUTF8(&iter, source->dataOf(i), source->lengthOf(i)); 440 state[0] = 0; 441 state[1] = 0; 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); 445 events++; 446 } 447 } 448 free(part); 449} 450 451long NextSortKeyPartUTF8::getOperationsPerIteration() 452{ 453 return source->count; 454} 455 456long NextSortKeyPartUTF8::getEventsPerIteration() 457{ 458 return events; 459} 460 461// CPP API test cases 462 463// 464// Test case taking a single test data array, calling Collator::compare by permuting the test data 465// 466class CppCompare : public UPerfFunction 467{ 468public: 469 CppCompare(const Collator* coll, const CA_uchar* source, UBool useLen); 470 ~CppCompare(); 471 virtual void call(UErrorCode* status); 472 virtual long getOperationsPerIteration(); 473 474private: 475 const Collator *coll; 476 const CA_uchar *source; 477 UBool useLen; 478 int32_t maxTestStrings; 479}; 480 481CppCompare::CppCompare(const Collator* coll, const CA_uchar* source, UBool useLen) 482 : coll(coll), 483 source(source), 484 useLen(useLen) 485{ 486 maxTestStrings = source->count > MAX_TEST_STRINGS_FOR_PERMUTING ? MAX_TEST_STRINGS_FOR_PERMUTING : source->count; 487} 488 489CppCompare::~CppCompare() 490{ 491} 492 493void CppCompare::call(UErrorCode* status) { 494 if (U_FAILURE(*status)) return; 495 496 // call compare for permutation of test data 497 int32_t divisor = source->count / maxTestStrings; 498 int32_t srcLen, tgtLen; 499 int32_t cmp = 0; 500 for (int32_t i = 0, numTestStringsI = 0; i < source->count && numTestStringsI < maxTestStrings; i++) { 501 if (i % divisor) continue; 502 numTestStringsI++; 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; 506 numTestStringsJ++; 507 tgtLen = useLen ? source->lengthOf(j) : -1; 508 cmp += coll->compare(source->dataOf(i), srcLen, source->dataOf(j), tgtLen); 509 } 510 } 511 // At the end, cmp must be 0 512 if (cmp != 0) { 513 *status = U_INTERNAL_PROGRAM_ERROR; 514 } 515} 516 517long CppCompare::getOperationsPerIteration() 518{ 519 return maxTestStrings * maxTestStrings; 520} 521 522// 523// Test case taking two test data arrays, calling Collator::compare for strings at a same index 524// 525class CppCompare_2 : public UPerfFunction 526{ 527public: 528 CppCompare_2(const Collator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen); 529 ~CppCompare_2(); 530 virtual void call(UErrorCode* status); 531 virtual long getOperationsPerIteration(); 532 533private: 534 const Collator *coll; 535 const CA_uchar *source; 536 const CA_uchar *target; 537 UBool useLen; 538}; 539 540CppCompare_2::CppCompare_2(const Collator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen) 541 : coll(coll), 542 source(source), 543 target(target), 544 useLen(useLen) 545{ 546} 547 548CppCompare_2::~CppCompare_2() 549{ 550} 551 552void CppCompare_2::call(UErrorCode* status) { 553 if (U_FAILURE(*status)) return; 554 555 // call strcoll for two strings at the same index 556 if (source->count < target->count) { 557 *status = U_ILLEGAL_ARGUMENT_ERROR; 558 } else { 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); 563 } 564 } 565} 566 567long CppCompare_2::getOperationsPerIteration() 568{ 569 return source->count; 570} 571 572 573// 574// Test case taking a single test data array, calling Collator::compareUTF8 by permuting the test data 575// 576class CppCompareUTF8 : public UPerfFunction 577{ 578public: 579 CppCompareUTF8(const Collator* coll, const CA_char* source, UBool useLen); 580 ~CppCompareUTF8(); 581 virtual void call(UErrorCode* status); 582 virtual long getOperationsPerIteration(); 583 584private: 585 const Collator *coll; 586 const CA_char *source; 587 UBool useLen; 588 int32_t maxTestStrings; 589}; 590 591CppCompareUTF8::CppCompareUTF8(const Collator* coll, const CA_char* source, UBool useLen) 592 : coll(coll), 593 source(source), 594 useLen(useLen) 595{ 596 maxTestStrings = source->count > MAX_TEST_STRINGS_FOR_PERMUTING ? MAX_TEST_STRINGS_FOR_PERMUTING : source->count; 597} 598 599CppCompareUTF8::~CppCompareUTF8() 600{ 601} 602 603void CppCompareUTF8::call(UErrorCode* status) { 604 if (U_FAILURE(*status)) return; 605 606 // call compareUTF8 for all permutations 607 int32_t divisor = source->count / maxTestStrings; 608 StringPiece src, tgt; 609 int32_t cmp = 0; 610 for (int32_t i = 0, numTestStringsI = 0; U_SUCCESS(*status) && i < source->count && numTestStringsI < maxTestStrings; i++) { 611 if (i % divisor) continue; 612 numTestStringsI++; 613 614 if (useLen) { 615 src.set(source->dataOf(i), source->lengthOf(i)); 616 } else { 617 src.set(source->dataOf(i)); 618 } 619 for (int32_t j = 0, numTestStringsJ = 0; U_SUCCESS(*status) && j < source->count && numTestStringsJ < maxTestStrings; j++) { 620 if (j % divisor) continue; 621 numTestStringsJ++; 622 623 if (useLen) { 624 tgt.set(source->dataOf(i), source->lengthOf(i)); 625 } else { 626 tgt.set(source->dataOf(i)); 627 } 628 cmp += coll->compareUTF8(src, tgt, *status); 629 } 630 } 631 // At the end, cmp must be 0 632 if (cmp != 0) { 633 *status = U_INTERNAL_PROGRAM_ERROR; 634 } 635} 636 637long CppCompareUTF8::getOperationsPerIteration() 638{ 639 return maxTestStrings * maxTestStrings; 640} 641 642 643// 644// Test case taking two test data arrays, calling Collator::compareUTF8 for strings at a same index 645// 646class CppCompareUTF8_2 : public UPerfFunction 647{ 648public: 649 CppCompareUTF8_2(const Collator* coll, const CA_char* source, const CA_char* target, UBool useLen); 650 ~CppCompareUTF8_2(); 651 virtual void call(UErrorCode* status); 652 virtual long getOperationsPerIteration(); 653 654private: 655 const Collator *coll; 656 const CA_char *source; 657 const CA_char *target; 658 UBool useLen; 659}; 660 661CppCompareUTF8_2::CppCompareUTF8_2(const Collator* coll, const CA_char* source, const CA_char* target, UBool useLen) 662 : coll(coll), 663 source(source), 664 target(target), 665 useLen(useLen) 666{ 667} 668 669CppCompareUTF8_2::~CppCompareUTF8_2() 670{ 671} 672 673void CppCompareUTF8_2::call(UErrorCode* status) { 674 if (U_FAILURE(*status)) return; 675 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; 680 } else { 681 for (int32_t i = 0; U_SUCCESS(*status) && i < source->count; i++) { 682 if (useLen) { 683 src.set(source->dataOf(i), source->lengthOf(i)); 684 tgt.set(target->dataOf(i), target->lengthOf(i)); 685 } else { 686 src.set(source->dataOf(i)); 687 tgt.set(target->dataOf(i)); 688 } 689 coll->compareUTF8(src, tgt, *status); 690 } 691 } 692} 693 694long CppCompareUTF8_2::getOperationsPerIteration() 695{ 696 return source->count; 697} 698 699 700// 701// Test case taking a single test data array, calling Collator::getCollationKey for each 702// 703class CppGetCollationKey : public UPerfFunction 704{ 705public: 706 CppGetCollationKey(const Collator* coll, const CA_uchar* source, UBool useLen); 707 ~CppGetCollationKey(); 708 virtual void call(UErrorCode* status); 709 virtual long getOperationsPerIteration(); 710 711private: 712 const Collator *coll; 713 const CA_uchar *source; 714 UBool useLen; 715}; 716 717CppGetCollationKey::CppGetCollationKey(const Collator* coll, const CA_uchar* source, UBool useLen) 718 : coll(coll), 719 source(source), 720 useLen(useLen) 721{ 722} 723 724CppGetCollationKey::~CppGetCollationKey() 725{ 726} 727 728void CppGetCollationKey::call(UErrorCode* status) 729{ 730 if (U_FAILURE(*status)) return; 731 732 CollationKey key; 733 for (int32_t i = 0; U_SUCCESS(*status) && i < source->count; i++) { 734 coll->getCollationKey(source->dataOf(i), source->lengthOf(i), key, *status); 735 } 736} 737 738long CppGetCollationKey::getOperationsPerIteration() { 739 return source->count; 740} 741 742namespace { 743 744struct 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; 750 int32_t counter; 751}; 752 753int32_t U_CALLCONV 754UniStrCollatorComparator(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; 759 ++cc.counter; 760 return cc.coll.compare(leftString, rightString, errorCode); 761} 762 763} // namespace 764 765class CollPerfFunction : public UPerfFunction { 766public: 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(); 772 773protected: 774 const Collator& coll; 775 const UCollator *ucoll; 776 int32_t ops; 777}; 778 779CollPerfFunction::~CollPerfFunction() {} 780 781long CollPerfFunction::getOperationsPerIteration() { 782 UErrorCode errorCode = U_ZERO_ERROR; 783 call(&errorCode); 784 return U_SUCCESS(errorCode) ? ops : 0; 785} 786 787class UniStrCollPerfFunction : public CollPerfFunction { 788public: 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)); 794 } 795 } 796 virtual ~UniStrCollPerfFunction(); 797 798protected: 799 const CA_uchar* d16; 800 UnicodeString** source; 801}; 802 803UniStrCollPerfFunction::~UniStrCollPerfFunction() { 804 for (int32_t i = 0; i < d16->count; ++i) { 805 delete source[i]; 806 } 807 delete[] source; 808} 809 810// 811// Test case sorting an array of UnicodeString pointers. 812// 813class UniStrSort : public UniStrCollPerfFunction { 814public: 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); 820 821private: 822 UnicodeString** dest; // aliases only 823}; 824 825UniStrSort::~UniStrSort() { 826 delete[] dest; 827} 828 829void UniStrSort::call(UErrorCode* status) { 830 if (U_FAILURE(*status)) return; 831 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); 837 ops = cc.counter; 838} 839 840namespace { 841 842int32_t U_CALLCONV 843StringPieceCollatorComparator(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; 848 ++cc.counter; 849 return cc.coll.compareUTF8(leftString, rightString, errorCode); 850} 851 852int32_t U_CALLCONV 853StringPieceUCollatorComparator(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; 858 ++cc.counter; 859 return ucol_strcollUTF8(cc.ucoll, 860 leftString.data(), leftString.length(), 861 rightString.data(), rightString.length(), &errorCode); 862} 863 864} // namespace 865 866class StringPieceCollPerfFunction : public CollPerfFunction { 867public: 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)); 873 } 874 } 875 virtual ~StringPieceCollPerfFunction(); 876 877protected: 878 const CA_char* d8; 879 StringPiece* source; 880}; 881 882StringPieceCollPerfFunction::~StringPieceCollPerfFunction() { 883 delete[] source; 884} 885 886class StringPieceSort : public StringPieceCollPerfFunction { 887public: 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(); 892 893protected: 894 StringPiece* dest; 895}; 896 897StringPieceSort::~StringPieceSort() { 898 delete[] dest; 899} 900 901// 902// Test case sorting an array of UTF-8 StringPiece's with Collator::compareUTF8(). 903// 904class StringPieceSortCpp : public StringPieceSort { 905public: 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); 910}; 911 912StringPieceSortCpp::~StringPieceSortCpp() {} 913 914void StringPieceSortCpp::call(UErrorCode* status) { 915 if (U_FAILURE(*status)) return; 916 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); 922 ops = cc.counter; 923} 924 925// 926// Test case sorting an array of UTF-8 StringPiece's with ucol_strcollUTF8(). 927// 928class StringPieceSortC : public StringPieceSort { 929public: 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); 934}; 935 936StringPieceSortC::~StringPieceSortC() {} 937 938void StringPieceSortC::call(UErrorCode* status) { 939 if (U_FAILURE(*status)) return; 940 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); 946 ops = cc.counter; 947} 948 949// 950// Test case performing binary searches in a sorted array of UnicodeString pointers. 951// 952class UniStrBinSearch : public UniStrCollPerfFunction { 953public: 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); 958}; 959 960UniStrBinSearch::~UniStrBinSearch() {} 961 962void UniStrBinSearch::call(UErrorCode* status) { 963 if (U_FAILURE(*status)) return; 964 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); 971 } 972 ops = cc.counter; 973} 974 975class StringPieceBinSearch : public StringPieceCollPerfFunction { 976public: 977 StringPieceBinSearch(const Collator& coll, const UCollator *ucoll, const CA_char* data8) 978 : StringPieceCollPerfFunction(coll, ucoll, data8) {} 979 virtual ~StringPieceBinSearch(); 980}; 981 982StringPieceBinSearch::~StringPieceBinSearch() {} 983 984// 985// Test case performing binary searches in a sorted array of UTF-8 StringPiece's 986// with Collator::compareUTF8(). 987// 988class StringPieceBinSearchCpp : public StringPieceBinSearch { 989public: 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); 994}; 995 996StringPieceBinSearchCpp::~StringPieceBinSearchCpp() {} 997 998void StringPieceBinSearchCpp::call(UErrorCode* status) { 999 if (U_FAILURE(*status)) return; 1000 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); 1007 } 1008 ops = cc.counter; 1009} 1010 1011// 1012// Test case performing binary searches in a sorted array of UTF-8 StringPiece's 1013// with ucol_strcollUTF8(). 1014// 1015class StringPieceBinSearchC : public StringPieceBinSearch { 1016public: 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); 1021}; 1022 1023StringPieceBinSearchC::~StringPieceBinSearchC() {} 1024 1025void StringPieceBinSearchC::call(UErrorCode* status) { 1026 if (U_FAILURE(*status)) return; 1027 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); 1034 } 1035 ops = cc.counter; 1036} 1037 1038 1039class CollPerf2Test : public UPerfTest 1040{ 1041public: 1042 CollPerf2Test(int32_t argc, const char *argv[], UErrorCode &status); 1043 ~CollPerf2Test(); 1044 virtual UPerfFunction* runIndexedTest( 1045 int32_t index, UBool exec, const char *&name, char *par = NULL); 1046 1047private: 1048 UCollator* coll; 1049 Collator* collObj; 1050 1051 int32_t count; 1052 CA_uchar* data16; 1053 CA_char* data8; 1054 1055 CA_uchar* modData16; 1056 CA_char* modData8; 1057 1058 CA_uchar* sortedData16; 1059 CA_char* sortedData8; 1060 1061 CA_uchar* randomData16; 1062 CA_char* randomData8; 1063 1064 const CA_uchar* getData16(UErrorCode &status); 1065 const CA_char* getData8(UErrorCode &status); 1066 1067 const CA_uchar* getModData16(UErrorCode &status); 1068 const CA_char* getModData8(UErrorCode &status); 1069 1070 const CA_uchar* getSortedData16(UErrorCode &status); 1071 const CA_char* getSortedData8(UErrorCode &status); 1072 1073 const CA_uchar* getRandomData16(UErrorCode &status); 1074 const CA_char* getRandomData8(UErrorCode &status); 1075 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); 1081 1082 UPerfFunction* TestStrcoll(); 1083 UPerfFunction* TestStrcollNull(); 1084 UPerfFunction* TestStrcollSimilar(); 1085 1086 UPerfFunction* TestStrcollUTF8(); 1087 UPerfFunction* TestStrcollUTF8Null(); 1088 UPerfFunction* TestStrcollUTF8Similar(); 1089 1090 UPerfFunction* TestGetSortKey(); 1091 UPerfFunction* TestGetSortKeyNull(); 1092 1093 UPerfFunction* TestNextSortKeyPart_4All(); 1094 UPerfFunction* TestNextSortKeyPart_4x2(); 1095 UPerfFunction* TestNextSortKeyPart_4x4(); 1096 UPerfFunction* TestNextSortKeyPart_4x8(); 1097 UPerfFunction* TestNextSortKeyPart_32All(); 1098 UPerfFunction* TestNextSortKeyPart_32x2(); 1099 1100 UPerfFunction* TestNextSortKeyPartUTF8_4All(); 1101 UPerfFunction* TestNextSortKeyPartUTF8_4x2(); 1102 UPerfFunction* TestNextSortKeyPartUTF8_4x4(); 1103 UPerfFunction* TestNextSortKeyPartUTF8_4x8(); 1104 UPerfFunction* TestNextSortKeyPartUTF8_32All(); 1105 UPerfFunction* TestNextSortKeyPartUTF8_32x2(); 1106 1107 UPerfFunction* TestCppCompare(); 1108 UPerfFunction* TestCppCompareNull(); 1109 UPerfFunction* TestCppCompareSimilar(); 1110 1111 UPerfFunction* TestCppCompareUTF8(); 1112 UPerfFunction* TestCppCompareUTF8Null(); 1113 UPerfFunction* TestCppCompareUTF8Similar(); 1114 1115 UPerfFunction* TestCppGetCollationKey(); 1116 UPerfFunction* TestCppGetCollationKeyNull(); 1117 1118 UPerfFunction* TestUniStrSort(); 1119 UPerfFunction* TestStringPieceSortCpp(); 1120 UPerfFunction* TestStringPieceSortC(); 1121 1122 UPerfFunction* TestUniStrBinSearch(); 1123 UPerfFunction* TestStringPieceBinSearchCpp(); 1124 UPerfFunction* TestStringPieceBinSearchC(); 1125}; 1126 1127CollPerf2Test::CollPerf2Test(int32_t argc, const char *argv[], UErrorCode &status) : 1128 UPerfTest(argc, argv, status), 1129 coll(NULL), 1130 collObj(NULL), 1131 count(0), 1132 data16(NULL), 1133 data8(NULL), 1134 modData16(NULL), 1135 modData8(NULL), 1136 sortedData16(NULL), 1137 sortedData8(NULL), 1138 randomData16(NULL), 1139 randomData8(NULL) 1140{ 1141 if (U_FAILURE(status)) { 1142 return; 1143 } 1144 1145 if (locale == NULL){ 1146 locale = "root"; 1147 } 1148 1149 // Set up an ICU collator. 1150 // Starting with ICU 54 (ticket #8260), this supports standard collation locale keywords. 1151 coll = ucol_open(locale, &status); 1152 collObj = Collator::createInstance(locale, status); 1153} 1154 1155CollPerf2Test::~CollPerf2Test() 1156{ 1157 ucol_close(coll); 1158 delete collObj; 1159 1160 delete data16; 1161 delete data8; 1162 delete modData16; 1163 delete modData8; 1164 delete sortedData16; 1165 delete sortedData8; 1166 delete randomData16; 1167 delete randomData8; 1168} 1169 1170#define MAX_NUM_DATA 10000 1171 1172const CA_uchar* CollPerf2Test::getData16(UErrorCode &status) 1173{ 1174 if (U_FAILURE(status)) return NULL; 1175 if (data16) return data16; 1176 1177 CA_uchar* d16 = new CA_uchar(); 1178 const UChar *line = NULL; 1179 int32_t len = 0; 1180 int32_t numData = 0; 1181 1182 for (;;) { 1183 line = ucbuf_readline(ucharBuf, &len, &status); 1184 if (line == NULL || U_FAILURE(status)) break; 1185 1186 // Refer to the source code of ucbuf_readline() 1187 // 1. 'len' includes the line terminal symbols 1188 // 2. The length of the line terminal symbols is only one character 1189 // 3. The Windows CR LF line terminal symbols will be converted to CR 1190 1191 if (len == 1 || line[0] == 0x23 /* '#' */) { 1192 continue; // skip empty/comment line 1193 } else { 1194 d16->append_one(len); 1195 UChar *p = d16->last(); 1196 u_memcpy(p, line, len - 1); // exclude the CR 1197 p[len - 1] = 0; // NUL-terminate 1198 1199 numData++; 1200 if (numData >= MAX_NUM_DATA) break; 1201 } 1202 } 1203 1204 if (U_SUCCESS(status)) { 1205 data16 = d16; 1206 } else { 1207 delete d16; 1208 } 1209 1210 return data16; 1211} 1212 1213const CA_char* CollPerf2Test::getData8(UErrorCode &status) 1214{ 1215 if (U_FAILURE(status)) return NULL; 1216 if (data8) return data8; 1217 return data8 = getData8FromData16(getData16(status), status); 1218} 1219 1220const CA_uchar* CollPerf2Test::getModData16(UErrorCode &status) 1221{ 1222 if (U_FAILURE(status)) return NULL; 1223 if (modData16) return modData16; 1224 1225 const CA_uchar* d16 = getData16(status); 1226 if (U_FAILURE(status)) return NULL; 1227 1228 CA_uchar* modData16 = new CA_uchar(); 1229 1230 for (int32_t i = 0; i < d16->count; i++) { 1231 const UChar *s = d16->dataOf(i); 1232 int32_t len = d16->lengthOf(i) + 1; // including NULL terminator 1233 1234 modData16->append_one(len); 1235 u_memcpy(modData16->last(), s, len); 1236 1237 // replacing the last character with a different character 1238 UChar *lastChar = &modData16->last()[len -2]; 1239 for (int32_t j = i + 1; j != i; j++) { 1240 if (j >= d16->count) { 1241 j = 0; 1242 } 1243 const UChar *s1 = d16->dataOf(j); 1244 UChar lastChar1 = s1[d16->lengthOf(j) - 1]; 1245 if (*lastChar != lastChar1) { 1246 *lastChar = lastChar1; 1247 break; 1248 } 1249 } 1250 } 1251 1252 return modData16; 1253} 1254 1255const CA_char* CollPerf2Test::getModData8(UErrorCode &status) 1256{ 1257 if (U_FAILURE(status)) return NULL; 1258 if (modData8) return modData8; 1259 return modData8 = getData8FromData16(getModData16(status), status); 1260} 1261 1262namespace { 1263 1264struct ArrayAndColl { 1265 ArrayAndColl(const CA_uchar* a, const Collator& c) : d16(a), coll(c) {} 1266 const CA_uchar* d16; 1267 const Collator& coll; 1268}; 1269 1270int32_t U_CALLCONV 1271U16CollatorComparator(const void* context, const void* left, const void* right) { 1272 const ArrayAndColl& ac = *(const ArrayAndColl*)context; 1273 const CA_uchar* d16 = ac.d16; 1274 int32_t leftIndex = *(const int32_t*)left; 1275 int32_t rightIndex = *(const int32_t*)right; 1276 UErrorCode errorCode = U_ZERO_ERROR; 1277 return ac.coll.compare(d16->dataOf(leftIndex), d16->lengthOf(leftIndex), 1278 d16->dataOf(rightIndex), d16->lengthOf(rightIndex), 1279 errorCode); 1280} 1281 1282int32_t U_CALLCONV 1283U16HashComparator(const void* context, const void* left, const void* right) { 1284 const CA_uchar* d16 = (const CA_uchar*)context; 1285 int32_t leftIndex = *(const int32_t*)left; 1286 int32_t rightIndex = *(const int32_t*)right; 1287 int32_t leftHash = ustr_hashUCharsN(d16->dataOf(leftIndex), d16->lengthOf(leftIndex)); 1288 int32_t rightHash = ustr_hashUCharsN(d16->dataOf(rightIndex), d16->lengthOf(rightIndex)); 1289 return leftHash < rightHash ? -1 : leftHash == rightHash ? 0 : 1; 1290} 1291 1292} // namespace 1293 1294const CA_uchar* CollPerf2Test::getSortedData16(UErrorCode &status) { 1295 if (U_FAILURE(status)) return NULL; 1296 if (sortedData16) return sortedData16; 1297 1298 ArrayAndColl ac(getData16(status), *collObj); 1299 return sortedData16 = sortData16(ac.d16, U16CollatorComparator, &ac, status); 1300} 1301 1302const CA_char* CollPerf2Test::getSortedData8(UErrorCode &status) { 1303 if (U_FAILURE(status)) return NULL; 1304 if (sortedData8) return sortedData8; 1305 return sortedData8 = getData8FromData16(getSortedData16(status), status); 1306} 1307 1308const CA_uchar* CollPerf2Test::getRandomData16(UErrorCode &status) { 1309 if (U_FAILURE(status)) return NULL; 1310 if (randomData16) return randomData16; 1311 1312 // Sort the strings by their hash codes, which should be a reasonably pseudo-random order. 1313 const CA_uchar* d16 = getData16(status); 1314 return randomData16 = sortData16(d16, U16HashComparator, d16, status); 1315} 1316 1317const CA_char* CollPerf2Test::getRandomData8(UErrorCode &status) { 1318 if (U_FAILURE(status)) return NULL; 1319 if (randomData8) return randomData8; 1320 return randomData8 = getData8FromData16(getRandomData16(status), status); 1321} 1322 1323CA_uchar* CollPerf2Test::sortData16(const CA_uchar* d16, 1324 UComparator *cmp, const void *context, 1325 UErrorCode &status) { 1326 if (U_FAILURE(status)) return NULL; 1327 1328 LocalArray<int32_t> indexes(new int32_t[d16->count]); 1329 for (int32_t i = 0; i < d16->count; ++i) { 1330 indexes[i] = i; 1331 } 1332 uprv_sortArray(indexes.getAlias(), d16->count, 4, cmp, context, TRUE, &status); 1333 if (U_FAILURE(status)) return NULL; 1334 1335 // Copy the strings in sorted order into a new array. 1336 LocalPointer<CA_uchar> newD16(new CA_uchar()); 1337 for (int32_t i = 0; i < d16->count; i++) { 1338 int32_t j = indexes[i]; 1339 const UChar* s = d16->dataOf(j); 1340 int32_t len = d16->lengthOf(j); 1341 int32_t capacity = len + 1; // including NULL terminator 1342 newD16->append_one(capacity); 1343 u_memcpy(newD16->last(), s, capacity); 1344 } 1345 1346 if (U_SUCCESS(status)) { 1347 return newD16.orphan(); 1348 } else { 1349 return NULL; 1350 } 1351} 1352 1353CA_char* CollPerf2Test::getData8FromData16(const CA_uchar* d16, UErrorCode &status) { 1354 if (U_FAILURE(status)) return NULL; 1355 1356 // UTF-16 -> UTF-8 conversion 1357 LocalPointer<CA_char> d8(new CA_char()); 1358 for (int32_t i = 0; i < d16->count; i++) { 1359 const UChar *s16 = d16->dataOf(i); 1360 int32_t length16 = d16->lengthOf(i); 1361 1362 // get length in UTF-8 1363 int32_t length8; 1364 u_strToUTF8(NULL, 0, &length8, s16, length16, &status); 1365 if (status == U_BUFFER_OVERFLOW_ERROR || status == U_ZERO_ERROR){ 1366 status = U_ZERO_ERROR; 1367 } else { 1368 break; 1369 } 1370 int32_t capacity8 = length8 + 1; // plus terminal NULL 1371 d8->append_one(capacity8); 1372 1373 // convert to UTF-8 1374 u_strToUTF8(d8->last(), capacity8, NULL, s16, length16, &status); 1375 if (U_FAILURE(status)) break; 1376 } 1377 1378 if (U_SUCCESS(status)) { 1379 return d8.orphan(); 1380 } else { 1381 return NULL; 1382 } 1383} 1384 1385UPerfFunction* 1386CollPerf2Test::runIndexedTest(int32_t index, UBool exec, const char *&name, char *par /*= NULL*/) 1387{ 1388 (void)par; 1389 TESTCASE_AUTO_BEGIN; 1390 1391 TESTCASE_AUTO(TestStrcoll); 1392 TESTCASE_AUTO(TestStrcollNull); 1393 TESTCASE_AUTO(TestStrcollSimilar); 1394 1395 TESTCASE_AUTO(TestStrcollUTF8); 1396 TESTCASE_AUTO(TestStrcollUTF8Null); 1397 TESTCASE_AUTO(TestStrcollUTF8Similar); 1398 1399 TESTCASE_AUTO(TestGetSortKey); 1400 TESTCASE_AUTO(TestGetSortKeyNull); 1401 1402 TESTCASE_AUTO(TestNextSortKeyPart_4All); 1403 TESTCASE_AUTO(TestNextSortKeyPart_4x4); 1404 TESTCASE_AUTO(TestNextSortKeyPart_4x8); 1405 TESTCASE_AUTO(TestNextSortKeyPart_32All); 1406 TESTCASE_AUTO(TestNextSortKeyPart_32x2); 1407 1408 TESTCASE_AUTO(TestNextSortKeyPartUTF8_4All); 1409 TESTCASE_AUTO(TestNextSortKeyPartUTF8_4x4); 1410 TESTCASE_AUTO(TestNextSortKeyPartUTF8_4x8); 1411 TESTCASE_AUTO(TestNextSortKeyPartUTF8_32All); 1412 TESTCASE_AUTO(TestNextSortKeyPartUTF8_32x2); 1413 1414 TESTCASE_AUTO(TestCppCompare); 1415 TESTCASE_AUTO(TestCppCompareNull); 1416 TESTCASE_AUTO(TestCppCompareSimilar); 1417 1418 TESTCASE_AUTO(TestCppCompareUTF8); 1419 TESTCASE_AUTO(TestCppCompareUTF8Null); 1420 TESTCASE_AUTO(TestCppCompareUTF8Similar); 1421 1422 TESTCASE_AUTO(TestCppGetCollationKey); 1423 TESTCASE_AUTO(TestCppGetCollationKeyNull); 1424 1425 TESTCASE_AUTO(TestUniStrSort); 1426 TESTCASE_AUTO(TestStringPieceSortCpp); 1427 TESTCASE_AUTO(TestStringPieceSortC); 1428 1429 TESTCASE_AUTO(TestUniStrBinSearch); 1430 TESTCASE_AUTO(TestStringPieceBinSearchCpp); 1431 TESTCASE_AUTO(TestStringPieceBinSearchC); 1432 1433 TESTCASE_AUTO_END; 1434 return NULL; 1435} 1436 1437 1438 1439UPerfFunction* CollPerf2Test::TestStrcoll() 1440{ 1441 UErrorCode status = U_ZERO_ERROR; 1442 Strcoll *testCase = new Strcoll(coll, getData16(status), TRUE /* useLen */); 1443 if (U_FAILURE(status)) { 1444 delete testCase; 1445 return NULL; 1446 } 1447 return testCase; 1448} 1449 1450UPerfFunction* CollPerf2Test::TestStrcollNull() 1451{ 1452 UErrorCode status = U_ZERO_ERROR; 1453 Strcoll *testCase = new Strcoll(coll, getData16(status), FALSE /* useLen */); 1454 if (U_FAILURE(status)) { 1455 delete testCase; 1456 return NULL; 1457 } 1458 return testCase; 1459} 1460 1461UPerfFunction* CollPerf2Test::TestStrcollSimilar() 1462{ 1463 UErrorCode status = U_ZERO_ERROR; 1464 Strcoll_2 *testCase = new Strcoll_2(coll, getData16(status), getModData16(status), TRUE /* useLen */); 1465 if (U_FAILURE(status)) { 1466 delete testCase; 1467 return NULL; 1468 } 1469 return testCase; 1470} 1471 1472UPerfFunction* CollPerf2Test::TestStrcollUTF8() 1473{ 1474 UErrorCode status = U_ZERO_ERROR; 1475 StrcollUTF8 *testCase = new StrcollUTF8(coll, getData8(status), TRUE /* useLen */); 1476 if (U_FAILURE(status)) { 1477 delete testCase; 1478 return NULL; 1479 } 1480 return testCase; 1481} 1482 1483UPerfFunction* CollPerf2Test::TestStrcollUTF8Null() 1484{ 1485 UErrorCode status = U_ZERO_ERROR; 1486 StrcollUTF8 *testCase = new StrcollUTF8(coll, getData8(status),FALSE /* useLen */); 1487 if (U_FAILURE(status)) { 1488 delete testCase; 1489 return NULL; 1490 } 1491 return testCase; 1492} 1493 1494UPerfFunction* CollPerf2Test::TestStrcollUTF8Similar() 1495{ 1496 UErrorCode status = U_ZERO_ERROR; 1497 StrcollUTF8_2 *testCase = new StrcollUTF8_2(coll, getData8(status), getModData8(status), TRUE /* useLen */); 1498 if (U_FAILURE(status)) { 1499 delete testCase; 1500 return NULL; 1501 } 1502 return testCase; 1503} 1504 1505UPerfFunction* CollPerf2Test::TestGetSortKey() 1506{ 1507 UErrorCode status = U_ZERO_ERROR; 1508 GetSortKey *testCase = new GetSortKey(coll, getData16(status), TRUE /* useLen */); 1509 if (U_FAILURE(status)) { 1510 delete testCase; 1511 return NULL; 1512 } 1513 return testCase; 1514} 1515 1516UPerfFunction* CollPerf2Test::TestGetSortKeyNull() 1517{ 1518 UErrorCode status = U_ZERO_ERROR; 1519 GetSortKey *testCase = new GetSortKey(coll, getData16(status), FALSE /* useLen */); 1520 if (U_FAILURE(status)) { 1521 delete testCase; 1522 return NULL; 1523 } 1524 return testCase; 1525} 1526 1527UPerfFunction* CollPerf2Test::TestNextSortKeyPart_4All() 1528{ 1529 UErrorCode status = U_ZERO_ERROR; 1530 NextSortKeyPart *testCase = new NextSortKeyPart(coll, getData16(status), 4 /* bufSize */); 1531 if (U_FAILURE(status)) { 1532 delete testCase; 1533 return NULL; 1534 } 1535 return testCase; 1536} 1537 1538UPerfFunction* CollPerf2Test::TestNextSortKeyPart_4x4() 1539{ 1540 UErrorCode status = U_ZERO_ERROR; 1541 NextSortKeyPart *testCase = new NextSortKeyPart(coll, getData16(status), 4 /* bufSize */, 4 /* maxIteration */); 1542 if (U_FAILURE(status)) { 1543 delete testCase; 1544 return NULL; 1545 } 1546 return testCase; 1547} 1548 1549UPerfFunction* CollPerf2Test::TestNextSortKeyPart_4x8() 1550{ 1551 UErrorCode status = U_ZERO_ERROR; 1552 NextSortKeyPart *testCase = new NextSortKeyPart(coll, getData16(status), 4 /* bufSize */, 8 /* maxIteration */); 1553 if (U_FAILURE(status)) { 1554 delete testCase; 1555 return NULL; 1556 } 1557 return testCase; 1558} 1559 1560UPerfFunction* CollPerf2Test::TestNextSortKeyPart_32All() 1561{ 1562 UErrorCode status = U_ZERO_ERROR; 1563 NextSortKeyPart *testCase = new NextSortKeyPart(coll, getData16(status), 32 /* bufSize */); 1564 if (U_FAILURE(status)) { 1565 delete testCase; 1566 return NULL; 1567 } 1568 return testCase; 1569} 1570 1571UPerfFunction* CollPerf2Test::TestNextSortKeyPart_32x2() 1572{ 1573 UErrorCode status = U_ZERO_ERROR; 1574 NextSortKeyPart *testCase = new NextSortKeyPart(coll, getData16(status), 32 /* bufSize */, 2 /* maxIteration */); 1575 if (U_FAILURE(status)) { 1576 delete testCase; 1577 return NULL; 1578 } 1579 return testCase; 1580} 1581 1582UPerfFunction* CollPerf2Test::TestNextSortKeyPartUTF8_4All() 1583{ 1584 UErrorCode status = U_ZERO_ERROR; 1585 NextSortKeyPartUTF8 *testCase = new NextSortKeyPartUTF8(coll, getData8(status), 4 /* bufSize */); 1586 if (U_FAILURE(status)) { 1587 delete testCase; 1588 return NULL; 1589 } 1590 return testCase; 1591} 1592 1593UPerfFunction* CollPerf2Test::TestNextSortKeyPartUTF8_4x4() 1594{ 1595 UErrorCode status = U_ZERO_ERROR; 1596 NextSortKeyPartUTF8 *testCase = new NextSortKeyPartUTF8(coll, getData8(status), 4 /* bufSize */, 4 /* maxIteration */); 1597 if (U_FAILURE(status)) { 1598 delete testCase; 1599 return NULL; 1600 } 1601 return testCase; 1602} 1603 1604UPerfFunction* CollPerf2Test::TestNextSortKeyPartUTF8_4x8() 1605{ 1606 UErrorCode status = U_ZERO_ERROR; 1607 NextSortKeyPartUTF8 *testCase = new NextSortKeyPartUTF8(coll, getData8(status), 4 /* bufSize */, 8 /* maxIteration */); 1608 if (U_FAILURE(status)) { 1609 delete testCase; 1610 return NULL; 1611 } 1612 return testCase; 1613} 1614 1615UPerfFunction* CollPerf2Test::TestNextSortKeyPartUTF8_32All() 1616{ 1617 UErrorCode status = U_ZERO_ERROR; 1618 NextSortKeyPartUTF8 *testCase = new NextSortKeyPartUTF8(coll, getData8(status), 32 /* bufSize */); 1619 if (U_FAILURE(status)) { 1620 delete testCase; 1621 return NULL; 1622 } 1623 return testCase; 1624} 1625 1626UPerfFunction* CollPerf2Test::TestNextSortKeyPartUTF8_32x2() 1627{ 1628 UErrorCode status = U_ZERO_ERROR; 1629 NextSortKeyPartUTF8 *testCase = new NextSortKeyPartUTF8(coll, getData8(status), 32 /* bufSize */, 2 /* maxIteration */); 1630 if (U_FAILURE(status)) { 1631 delete testCase; 1632 return NULL; 1633 } 1634 return testCase; 1635} 1636 1637UPerfFunction* CollPerf2Test::TestCppCompare() 1638{ 1639 UErrorCode status = U_ZERO_ERROR; 1640 CppCompare *testCase = new CppCompare(collObj, getData16(status), TRUE /* useLen */); 1641 if (U_FAILURE(status)) { 1642 delete testCase; 1643 return NULL; 1644 } 1645 return testCase; 1646} 1647 1648UPerfFunction* CollPerf2Test::TestCppCompareNull() 1649{ 1650 UErrorCode status = U_ZERO_ERROR; 1651 CppCompare *testCase = new CppCompare(collObj, getData16(status), FALSE /* useLen */); 1652 if (U_FAILURE(status)) { 1653 delete testCase; 1654 return NULL; 1655 } 1656 return testCase; 1657} 1658 1659UPerfFunction* CollPerf2Test::TestCppCompareSimilar() 1660{ 1661 UErrorCode status = U_ZERO_ERROR; 1662 CppCompare_2 *testCase = new CppCompare_2(collObj, getData16(status), getModData16(status), TRUE /* useLen */); 1663 if (U_FAILURE(status)) { 1664 delete testCase; 1665 return NULL; 1666 } 1667 return testCase; 1668} 1669 1670UPerfFunction* CollPerf2Test::TestCppCompareUTF8() 1671{ 1672 UErrorCode status = U_ZERO_ERROR; 1673 CppCompareUTF8 *testCase = new CppCompareUTF8(collObj, getData8(status), TRUE /* useLen */); 1674 if (U_FAILURE(status)) { 1675 delete testCase; 1676 return NULL; 1677 } 1678 return testCase; 1679} 1680 1681UPerfFunction* CollPerf2Test::TestCppCompareUTF8Null() 1682{ 1683 UErrorCode status = U_ZERO_ERROR; 1684 CppCompareUTF8 *testCase = new CppCompareUTF8(collObj, getData8(status), FALSE /* useLen */); 1685 if (U_FAILURE(status)) { 1686 delete testCase; 1687 return NULL; 1688 } 1689 return testCase; 1690} 1691 1692UPerfFunction* CollPerf2Test::TestCppCompareUTF8Similar() 1693{ 1694 UErrorCode status = U_ZERO_ERROR; 1695 CppCompareUTF8_2 *testCase = new CppCompareUTF8_2(collObj, getData8(status), getModData8(status), TRUE /* useLen */); 1696 if (U_FAILURE(status)) { 1697 delete testCase; 1698 return NULL; 1699 } 1700 return testCase; 1701} 1702 1703UPerfFunction* CollPerf2Test::TestCppGetCollationKey() 1704{ 1705 UErrorCode status = U_ZERO_ERROR; 1706 CppGetCollationKey *testCase = new CppGetCollationKey(collObj, getData16(status), TRUE /* useLen */); 1707 if (U_FAILURE(status)) { 1708 delete testCase; 1709 return NULL; 1710 } 1711 return testCase; 1712} 1713 1714UPerfFunction* CollPerf2Test::TestCppGetCollationKeyNull() 1715{ 1716 UErrorCode status = U_ZERO_ERROR; 1717 CppGetCollationKey *testCase = new CppGetCollationKey(collObj, getData16(status), FALSE /* useLen */); 1718 if (U_FAILURE(status)) { 1719 delete testCase; 1720 return NULL; 1721 } 1722 return testCase; 1723} 1724 1725UPerfFunction* CollPerf2Test::TestUniStrSort() { 1726 UErrorCode status = U_ZERO_ERROR; 1727 UPerfFunction *testCase = new UniStrSort(*collObj, coll, getRandomData16(status)); 1728 if (U_FAILURE(status)) { 1729 delete testCase; 1730 return NULL; 1731 } 1732 return testCase; 1733} 1734 1735UPerfFunction* CollPerf2Test::TestStringPieceSortCpp() { 1736 UErrorCode status = U_ZERO_ERROR; 1737 UPerfFunction *testCase = new StringPieceSortCpp(*collObj, coll, getRandomData8(status)); 1738 if (U_FAILURE(status)) { 1739 delete testCase; 1740 return NULL; 1741 } 1742 return testCase; 1743} 1744 1745UPerfFunction* CollPerf2Test::TestStringPieceSortC() { 1746 UErrorCode status = U_ZERO_ERROR; 1747 UPerfFunction *testCase = new StringPieceSortC(*collObj, coll, getRandomData8(status)); 1748 if (U_FAILURE(status)) { 1749 delete testCase; 1750 return NULL; 1751 } 1752 return testCase; 1753} 1754 1755UPerfFunction* CollPerf2Test::TestUniStrBinSearch() { 1756 UErrorCode status = U_ZERO_ERROR; 1757 UPerfFunction *testCase = new UniStrBinSearch(*collObj, coll, getSortedData16(status)); 1758 if (U_FAILURE(status)) { 1759 delete testCase; 1760 return NULL; 1761 } 1762 return testCase; 1763} 1764 1765UPerfFunction* CollPerf2Test::TestStringPieceBinSearchCpp() { 1766 UErrorCode status = U_ZERO_ERROR; 1767 UPerfFunction *testCase = new StringPieceBinSearchCpp(*collObj, coll, getSortedData8(status)); 1768 if (U_FAILURE(status)) { 1769 delete testCase; 1770 return NULL; 1771 } 1772 return testCase; 1773} 1774 1775UPerfFunction* CollPerf2Test::TestStringPieceBinSearchC() { 1776 UErrorCode status = U_ZERO_ERROR; 1777 UPerfFunction *testCase = new StringPieceBinSearchC(*collObj, coll, getSortedData8(status)); 1778 if (U_FAILURE(status)) { 1779 delete testCase; 1780 return NULL; 1781 } 1782 return testCase; 1783} 1784 1785 1786int main(int argc, const char *argv[]) 1787{ 1788 UErrorCode status = U_ZERO_ERROR; 1789 CollPerf2Test test(argc, argv, status); 1790 1791 if (U_FAILURE(status)){ 1792 printf("The error is %s\n", u_errorName(status)); 1793 //TODO: print usage here 1794 return status; 1795 } 1796 1797 if (test.run() == FALSE){ 1798 fprintf(stderr, "FAILED: Tests could not be run please check the arguments.\n"); 1799 return -1; 1800 } 1801 return 0; 1802} 1803