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