1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/********************************************************************
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* COPYRIGHT:
354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius* Copyright (C) 2001-2012 IBM, Inc.   All Rights Reserved.
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru********************************************************************/
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h>
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdlib.h>
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <locale.h>
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <limits.h>
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <string.h>
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uperf.h"
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uoptions.h"
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/coll.h"
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <unicode/ucoleitr.h>
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if !U_PLATFORM_HAS_WIN32_API
1854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define DWORD uint32_t
1954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define WCHAR wchar_t
2054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* To store an array of string<UNIT> in continue space.
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSince string<UNIT> itself is treated as an array of UNIT, this
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass will ease our memory management for an array of string<UNIT>.
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//template<typename UNIT>
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define COMPATCT_ARRAY(CompactArrays, UNIT) \
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct CompactArrays{\
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CompactArrays(const CompactArrays & );\
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CompactArrays & operator=(const CompactArrays & );\
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t   count;/*total number of the strings*/ \
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t * index;/*relative offset in data*/ \
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UNIT    * data; /*the real space to hold strings*/ \
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    \
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ~CompactArrays(){free(index);free(data);} \
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CompactArrays():data(NULL), index(NULL), count(0){ \
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    index = (int32_t *) realloc(index, sizeof(int32_t)); \
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    index[0] = 0; \
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } \
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void append_one(int32_t theLen){ /*include terminal NULL*/ \
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    count++; \
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    index = (int32_t *) realloc(index, sizeof(int32_t) * (count + 1)); \
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    index[count] = index[count - 1] + theLen; \
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    data = (UNIT *) realloc(data, sizeof(UNIT) * index[count]); \
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } \
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UNIT * last(){return data + index[count - 1];} \
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UNIT * dataOf(int32_t i){return data + index[i];} \
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t lengthOf(int i){return index[i+1] - index[i] - 1; }	/*exclude terminating NULL*/  \
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//typedef CompactArrays<UChar> CA_uchar;
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//typedef CompactArrays<char> CA_char;
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//typedef CompactArrays<uint8_t> CA_uint8;
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//typedef CompactArrays<WCHAR> CA_win_wchar;
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCOMPATCT_ARRAY(CA_uchar, UChar)
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCOMPATCT_ARRAY(CA_char, char)
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCOMPATCT_ARRAY(CA_uint8, uint8_t)
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCOMPATCT_ARRAY(CA_win_wchar, WCHAR)
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct DataIndex {
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static DWORD        win_langid;     // for qsort callback function
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static UCollator *  col;            // for qsort callback function
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uint8_t *   icu_key;
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar *     icu_data;
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     icu_data_len;
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char*       posix_key;
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char*       posix_data;
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     posix_data_len;
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char*       win_key;
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    WCHAR *     win_data;
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     win_data_len;
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDWORD DataIndex::win_langid;
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUCollator * DataIndex::col;
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass CmdKeyGen : public UPerfFunction {
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    typedef	void (CmdKeyGen::* Func)(int32_t);
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    enum{MAX_KEY_LENGTH = 5000};
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCollator * col;
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DWORD       win_langid;
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     count;
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * data;
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Func 	    fn;
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    union { // to save sapce
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uint8_t		icu_key[MAX_KEY_LENGTH];
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        char        posix_key[MAX_KEY_LENGTH];
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        WCHAR		win_key[MAX_KEY_LENGTH];
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    };
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CmdKeyGen(UErrorCode, UCollator * col,DWORD win_langid, int32_t count, DataIndex * data,Func fn,int32_t)
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        :col(col),win_langid(win_langid), count(count), data(data), fn(fn){}
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        virtual long getOperationsPerIteration(){return count;}
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        virtual void call(UErrorCode* status){
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            for(int32_t i = 0; i< count; i++){
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                (this->*fn)(i);
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void icu_key_null(int32_t i){
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_getSortKey(col, data[i].icu_data, -1, icu_key, MAX_KEY_LENGTH);
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void icu_key_len(int32_t i){
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_getSortKey(col, data[i].icu_data, data[i].icu_data_len, icu_key, MAX_KEY_LENGTH);
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
11554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // pre-generated in CollPerfTest::prepareData(), need not to check error here
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void win_key_null(int32_t i){
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            //LCMAP_SORTsk             0x00000400  // WC sort sk (normalize)
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            LCMapStringW(win_langid, LCMAP_SORTKEY, data[i].win_data, -1, win_key, MAX_KEY_LENGTH);
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void win_key_len(int32_t i){
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            LCMapStringW(win_langid, LCMAP_SORTKEY, data[i].win_data, data[i].win_data_len, win_key, MAX_KEY_LENGTH);
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
12554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void posix_key_null(int32_t i){
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            strxfrm(posix_key, data[i].posix_data, MAX_KEY_LENGTH);
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass CmdIter : public UPerfFunction {
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    typedef	void (CmdIter::* Func)(UErrorCode* , int32_t );
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t             count;
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CA_uchar *          data;
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Func                fn;
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCollationElements *iter;
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t             exec_count;
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CmdIter(UErrorCode & status, UCollator * col, int32_t count, CA_uchar *data, Func fn, int32_t,int32_t)
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        :count(count), data(data), fn(fn){
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exec_count = 0;
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UChar dummytext[] = {0, 0};
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            iter = ucol_openElements(col, NULL, 0, &status);
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setText(iter, dummytext, 1, &status);
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ~CmdIter(){
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_closeElements(iter);
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        virtual long getOperationsPerIteration(){return exec_count ? exec_count : 1;}
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        virtual void call(UErrorCode* status){
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exec_count = 0;
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            for(int32_t i = 0; i< count; i++){
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                (this->*fn)(status, i);
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void icu_forward_null(UErrorCode* status, int32_t i){
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setText(iter, data->dataOf(i), -1, status);
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while (ucol_next(iter, status) != UCOL_NULLORDER) exec_count++;
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void icu_forward_len(UErrorCode* status, int32_t i){
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setText(iter, data->dataOf(i), data->lengthOf(i) , status);
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while (ucol_next(iter, status) != UCOL_NULLORDER) exec_count++;
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void icu_backward_null(UErrorCode* status, int32_t i){
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setText(iter, data->dataOf(i), -1, status);
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while (ucol_previous(iter, status) != UCOL_NULLORDER) exec_count++;
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void icu_backward_len(UErrorCode* status, int32_t i){
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setText(iter, data->dataOf(i), data->lengthOf(i) , status);
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while (ucol_previous(iter, status) != UCOL_NULLORDER) exec_count++;
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass CmdIterAll : public UPerfFunction {
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    typedef	void (CmdIterAll::* Func)(UErrorCode* status);
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     count;
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar *     data;
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Func        fn;
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCollationElements *iter;
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     exec_count;
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    enum CALL {forward_null, forward_len, backward_null, backward_len};
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ~CmdIterAll(){
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucol_closeElements(iter);
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CmdIterAll(UErrorCode & status, UCollator * col, int32_t count,  UChar * data, CALL call,int32_t,int32_t)
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        :count(count),data(data)
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    {
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        exec_count = 0;
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (call == forward_null || call == backward_null) {
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            iter = ucol_openElements(col, data, -1, &status);
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            iter = ucol_openElements(col, data, count, &status);
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (call == forward_null || call == forward_len){
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fn = &CmdIterAll::icu_forward_all;
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fn = &CmdIterAll::icu_backward_all;
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    virtual long getOperationsPerIteration(){return exec_count ? exec_count : 1;}
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    virtual void call(UErrorCode* status){
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        (this->*fn)(status);
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void icu_forward_all(UErrorCode* status){
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int strlen = count - 5;
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int count5 = 5;
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int strindex = 0;
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucol_setOffset(iter, strindex, status);
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (TRUE) {
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (ucol_next(iter, status) == UCOL_NULLORDER) {
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exec_count++;
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            count5 --;
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (count5 == 0) {
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                strindex += 10;
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (strindex > strlen) {
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ucol_setOffset(iter, strindex, status);
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                count5 = 5;
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void icu_backward_all(UErrorCode* status){
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int strlen = count;
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int count5 = 5;
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int strindex = 5;
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucol_setOffset(iter, strindex, status);
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (TRUE) {
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (ucol_previous(iter, status) == UCOL_NULLORDER) {
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exec_count++;
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            count5 --;
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (count5 == 0) {
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                strindex += 10;
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (strindex > strlen) {
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ucol_setOffset(iter, strindex, status);
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                count5 = 5;
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct CmdQsort : public UPerfFunction{
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int q_random(const void * a, const void * b){
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uint8_t * key_a = ((DataIndex *)a)->icu_key;
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uint8_t * key_b = ((DataIndex *)b)->icu_key;
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int   val_a = 0;
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int   val_b = 0;
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (*key_a != 0) {val_a += val_a*37 + *key_a++;}
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (*key_b != 0) {val_b += val_b*37 + *key_b++;}
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return val_a - val_b;
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define QCAST() \
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * da = (DataIndex *) a; \
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * db = (DataIndex *) b; \
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ++exec_count
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int icu_strcoll_null(const void *a, const void *b){
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        QCAST();
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return ucol_strcoll(da->col, da->icu_data, -1, db->icu_data, -1) - UCOL_EQUAL;
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int icu_strcoll_len(const void *a, const void *b){
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        QCAST();
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return ucol_strcoll(da->col, da->icu_data, da->icu_data_len, db->icu_data, db->icu_data_len) - UCOL_EQUAL;
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int icu_cmpkey (const void *a, const void *b){
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        QCAST();
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return strcmp((char *) da->icu_key, (char *) db->icu_key);
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
29754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int win_cmp_null(const void *a, const void *b) {
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        QCAST();
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        //CSTR_LESS_THAN		1
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        //CSTR_EQUAL			2
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        //CSTR_GREATER_THAN		3
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int t = CompareStringW(da->win_langid, 0, da->win_data, -1, db->win_data, -1);
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (t == 0){
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stderr, "CompareStringW error, error number %x\n", GetLastError());
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exit(-1);
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else{
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return t - CSTR_EQUAL;
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int win_cmp_len(const void *a, const void *b) {
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        QCAST();
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int t = CompareStringW(da->win_langid, 0, da->win_data, da->win_data_len, db->win_data, db->win_data_len);
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (t == 0){
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fprintf(stderr, "CompareStringW error, error number %x\n", GetLastError());
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exit(-1);
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else{
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return t - CSTR_EQUAL;
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
32254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define QFUNC(name, func, data) \
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int name (const void *a, const void *b){ \
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    QCAST(); \
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return func(da->data, db->data); \
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    QFUNC(posix_strcoll_null, strcoll, posix_data)
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        QFUNC(posix_cmpkey, strcmp, posix_key)
33254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        QFUNC(win_cmpkey, strcmp, win_key)
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        QFUNC(win_wcscmp, wcscmp, win_data)
33554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        QFUNC(icu_strcmp, u_strcmp, icu_data)
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        QFUNC(icu_cmpcpo, u_strcmpCodePointOrder, icu_data)
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate:
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int32_t exec_count; // potential muilt-thread problem
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    typedef	int (* Func)(const void *, const void *);
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Func    fn;
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void *  base;   //Start of target array.
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t num;    //Array size in elements.
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t width;  //Element size in bytes.
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void *  backup; //copy source of base
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CmdQsort(UErrorCode & status,void *theBase, int32_t num, int32_t width, Func fn, int32_t,int32_t)
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        :backup(theBase),num(num),width(width),fn(fn){
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            base = malloc(num * width);
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            time_empty(100, &status); // warm memory/cache
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ~CmdQsort(){
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            free(base);
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void empty_call(){
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exec_count = 0;
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            memcpy(base, backup, num * width);
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        double time_empty(int32_t n, UErrorCode* status) {
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UTimer start, stop;
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            utimer_getTime(&start);
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while (n-- > 0) {
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                empty_call();
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            utimer_getTime(&stop);
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return utimer_getDeltaSeconds(&start,&stop); // ms
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        virtual void call(UErrorCode* status){
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exec_count = 0;
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            memcpy(base, backup, num * width);
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            qsort(base, num, width, fn);
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        virtual double time(int32_t n, UErrorCode* status) {
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            double t1 = time_empty(n,status);
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            double t2 = UPerfFunction::time(n, status);
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return  t2-t1;// < 0 ? t2 : t2-t1;
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        virtual long getOperationsPerIteration(){ return exec_count?exec_count:1;}
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t CmdQsort::exec_count;
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass CmdBinSearch : public UPerfFunction{
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    typedef	int (CmdBinSearch::* Func)(int, int);
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCollator * col;
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DWORD       win_langid;
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     count;
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * rnd;
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * ord;
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    Func 	    fn;
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     exec_count;
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CmdBinSearch(UErrorCode, UCollator * col,DWORD win_langid,int32_t count,DataIndex * rnd,DataIndex * ord,Func fn)
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        :col(col),win_langid(win_langid), count(count), rnd(rnd), ord(ord), fn(fn),exec_count(0){}
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        virtual void call(UErrorCode* status){
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            exec_count = 0;
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            for(int32_t i = 0; i< count; i++){ // search all data
411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                binary_search(i);
412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        virtual long getOperationsPerIteration(){ return exec_count?exec_count:1;}
415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        void binary_search(int32_t random)	{
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int low   = 0;
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int high  = count - 1;
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int guess;
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int last_guess = -1;
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int r;
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            while (TRUE) {
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                guess = (high + low)/2;
424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (last_guess == guess) break; // nothing to search
425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                r = (this->*fn)(random, guess);
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                exec_count++;
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (r == 0)
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    return;	// found, search end.
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (r < 0) {
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    high = guess;
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else {
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    low  = guess;
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                last_guess = guess;
437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int icu_strcoll_null(int32_t i, int32_t j){
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return ucol_strcoll(col, rnd[i].icu_data, -1, ord[j].icu_data,-1);
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int icu_strcoll_len(int32_t i, int32_t j){
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return ucol_strcoll(col, rnd[i].icu_data, rnd[i].icu_data_len, ord[j].icu_data, ord[j].icu_data_len);
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int icu_cmpkey(int32_t i, int32_t j) {
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return strcmp( (char *) rnd[i].icu_key, (char *) ord[j].icu_key );
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
45254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int win_cmp_null(int32_t i, int32_t j) {
454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int t = CompareStringW(win_langid, 0, rnd[i].win_data, -1, ord[j].win_data, -1);
455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (t == 0){
456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stderr, "CompareStringW error, error number %x\n", GetLastError());
457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                exit(-1);
458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else{
459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return t - CSTR_EQUAL;
460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int win_cmp_len(int32_t i, int32_t j) {
464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int t = CompareStringW(win_langid, 0, rnd[i].win_data, rnd[i].win_data_len, ord[j].win_data, ord[j].win_data_len);
465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (t == 0){
466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stderr, "CompareStringW error, error number %x\n", GetLastError());
467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                exit(-1);
468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else{
469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return t - CSTR_EQUAL;
470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
47254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define BFUNC(name, func, data) \
475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int name(int32_t i, int32_t j) { \
476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return func(rnd[i].data, ord[j].data); \
477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        BFUNC(posix_strcoll_null, strcoll, posix_data)
480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            BFUNC(posix_cmpkey, strcmp, posix_key)
481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            BFUNC(win_cmpkey, strcmp, win_key)
482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            BFUNC(win_wcscmp, wcscmp, win_data)
483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            BFUNC(icu_strcmp, u_strcmp, icu_data)
484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            BFUNC(icu_cmpcpo, u_strcmpCodePointOrder, icu_data)
485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass CollPerfTest : public UPerfTest {
488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UCollator *     col;
490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DWORD           win_langid;
491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UChar * icu_data_all;
493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t icu_data_all_len;
494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t         count;
496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CA_uchar *      icu_data;
497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CA_uint8 *      icu_key;
498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CA_char *       posix_data;
499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CA_char *       posix_key;
500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CA_win_wchar *  win_data;
501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CA_char *       win_key;
502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * rnd_index; // random by icu key
504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * ord_win_data;
505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * ord_win_key;
506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * ord_posix_data;
507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * ord_posix_key;
508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * ord_icu_data;
509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * ord_icu_key;
510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * ord_win_wcscmp;
511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * ord_icu_strcmp;
512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DataIndex * ord_icu_cmpcpo;
513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    virtual ~CollPerfTest(){
515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucol_close(col);
516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete [] icu_data_all;
517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete icu_data;
518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete icu_key;
519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete posix_data;
520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete posix_key;
521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete win_data;
522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete win_key;
523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] rnd_index;
524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] ord_win_data;
525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] ord_win_key;
526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] ord_posix_data;
527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] ord_posix_key;
528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] ord_icu_data;
529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] ord_icu_key;
530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] ord_win_wcscmp;
531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] ord_icu_strcmp;
532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] ord_icu_cmpcpo;
533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CollPerfTest(int32_t argc, const char* argv[], UErrorCode& status):UPerfTest(argc, argv, status){
536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        col = NULL;
537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        icu_data_all = NULL;
538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        icu_data = NULL;
539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        icu_key = NULL;
540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        posix_data = NULL;
541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        posix_key = NULL;
542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        win_data =NULL;
543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        win_key = NULL;
544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        rnd_index = NULL;
546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ord_win_data= NULL;
547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ord_win_key= NULL;
548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ord_posix_data= NULL;
549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ord_posix_key= NULL;
550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ord_icu_data= NULL;
551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ord_icu_key= NULL;
552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ord_win_wcscmp = NULL;
553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ord_icu_strcmp = NULL;
554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ord_icu_cmpcpo = NULL;
555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(status)){
557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Parse additional arguments
561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UOption options[] = {
563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UOPTION_DEF("langid", 'i', UOPT_REQUIRES_ARG),        // Windows Language ID number.
564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UOPTION_DEF("rulefile", 'r', UOPT_REQUIRES_ARG),      // --rulefile <filename>
565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // Collation related arguments. All are optional.
566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // To simplify parsing, two choice arguments are disigned as NO_ARG.
567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // The default value is UPPER word in the comment
568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UOPTION_DEF("c_french", 'f', UOPT_NO_ARG),          // --french <on | OFF>
569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UOPTION_DEF("c_alternate", 'a', UOPT_NO_ARG),       // --alternate <NON_IGNORE | shifted>
570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UOPTION_DEF("c_casefirst", 'c', UOPT_REQUIRES_ARG), // --casefirst <lower | upper | OFF>
571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UOPTION_DEF("c_caselevel", 'l', UOPT_NO_ARG),       // --caselevel <on | OFF>
572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UOPTION_DEF("c_normal", 'n', UOPT_NO_ARG),          // --normal <on | OFF>
573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UOPTION_DEF("c_strength", 's', UOPT_REQUIRES_ARG),  // --strength <1-5>
574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        };
575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t opt_len = (sizeof(options)/sizeof(options[0]));
576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        enum {i, r,f,a,c,l,n,s};   // The buffer between the option items' order and their references
577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        _remainingArgc = u_parseArgs(_remainingArgc, (char**)argv, opt_len, options);
579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (_remainingArgc < 0){
581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            status = U_ILLEGAL_ARGUMENT_ERROR;
582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (locale == NULL){
586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            locale = "en_US";   // set default locale
587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
58954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[i].doesOccur) {
591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            char *endp;
592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int tmp = strtol(options[i].value, &endp, 0);
593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (endp == options[i].value) {
594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                status = U_ILLEGAL_ARGUMENT_ERROR;
595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            win_langid = MAKELCID(tmp, SORT_DEFAULT);
598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            win_langid = uloc_getLCID(locale);
600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
60154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        //  Set up an ICU collator
604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[r].doesOccur) {
605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // TODO: implement it
606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            col = ucol_open(locale, &status);
608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(status)) {
609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[f].doesOccur) {
614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setAttribute(col, UCOL_FRENCH_COLLATION, UCOL_ON, &status);
615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setAttribute(col, UCOL_FRENCH_COLLATION, UCOL_OFF, &status);
617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[a].doesOccur) {
620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setAttribute(col, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED, &status);
621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[c].doesOccur) { // strcmp() has i18n encoding problem
624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (strcmp("lower", options[c].value) == 0){
625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ucol_setAttribute(col, UCOL_CASE_FIRST, UCOL_LOWER_FIRST, &status);
626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else if (strcmp("upper", options[c].value) == 0) {
627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ucol_setAttribute(col, UCOL_CASE_FIRST, UCOL_UPPER_FIRST, &status);
628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                status = U_ILLEGAL_ARGUMENT_ERROR;
630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[l].doesOccur){
635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setAttribute(col, UCOL_CASE_LEVEL, UCOL_ON, &status);
636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[n].doesOccur){
639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setAttribute(col, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (options[s].doesOccur) {
643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            char *endp;
644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int tmp = strtol(options[l].value, &endp, 0);
645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (endp == options[l].value) {
646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                status = U_ILLEGAL_ARGUMENT_ERROR;
647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            switch (tmp) {
650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            case 1:	ucol_setAttribute(col, UCOL_STRENGTH, UCOL_PRIMARY, &status);		break;
651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            case 2:	ucol_setAttribute(col, UCOL_STRENGTH, UCOL_SECONDARY, &status);		break;
652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            case 3:	ucol_setAttribute(col, UCOL_STRENGTH, UCOL_TERTIARY, &status);		break;
653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            case 4:	ucol_setAttribute(col, UCOL_STRENGTH, UCOL_QUATERNARY, &status);	break;
654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            case 5:	ucol_setAttribute(col, UCOL_STRENGTH, UCOL_IDENTICAL, &status);		break;
655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            default: status = U_ILLEGAL_ARGUMENT_ERROR;					return;
656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        prepareData(status);
659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //to avoid use the annoying 'id' in TESTCASE(id,test) macro or the like
662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define TEST(testname, classname, arg1, arg2, arg3, arg4, arg5, arg6) \
663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(temp == index) {\
664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    name = #testname;\
665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (exec) {\
666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;\
667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UPerfFunction * t = new classname(status,arg1, arg2, arg3, arg4, arg5, arg6);\
668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {\
669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete t;\
670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return NULL;\
671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {\
672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return t;\
673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }\
674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {\
675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return NULL;\
676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }\
677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }\
678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    temp++\
679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    virtual UPerfFunction* runIndexedTest( /*[in]*/int32_t index, /*[in]*/UBool exec, /*[out]*/const char* &name, /*[in]*/ char* par = NULL ){
682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int temp = 0;
683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define TEST_KEYGEN(testname, func)\
685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TEST(testname, CmdKeyGen, col, win_langid, count, rnd_index, &CmdKeyGen::func, 0)
686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_KEYGEN(TestIcu_KeyGen_null, icu_key_null);
687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_KEYGEN(TestIcu_KeyGen_len,  icu_key_len);
688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_KEYGEN(TestPosix_KeyGen_null, posix_key_null);
68954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_KEYGEN(TestWin_KeyGen_null, win_key_null);
691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_KEYGEN(TestWin_KeyGen_len, win_key_len);
69254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define TEST_ITER(testname, func)\
695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TEST(testname, CmdIter, col, count, icu_data, &CmdIter::func,0,0)
696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_ITER(TestIcu_ForwardIter_null, icu_forward_null);
697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_ITER(TestIcu_ForwardIter_len, icu_forward_len);
698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_ITER(TestIcu_BackwardIter_null, icu_backward_null);
699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_ITER(TestIcu_BackwardIter_len, icu_backward_len);
700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define TEST_ITER_ALL(testname, func)\
702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TEST(testname, CmdIterAll, col, icu_data_all_len, icu_data_all, CmdIterAll::func,0,0)
703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_ITER_ALL(TestIcu_ForwardIter_all_null, forward_null);
704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_ITER_ALL(TestIcu_ForwardIter_all_len, forward_len);
705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_ITER_ALL(TestIcu_BackwardIter_all_null, backward_null);
706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_ITER_ALL(TestIcu_BackwardIter_all_len, backward_len);
707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define TEST_QSORT(testname, func)\
709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TEST(testname, CmdQsort, rnd_index, count, sizeof(DataIndex), CmdQsort::func,0,0)
710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_QSORT(TestIcu_qsort_strcoll_null, icu_strcoll_null);
711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_QSORT(TestIcu_qsort_strcoll_len, icu_strcoll_len);
712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_QSORT(TestIcu_qsort_usekey, icu_cmpkey);
713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_QSORT(TestPosix_qsort_strcoll_null, posix_strcoll_null);
714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_QSORT(TestPosix_qsort_usekey, posix_cmpkey);
71554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_QSORT(TestWin_qsort_CompareStringW_null, win_cmp_null);
717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_QSORT(TestWin_qsort_CompareStringW_len, win_cmp_len);
718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_QSORT(TestWin_qsort_usekey, win_cmpkey);
71954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define TEST_BIN(testname, func)\
722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TEST(testname, CmdBinSearch, col, win_langid, count, rnd_index, ord_icu_key, &CmdBinSearch::func)
723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestIcu_BinarySearch_strcoll_null, icu_strcoll_null);
724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestIcu_BinarySearch_strcoll_len, icu_strcoll_len);
725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestIcu_BinarySearch_usekey, icu_cmpkey);
726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestIcu_BinarySearch_strcmp, icu_strcmp);
727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestIcu_BinarySearch_cmpCPO, icu_cmpcpo);
728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestPosix_BinarySearch_strcoll_null, posix_strcoll_null);
729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestPosix_BinarySearch_usekey, posix_cmpkey);
73054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestWin_BinarySearch_CompareStringW_null, win_cmp_null);
732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestWin_BinarySearch_CompareStringW_len, win_cmp_len);
73354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestWin_BinarySearch_usekey, win_cmpkey);
735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TEST_BIN(TestWin_BinarySearch_wcscmp, win_wcscmp);
736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        name="";
738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return NULL;
739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void prepareData(UErrorCode& status){
744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(U_FAILURE(status)) return;
745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (icu_data) return; // prepared
746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        icu_data = new CA_uchar();
748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Following code is borrowed from UPerfTest::getLines();
750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        const UChar*    line=NULL;
751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t         len =0;
752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (;;) {
753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            line = ucbuf_readline(ucharBuf,&len,&status);
754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(line == NULL || U_FAILURE(status)){break;}
755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Refer to the source code of ucbuf_readline()
757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // 1. 'len' includs the line terminal symbols
758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // 2. The length of the line terminal symbols is only one character
759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // 3. The Windows CR LF line terminal symbols will be converted to CR
760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (len == 1) {
762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                continue; //skip empty line
763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                icu_data->append_one(len);
765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                memcpy(icu_data->last(), line, len * sizeof(UChar));
766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                icu_data->last()[len -1] = NULL;
767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(U_FAILURE(status)) return;
770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // UTF-16 -> UTF-8 conversion.
772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UConverter   *conv = ucnv_open("utf-8", &status); // just UTF-8 for now.
773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_FAILURE(status)) return;
774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        count = icu_data->count;
776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        icu_data_all_len =  icu_data->index[count]; // includes all NULLs
778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        icu_data_all_len -= count;  // excludes all NULLs
779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        icu_data_all_len += 1;      // the terminal NULL
780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        icu_data_all = new UChar[icu_data_all_len];
781ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        icu_data_all[icu_data_all_len - 1] = 0; //the terminal NULL
782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        icu_key  = new CA_uint8;
784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        win_data = new CA_win_wchar;
785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        win_key  = new CA_char;
786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        posix_data = new CA_char;
787ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        posix_key = new CA_char;
788ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        rnd_index = new DataIndex[count];
789ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        DataIndex::win_langid = win_langid;
790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        DataIndex::col        = col;
791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar * p = icu_data_all;
794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t s;
795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t t;
796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (int i=0; i < count; i++) {
797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // ICU all data
798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            s = sizeof(UChar) * icu_data->lengthOf(i);
799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            memcpy(p, icu_data->dataOf(i), s);
800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            p += icu_data->lengthOf(i);
801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // ICU data
803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // ICU key
805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            s = ucol_getSortKey(col, icu_data->dataOf(i), -1,NULL, 0);
806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            icu_key->append_one(s);
807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            t = ucol_getSortKey(col, icu_data->dataOf(i), -1,icu_key->last(), s);
808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (t != s) {status = U_INVALID_FORMAT_ERROR;return;}
809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // POSIX data
811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            s = ucnv_fromUChars(conv,NULL, 0, icu_data->dataOf(i), icu_data->lengthOf(i), &status);
812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (status == U_BUFFER_OVERFLOW_ERROR || status == U_ZERO_ERROR){
813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                status = U_ZERO_ERROR;
814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return;
816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            posix_data->append_one(s + 1); // plus terminal NULL
818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            t = ucnv_fromUChars(conv,posix_data->last(), s, icu_data->dataOf(i), icu_data->lengthOf(i), &status);
819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (U_FAILURE(status)) return;
820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if ( t != s){status = U_INVALID_FORMAT_ERROR;return;}
821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            posix_data->last()[s] = 0;
822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // POSIX key
824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            s = strxfrm(NULL, posix_data->dataOf(i), 0);
825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (s == INT_MAX){status = U_INVALID_FORMAT_ERROR;return;}
826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            posix_key->append_one(s);
827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            t = strxfrm(posix_key->last(), posix_data->dataOf(i), s);
828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (t != s) {status = U_INVALID_FORMAT_ERROR;return;}
829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
83054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Win data
832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            s = icu_data->lengthOf(i) + 1; // plus terminal NULL
833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            win_data->append_one(s);
834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            memcpy(win_data->last(), icu_data->dataOf(i), sizeof(WCHAR) * s);
835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Win key
837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            s = LCMapStringW(win_langid, LCMAP_SORTKEY, win_data->dataOf(i), win_data->lengthOf(i), NULL,0);
838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (s == 0) {status = U_INVALID_FORMAT_ERROR;return;}
839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            win_key->append_one(s);
840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            t = LCMapStringW(win_langid, LCMAP_SORTKEY, win_data->dataOf(i), win_data->lengthOf(i), (WCHAR *)(win_key->last()),s);
841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (t != s) {status = U_INVALID_FORMAT_ERROR;return;}
84254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        };
844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // append_one() will make points shifting, should not merge following code into previous iteration
846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (int i=0; i < count; i++) {
847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rnd_index[i].icu_key = icu_key->dataOf(i);
848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rnd_index[i].icu_data = icu_data->dataOf(i);
849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rnd_index[i].icu_data_len = icu_data->lengthOf(i);
850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rnd_index[i].posix_key = posix_key->last();
851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rnd_index[i].posix_data = posix_data->dataOf(i);
852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rnd_index[i].posix_data_len = posix_data->lengthOf(i);
85354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rnd_index[i].win_key = win_key->dataOf(i);
855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rnd_index[i].win_data = win_data->dataOf(i);
856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rnd_index[i].win_data_len = win_data->lengthOf(i);
85754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        };
859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucnv_close(conv);
861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        qsort(rnd_index, count, sizeof(DataIndex), CmdQsort::q_random);
862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SORT(data, func) \
864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    data = new DataIndex[count];\
865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    memcpy(data, rnd_index, count * sizeof(DataIndex));\
866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    qsort(data, count, sizeof(DataIndex), CmdQsort::func)
867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SORT(ord_icu_data, icu_strcoll_len);
869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SORT(ord_icu_key, icu_cmpkey);
870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SORT(ord_posix_data, posix_strcoll_null);
871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SORT(ord_posix_key, posix_cmpkey);
87254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#if U_PLATFORM_HAS_WIN32_API
873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SORT(ord_win_data, win_cmp_len);
874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SORT(ord_win_key, win_cmpkey);
875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SORT(ord_win_wcscmp, win_wcscmp);
87654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#endif
877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SORT(ord_icu_strcmp, icu_strcmp);
878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        SORT(ord_icu_cmpcpo, icu_cmpcpo);
879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint main(int argc, const char *argv[])
884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CollPerfTest test(argc, argv, status);
888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)){
890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        printf("The error is %s\n", u_errorName(status));
891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        //TODO: print usage here
892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return status;
893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (test.run() == FALSE){
896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fprintf(stderr, "FAILED: Tests could not be run please check the "
897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            "arguments.\n");
898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return -1;
899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return 0;
901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
903