| Index: source/test/perf/collperf2/collperf2.cpp | 
| diff --git a/source/test/perf/collperf2/collperf2.cpp b/source/test/perf/collperf2/collperf2.cpp | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..5f953c18735ccf08ed4ab256bf614ff432390f06 | 
| --- /dev/null | 
| +++ b/source/test/perf/collperf2/collperf2.cpp | 
| @@ -0,0 +1,1802 @@ | 
| +/* | 
| +********************************************************************** | 
| +* Copyright (c) 2013-2014, International Business Machines | 
| +* Corporation and others.  All Rights Reserved. | 
| +********************************************************************** | 
| +*/ | 
| + | 
| +#include <string.h> | 
| +#include "unicode/localpointer.h" | 
| +#include "unicode/uperf.h" | 
| +#include "unicode/ucol.h" | 
| +#include "unicode/coll.h" | 
| +#include "unicode/uiter.h" | 
| +#include "unicode/ustring.h" | 
| +#include "unicode/sortkey.h" | 
| +#include "uarrsort.h" | 
| +#include "uoptions.h" | 
| +#include "ustr_imp.h" | 
| + | 
| +#define COMPACT_ARRAY(CompactArrays, UNIT) \ | 
| +struct CompactArrays{\ | 
| +    CompactArrays(const CompactArrays & );\ | 
| +    CompactArrays & operator=(const CompactArrays & );\ | 
| +    int32_t   count;/*total number of the strings*/ \ | 
| +    int32_t * index;/*relative offset in data*/ \ | 
| +    UNIT    * data; /*the real space to hold strings*/ \ | 
| +    \ | 
| +    ~CompactArrays(){free(index);free(data);} \ | 
| +    CompactArrays() : count(0), index(NULL), data(NULL) { \ | 
| +        index = (int32_t *) realloc(index, sizeof(int32_t)); \ | 
| +        index[0] = 0; \ | 
| +    } \ | 
| +    void append_one(int32_t theLen){ /*include terminal NULL*/ \ | 
| +        count++; \ | 
| +        index = (int32_t *) realloc(index, sizeof(int32_t) * (count + 1)); \ | 
| +        index[count] = index[count - 1] + theLen; \ | 
| +        data = (UNIT *) realloc(data, sizeof(UNIT) * index[count]); \ | 
| +    } \ | 
| +    UNIT * last(){return data + index[count - 1];} \ | 
| +    const UNIT * dataOf(int32_t i) const {return data + index[i];} \ | 
| +    int32_t lengthOf(int i) const {return index[i+1] - index[i] - 1; } /*exclude terminating NULL*/  \ | 
| +}; | 
| + | 
| +COMPACT_ARRAY(CA_uchar, UChar) | 
| +COMPACT_ARRAY(CA_char, char) | 
| + | 
| +#define MAX_TEST_STRINGS_FOR_PERMUTING 1000 | 
| + | 
| +// C API test cases | 
| + | 
| +// | 
| +// Test case taking a single test data array, calling ucol_strcoll by permuting the test data | 
| +// | 
| +class Strcoll : public UPerfFunction | 
| +{ | 
| +public: | 
| +    Strcoll(const UCollator* coll, const CA_uchar* source, UBool useLen); | 
| +    ~Strcoll(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +private: | 
| +    const UCollator *coll; | 
| +    const CA_uchar *source; | 
| +    UBool useLen; | 
| +    int32_t maxTestStrings; | 
| +}; | 
| + | 
| +Strcoll::Strcoll(const UCollator* coll, const CA_uchar* source, UBool useLen) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        useLen(useLen) | 
| +{ | 
| +    maxTestStrings = source->count > MAX_TEST_STRINGS_FOR_PERMUTING ? MAX_TEST_STRINGS_FOR_PERMUTING : source->count; | 
| +} | 
| + | 
| +Strcoll::~Strcoll() | 
| +{ | 
| +} | 
| + | 
| +void Strcoll::call(UErrorCode* status) | 
| +{ | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    // call strcoll for permutation | 
| +    int32_t divisor = source->count / maxTestStrings; | 
| +    int32_t srcLen, tgtLen; | 
| +    int32_t cmp = 0; | 
| +    for (int32_t i = 0, numTestStringsI = 0; i < source->count && numTestStringsI < maxTestStrings; i++) { | 
| +        if (i % divisor) continue; | 
| +        numTestStringsI++; | 
| +        srcLen = useLen ? source->lengthOf(i) : -1; | 
| +        for (int32_t j = 0, numTestStringsJ = 0; j < source->count && numTestStringsJ < maxTestStrings; j++) { | 
| +            if (j % divisor) continue; | 
| +            numTestStringsJ++; | 
| +            tgtLen = useLen ? source->lengthOf(j) : -1; | 
| +            cmp += ucol_strcoll(coll, source->dataOf(i), srcLen, source->dataOf(j), tgtLen); | 
| +        } | 
| +    } | 
| +    // At the end, cmp must be 0 | 
| +    if (cmp != 0) { | 
| +        *status = U_INTERNAL_PROGRAM_ERROR; | 
| +    } | 
| +} | 
| + | 
| +long Strcoll::getOperationsPerIteration() | 
| +{ | 
| +    return maxTestStrings * maxTestStrings; | 
| +} | 
| + | 
| +// | 
| +// Test case taking two test data arrays, calling ucol_strcoll for strings at a same index | 
| +// | 
| +class Strcoll_2 : public UPerfFunction | 
| +{ | 
| +public: | 
| +    Strcoll_2(const UCollator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen); | 
| +    ~Strcoll_2(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +private: | 
| +    const UCollator *coll; | 
| +    const CA_uchar *source; | 
| +    const CA_uchar *target; | 
| +    UBool useLen; | 
| +}; | 
| + | 
| +Strcoll_2::Strcoll_2(const UCollator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        target(target), | 
| +        useLen(useLen) | 
| +{ | 
| +} | 
| + | 
| +Strcoll_2::~Strcoll_2() | 
| +{ | 
| +} | 
| + | 
| +void Strcoll_2::call(UErrorCode* status) | 
| +{ | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    // call strcoll for two strings at the same index | 
| +    if (source->count < target->count) { | 
| +        *status = U_ILLEGAL_ARGUMENT_ERROR; | 
| +    } else { | 
| +        for (int32_t i = 0; i < source->count; i++) { | 
| +            int32_t srcLen = useLen ? source->lengthOf(i) : -1; | 
| +            int32_t tgtLen = useLen ? target->lengthOf(i) : -1; | 
| +            ucol_strcoll(coll, source->dataOf(i), srcLen, target->dataOf(i), tgtLen); | 
| +        } | 
| +    } | 
| +} | 
| + | 
| +long Strcoll_2::getOperationsPerIteration() | 
| +{ | 
| +    return source->count; | 
| +} | 
| + | 
| + | 
| +// | 
| +// Test case taking a single test data array, calling ucol_strcollUTF8 by permuting the test data | 
| +// | 
| +class StrcollUTF8 : public UPerfFunction | 
| +{ | 
| +public: | 
| +    StrcollUTF8(const UCollator* coll, const CA_char* source, UBool useLen); | 
| +    ~StrcollUTF8(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +private: | 
| +    const UCollator *coll; | 
| +    const CA_char *source; | 
| +    UBool useLen; | 
| +    int32_t maxTestStrings; | 
| +}; | 
| + | 
| +StrcollUTF8::StrcollUTF8(const UCollator* coll, const CA_char* source, UBool useLen) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        useLen(useLen) | 
| +{ | 
| +    maxTestStrings = source->count > MAX_TEST_STRINGS_FOR_PERMUTING ? MAX_TEST_STRINGS_FOR_PERMUTING : source->count; | 
| +} | 
| + | 
| +StrcollUTF8::~StrcollUTF8() | 
| +{ | 
| +} | 
| + | 
| +void StrcollUTF8::call(UErrorCode* status) | 
| +{ | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    // call strcollUTF8 for permutation | 
| +    int32_t divisor = source->count / maxTestStrings; | 
| +    int32_t srcLen, tgtLen; | 
| +    int32_t cmp = 0; | 
| +    for (int32_t i = 0, numTestStringsI = 0; U_SUCCESS(*status) && i < source->count && numTestStringsI < maxTestStrings; i++) { | 
| +        if (i % divisor) continue; | 
| +        numTestStringsI++; | 
| +        srcLen = useLen ? source->lengthOf(i) : -1; | 
| +        for (int32_t j = 0, numTestStringsJ = 0; U_SUCCESS(*status) && j < source->count && numTestStringsJ < maxTestStrings; j++) { | 
| +            if (j % divisor) continue; | 
| +            numTestStringsJ++; | 
| +            tgtLen = useLen ? source->lengthOf(j) : -1; | 
| +            cmp += ucol_strcollUTF8(coll, source->dataOf(i), srcLen, source->dataOf(j), tgtLen, status); | 
| +        } | 
| +    } | 
| +    // At the end, cmp must be 0 | 
| +    if (cmp != 0) { | 
| +        *status = U_INTERNAL_PROGRAM_ERROR; | 
| +    } | 
| +} | 
| + | 
| +long StrcollUTF8::getOperationsPerIteration() | 
| +{ | 
| +    return maxTestStrings * maxTestStrings; | 
| +} | 
| + | 
| +// | 
| +// Test case taking two test data arrays, calling ucol_strcoll for strings at a same index | 
| +// | 
| +class StrcollUTF8_2 : public UPerfFunction | 
| +{ | 
| +public: | 
| +    StrcollUTF8_2(const UCollator* coll, const CA_char* source, const CA_char* target, UBool useLen); | 
| +    ~StrcollUTF8_2(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +private: | 
| +    const UCollator *coll; | 
| +    const CA_char *source; | 
| +    const CA_char *target; | 
| +    UBool useLen; | 
| +}; | 
| + | 
| +StrcollUTF8_2::StrcollUTF8_2(const UCollator* coll, const CA_char* source, const CA_char* target, UBool useLen) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        target(target), | 
| +        useLen(useLen) | 
| +{ | 
| +} | 
| + | 
| +StrcollUTF8_2::~StrcollUTF8_2() | 
| +{ | 
| +} | 
| + | 
| +void StrcollUTF8_2::call(UErrorCode* status) | 
| +{ | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    // call strcoll for two strings at the same index | 
| +    if (source->count < target->count) { | 
| +        *status = U_ILLEGAL_ARGUMENT_ERROR; | 
| +    } else { | 
| +        for (int32_t i = 0; U_SUCCESS(*status) && i < source->count; i++) { | 
| +            int32_t srcLen = useLen ? source->lengthOf(i) : -1; | 
| +            int32_t tgtLen = useLen ? target->lengthOf(i) : -1; | 
| +            ucol_strcollUTF8(coll, source->dataOf(i), srcLen, target->dataOf(i), tgtLen, status); | 
| +        } | 
| +    } | 
| +} | 
| + | 
| +long StrcollUTF8_2::getOperationsPerIteration() | 
| +{ | 
| +    return source->count; | 
| +} | 
| + | 
| +// | 
| +// Test case taking a single test data array, calling ucol_getSortKey for each | 
| +// | 
| +class GetSortKey : public UPerfFunction | 
| +{ | 
| +public: | 
| +    GetSortKey(const UCollator* coll, const CA_uchar* source, UBool useLen); | 
| +    ~GetSortKey(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +private: | 
| +    const UCollator *coll; | 
| +    const CA_uchar *source; | 
| +    UBool useLen; | 
| +}; | 
| + | 
| +GetSortKey::GetSortKey(const UCollator* coll, const CA_uchar* source, UBool useLen) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        useLen(useLen) | 
| +{ | 
| +} | 
| + | 
| +GetSortKey::~GetSortKey() | 
| +{ | 
| +} | 
| + | 
| +#define KEY_BUF_SIZE 512 | 
| + | 
| +void GetSortKey::call(UErrorCode* status) | 
| +{ | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    uint8_t key[KEY_BUF_SIZE]; | 
| +    int32_t len; | 
| + | 
| +    if (useLen) { | 
| +        for (int32_t i = 0; i < source->count; i++) { | 
| +            len = ucol_getSortKey(coll, source->dataOf(i), source->lengthOf(i), key, KEY_BUF_SIZE); | 
| +        } | 
| +    } else { | 
| +        for (int32_t i = 0; i < source->count; i++) { | 
| +            len = ucol_getSortKey(coll, source->dataOf(i), -1, key, KEY_BUF_SIZE); | 
| +        } | 
| +    } | 
| +} | 
| + | 
| +long GetSortKey::getOperationsPerIteration() | 
| +{ | 
| +    return source->count; | 
| +} | 
| + | 
| +// | 
| +// Test case taking a single test data array in UTF-16, calling ucol_nextSortKeyPart for each for the | 
| +// given buffer size | 
| +// | 
| +class NextSortKeyPart : public UPerfFunction | 
| +{ | 
| +public: | 
| +    NextSortKeyPart(const UCollator* coll, const CA_uchar* source, int32_t bufSize, int32_t maxIteration = -1); | 
| +    ~NextSortKeyPart(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| +    virtual long getEventsPerIteration(); | 
| + | 
| +private: | 
| +    const UCollator *coll; | 
| +    const CA_uchar *source; | 
| +    int32_t bufSize; | 
| +    int32_t maxIteration; | 
| +    long events; | 
| +}; | 
| + | 
| +// Note: maxIteration = -1 -> repeat until the end of collation key | 
| +NextSortKeyPart::NextSortKeyPart(const UCollator* coll, const CA_uchar* source, int32_t bufSize, int32_t maxIteration /* = -1 */) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        bufSize(bufSize), | 
| +        maxIteration(maxIteration), | 
| +        events(0) | 
| +{ | 
| +} | 
| + | 
| +NextSortKeyPart::~NextSortKeyPart() | 
| +{ | 
| +} | 
| + | 
| +void NextSortKeyPart::call(UErrorCode* status) | 
| +{ | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    uint8_t *part = (uint8_t *)malloc(bufSize); | 
| +    uint32_t state[2]; | 
| +    UCharIterator iter; | 
| + | 
| +    events = 0; | 
| +    for (int i = 0; i < source->count && U_SUCCESS(*status); i++) { | 
| +        uiter_setString(&iter, source->dataOf(i), source->lengthOf(i)); | 
| +        state[0] = 0; | 
| +        state[1] = 0; | 
| +        int32_t partLen = bufSize; | 
| +        for (int32_t n = 0; U_SUCCESS(*status) && partLen == bufSize && (maxIteration < 0 || n < maxIteration); n++) { | 
| +            partLen = ucol_nextSortKeyPart(coll, &iter, state, part, bufSize, status); | 
| +            events++; | 
| +        } | 
| +    } | 
| +    free(part); | 
| +} | 
| + | 
| +long NextSortKeyPart::getOperationsPerIteration() | 
| +{ | 
| +    return source->count; | 
| +} | 
| + | 
| +long NextSortKeyPart::getEventsPerIteration() | 
| +{ | 
| +    return events; | 
| +} | 
| + | 
| +// | 
| +// Test case taking a single test data array in UTF-8, calling ucol_nextSortKeyPart for each for the | 
| +// given buffer size | 
| +// | 
| +class NextSortKeyPartUTF8 : public UPerfFunction | 
| +{ | 
| +public: | 
| +    NextSortKeyPartUTF8(const UCollator* coll, const CA_char* source, int32_t bufSize, int32_t maxIteration = -1); | 
| +    ~NextSortKeyPartUTF8(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| +    virtual long getEventsPerIteration(); | 
| + | 
| +private: | 
| +    const UCollator *coll; | 
| +    const CA_char *source; | 
| +    int32_t bufSize; | 
| +    int32_t maxIteration; | 
| +    long events; | 
| +}; | 
| + | 
| +// Note: maxIteration = -1 -> repeat until the end of collation key | 
| +NextSortKeyPartUTF8::NextSortKeyPartUTF8(const UCollator* coll, const CA_char* source, int32_t bufSize, int32_t maxIteration /* = -1 */) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        bufSize(bufSize), | 
| +        maxIteration(maxIteration), | 
| +        events(0) | 
| +{ | 
| +} | 
| + | 
| +NextSortKeyPartUTF8::~NextSortKeyPartUTF8() | 
| +{ | 
| +} | 
| + | 
| +void NextSortKeyPartUTF8::call(UErrorCode* status) | 
| +{ | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    uint8_t *part = (uint8_t *)malloc(bufSize); | 
| +    uint32_t state[2]; | 
| +    UCharIterator iter; | 
| + | 
| +    events = 0; | 
| +    for (int i = 0; i < source->count && U_SUCCESS(*status); i++) { | 
| +        uiter_setUTF8(&iter, source->dataOf(i), source->lengthOf(i)); | 
| +        state[0] = 0; | 
| +        state[1] = 0; | 
| +        int32_t partLen = bufSize; | 
| +        for (int32_t n = 0; U_SUCCESS(*status) && partLen == bufSize && (maxIteration < 0 || n < maxIteration); n++) { | 
| +            partLen = ucol_nextSortKeyPart(coll, &iter, state, part, bufSize, status); | 
| +            events++; | 
| +        } | 
| +    } | 
| +    free(part); | 
| +} | 
| + | 
| +long NextSortKeyPartUTF8::getOperationsPerIteration() | 
| +{ | 
| +    return source->count; | 
| +} | 
| + | 
| +long NextSortKeyPartUTF8::getEventsPerIteration() | 
| +{ | 
| +    return events; | 
| +} | 
| + | 
| +// CPP API test cases | 
| + | 
| +// | 
| +// Test case taking a single test data array, calling Collator::compare by permuting the test data | 
| +// | 
| +class CppCompare : public UPerfFunction | 
| +{ | 
| +public: | 
| +    CppCompare(const Collator* coll, const CA_uchar* source, UBool useLen); | 
| +    ~CppCompare(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +private: | 
| +    const Collator *coll; | 
| +    const CA_uchar *source; | 
| +    UBool useLen; | 
| +    int32_t maxTestStrings; | 
| +}; | 
| + | 
| +CppCompare::CppCompare(const Collator* coll, const CA_uchar* source, UBool useLen) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        useLen(useLen) | 
| +{ | 
| +    maxTestStrings = source->count > MAX_TEST_STRINGS_FOR_PERMUTING ? MAX_TEST_STRINGS_FOR_PERMUTING : source->count; | 
| +} | 
| + | 
| +CppCompare::~CppCompare() | 
| +{ | 
| +} | 
| + | 
| +void CppCompare::call(UErrorCode* status) { | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    // call compare for permutation of test data | 
| +    int32_t divisor = source->count / maxTestStrings; | 
| +    int32_t srcLen, tgtLen; | 
| +    int32_t cmp = 0; | 
| +    for (int32_t i = 0, numTestStringsI = 0; i < source->count && numTestStringsI < maxTestStrings; i++) { | 
| +        if (i % divisor) continue; | 
| +        numTestStringsI++; | 
| +        srcLen = useLen ? source->lengthOf(i) : -1; | 
| +        for (int32_t j = 0, numTestStringsJ = 0; j < source->count && numTestStringsJ < maxTestStrings; j++) { | 
| +            if (j % divisor) continue; | 
| +            numTestStringsJ++; | 
| +            tgtLen = useLen ? source->lengthOf(j) : -1; | 
| +            cmp += coll->compare(source->dataOf(i), srcLen, source->dataOf(j), tgtLen); | 
| +        } | 
| +    } | 
| +    // At the end, cmp must be 0 | 
| +    if (cmp != 0) { | 
| +        *status = U_INTERNAL_PROGRAM_ERROR; | 
| +    } | 
| +} | 
| + | 
| +long CppCompare::getOperationsPerIteration() | 
| +{ | 
| +    return maxTestStrings * maxTestStrings; | 
| +} | 
| + | 
| +// | 
| +// Test case taking two test data arrays, calling Collator::compare for strings at a same index | 
| +// | 
| +class CppCompare_2 : public UPerfFunction | 
| +{ | 
| +public: | 
| +    CppCompare_2(const Collator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen); | 
| +    ~CppCompare_2(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +private: | 
| +    const Collator *coll; | 
| +    const CA_uchar *source; | 
| +    const CA_uchar *target; | 
| +    UBool useLen; | 
| +}; | 
| + | 
| +CppCompare_2::CppCompare_2(const Collator* coll, const CA_uchar* source, const CA_uchar* target, UBool useLen) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        target(target), | 
| +        useLen(useLen) | 
| +{ | 
| +} | 
| + | 
| +CppCompare_2::~CppCompare_2() | 
| +{ | 
| +} | 
| + | 
| +void CppCompare_2::call(UErrorCode* status) { | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    // call strcoll for two strings at the same index | 
| +    if (source->count < target->count) { | 
| +        *status = U_ILLEGAL_ARGUMENT_ERROR; | 
| +    } else { | 
| +        for (int32_t i = 0; i < source->count; i++) { | 
| +            int32_t srcLen = useLen ? source->lengthOf(i) : -1; | 
| +            int32_t tgtLen = useLen ? target->lengthOf(i) : -1; | 
| +            coll->compare(source->dataOf(i), srcLen, target->dataOf(i), tgtLen); | 
| +        } | 
| +    } | 
| +} | 
| + | 
| +long CppCompare_2::getOperationsPerIteration() | 
| +{ | 
| +    return source->count; | 
| +} | 
| + | 
| + | 
| +// | 
| +// Test case taking a single test data array, calling Collator::compareUTF8 by permuting the test data | 
| +// | 
| +class CppCompareUTF8 : public UPerfFunction | 
| +{ | 
| +public: | 
| +    CppCompareUTF8(const Collator* coll, const CA_char* source, UBool useLen); | 
| +    ~CppCompareUTF8(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +private: | 
| +    const Collator *coll; | 
| +    const CA_char *source; | 
| +    UBool useLen; | 
| +    int32_t maxTestStrings; | 
| +}; | 
| + | 
| +CppCompareUTF8::CppCompareUTF8(const Collator* coll, const CA_char* source, UBool useLen) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        useLen(useLen) | 
| +{ | 
| +    maxTestStrings = source->count > MAX_TEST_STRINGS_FOR_PERMUTING ? MAX_TEST_STRINGS_FOR_PERMUTING : source->count; | 
| +} | 
| + | 
| +CppCompareUTF8::~CppCompareUTF8() | 
| +{ | 
| +} | 
| + | 
| +void CppCompareUTF8::call(UErrorCode* status) { | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    // call compareUTF8 for all permutations | 
| +    int32_t divisor = source->count / maxTestStrings; | 
| +    StringPiece src, tgt; | 
| +    int32_t cmp = 0; | 
| +    for (int32_t i = 0, numTestStringsI = 0; U_SUCCESS(*status) && i < source->count && numTestStringsI < maxTestStrings; i++) { | 
| +        if (i % divisor) continue; | 
| +        numTestStringsI++; | 
| + | 
| +        if (useLen) { | 
| +            src.set(source->dataOf(i), source->lengthOf(i)); | 
| +        } else { | 
| +            src.set(source->dataOf(i)); | 
| +        } | 
| +        for (int32_t j = 0, numTestStringsJ = 0; U_SUCCESS(*status) && j < source->count && numTestStringsJ < maxTestStrings; j++) { | 
| +            if (j % divisor) continue; | 
| +            numTestStringsJ++; | 
| + | 
| +            if (useLen) { | 
| +                tgt.set(source->dataOf(i), source->lengthOf(i)); | 
| +            } else { | 
| +                tgt.set(source->dataOf(i)); | 
| +            } | 
| +            cmp += coll->compareUTF8(src, tgt, *status); | 
| +        } | 
| +    } | 
| +    // At the end, cmp must be 0 | 
| +    if (cmp != 0) { | 
| +        *status = U_INTERNAL_PROGRAM_ERROR; | 
| +    } | 
| +} | 
| + | 
| +long CppCompareUTF8::getOperationsPerIteration() | 
| +{ | 
| +    return maxTestStrings * maxTestStrings; | 
| +} | 
| + | 
| + | 
| +// | 
| +// Test case taking two test data arrays, calling Collator::compareUTF8 for strings at a same index | 
| +// | 
| +class CppCompareUTF8_2 : public UPerfFunction | 
| +{ | 
| +public: | 
| +    CppCompareUTF8_2(const Collator* coll, const CA_char* source, const CA_char* target, UBool useLen); | 
| +    ~CppCompareUTF8_2(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +private: | 
| +    const Collator *coll; | 
| +    const CA_char *source; | 
| +    const CA_char *target; | 
| +    UBool useLen; | 
| +}; | 
| + | 
| +CppCompareUTF8_2::CppCompareUTF8_2(const Collator* coll, const CA_char* source, const CA_char* target, UBool useLen) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        target(target), | 
| +        useLen(useLen) | 
| +{ | 
| +} | 
| + | 
| +CppCompareUTF8_2::~CppCompareUTF8_2() | 
| +{ | 
| +} | 
| + | 
| +void CppCompareUTF8_2::call(UErrorCode* status) { | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    // call strcoll for two strings at the same index | 
| +    StringPiece src, tgt; | 
| +    if (source->count < target->count) { | 
| +        *status = U_ILLEGAL_ARGUMENT_ERROR; | 
| +    } else { | 
| +        for (int32_t i = 0; U_SUCCESS(*status) && i < source->count; i++) { | 
| +            if (useLen) { | 
| +                src.set(source->dataOf(i), source->lengthOf(i)); | 
| +                tgt.set(target->dataOf(i), target->lengthOf(i)); | 
| +            } else { | 
| +                src.set(source->dataOf(i)); | 
| +                tgt.set(target->dataOf(i)); | 
| +            } | 
| +            coll->compareUTF8(src, tgt, *status); | 
| +        } | 
| +    } | 
| +} | 
| + | 
| +long CppCompareUTF8_2::getOperationsPerIteration() | 
| +{ | 
| +    return source->count; | 
| +} | 
| + | 
| + | 
| +// | 
| +// Test case taking a single test data array, calling Collator::getCollationKey for each | 
| +// | 
| +class CppGetCollationKey : public UPerfFunction | 
| +{ | 
| +public: | 
| +    CppGetCollationKey(const Collator* coll, const CA_uchar* source, UBool useLen); | 
| +    ~CppGetCollationKey(); | 
| +    virtual void call(UErrorCode* status); | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +private: | 
| +    const Collator *coll; | 
| +    const CA_uchar *source; | 
| +    UBool useLen; | 
| +}; | 
| + | 
| +CppGetCollationKey::CppGetCollationKey(const Collator* coll, const CA_uchar* source, UBool useLen) | 
| +    :   coll(coll), | 
| +        source(source), | 
| +        useLen(useLen) | 
| +{ | 
| +} | 
| + | 
| +CppGetCollationKey::~CppGetCollationKey() | 
| +{ | 
| +} | 
| + | 
| +void CppGetCollationKey::call(UErrorCode* status) | 
| +{ | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    CollationKey key; | 
| +    for (int32_t i = 0; U_SUCCESS(*status) && i < source->count; i++) { | 
| +        coll->getCollationKey(source->dataOf(i), source->lengthOf(i), key, *status); | 
| +    } | 
| +} | 
| + | 
| +long CppGetCollationKey::getOperationsPerIteration() { | 
| +    return source->count; | 
| +} | 
| + | 
| +namespace { | 
| + | 
| +struct CollatorAndCounter { | 
| +    CollatorAndCounter(const Collator& coll) : coll(coll), ucoll(NULL), counter(0) {} | 
| +    CollatorAndCounter(const Collator& coll, const UCollator *ucoll) | 
| +            : coll(coll), ucoll(ucoll), counter(0) {} | 
| +    const Collator& coll; | 
| +    const UCollator *ucoll; | 
| +    int32_t counter; | 
| +}; | 
| + | 
| +int32_t U_CALLCONV | 
| +UniStrCollatorComparator(const void* context, const void* left, const void* right) { | 
| +    CollatorAndCounter& cc = *(CollatorAndCounter*)context; | 
| +    const UnicodeString& leftString = **(const UnicodeString**)left; | 
| +    const UnicodeString& rightString = **(const UnicodeString**)right; | 
| +    UErrorCode errorCode = U_ZERO_ERROR; | 
| +    ++cc.counter; | 
| +    return cc.coll.compare(leftString, rightString, errorCode); | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +class CollPerfFunction : public UPerfFunction { | 
| +public: | 
| +    CollPerfFunction(const Collator& coll, const UCollator *ucoll) | 
| +            : coll(coll), ucoll(ucoll), ops(0) {} | 
| +    virtual ~CollPerfFunction(); | 
| +    /** Calls call() to set the ops field, and returns that. */ | 
| +    virtual long getOperationsPerIteration(); | 
| + | 
| +protected: | 
| +    const Collator& coll; | 
| +    const UCollator *ucoll; | 
| +    int32_t ops; | 
| +}; | 
| + | 
| +CollPerfFunction::~CollPerfFunction() {} | 
| + | 
| +long CollPerfFunction::getOperationsPerIteration() { | 
| +    UErrorCode errorCode = U_ZERO_ERROR; | 
| +    call(&errorCode); | 
| +    return U_SUCCESS(errorCode) ? ops : 0; | 
| +} | 
| + | 
| +class UniStrCollPerfFunction : public CollPerfFunction { | 
| +public: | 
| +    UniStrCollPerfFunction(const Collator& coll, const UCollator *ucoll, const CA_uchar* data16) | 
| +            : CollPerfFunction(coll, ucoll), d16(data16), | 
| +              source(new UnicodeString*[d16->count]) { | 
| +        for (int32_t i = 0; i < d16->count; ++i) { | 
| +            source[i] = new UnicodeString(TRUE, d16->dataOf(i), d16->lengthOf(i)); | 
| +        } | 
| +    } | 
| +    virtual ~UniStrCollPerfFunction(); | 
| + | 
| +protected: | 
| +    const CA_uchar* d16; | 
| +    UnicodeString** source; | 
| +}; | 
| + | 
| +UniStrCollPerfFunction::~UniStrCollPerfFunction() { | 
| +    for (int32_t i = 0; i < d16->count; ++i) { | 
| +        delete source[i]; | 
| +    } | 
| +    delete[] source; | 
| +} | 
| + | 
| +// | 
| +// Test case sorting an array of UnicodeString pointers. | 
| +// | 
| +class UniStrSort : public UniStrCollPerfFunction { | 
| +public: | 
| +    UniStrSort(const Collator& coll, const UCollator *ucoll, const CA_uchar* data16) | 
| +            : UniStrCollPerfFunction(coll, ucoll, data16), | 
| +              dest(new UnicodeString*[d16->count]) {} | 
| +    virtual ~UniStrSort(); | 
| +    virtual void call(UErrorCode* status); | 
| + | 
| +private: | 
| +    UnicodeString** dest;  // aliases only | 
| +}; | 
| + | 
| +UniStrSort::~UniStrSort() { | 
| +    delete[] dest; | 
| +} | 
| + | 
| +void UniStrSort::call(UErrorCode* status) { | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    CollatorAndCounter cc(coll); | 
| +    int32_t count = d16->count; | 
| +    memcpy(dest, source, count * sizeof(UnicodeString *)); | 
| +    uprv_sortArray(dest, count, (int32_t)sizeof(UnicodeString *), | 
| +                   UniStrCollatorComparator, &cc, TRUE, status); | 
| +    ops = cc.counter; | 
| +} | 
| + | 
| +namespace { | 
| + | 
| +int32_t U_CALLCONV | 
| +StringPieceCollatorComparator(const void* context, const void* left, const void* right) { | 
| +    CollatorAndCounter& cc = *(CollatorAndCounter*)context; | 
| +    const StringPiece& leftString = *(const StringPiece*)left; | 
| +    const StringPiece& rightString = *(const StringPiece*)right; | 
| +    UErrorCode errorCode = U_ZERO_ERROR; | 
| +    ++cc.counter; | 
| +    return cc.coll.compareUTF8(leftString, rightString, errorCode); | 
| +} | 
| + | 
| +int32_t U_CALLCONV | 
| +StringPieceUCollatorComparator(const void* context, const void* left, const void* right) { | 
| +    CollatorAndCounter& cc = *(CollatorAndCounter*)context; | 
| +    const StringPiece& leftString = *(const StringPiece*)left; | 
| +    const StringPiece& rightString = *(const StringPiece*)right; | 
| +    UErrorCode errorCode = U_ZERO_ERROR; | 
| +    ++cc.counter; | 
| +    return ucol_strcollUTF8(cc.ucoll, | 
| +                            leftString.data(), leftString.length(), | 
| +                            rightString.data(), rightString.length(), &errorCode); | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +class StringPieceCollPerfFunction : public CollPerfFunction { | 
| +public: | 
| +    StringPieceCollPerfFunction(const Collator& coll, const UCollator *ucoll, const CA_char* data8) | 
| +            : CollPerfFunction(coll, ucoll), d8(data8), | 
| +              source(new StringPiece[d8->count]) { | 
| +        for (int32_t i = 0; i < d8->count; ++i) { | 
| +            source[i].set(d8->dataOf(i), d8->lengthOf(i)); | 
| +        } | 
| +    } | 
| +    virtual ~StringPieceCollPerfFunction(); | 
| + | 
| +protected: | 
| +    const CA_char* d8; | 
| +    StringPiece* source; | 
| +}; | 
| + | 
| +StringPieceCollPerfFunction::~StringPieceCollPerfFunction() { | 
| +    delete[] source; | 
| +} | 
| + | 
| +class StringPieceSort : public StringPieceCollPerfFunction { | 
| +public: | 
| +    StringPieceSort(const Collator& coll, const UCollator *ucoll, const CA_char* data8) | 
| +            : StringPieceCollPerfFunction(coll, ucoll, data8), | 
| +              dest(new StringPiece[d8->count]) {} | 
| +    virtual ~StringPieceSort(); | 
| + | 
| +protected: | 
| +    StringPiece* dest; | 
| +}; | 
| + | 
| +StringPieceSort::~StringPieceSort() { | 
| +    delete[] dest; | 
| +} | 
| + | 
| +// | 
| +// Test case sorting an array of UTF-8 StringPiece's with Collator::compareUTF8(). | 
| +// | 
| +class StringPieceSortCpp : public StringPieceSort { | 
| +public: | 
| +    StringPieceSortCpp(const Collator& coll, const UCollator *ucoll, const CA_char* data8) | 
| +            : StringPieceSort(coll, ucoll, data8) {} | 
| +    virtual ~StringPieceSortCpp(); | 
| +    virtual void call(UErrorCode* status); | 
| +}; | 
| + | 
| +StringPieceSortCpp::~StringPieceSortCpp() {} | 
| + | 
| +void StringPieceSortCpp::call(UErrorCode* status) { | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    CollatorAndCounter cc(coll); | 
| +    int32_t count = d8->count; | 
| +    memcpy(dest, source, count * sizeof(StringPiece)); | 
| +    uprv_sortArray(dest, count, (int32_t)sizeof(StringPiece), | 
| +                   StringPieceCollatorComparator, &cc, TRUE, status); | 
| +    ops = cc.counter; | 
| +} | 
| + | 
| +// | 
| +// Test case sorting an array of UTF-8 StringPiece's with ucol_strcollUTF8(). | 
| +// | 
| +class StringPieceSortC : public StringPieceSort { | 
| +public: | 
| +    StringPieceSortC(const Collator& coll, const UCollator *ucoll, const CA_char* data8) | 
| +            : StringPieceSort(coll, ucoll, data8) {} | 
| +    virtual ~StringPieceSortC(); | 
| +    virtual void call(UErrorCode* status); | 
| +}; | 
| + | 
| +StringPieceSortC::~StringPieceSortC() {} | 
| + | 
| +void StringPieceSortC::call(UErrorCode* status) { | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    CollatorAndCounter cc(coll, ucoll); | 
| +    int32_t count = d8->count; | 
| +    memcpy(dest, source, count * sizeof(StringPiece)); | 
| +    uprv_sortArray(dest, count, (int32_t)sizeof(StringPiece), | 
| +                   StringPieceUCollatorComparator, &cc, TRUE, status); | 
| +    ops = cc.counter; | 
| +} | 
| + | 
| +// | 
| +// Test case performing binary searches in a sorted array of UnicodeString pointers. | 
| +// | 
| +class UniStrBinSearch : public UniStrCollPerfFunction { | 
| +public: | 
| +    UniStrBinSearch(const Collator& coll, const UCollator *ucoll, const CA_uchar* data16) | 
| +            : UniStrCollPerfFunction(coll, ucoll, data16) {} | 
| +    virtual ~UniStrBinSearch(); | 
| +    virtual void call(UErrorCode* status); | 
| +}; | 
| + | 
| +UniStrBinSearch::~UniStrBinSearch() {} | 
| + | 
| +void UniStrBinSearch::call(UErrorCode* status) { | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    CollatorAndCounter cc(coll); | 
| +    int32_t count = d16->count; | 
| +    for (int32_t i = 0; i < count; ++i) { | 
| +        (void)uprv_stableBinarySearch((char *)source, count, | 
| +                                      source + i, (int32_t)sizeof(UnicodeString *), | 
| +                                      UniStrCollatorComparator, &cc); | 
| +    } | 
| +    ops = cc.counter; | 
| +} | 
| + | 
| +class StringPieceBinSearch : public StringPieceCollPerfFunction { | 
| +public: | 
| +    StringPieceBinSearch(const Collator& coll, const UCollator *ucoll, const CA_char* data8) | 
| +            : StringPieceCollPerfFunction(coll, ucoll, data8) {} | 
| +    virtual ~StringPieceBinSearch(); | 
| +}; | 
| + | 
| +StringPieceBinSearch::~StringPieceBinSearch() {} | 
| + | 
| +// | 
| +// Test case performing binary searches in a sorted array of UTF-8 StringPiece's | 
| +// with Collator::compareUTF8(). | 
| +// | 
| +class StringPieceBinSearchCpp : public StringPieceBinSearch { | 
| +public: | 
| +    StringPieceBinSearchCpp(const Collator& coll, const UCollator *ucoll, const CA_char* data8) | 
| +            : StringPieceBinSearch(coll, ucoll, data8) {} | 
| +    virtual ~StringPieceBinSearchCpp(); | 
| +    virtual void call(UErrorCode* status); | 
| +}; | 
| + | 
| +StringPieceBinSearchCpp::~StringPieceBinSearchCpp() {} | 
| + | 
| +void StringPieceBinSearchCpp::call(UErrorCode* status) { | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    CollatorAndCounter cc(coll); | 
| +    int32_t count = d8->count; | 
| +    for (int32_t i = 0; i < count; ++i) { | 
| +        (void)uprv_stableBinarySearch((char *)source, count, | 
| +                                      source + i, (int32_t)sizeof(StringPiece), | 
| +                                      StringPieceCollatorComparator, &cc); | 
| +    } | 
| +    ops = cc.counter; | 
| +} | 
| + | 
| +// | 
| +// Test case performing binary searches in a sorted array of UTF-8 StringPiece's | 
| +// with ucol_strcollUTF8(). | 
| +// | 
| +class StringPieceBinSearchC : public StringPieceBinSearch { | 
| +public: | 
| +    StringPieceBinSearchC(const Collator& coll, const UCollator *ucoll, const CA_char* data8) | 
| +            : StringPieceBinSearch(coll, ucoll, data8) {} | 
| +    virtual ~StringPieceBinSearchC(); | 
| +    virtual void call(UErrorCode* status); | 
| +}; | 
| + | 
| +StringPieceBinSearchC::~StringPieceBinSearchC() {} | 
| + | 
| +void StringPieceBinSearchC::call(UErrorCode* status) { | 
| +    if (U_FAILURE(*status)) return; | 
| + | 
| +    CollatorAndCounter cc(coll, ucoll); | 
| +    int32_t count = d8->count; | 
| +    for (int32_t i = 0; i < count; ++i) { | 
| +        (void)uprv_stableBinarySearch((char *)source, count, | 
| +                                      source + i, (int32_t)sizeof(StringPiece), | 
| +                                      StringPieceUCollatorComparator, &cc); | 
| +    } | 
| +    ops = cc.counter; | 
| +} | 
| + | 
| + | 
| +class CollPerf2Test : public UPerfTest | 
| +{ | 
| +public: | 
| +    CollPerf2Test(int32_t argc, const char *argv[], UErrorCode &status); | 
| +    ~CollPerf2Test(); | 
| +    virtual UPerfFunction* runIndexedTest( | 
| +        int32_t index, UBool exec, const char *&name, char *par = NULL); | 
| + | 
| +private: | 
| +    UCollator* coll; | 
| +    Collator* collObj; | 
| + | 
| +    int32_t count; | 
| +    CA_uchar* data16; | 
| +    CA_char* data8; | 
| + | 
| +    CA_uchar* modData16; | 
| +    CA_char* modData8; | 
| + | 
| +    CA_uchar* sortedData16; | 
| +    CA_char* sortedData8; | 
| + | 
| +    CA_uchar* randomData16; | 
| +    CA_char* randomData8; | 
| + | 
| +    const CA_uchar* getData16(UErrorCode &status); | 
| +    const CA_char* getData8(UErrorCode &status); | 
| + | 
| +    const CA_uchar* getModData16(UErrorCode &status); | 
| +    const CA_char* getModData8(UErrorCode &status); | 
| + | 
| +    const CA_uchar* getSortedData16(UErrorCode &status); | 
| +    const CA_char* getSortedData8(UErrorCode &status); | 
| + | 
| +    const CA_uchar* getRandomData16(UErrorCode &status); | 
| +    const CA_char* getRandomData8(UErrorCode &status); | 
| + | 
| +    static CA_uchar* sortData16( | 
| +            const CA_uchar* d16, | 
| +            UComparator *cmp, const void *context, | 
| +            UErrorCode &status); | 
| +    static CA_char* getData8FromData16(const CA_uchar* d16, UErrorCode &status); | 
| + | 
| +    UPerfFunction* TestStrcoll(); | 
| +    UPerfFunction* TestStrcollNull(); | 
| +    UPerfFunction* TestStrcollSimilar(); | 
| + | 
| +    UPerfFunction* TestStrcollUTF8(); | 
| +    UPerfFunction* TestStrcollUTF8Null(); | 
| +    UPerfFunction* TestStrcollUTF8Similar(); | 
| + | 
| +    UPerfFunction* TestGetSortKey(); | 
| +    UPerfFunction* TestGetSortKeyNull(); | 
| + | 
| +    UPerfFunction* TestNextSortKeyPart_4All(); | 
| +    UPerfFunction* TestNextSortKeyPart_4x2(); | 
| +    UPerfFunction* TestNextSortKeyPart_4x4(); | 
| +    UPerfFunction* TestNextSortKeyPart_4x8(); | 
| +    UPerfFunction* TestNextSortKeyPart_32All(); | 
| +    UPerfFunction* TestNextSortKeyPart_32x2(); | 
| + | 
| +    UPerfFunction* TestNextSortKeyPartUTF8_4All(); | 
| +    UPerfFunction* TestNextSortKeyPartUTF8_4x2(); | 
| +    UPerfFunction* TestNextSortKeyPartUTF8_4x4(); | 
| +    UPerfFunction* TestNextSortKeyPartUTF8_4x8(); | 
| +    UPerfFunction* TestNextSortKeyPartUTF8_32All(); | 
| +    UPerfFunction* TestNextSortKeyPartUTF8_32x2(); | 
| + | 
| +    UPerfFunction* TestCppCompare(); | 
| +    UPerfFunction* TestCppCompareNull(); | 
| +    UPerfFunction* TestCppCompareSimilar(); | 
| + | 
| +    UPerfFunction* TestCppCompareUTF8(); | 
| +    UPerfFunction* TestCppCompareUTF8Null(); | 
| +    UPerfFunction* TestCppCompareUTF8Similar(); | 
| + | 
| +    UPerfFunction* TestCppGetCollationKey(); | 
| +    UPerfFunction* TestCppGetCollationKeyNull(); | 
| + | 
| +    UPerfFunction* TestUniStrSort(); | 
| +    UPerfFunction* TestStringPieceSortCpp(); | 
| +    UPerfFunction* TestStringPieceSortC(); | 
| + | 
| +    UPerfFunction* TestUniStrBinSearch(); | 
| +    UPerfFunction* TestStringPieceBinSearchCpp(); | 
| +    UPerfFunction* TestStringPieceBinSearchC(); | 
| +}; | 
| + | 
| +CollPerf2Test::CollPerf2Test(int32_t argc, const char *argv[], UErrorCode &status) : | 
| +    UPerfTest(argc, argv, status), | 
| +    coll(NULL), | 
| +    collObj(NULL), | 
| +    count(0), | 
| +    data16(NULL), | 
| +    data8(NULL), | 
| +    modData16(NULL), | 
| +    modData8(NULL), | 
| +    sortedData16(NULL), | 
| +    sortedData8(NULL), | 
| +    randomData16(NULL), | 
| +    randomData8(NULL) | 
| +{ | 
| +    if (U_FAILURE(status)) { | 
| +        return; | 
| +    } | 
| + | 
| +    if (locale == NULL){ | 
| +        locale = "root"; | 
| +    } | 
| + | 
| +    // Set up an ICU collator. | 
| +    // Starting with ICU 54 (ticket #8260), this supports standard collation locale keywords. | 
| +    coll = ucol_open(locale, &status); | 
| +    collObj = Collator::createInstance(locale, status); | 
| +} | 
| + | 
| +CollPerf2Test::~CollPerf2Test() | 
| +{ | 
| +    ucol_close(coll); | 
| +    delete collObj; | 
| + | 
| +    delete data16; | 
| +    delete data8; | 
| +    delete modData16; | 
| +    delete modData8; | 
| +    delete sortedData16; | 
| +    delete sortedData8; | 
| +    delete randomData16; | 
| +    delete randomData8; | 
| +} | 
| + | 
| +#define MAX_NUM_DATA 10000 | 
| + | 
| +const CA_uchar* CollPerf2Test::getData16(UErrorCode &status) | 
| +{ | 
| +    if (U_FAILURE(status)) return NULL; | 
| +    if (data16) return data16; | 
| + | 
| +    CA_uchar* d16 = new CA_uchar(); | 
| +    const UChar *line = NULL; | 
| +    int32_t len = 0; | 
| +    int32_t numData = 0; | 
| + | 
| +    for (;;) { | 
| +        line = ucbuf_readline(ucharBuf, &len, &status); | 
| +        if (line == NULL || U_FAILURE(status)) break; | 
| + | 
| +        // Refer to the source code of ucbuf_readline() | 
| +        // 1. 'len' includes the line terminal symbols | 
| +        // 2. The length of the line terminal symbols is only one character | 
| +        // 3. The Windows CR LF line terminal symbols will be converted to CR | 
| + | 
| +        if (len == 1 || line[0] == 0x23 /* '#' */) { | 
| +            continue; // skip empty/comment line | 
| +        } else { | 
| +            d16->append_one(len); | 
| +            UChar *p = d16->last(); | 
| +            u_memcpy(p, line, len - 1);  // exclude the CR | 
| +            p[len - 1] = 0;  // NUL-terminate | 
| + | 
| +            numData++; | 
| +            if (numData >= MAX_NUM_DATA) break; | 
| +        } | 
| +    } | 
| + | 
| +    if (U_SUCCESS(status)) { | 
| +        data16 = d16; | 
| +    } else { | 
| +        delete d16; | 
| +    } | 
| + | 
| +    return data16; | 
| +} | 
| + | 
| +const CA_char* CollPerf2Test::getData8(UErrorCode &status) | 
| +{ | 
| +    if (U_FAILURE(status)) return NULL; | 
| +    if (data8) return data8; | 
| +    return data8 = getData8FromData16(getData16(status), status); | 
| +} | 
| + | 
| +const CA_uchar* CollPerf2Test::getModData16(UErrorCode &status) | 
| +{ | 
| +    if (U_FAILURE(status)) return NULL; | 
| +    if (modData16) return modData16; | 
| + | 
| +    const CA_uchar* d16 = getData16(status); | 
| +    if (U_FAILURE(status)) return NULL; | 
| + | 
| +    CA_uchar* modData16 = new CA_uchar(); | 
| + | 
| +    for (int32_t i = 0; i < d16->count; i++) { | 
| +        const UChar *s = d16->dataOf(i); | 
| +        int32_t len = d16->lengthOf(i) + 1; // including NULL terminator | 
| + | 
| +        modData16->append_one(len); | 
| +        u_memcpy(modData16->last(), s, len); | 
| + | 
| +        // replacing the last character with a different character | 
| +        UChar *lastChar = &modData16->last()[len -2]; | 
| +        for (int32_t j = i + 1; j != i; j++) { | 
| +            if (j >= d16->count) { | 
| +                j = 0; | 
| +            } | 
| +            const UChar *s1 = d16->dataOf(j); | 
| +            UChar lastChar1 = s1[d16->lengthOf(j) - 1]; | 
| +            if (*lastChar != lastChar1) { | 
| +                *lastChar = lastChar1; | 
| +                break; | 
| +            } | 
| +        } | 
| +    } | 
| + | 
| +    return modData16; | 
| +} | 
| + | 
| +const CA_char* CollPerf2Test::getModData8(UErrorCode &status) | 
| +{ | 
| +    if (U_FAILURE(status)) return NULL; | 
| +    if (modData8) return modData8; | 
| +    return modData8 = getData8FromData16(getModData16(status), status); | 
| +} | 
| + | 
| +namespace { | 
| + | 
| +struct ArrayAndColl { | 
| +    ArrayAndColl(const CA_uchar* a, const Collator& c) : d16(a), coll(c) {} | 
| +    const CA_uchar* d16; | 
| +    const Collator& coll; | 
| +}; | 
| + | 
| +int32_t U_CALLCONV | 
| +U16CollatorComparator(const void* context, const void* left, const void* right) { | 
| +    const ArrayAndColl& ac = *(const ArrayAndColl*)context; | 
| +    const CA_uchar* d16 = ac.d16; | 
| +    int32_t leftIndex = *(const int32_t*)left; | 
| +    int32_t rightIndex = *(const int32_t*)right; | 
| +    UErrorCode errorCode = U_ZERO_ERROR; | 
| +    return ac.coll.compare(d16->dataOf(leftIndex), d16->lengthOf(leftIndex), | 
| +                           d16->dataOf(rightIndex), d16->lengthOf(rightIndex), | 
| +                           errorCode); | 
| +} | 
| + | 
| +int32_t U_CALLCONV | 
| +U16HashComparator(const void* context, const void* left, const void* right) { | 
| +    const CA_uchar* d16 = (const CA_uchar*)context; | 
| +    int32_t leftIndex = *(const int32_t*)left; | 
| +    int32_t rightIndex = *(const int32_t*)right; | 
| +    int32_t leftHash = ustr_hashUCharsN(d16->dataOf(leftIndex), d16->lengthOf(leftIndex)); | 
| +    int32_t rightHash = ustr_hashUCharsN(d16->dataOf(rightIndex), d16->lengthOf(rightIndex)); | 
| +    return leftHash < rightHash ? -1 : leftHash == rightHash ? 0 : 1; | 
| +} | 
| + | 
| +}  // namespace | 
| + | 
| +const CA_uchar* CollPerf2Test::getSortedData16(UErrorCode &status) { | 
| +    if (U_FAILURE(status)) return NULL; | 
| +    if (sortedData16) return sortedData16; | 
| + | 
| +    ArrayAndColl ac(getData16(status), *collObj); | 
| +    return sortedData16 = sortData16(ac.d16, U16CollatorComparator, &ac, status); | 
| +} | 
| + | 
| +const CA_char* CollPerf2Test::getSortedData8(UErrorCode &status) { | 
| +    if (U_FAILURE(status)) return NULL; | 
| +    if (sortedData8) return sortedData8; | 
| +    return sortedData8 = getData8FromData16(getSortedData16(status), status); | 
| +} | 
| + | 
| +const CA_uchar* CollPerf2Test::getRandomData16(UErrorCode &status) { | 
| +    if (U_FAILURE(status)) return NULL; | 
| +    if (randomData16) return randomData16; | 
| + | 
| +    // Sort the strings by their hash codes, which should be a reasonably pseudo-random order. | 
| +    const CA_uchar* d16 = getData16(status); | 
| +    return randomData16 = sortData16(d16, U16HashComparator, d16, status); | 
| +} | 
| + | 
| +const CA_char* CollPerf2Test::getRandomData8(UErrorCode &status) { | 
| +    if (U_FAILURE(status)) return NULL; | 
| +    if (randomData8) return randomData8; | 
| +    return randomData8 = getData8FromData16(getRandomData16(status), status); | 
| +} | 
| + | 
| +CA_uchar* CollPerf2Test::sortData16(const CA_uchar* d16, | 
| +                                    UComparator *cmp, const void *context, | 
| +                                    UErrorCode &status) { | 
| +    if (U_FAILURE(status)) return NULL; | 
| + | 
| +    LocalArray<int32_t> indexes(new int32_t[d16->count]); | 
| +    for (int32_t i = 0; i < d16->count; ++i) { | 
| +        indexes[i] = i; | 
| +    } | 
| +    uprv_sortArray(indexes.getAlias(), d16->count, 4, cmp, context, TRUE, &status); | 
| +    if (U_FAILURE(status)) return NULL; | 
| + | 
| +    // Copy the strings in sorted order into a new array. | 
| +    LocalPointer<CA_uchar> newD16(new CA_uchar()); | 
| +    for (int32_t i = 0; i < d16->count; i++) { | 
| +        int32_t j = indexes[i]; | 
| +        const UChar* s = d16->dataOf(j); | 
| +        int32_t len = d16->lengthOf(j); | 
| +        int32_t capacity = len + 1;  // including NULL terminator | 
| +        newD16->append_one(capacity); | 
| +        u_memcpy(newD16->last(), s, capacity); | 
| +    } | 
| + | 
| +    if (U_SUCCESS(status)) { | 
| +        return newD16.orphan(); | 
| +    } else { | 
| +        return NULL; | 
| +    } | 
| +} | 
| + | 
| +CA_char* CollPerf2Test::getData8FromData16(const CA_uchar* d16, UErrorCode &status) { | 
| +    if (U_FAILURE(status)) return NULL; | 
| + | 
| +    // UTF-16 -> UTF-8 conversion | 
| +    LocalPointer<CA_char> d8(new CA_char()); | 
| +    for (int32_t i = 0; i < d16->count; i++) { | 
| +        const UChar *s16 = d16->dataOf(i); | 
| +        int32_t length16 = d16->lengthOf(i); | 
| + | 
| +        // get length in UTF-8 | 
| +        int32_t length8; | 
| +        u_strToUTF8(NULL, 0, &length8, s16, length16, &status); | 
| +        if (status == U_BUFFER_OVERFLOW_ERROR || status == U_ZERO_ERROR){ | 
| +            status = U_ZERO_ERROR; | 
| +        } else { | 
| +            break; | 
| +        } | 
| +        int32_t capacity8 = length8 + 1;  // plus terminal NULL | 
| +        d8->append_one(capacity8); | 
| + | 
| +        // convert to UTF-8 | 
| +        u_strToUTF8(d8->last(), capacity8, NULL, s16, length16, &status); | 
| +        if (U_FAILURE(status)) break; | 
| +    } | 
| + | 
| +    if (U_SUCCESS(status)) { | 
| +        return d8.orphan(); | 
| +    } else { | 
| +        return NULL; | 
| +    } | 
| +} | 
| + | 
| +UPerfFunction* | 
| +CollPerf2Test::runIndexedTest(int32_t index, UBool exec, const char *&name, char *par /*= NULL*/) | 
| +{ | 
| +    (void)par; | 
| +    TESTCASE_AUTO_BEGIN; | 
| + | 
| +    TESTCASE_AUTO(TestStrcoll); | 
| +    TESTCASE_AUTO(TestStrcollNull); | 
| +    TESTCASE_AUTO(TestStrcollSimilar); | 
| + | 
| +    TESTCASE_AUTO(TestStrcollUTF8); | 
| +    TESTCASE_AUTO(TestStrcollUTF8Null); | 
| +    TESTCASE_AUTO(TestStrcollUTF8Similar); | 
| + | 
| +    TESTCASE_AUTO(TestGetSortKey); | 
| +    TESTCASE_AUTO(TestGetSortKeyNull); | 
| + | 
| +    TESTCASE_AUTO(TestNextSortKeyPart_4All); | 
| +    TESTCASE_AUTO(TestNextSortKeyPart_4x4); | 
| +    TESTCASE_AUTO(TestNextSortKeyPart_4x8); | 
| +    TESTCASE_AUTO(TestNextSortKeyPart_32All); | 
| +    TESTCASE_AUTO(TestNextSortKeyPart_32x2); | 
| + | 
| +    TESTCASE_AUTO(TestNextSortKeyPartUTF8_4All); | 
| +    TESTCASE_AUTO(TestNextSortKeyPartUTF8_4x4); | 
| +    TESTCASE_AUTO(TestNextSortKeyPartUTF8_4x8); | 
| +    TESTCASE_AUTO(TestNextSortKeyPartUTF8_32All); | 
| +    TESTCASE_AUTO(TestNextSortKeyPartUTF8_32x2); | 
| + | 
| +    TESTCASE_AUTO(TestCppCompare); | 
| +    TESTCASE_AUTO(TestCppCompareNull); | 
| +    TESTCASE_AUTO(TestCppCompareSimilar); | 
| + | 
| +    TESTCASE_AUTO(TestCppCompareUTF8); | 
| +    TESTCASE_AUTO(TestCppCompareUTF8Null); | 
| +    TESTCASE_AUTO(TestCppCompareUTF8Similar); | 
| + | 
| +    TESTCASE_AUTO(TestCppGetCollationKey); | 
| +    TESTCASE_AUTO(TestCppGetCollationKeyNull); | 
| + | 
| +    TESTCASE_AUTO(TestUniStrSort); | 
| +    TESTCASE_AUTO(TestStringPieceSortCpp); | 
| +    TESTCASE_AUTO(TestStringPieceSortC); | 
| + | 
| +    TESTCASE_AUTO(TestUniStrBinSearch); | 
| +    TESTCASE_AUTO(TestStringPieceBinSearchCpp); | 
| +    TESTCASE_AUTO(TestStringPieceBinSearchC); | 
| + | 
| +    TESTCASE_AUTO_END; | 
| +    return NULL; | 
| +} | 
| + | 
| + | 
| + | 
| +UPerfFunction* CollPerf2Test::TestStrcoll() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    Strcoll *testCase = new Strcoll(coll, getData16(status), TRUE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestStrcollNull() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    Strcoll *testCase = new Strcoll(coll, getData16(status), FALSE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestStrcollSimilar() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    Strcoll_2 *testCase = new Strcoll_2(coll, getData16(status), getModData16(status), TRUE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestStrcollUTF8() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    StrcollUTF8 *testCase = new StrcollUTF8(coll, getData8(status), TRUE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestStrcollUTF8Null() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    StrcollUTF8 *testCase = new StrcollUTF8(coll, getData8(status),FALSE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestStrcollUTF8Similar() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    StrcollUTF8_2 *testCase = new StrcollUTF8_2(coll, getData8(status), getModData8(status), TRUE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestGetSortKey() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    GetSortKey *testCase = new GetSortKey(coll, getData16(status), TRUE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestGetSortKeyNull() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    GetSortKey *testCase = new GetSortKey(coll, getData16(status), FALSE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestNextSortKeyPart_4All() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    NextSortKeyPart *testCase = new NextSortKeyPart(coll, getData16(status), 4 /* bufSize */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestNextSortKeyPart_4x4() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    NextSortKeyPart *testCase = new NextSortKeyPart(coll, getData16(status), 4 /* bufSize */, 4 /* maxIteration */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestNextSortKeyPart_4x8() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    NextSortKeyPart *testCase = new NextSortKeyPart(coll, getData16(status), 4 /* bufSize */, 8 /* maxIteration */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestNextSortKeyPart_32All() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    NextSortKeyPart *testCase = new NextSortKeyPart(coll, getData16(status), 32 /* bufSize */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestNextSortKeyPart_32x2() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    NextSortKeyPart *testCase = new NextSortKeyPart(coll, getData16(status), 32 /* bufSize */, 2 /* maxIteration */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestNextSortKeyPartUTF8_4All() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    NextSortKeyPartUTF8 *testCase = new NextSortKeyPartUTF8(coll, getData8(status), 4 /* bufSize */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestNextSortKeyPartUTF8_4x4() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    NextSortKeyPartUTF8 *testCase = new NextSortKeyPartUTF8(coll, getData8(status), 4 /* bufSize */, 4 /* maxIteration */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestNextSortKeyPartUTF8_4x8() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    NextSortKeyPartUTF8 *testCase = new NextSortKeyPartUTF8(coll, getData8(status), 4 /* bufSize */, 8 /* maxIteration */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestNextSortKeyPartUTF8_32All() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    NextSortKeyPartUTF8 *testCase = new NextSortKeyPartUTF8(coll, getData8(status), 32 /* bufSize */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestNextSortKeyPartUTF8_32x2() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    NextSortKeyPartUTF8 *testCase = new NextSortKeyPartUTF8(coll, getData8(status), 32 /* bufSize */, 2 /* maxIteration */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestCppCompare() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    CppCompare *testCase = new CppCompare(collObj, getData16(status), TRUE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestCppCompareNull() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    CppCompare *testCase = new CppCompare(collObj, getData16(status), FALSE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestCppCompareSimilar() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    CppCompare_2 *testCase = new CppCompare_2(collObj, getData16(status), getModData16(status), TRUE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestCppCompareUTF8() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    CppCompareUTF8 *testCase = new CppCompareUTF8(collObj, getData8(status), TRUE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestCppCompareUTF8Null() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    CppCompareUTF8 *testCase = new CppCompareUTF8(collObj, getData8(status), FALSE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestCppCompareUTF8Similar() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    CppCompareUTF8_2 *testCase = new CppCompareUTF8_2(collObj, getData8(status), getModData8(status), TRUE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestCppGetCollationKey() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    CppGetCollationKey *testCase = new CppGetCollationKey(collObj, getData16(status), TRUE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestCppGetCollationKeyNull() | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    CppGetCollationKey *testCase = new CppGetCollationKey(collObj, getData16(status), FALSE /* useLen */); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestUniStrSort() { | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    UPerfFunction *testCase = new UniStrSort(*collObj, coll, getRandomData16(status)); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestStringPieceSortCpp() { | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    UPerfFunction *testCase = new StringPieceSortCpp(*collObj, coll, getRandomData8(status)); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestStringPieceSortC() { | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    UPerfFunction *testCase = new StringPieceSortC(*collObj, coll, getRandomData8(status)); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestUniStrBinSearch() { | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    UPerfFunction *testCase = new UniStrBinSearch(*collObj, coll, getSortedData16(status)); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestStringPieceBinSearchCpp() { | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    UPerfFunction *testCase = new StringPieceBinSearchCpp(*collObj, coll, getSortedData8(status)); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| +UPerfFunction* CollPerf2Test::TestStringPieceBinSearchC() { | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    UPerfFunction *testCase = new StringPieceBinSearchC(*collObj, coll, getSortedData8(status)); | 
| +    if (U_FAILURE(status)) { | 
| +        delete testCase; | 
| +        return NULL; | 
| +    } | 
| +    return testCase; | 
| +} | 
| + | 
| + | 
| +int main(int argc, const char *argv[]) | 
| +{ | 
| +    UErrorCode status = U_ZERO_ERROR; | 
| +    CollPerf2Test test(argc, argv, status); | 
| + | 
| +    if (U_FAILURE(status)){ | 
| +        printf("The error is %s\n", u_errorName(status)); | 
| +        //TODO: print usage here | 
| +        return status; | 
| +    } | 
| + | 
| +    if (test.run() == FALSE){ | 
| +        fprintf(stderr, "FAILED: Tests could not be run please check the arguments.\n"); | 
| +        return -1; | 
| +    } | 
| +    return 0; | 
| +} | 
|  |