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) \ 21 struct CompactArrays{\ 22 CompactArrays(const CompactArrays & );\ 23 CompactArrays & operator=(const CompactArrays & );\ 24 int32_t count;/*total number of the strings*/ \ 25 int32_t * index;/*relative offset in data*/ \ 26 UNIT * data; /*the real space to hold strings*/ \ 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 44 COMPACT_ARRAY(CA_uchar, UChar) 45 COMPACT_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 // 54 class Strcoll : public UPerfFunction 55 { 56 public: 57 Strcoll(const UCollator* coll, const CA_uchar* source, UBool useLen); 58 ~Strcoll(); 59 virtual void call(UErrorCode* status); 60 virtual long getOperationsPerIteration(); 61 62 private: 63 const UCollator *coll; 64 const CA_uchar *source; 65 UBool useLen; 66 int32_t maxTestStrings; 67 }; 68 69 Strcoll::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 77 Strcoll::~Strcoll() 78 { 79 } 80 81 void 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 106 long 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 // 114 class Strcoll_2 : public UPerfFunction 115 { 116 public: 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 122 private: 123 const UCollator *coll; 124 const CA_uchar *source; 125 const CA_uchar *target; 126 UBool useLen; 127 }; 128 129 Strcoll_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 137 Strcoll_2::~Strcoll_2() 138 { 139 } 140 141 void 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 157 long 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 // 166 class StrcollUTF8 : public UPerfFunction 167 { 168 public: 169 StrcollUTF8(const UCollator* coll, const CA_char* source, UBool useLen); 170 ~StrcollUTF8(); 171 virtual void call(UErrorCode* status); 172 virtual long getOperationsPerIteration(); 173 174 private: 175 const UCollator *coll; 176 const CA_char *source; 177 UBool useLen; 178 int32_t maxTestStrings; 179 }; 180 181 StrcollUTF8::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 189 StrcollUTF8::~StrcollUTF8() 190 { 191 } 192 193 void 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 218 long 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 // 226 class StrcollUTF8_2 : public UPerfFunction 227 { 228 public: 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 234 private: 235 const UCollator *coll; 236 const CA_char *source; 237 const CA_char *target; 238 UBool useLen; 239 }; 240 241 StrcollUTF8_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 249 StrcollUTF8_2::~StrcollUTF8_2() 250 { 251 } 252 253 void 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 269 long 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 // 277 class GetSortKey : public UPerfFunction 278 { 279 public: 280 GetSortKey(const UCollator* coll, const CA_uchar* source, UBool useLen); 281 ~GetSortKey(); 282 virtual void call(UErrorCode* status); 283 virtual long getOperationsPerIteration(); 284 285 private: 286 const UCollator *coll; 287 const CA_uchar *source; 288 UBool useLen; 289 }; 290 291 GetSortKey::GetSortKey(const UCollator* coll, const CA_uchar* source, UBool useLen) 292 : coll(coll), 293 source(source), 294 useLen(useLen) 295 { 296 } 297 298 GetSortKey::~GetSortKey() 299 { 300 } 301 302 #define KEY_BUF_SIZE 512 303 304 void 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 322 long 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 // 331 class NextSortKeyPart : public UPerfFunction 332 { 333 public: 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 340 private: 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 349 NextSortKeyPart::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 358 NextSortKeyPart::~NextSortKeyPart() 359 { 360 } 361 362 void 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 384 long NextSortKeyPart::getOperationsPerIteration() 385 { 386 return source->count; 387 } 388 389 long 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 // 398 class NextSortKeyPartUTF8 : public UPerfFunction 399 { 400 public: 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 407 private: 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 416 NextSortKeyPartUTF8::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 425 NextSortKeyPartUTF8::~NextSortKeyPartUTF8() 426 { 427 } 428 429 void 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 451 long NextSortKeyPartUTF8::getOperationsPerIteration() 452 { 453 return source->count; 454 } 455 456 long 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 // 466 class CppCompare : public UPerfFunction 467 { 468 public: 469 CppCompare(const Collator* coll, const CA_uchar* source, UBool useLen); 470 ~CppCompare(); 471 virtual void call(UErrorCode* status); 472 virtual long getOperationsPerIteration(); 473 474 private: 475 const Collator *coll; 476 const CA_uchar *source; 477 UBool useLen; 478 int32_t maxTestStrings; 479 }; 480 481 CppCompare::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 489 CppCompare::~CppCompare() 490 { 491 } 492 493 void 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 517 long 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 // 525 class CppCompare_2 : public UPerfFunction 526 { 527 public: 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 533 private: 534 const Collator *coll; 535 const CA_uchar *source; 536 const CA_uchar *target; 537 UBool useLen; 538 }; 539 540 CppCompare_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 548 CppCompare_2::~CppCompare_2() 549 { 550 } 551 552 void 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 567 long 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 // 576 class CppCompareUTF8 : public UPerfFunction 577 { 578 public: 579 CppCompareUTF8(const Collator* coll, const CA_char* source, UBool useLen); 580 ~CppCompareUTF8(); 581 virtual void call(UErrorCode* status); 582 virtual long getOperationsPerIteration(); 583 584 private: 585 const Collator *coll; 586 const CA_char *source; 587 UBool useLen; 588 int32_t maxTestStrings; 589 }; 590 591 CppCompareUTF8::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 599 CppCompareUTF8::~CppCompareUTF8() 600 { 601 } 602 603 void 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 637 long 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 // 646 class CppCompareUTF8_2 : public UPerfFunction 647 { 648 public: 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 654 private: 655 const Collator *coll; 656 const CA_char *source; 657 const CA_char *target; 658 UBool useLen; 659 }; 660 661 CppCompareUTF8_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 669 CppCompareUTF8_2::~CppCompareUTF8_2() 670 { 671 } 672 673 void 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 694 long 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 // 703 class CppGetCollationKey : public UPerfFunction 704 { 705 public: 706 CppGetCollationKey(const Collator* coll, const CA_uchar* source, UBool useLen); 707 ~CppGetCollationKey(); 708 virtual void call(UErrorCode* status); 709 virtual long getOperationsPerIteration(); 710 711 private: 712 const Collator *coll; 713 const CA_uchar *source; 714 UBool useLen; 715 }; 716 717 CppGetCollationKey::CppGetCollationKey(const Collator* coll, const CA_uchar* source, UBool useLen) 718 : coll(coll), 719 source(source), 720 useLen(useLen) 721 { 722 } 723 724 CppGetCollationKey::~CppGetCollationKey() 725 { 726 } 727 728 void 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 738 long CppGetCollationKey::getOperationsPerIteration() { 739 return source->count; 740 } 741 742 namespace { 743 744 struct CollatorAndCounter { 745 CollatorAndCounter(const Collator& coll) : coll(coll), ucoll(NULL), counter(0) {} 746 CollatorAndCounter(const Collator& coll, const UCollator *ucoll) 747 : coll(coll), ucoll(ucoll), counter(0) {} 748 const Collator& coll; 749 const UCollator *ucoll; 750 int32_t counter; 751 }; 752 753 int32_t U_CALLCONV 754 UniStrCollatorComparator(const void* context, const void* left, const void* right) { 755 CollatorAndCounter& cc = *(CollatorAndCounter*)context; 756 const UnicodeString& leftString = **(const UnicodeString**)left; 757 const UnicodeString& rightString = **(const UnicodeString**)right; 758 UErrorCode errorCode = U_ZERO_ERROR; 759 ++cc.counter; 760 return cc.coll.compare(leftString, rightString, errorCode); 761 } 762 763 } // namespace 764 765 class CollPerfFunction : public UPerfFunction { 766 public: 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 773 protected: 774 const Collator& coll; 775 const UCollator *ucoll; 776 int32_t ops; 777 }; 778 779 CollPerfFunction::~CollPerfFunction() {} 780 781 long CollPerfFunction::getOperationsPerIteration() { 782 UErrorCode errorCode = U_ZERO_ERROR; 783 call(&errorCode); 784 return U_SUCCESS(errorCode) ? ops : 0; 785 } 786 787 class UniStrCollPerfFunction : public CollPerfFunction { 788 public: 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 798 protected: 799 const CA_uchar* d16; 800 UnicodeString** source; 801 }; 802 803 UniStrCollPerfFunction::~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 // 813 class UniStrSort : public UniStrCollPerfFunction { 814 public: 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 821 private: 822 UnicodeString** dest; // aliases only 823 }; 824 825 UniStrSort::~UniStrSort() { 826 delete[] dest; 827 } 828 829 void 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 840 namespace { 841 842 int32_t U_CALLCONV 843 StringPieceCollatorComparator(const void* context, const void* left, const void* right) { 844 CollatorAndCounter& cc = *(CollatorAndCounter*)context; 845 const StringPiece& leftString = *(const StringPiece*)left; 846 const StringPiece& rightString = *(const StringPiece*)right; 847 UErrorCode errorCode = U_ZERO_ERROR; 848 ++cc.counter; 849 return cc.coll.compareUTF8(leftString, rightString, errorCode); 850 } 851 852 int32_t U_CALLCONV 853 StringPieceUCollatorComparator(const void* context, const void* left, const void* right) { 854 CollatorAndCounter& cc = *(CollatorAndCounter*)context; 855 const StringPiece& leftString = *(const StringPiece*)left; 856 const StringPiece& rightString = *(const StringPiece*)right; 857 UErrorCode errorCode = U_ZERO_ERROR; 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 866 class StringPieceCollPerfFunction : public CollPerfFunction { 867 public: 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 877 protected: 878 const CA_char* d8; 879 StringPiece* source; 880 }; 881 882 StringPieceCollPerfFunction::~StringPieceCollPerfFunction() { 883 delete[] source; 884 } 885 886 class StringPieceSort : public StringPieceCollPerfFunction { 887 public: 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 893 protected: 894 StringPiece* dest; 895 }; 896 897 StringPieceSort::~StringPieceSort() { 898 delete[] dest; 899 } 900 901 // 902 // Test case sorting an array of UTF-8 StringPiece's with Collator::compareUTF8(). 903 // 904 class StringPieceSortCpp : public StringPieceSort { 905 public: 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 912 StringPieceSortCpp::~StringPieceSortCpp() {} 913 914 void 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 // 928 class StringPieceSortC : public StringPieceSort { 929 public: 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 936 StringPieceSortC::~StringPieceSortC() {} 937 938 void 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 // 952 class UniStrBinSearch : public UniStrCollPerfFunction { 953 public: 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 960 UniStrBinSearch::~UniStrBinSearch() {} 961 962 void 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 975 class StringPieceBinSearch : public StringPieceCollPerfFunction { 976 public: 977 StringPieceBinSearch(const Collator& coll, const UCollator *ucoll, const CA_char* data8) 978 : StringPieceCollPerfFunction(coll, ucoll, data8) {} 979 virtual ~StringPieceBinSearch(); 980 }; 981 982 StringPieceBinSearch::~StringPieceBinSearch() {} 983 984 // 985 // Test case performing binary searches in a sorted array of UTF-8 StringPiece's 986 // with Collator::compareUTF8(). 987 // 988 class StringPieceBinSearchCpp : public StringPieceBinSearch { 989 public: 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 996 StringPieceBinSearchCpp::~StringPieceBinSearchCpp() {} 997 998 void 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 // 1015 class StringPieceBinSearchC : public StringPieceBinSearch { 1016 public: 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 1023 StringPieceBinSearchC::~StringPieceBinSearchC() {} 1024 1025 void 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 1039 class CollPerf2Test : public UPerfTest 1040 { 1041 public: 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 1047 private: 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 1127 CollPerf2Test::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 1155 CollPerf2Test::~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 1172 const 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 1213 const 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 1220 const 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 1255 const 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 1262 namespace { 1263 1264 struct 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 1270 int32_t U_CALLCONV 1271 U16CollatorComparator(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 1282 int32_t U_CALLCONV 1283 U16HashComparator(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 1294 const 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 1302 const 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 1308 const 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 1317 const 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 1323 CA_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 1353 CA_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 1385 UPerfFunction* 1386 CollPerf2Test::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 1439 UPerfFunction* 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 1450 UPerfFunction* 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 1461 UPerfFunction* 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 1472 UPerfFunction* 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 1483 UPerfFunction* 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 1494 UPerfFunction* 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 1505 UPerfFunction* 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 1516 UPerfFunction* 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 1527 UPerfFunction* 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 1538 UPerfFunction* 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 1549 UPerfFunction* 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 1560 UPerfFunction* 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 1571 UPerfFunction* 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 1582 UPerfFunction* 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 1593 UPerfFunction* 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 1604 UPerfFunction* 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 1615 UPerfFunction* 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 1626 UPerfFunction* 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 1637 UPerfFunction* 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 1648 UPerfFunction* 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 1659 UPerfFunction* 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 1670 UPerfFunction* 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 1681 UPerfFunction* 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 1692 UPerfFunction* 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 1703 UPerfFunction* 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 1714 UPerfFunction* 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 1725 UPerfFunction* 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 1735 UPerfFunction* 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 1745 UPerfFunction* 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 1755 UPerfFunction* 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 1765 UPerfFunction* 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 1775 UPerfFunction* 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 1786 int 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