/*
***********************************************************************
* © 2016 and later: Unicode, Inc. and others.
* License & terms of use: http://www.unicode.org/copyright.html
***********************************************************************
***********************************************************************
* 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;
}
