]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/test/perf/CollationPerformanceTest.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / test / perf / CollationPerformanceTest.java
1 /**\r
2 *******************************************************************************\r
3 * Copyright (C) 2002-2007, International Business Machines Corporation and    *\r
4 * others. All Rights Reserved.                                                *\r
5 *******************************************************************************\r
6 */\r
7 \r
8 package com.ibm.icu.dev.test.perf;\r
9 \r
10 import com.ibm.icu.text.*;\r
11 import java.util.*;\r
12 import java.io.*;\r
13 import com.ibm.icu.impl.LocaleUtility;\r
14 \r
15 public class CollationPerformanceTest {\r
16     static final String usageString = \r
17         "usage:  collperf options...\n"\r
18         + "-help                      Display this message.\n"\r
19         + "-file file_name            utf-16 format file of names.\n"\r
20         + "-locale name               ICU locale to use.  Default is en_US\n"\r
21         + "-rules file_name           Collation rules file (overrides locale)\n"\r
22         //+ "-langid 0x1234             Windows Language ID number.  Default to value for -locale option\n"\r
23         //+ "                              see http://msdn.microsoft.com/library/psdk/winbase/nls_8xo3.htm\n"\r
24         //+ "-win                       Run test using Windows native services.  (ICU is default)\n"\r
25         //+ "-unix                      Run test using Unix strxfrm, strcoll services.\n"\r
26         //+ "-uselen                    Use API with string lengths.  Default is null-terminated strings\n"\r
27         + "-usekeys                   Run tests using sortkeys rather than strcoll\n"\r
28         + "-strcmp                    Run tests using u_strcmp rather than strcoll\n"\r
29         + "-strcmpCPO                 Run tests using u_strcmpCodePointOrder rather than strcoll\n"\r
30         + "-loop nnnn                 Loopcount for test.  Adjust for reasonable total running time.\n"\r
31         + "-iloop n                   Inner Loop Count.  Default = 1.  Number of calls to function\n"\r
32         + "                               under test at each call point.  For measuring test overhead.\n"\r
33         + "-terse                     Terse numbers-only output.  Intended for use by scripts.\n"\r
34         + "-french                    French accent ordering\n"\r
35         + "-frenchoff                 No French accent ordering (for use with French locales.)\n"\r
36         + "-norm                      Normalizing mode on\n"\r
37         + "-shifted                   Shifted mode\n"\r
38         + "-lower                     Lower case first\n"\r
39         + "-upper                     Upper case first\n"\r
40         + "-case                      Enable separate case level\n"\r
41         + "-level n                   Sort level, 1 to 5, for Primary, Secndary, Tertiary, Quaternary, Identical\n"\r
42         + "-keyhist                   Produce a table sort key size vs. string length\n"\r
43         + "-binsearch                 Binary Search timing test\n"\r
44         + "-keygen                    Sort Key Generation timing test\n"\r
45         + "-qsort                     Quicksort timing test\n"\r
46         + "-iter                      Iteration Performance Test\n"\r
47         + "-dump                      Display strings, sort keys and CEs.\n"\r
48         + "-java                      Run test using java.text.Collator.\n";\r
49     \r
50     //enum {FLAG, NUM, STRING} type;\r
51     static StringBuffer temp_opt_fName      = new StringBuffer("");\r
52     static StringBuffer temp_opt_locale     = new StringBuffer("en_US");\r
53     //static StringBuffer temp_opt_langid     = new StringBuffer("0");         // Defaults to value corresponding to opt_locale.\r
54     static StringBuffer temp_opt_rules      = new StringBuffer("");\r
55     static StringBuffer temp_opt_help       = new StringBuffer("");\r
56     static StringBuffer temp_opt_loopCount  = new StringBuffer("1");\r
57     static StringBuffer temp_opt_iLoopCount = new StringBuffer("1");\r
58     static StringBuffer temp_opt_terse      = new StringBuffer("false");\r
59     static StringBuffer temp_opt_qsort      = new StringBuffer("");\r
60     static StringBuffer temp_opt_binsearch  = new StringBuffer("");\r
61     static StringBuffer temp_opt_icu        = new StringBuffer("true");\r
62     //static StringBuffer opt_win        = new StringBuffer("");      // Run with Windows native functions.\r
63     //static StringBuffer opt_unix       = new StringBuffer("");      // Run with UNIX strcoll, strxfrm functions.\r
64     //static StringBuffer opt_uselen     = new StringBuffer("");\r
65     static StringBuffer temp_opt_usekeys    = new StringBuffer("");\r
66     static StringBuffer temp_opt_strcmp     = new StringBuffer("");\r
67     static StringBuffer temp_opt_strcmpCPO  = new StringBuffer("");\r
68     static StringBuffer temp_opt_norm       = new StringBuffer("");\r
69     static StringBuffer temp_opt_keygen     = new StringBuffer("");\r
70     static StringBuffer temp_opt_french     = new StringBuffer("");\r
71     static StringBuffer temp_opt_frenchoff  = new StringBuffer("");\r
72     static StringBuffer temp_opt_shifted    = new StringBuffer("");\r
73     static StringBuffer temp_opt_lower      = new StringBuffer("");\r
74     static StringBuffer temp_opt_upper      = new StringBuffer("");\r
75     static StringBuffer temp_opt_case       = new StringBuffer("");\r
76     static StringBuffer temp_opt_level      = new StringBuffer("0");\r
77     static StringBuffer temp_opt_keyhist    = new StringBuffer("");\r
78     static StringBuffer temp_opt_itertest   = new StringBuffer("");\r
79     static StringBuffer temp_opt_dump       = new StringBuffer("");\r
80     static StringBuffer temp_opt_java       = new StringBuffer("");\r
81     \r
82     \r
83     static String   opt_fName      = "";\r
84     static String   opt_locale     = "en_US";\r
85     //static int      opt_langid     = 0;         // Defaults to value corresponding to opt_locale.\r
86     static String   opt_rules      = "";\r
87     static boolean  opt_help       = false;\r
88     static int      opt_loopCount  = 1;\r
89     static int      opt_iLoopCount = 1;\r
90     static boolean  opt_terse      = false;\r
91     static boolean  opt_qsort      = false;\r
92     static boolean  opt_binsearch  = false;\r
93     static boolean  opt_icu        = true;\r
94     //static boolean  opt_win        = false;      // Run with Windows native functions.\r
95     //static boolean  opt_unix       = false;      // Run with UNIX strcoll, strxfrm functions.\r
96     //static boolean  opt_uselen     = false;\r
97     static boolean  opt_usekeys    = false;\r
98     static boolean  opt_strcmp     = false;\r
99     static boolean  opt_strcmpCPO  = false;\r
100     static boolean  opt_norm       = false;\r
101     static boolean  opt_keygen     = false;\r
102     static boolean  opt_french     = false;\r
103     static boolean  opt_frenchoff  = false;\r
104     static boolean  opt_shifted    = false;\r
105     static boolean  opt_lower      = false;\r
106     static boolean  opt_upper      = false;\r
107     static boolean  opt_case       = false;\r
108     static int      opt_level      = 0;\r
109     static boolean  opt_keyhist    = false;\r
110     static boolean  opt_itertest   = false;\r
111     static boolean  opt_dump       = false;\r
112     static boolean  opt_java       = false;\r
113 \r
114     static OptionSpec[] options = {\r
115         new OptionSpec("-file", 2, temp_opt_fName),\r
116         new OptionSpec("-locale", 2, temp_opt_locale),\r
117         //new OptionSpec("-langid", 1, temp_opt_langid),\r
118         new OptionSpec("-rules", 2, temp_opt_rules),\r
119         new OptionSpec("-qsort", 0, temp_opt_qsort),\r
120         new OptionSpec("-binsearch", 0, temp_opt_binsearch),\r
121         new OptionSpec("-iter", 0, temp_opt_itertest),\r
122         //new OptionSpec("-win", 0, temp_opt_win),\r
123         //new OptionSpec("-unix", 0, temp_opt_unix),\r
124         //new OptionSpec("-uselen", 0, temp_opt_uselen),\r
125         new OptionSpec("-usekeys", 0, temp_opt_usekeys),\r
126         new OptionSpec("-strcmp", 0, temp_opt_strcmp),\r
127         new OptionSpec("-strcmpCPO", 0, temp_opt_strcmpCPO),\r
128         new OptionSpec("-norm", 0, temp_opt_norm),\r
129         new OptionSpec("-french", 0, temp_opt_french),\r
130         new OptionSpec("-frenchoff", 0, temp_opt_frenchoff),\r
131         new OptionSpec("-shifted", 0, temp_opt_shifted),\r
132         new OptionSpec("-lower", 0, temp_opt_lower),\r
133         new OptionSpec("-upper", 0, temp_opt_upper),\r
134         new OptionSpec("-case", 0, temp_opt_case),\r
135         new OptionSpec("-level", 1, temp_opt_level),\r
136         new OptionSpec("-keyhist", 0, temp_opt_keyhist),\r
137         new OptionSpec("-keygen", 0, temp_opt_keygen),\r
138         new OptionSpec("-loop", 1, temp_opt_loopCount),\r
139         new OptionSpec("-iloop", 1, temp_opt_iLoopCount),\r
140         new OptionSpec("-terse", 0, temp_opt_terse),\r
141         new OptionSpec("-dump", 0, temp_opt_dump),\r
142         new OptionSpec("-help", 0, temp_opt_help),\r
143         new OptionSpec("-?", 0, temp_opt_help),\r
144         new OptionSpec("-java", 0, temp_opt_java),\r
145     };\r
146     \r
147     static java.text.Collator javaCol = null;\r
148     static com.ibm.icu.text.Collator icuCol = null;\r
149     static NumberFormat nf = null;\r
150     static NumberFormat percent = null;\r
151     ArrayList list = null;\r
152     String[] tests = null;\r
153     int globalCount = 0;\r
154     \r
155     public static void main(String[] args) {\r
156         CollationPerformanceTest collPerf = new CollationPerformanceTest();\r
157         if ( !CollationPerformanceTest.processOptions(args) || opt_help || opt_fName.length()==0) {\r
158             System.out.println(usageString);\r
159             System.exit(1);\r
160         }\r
161         \r
162         nf = NumberFormat.getInstance();\r
163         nf.setMaximumFractionDigits(2);\r
164         percent = NumberFormat.getPercentInstance();\r
165         \r
166         collPerf.setOptions();\r
167         collPerf.readDataLines();\r
168         \r
169         if (opt_dump) {\r
170             collPerf.doDump();\r
171         }\r
172         \r
173         if (opt_qsort) {\r
174             collPerf.doQSort();\r
175         }\r
176         \r
177         if (opt_binsearch) {\r
178             collPerf.doBinarySearch();\r
179         }\r
180         \r
181         if (opt_keygen) {\r
182             collPerf.doKeyGen();\r
183         }\r
184         \r
185         if (opt_keyhist) {\r
186             collPerf.doKeyHist();\r
187         }\r
188         \r
189         if (opt_itertest) {\r
190             collPerf.doIterTest();\r
191         }\r
192         \r
193     }\r
194     \r
195     //Dump file lines, CEs, Sort Keys if requested\r
196     void doDump() {\r
197         for(int i = 0; i < list.size(); i++) {\r
198             //print the line\r
199             String line = com.ibm.icu.impl.Utility.escape((String)list.get(i));\r
200             System.out.println(line);\r
201             \r
202             System.out.print("  CEs:  ");\r
203             CollationElementIterator CEiter = ((com.ibm.icu.text.RuleBasedCollator)icuCol).getCollationElementIterator(line);\r
204             int ce;\r
205             int j = 0;\r
206             for(;;) {\r
207                 ce = CEiter.next();\r
208                 if (ce == CollationElementIterator.NULLORDER) {\r
209                     break;\r
210                 }\r
211                 //System.out.print();\r
212                 String outStr = Integer.toHexString(ce); \r
213                 for (int len = 0; len < 8 - outStr.length(); len++) {\r
214                     outStr ='0' + outStr;\r
215                 }\r
216                 System.out.print(outStr + "  ");\r
217                 if(++j >8) {\r
218                     System.out.print("\n        ");\r
219                     j = 0;\r
220                 }\r
221             }\r
222                 \r
223             System.out.print("\n   ICU Sort Key: ");\r
224             CollationKey ck = ((com.ibm.icu.text.RuleBasedCollator)icuCol).getCollationKey(line);\r
225             byte[] cks = ck.toByteArray();\r
226             j = 0;\r
227             for(int k = 0; k < cks.length; k++) {\r
228                 String outStr = Integer.toHexString(cks[k]);\r
229                 switch (outStr.length()) {\r
230                 case 1:     outStr = '0' + outStr;\r
231                             break;\r
232                 case 8:     outStr = outStr.substring(6);\r
233                             break; \r
234                 }\r
235                 System.out.print(outStr);\r
236                 System.out.print("  ");\r
237                 j++;\r
238                 if(j > 0 && j % 20 == 0) {\r
239                     System.out.print("\n                 ");\r
240                 }\r
241             }\r
242             System.out.println("\n");\r
243         }\r
244     }\r
245     \r
246     /**---------------------------------------------------------------------------------------\r
247      *\r
248      *   doQSort()    The quick sort timing test.\r
249      *\r
250      *---------------------------------------------------------------------------------------\r
251      */\r
252     void doQSort() {\r
253         callGC();\r
254         //String[] sortTests = (String[]) tests.clone();\r
255         //Adjust loop count to compensate for file size. QSort should be nlog(n) \r
256         double dLoopCount = opt_loopCount * 3000 / ((Math.log(tests.length) / Math.log(10)* tests.length));\r
257  \r
258         if(opt_usekeys) {\r
259             dLoopCount *= 5;\r
260         }\r
261         \r
262         int adj_loopCount = (int)dLoopCount;\r
263         if(adj_loopCount < 1) {\r
264             adj_loopCount = 1;\r
265         }\r
266         \r
267         globalCount = 0;\r
268         long startTime = 0;\r
269         long endTime = 0;\r
270         if (opt_icu && opt_usekeys) {\r
271             startTime = System.currentTimeMillis();\r
272             qSortImpl_icu_usekeys(tests, 0, tests.length -1, icuCol);\r
273             endTime = System.currentTimeMillis();\r
274         }\r
275         if (opt_icu && !opt_usekeys){\r
276             startTime = System.currentTimeMillis();\r
277             qSortImpl_nokeys(tests, 0, tests.length -1, icuCol);\r
278             endTime = System.currentTimeMillis();\r
279         }\r
280         if (opt_java && opt_usekeys) {\r
281             startTime = System.currentTimeMillis();\r
282             qSortImpl_java_usekeys(tests, 0, tests.length -1, javaCol);\r
283             endTime = System.currentTimeMillis();\r
284         }\r
285         if (opt_java && !opt_usekeys){\r
286             startTime = System.currentTimeMillis();\r
287             qSortImpl_nokeys(tests, 0, tests.length -1, javaCol);\r
288             endTime = System.currentTimeMillis();\r
289         }\r
290         long elapsedTime = endTime - startTime;\r
291         int ns = (int)(1000000 * elapsedTime / (globalCount + 0.0));\r
292         if (!opt_terse) {\r
293             System.out.println("qsort:  total # of string compares = " + globalCount);\r
294             System.out.println("qsort:  time per compare = " + ns);\r
295         } else {\r
296             System.out.println(ns);\r
297         }\r
298     }\r
299     \r
300     /**---------------------------------------------------------------------------------------\r
301      *\r
302      *    doBinarySearch()    Binary Search timing test.  Each name from the list\r
303      *                        is looked up in the full sorted list of names.\r
304      *\r
305      *---------------------------------------------------------------------------------------\r
306      */\r
307     void doBinarySearch() {\r
308         callGC();\r
309         int gCount = 0;\r
310         int loops = 0;\r
311         double dLoopCount = opt_loopCount * 3000 / (Math.log(tests.length) / Math.log(10)* tests.length);\r
312         long startTime = 0;\r
313         long elapsedTime = 0;\r
314         \r
315         if(opt_usekeys) {\r
316             dLoopCount *= 5;\r
317         }\r
318         int adj_loopCount = (int)dLoopCount;\r
319         if(adj_loopCount < 1) {\r
320             adj_loopCount = 1;\r
321         }\r
322         \r
323         //int opt2 = 0;\r
324         \r
325         for(;;) {   //not really a loop, just allows "break" to work, to simplify \r
326                     //inadvertantly running more than one test through here\r
327             if(opt_strcmp) {\r
328                 int r = 0;\r
329                 startTime = System.currentTimeMillis();\r
330                 for(loops = 0; loops < adj_loopCount; loops++) {\r
331                     for (int j = 0; j < tests.length; j++) {\r
332                         int hi = tests.length-1;\r
333                         int lo = 0;\r
334                         int guess = -1;\r
335                         for(;;) {\r
336                             int newGuess = (hi + lo) / 2;\r
337                             if(newGuess == guess){\r
338                                 break;\r
339                             }\r
340                             guess = newGuess;\r
341                             r = tests[j].compareTo(tests[guess]);\r
342                             gCount++;\r
343                             if(r == 0) {\r
344                                 break;\r
345                             }\r
346                             if (r < 0) {\r
347                                 hi = guess;\r
348                             } else {\r
349                                 lo = guess;\r
350                             }\r
351                         }\r
352                     }\r
353                 }\r
354                 elapsedTime = System.currentTimeMillis() - startTime;\r
355                 break;\r
356             }\r
357             \r
358             if (opt_strcmpCPO) {\r
359                 int r = 0;\r
360                 startTime = System.currentTimeMillis();\r
361                 for(loops = 0; loops < adj_loopCount; loops++) {\r
362                     for (int j = 0; j < tests.length; j++) {\r
363                         int hi = tests.length-1;\r
364                         int lo = 0;\r
365                         int guess = -1;\r
366                         for(;;) {\r
367                             int newGuess = (hi + lo) / 2;\r
368                             if(newGuess == guess){\r
369                                 break;\r
370                             }\r
371                             guess = newGuess;\r
372                             r = com.ibm.icu.text.Normalizer.compare(tests[j], tests[guess], Normalizer.COMPARE_CODE_POINT_ORDER);\r
373                             gCount++;\r
374                             if(r == 0) {\r
375                                 break;\r
376                             }\r
377                             if (r < 0) {\r
378                                 hi = guess;\r
379                             } else {\r
380                                 lo = guess;\r
381                             }\r
382                         }\r
383                     }\r
384                 }\r
385                 elapsedTime = System.currentTimeMillis() - startTime;\r
386                 break;\r
387             }\r
388             \r
389             if (opt_icu) {\r
390                \r
391                 int r = 0;\r
392                 startTime = System.currentTimeMillis();\r
393                 for (loops = 0; loops < adj_loopCount; loops++) {\r
394                     for (int j = 0; j < tests.length; j++) {\r
395                         int hi = tests.length - 1;\r
396                         int lo = 0;\r
397                         int guess = -1;\r
398                         for (;;) {\r
399                             int newGuess = (hi + lo) / 2;\r
400                             if (newGuess == guess) {\r
401                                 break;\r
402                             }\r
403                             guess = newGuess;\r
404                             if (opt_usekeys) {\r
405                                 com.ibm.icu.text.CollationKey sortKey1 = icuCol.getCollationKey(tests[j]);\r
406                                 com.ibm.icu.text.CollationKey sortKey2 = icuCol.getCollationKey(tests[guess]);\r
407                                 r = sortKey1.compareTo(sortKey2);\r
408                                 gCount ++;\r
409                             } else {\r
410                                 r = icuCol.compare(tests[j], tests[guess]);\r
411                                 gCount++;\r
412                             }\r
413                             if (r == 0) {\r
414                                 break;\r
415                             }\r
416                             if (r < 0) {\r
417                                 hi = guess;\r
418                             } else {\r
419                                 lo = guess;\r
420                             }\r
421                         }\r
422                     }\r
423                 }\r
424                 elapsedTime = System.currentTimeMillis() - startTime;\r
425                 break;\r
426             }\r
427             if (opt_java) {\r
428                \r
429                 int r = 0;\r
430                 startTime = System.currentTimeMillis();\r
431                 for (loops = 0; loops < adj_loopCount; loops++) {\r
432                     for (int j = 0; j < tests.length; j++) {\r
433                         int hi = tests.length - 1;\r
434                         int lo = 0;\r
435                         int guess = -1;\r
436                         for (;;) {\r
437                             int newGuess = (hi + lo) / 2;\r
438                             if (newGuess == guess) {\r
439                                 break;\r
440                             }\r
441                             guess = newGuess;\r
442                             if (opt_usekeys) {\r
443                                 java.text.CollationKey sortKey1 = javaCol.getCollationKey(tests[j]);\r
444                                 java.text.CollationKey sortKey2 = javaCol.getCollationKey(tests[guess]);\r
445                                 r = sortKey1.compareTo(sortKey2);\r
446                                 gCount ++;\r
447                             } else {\r
448                                 r = javaCol.compare(tests[j], tests[guess]);\r
449                                 gCount++;\r
450                             }\r
451                             if (r == 0) {\r
452                                 break;\r
453                             }\r
454                             if (r < 0) {\r
455                                 hi = guess;\r
456                             } else {\r
457                                 lo = guess;\r
458                             }\r
459                         }\r
460                     }\r
461                 }\r
462                 elapsedTime = System.currentTimeMillis() - startTime;\r
463                 break;\r
464             }\r
465             break; \r
466         }\r
467         int ns = (int)((float)(1000000) * (float)elapsedTime / (float)gCount);\r
468         if (!opt_terse) {\r
469             System.out.println("binary search:  total # of string compares = " + gCount);\r
470             System.out.println("binary search:  compares per loop = " + gCount / loops);\r
471             System.out.println("binary search:  time per compare = " + ns);\r
472         } else {\r
473             System.out.println(ns);\r
474         }\r
475     }\r
476     \r
477     /**---------------------------------------------------------------------------------------\r
478      *\r
479      *   doKeyGen()     Key Generation Timing Test\r
480      *\r
481      *---------------------------------------------------------------------------------------\r
482      */\r
483     void doKeyGen() {\r
484         callGC();\r
485         \r
486         // Adjust loop count to compensate for file size.   Should be order n\r
487         double dLoopCount = opt_loopCount * (1000.0 /  (double)list.size());\r
488         int adj_loopCount = (int)dLoopCount;\r
489         if (adj_loopCount < 1) adj_loopCount = 1;\r
490 \r
491         long startTime = 0;\r
492         long totalKeyLen = 0;\r
493         long totalChars = 0;\r
494         if (opt_java) {\r
495             startTime = System.currentTimeMillis();\r
496             for (int loops=0; loops<adj_loopCount; loops++) {\r
497                 for (int line=0; line < tests.length; line++) {\r
498                     for (int iLoop=0; iLoop < opt_iLoopCount; iLoop++) {\r
499                         totalChars += tests[line].length();\r
500                         byte[] sortKey = javaCol.getCollationKey(tests[line]).toByteArray();\r
501                         totalKeyLen += sortKey.length;\r
502                     }\r
503                 }\r
504             }\r
505         } else {\r
506             startTime = System.currentTimeMillis();\r
507             for (int loops=0; loops<adj_loopCount; loops++) {\r
508                 for (int line=0; line < tests.length; line++) {\r
509                     for (int iLoop=0; iLoop < opt_iLoopCount; iLoop++) {\r
510                         totalChars += tests[line].length();\r
511                         byte[] sortKey = icuCol.getCollationKey(tests[line]).toByteArray();\r
512                         totalKeyLen += sortKey.length;\r
513                     }\r
514                 }\r
515             }\r
516         }\r
517         \r
518         long elapsedTime = System.currentTimeMillis() - startTime;\r
519         long ns = (long)(1000000 * elapsedTime / (adj_loopCount * tests.length + 0.0));\r
520         if (!opt_terse) {\r
521             System.out.println("Sort Key Generation:  total # of keys =" + adj_loopCount * tests.length);\r
522             System.out.println("Sort Key Generation:  time per key = " + ns + " ns");\r
523             System.out.println("Key Length / character = " + nf.format(totalKeyLen / (totalChars + 0.0)));\r
524         }\r
525         else {\r
526             System.out.print(ns + ",  ");\r
527             System.out.println(nf.format(totalKeyLen / (totalChars + 0.0)) + ", ");\r
528         }\r
529     }\r
530     \r
531     /**---------------------------------------------------------------------------------------\r
532      *\r
533      *    doKeyHist()       Output a table of data for average sort key size vs. string length.\r
534      *\r
535      *---------------------------------------------------------------------------------------\r
536      */\r
537     void doKeyHist() {\r
538         callGC();\r
539         int     maxLen = 0;\r
540 \r
541         // Find the maximum string length\r
542         for (int i = 0; i < tests.length; i++) {\r
543             if (tests[i].length() > maxLen) maxLen = tests[i].length();\r
544         }\r
545         \r
546         int[] accumulatedLen  = new int[maxLen + 1];\r
547         int[] numKeysOfSize   = new int[maxLen + 1];\r
548         \r
549         // Fill the arrays...\r
550         for (int i = 0; i < tests.length; i++) {\r
551             int len = tests[i].length();\r
552             accumulatedLen[len] += icuCol.getCollationKey(tests[i]).toByteArray().length;\r
553             numKeysOfSize[len]  += 1;\r
554         }\r
555         \r
556         // And write out averages\r
557         System.out.println("String Length,  Avg Key Length,  Avg Key Len per char");\r
558         for (int i = 1; i <= maxLen; i++) {\r
559             if (numKeysOfSize[i] > 0) {\r
560                 System.out.println(i + ", " + nf.format(accumulatedLen[i] / (numKeysOfSize[i]+ 0.0)) + ", " \r
561                     + nf.format(accumulatedLen[i] / (numKeysOfSize[i] * i + 0.0)));\r
562             }\r
563         }\r
564         \r
565     }\r
566     \r
567     void doForwardIterTest() {\r
568         callGC();\r
569         System.out.print("\n\nPerforming forward iteration performance test with ");\r
570         System.out.println("performance test on strings from file -----------");\r
571     \r
572         CollationElementIterator iter = ((RuleBasedCollator)icuCol).getCollationElementIterator("");\r
573         \r
574         int gCount = 0;\r
575         int count = 0;\r
576         long startTime = System.currentTimeMillis();\r
577         while (count < opt_loopCount) {\r
578             int linecount = 0;\r
579             while (linecount < tests.length) {\r
580                 String str = tests[linecount];\r
581                 iter.setText(str);\r
582                 while (iter.next() != CollationElementIterator.NULLORDER) {\r
583                     gCount++;\r
584                 }\r
585                 linecount ++;\r
586             }\r
587             count ++;\r
588         }\r
589         \r
590         long elapsedTime = System.currentTimeMillis() - startTime;\r
591         System.out.println("elapsedTime " + elapsedTime + " ms");\r
592         \r
593         // empty loop recalculation\r
594         count = 0;\r
595         startTime = System.currentTimeMillis();\r
596         while (count < opt_loopCount) { \r
597             int linecount = 0;\r
598             while (linecount < tests.length) {\r
599                 String str = tests[linecount];\r
600                 iter.setText(str);\r
601                 linecount ++;\r
602             }\r
603             count ++;\r
604         }\r
605         elapsedTime -= (System.currentTimeMillis() - startTime);\r
606         System.out.println("elapsedTime " + elapsedTime + " ms");\r
607 \r
608         int ns = (int)(1000000 * elapsedTime / (gCount + 0.0));\r
609         System.out.println("Total number of strings compared " + tests.length \r
610                             + "in " + opt_loopCount + " loops");\r
611         System.out.println("Average time per CollationElementIterator.next() nano seconds " + ns);\r
612         System.out.println("performance test on skipped-5 concatenated strings from file -----------");\r
613         \r
614         String totalStr = "";\r
615         int    strlen = 0;\r
616         // appending all the strings\r
617         int linecount = 0;\r
618         while (linecount < tests.length) {\r
619             totalStr += tests[linecount];\r
620             strlen += tests[linecount].length();\r
621             linecount ++;\r
622         }\r
623         System.out.println("Total size of strings " + strlen);\r
624         \r
625         gCount = 0;\r
626         count  = 0;\r
627         iter = ((RuleBasedCollator)icuCol).getCollationElementIterator(totalStr);\r
628         strlen -= 5; // any left over characters are not iterated,\r
629                      // this is to ensure the backwards and forwards iterators\r
630                      // gets the same position\r
631         int strindex = 0;\r
632         startTime = System.currentTimeMillis();\r
633         while (count < opt_loopCount) {\r
634             int count5 = 5;\r
635             strindex = 0;\r
636             iter.setOffset(strindex);\r
637             while (true) {\r
638                 if (iter.next() == CollationElementIterator.NULLORDER) {\r
639                     break;\r
640                 }\r
641                 gCount++;\r
642                 count5 --;\r
643                 if (count5 == 0) {\r
644                     strindex += 10;\r
645                     if (strindex > strlen) {\r
646                         break;\r
647                     }\r
648                     iter.setOffset(strindex);\r
649                     count5 = 5;\r
650                 }\r
651             }\r
652             count ++;\r
653         }\r
654     \r
655         elapsedTime = System.currentTimeMillis() - startTime;\r
656         System.out.println("elapsedTime " + elapsedTime);\r
657         \r
658         // empty loop recalculation\r
659         int tempgCount = 0;\r
660         count = 0;\r
661         startTime = System.currentTimeMillis();\r
662         while (count < opt_loopCount) {\r
663             int count5 = 5;\r
664             strindex = 0;\r
665             iter.setOffset(strindex);\r
666             while (true) {\r
667                 tempgCount ++;\r
668                 count5 --;\r
669                 if (count5 == 0) {\r
670                     strindex += 10;\r
671                     if (strindex > strlen) {\r
672                         break;\r
673                     }\r
674                     iter.setOffset(strindex);\r
675                     count5 = 5;\r
676                 }\r
677             }\r
678             count ++;\r
679         }\r
680         elapsedTime -= (System.currentTimeMillis() - startTime);\r
681         System.out.println("elapsedTime " + elapsedTime);\r
682     \r
683         System.out.println("gCount " + gCount);\r
684         ns = (int)(1000000 * elapsedTime / (gCount + 0.0));\r
685         System.out.println("Average time per CollationElementIterator.next() nano seconds " + ns);\r
686     }\r
687     \r
688     void doBackwardIterTest() {\r
689         System.out.print("\n\nPerforming backward iteration performance test with ");\r
690         System.out.println("performance test on strings from file -----------\n");\r
691         \r
692         CollationElementIterator iter = ((RuleBasedCollator)icuCol).getCollationElementIterator("");\r
693         \r
694         int gCount = 0;\r
695         int count = 0;\r
696         long startTime = System.currentTimeMillis();\r
697         while (count < opt_loopCount) {\r
698             int linecount = 0;\r
699             while (linecount < tests.length) {\r
700                 String str = tests[linecount];\r
701                 iter.setText(str);\r
702                 while (iter.previous() != CollationElementIterator.NULLORDER) {\r
703                     gCount++;\r
704                 }\r
705                 linecount ++;\r
706             }\r
707             count ++;\r
708         }\r
709         long elapsedTime = System.currentTimeMillis() - startTime;\r
710         System.out.println("elapsedTime " + elapsedTime + " ms");\r
711         \r
712         // empty loop recalculation\r
713         count = 0;\r
714         startTime = System.currentTimeMillis();\r
715         while (count < opt_loopCount) {\r
716             int linecount = 0;\r
717             while (linecount < tests.length) {\r
718                 String str = tests[linecount];\r
719                 iter.setText(str);\r
720                 linecount ++;\r
721             }\r
722             count ++;\r
723         }\r
724         elapsedTime -= (System.currentTimeMillis() - startTime);\r
725         System.out.println("elapsedTime " + elapsedTime + " ms");\r
726         \r
727         int ns = (int)(1000000 * elapsedTime / (gCount + 0.0));\r
728         System.out.println("Total number of strings compared " + tests.length \r
729                             + "in " + opt_loopCount + " loops");\r
730         System.out.println("Average time per CollationElementIterator.previous() nano seconds " + ns);\r
731         System.out.println("performance test on skipped-5 concatenated strings from file -----------");\r
732     \r
733         String totalStr = "";\r
734         int    strlen = 0;\r
735         // appending all the strings\r
736         int linecount = 0;\r
737         while (linecount < tests.length) {\r
738             totalStr += tests[linecount];\r
739             strlen += tests[linecount].length();\r
740             linecount ++;\r
741         }\r
742         System.out.println("Total size of strings " + strlen);\r
743         \r
744         gCount = 0;\r
745         count  = 0;\r
746     \r
747         iter = ((RuleBasedCollator)icuCol).getCollationElementIterator(totalStr);\r
748         int strindex = 0;\r
749         startTime = System.currentTimeMillis();\r
750         while (count < opt_loopCount) {\r
751             int count5 = 5;\r
752             strindex = 5;\r
753             iter.setOffset(strindex);\r
754             while (true) {\r
755                 if (iter.previous() == CollationElementIterator.NULLORDER) {\r
756                     break;\r
757                 }\r
758                  gCount ++;\r
759                  count5 --;\r
760                  if (count5 == 0) {\r
761                      strindex += 10;\r
762                      if (strindex > strlen) {\r
763                         break;\r
764                      }\r
765                      iter.setOffset(strindex);\r
766                      count5 = 5;\r
767                  }\r
768             }\r
769             count ++;\r
770         }\r
771     \r
772         elapsedTime = System.currentTimeMillis() - startTime;\r
773         System.out.println("elapsedTime " + elapsedTime);\r
774         \r
775         // empty loop recalculation\r
776         count = 0;\r
777         int tempgCount = 0;\r
778         startTime = System.currentTimeMillis();\r
779         while (count < opt_loopCount) {\r
780             int count5 = 5;\r
781             strindex = 5;\r
782             iter.setOffset(strindex);\r
783             while (true) {\r
784                  tempgCount ++;\r
785                  count5 --;\r
786                  if (count5 == 0) {\r
787                      strindex += 10;\r
788                      if (strindex > strlen) {\r
789                         break;\r
790                      }\r
791                      iter.setOffset(strindex);\r
792                      count5 = 5;\r
793                  }\r
794             }\r
795             count ++;\r
796         }\r
797         elapsedTime -= (System.currentTimeMillis() - startTime);\r
798         System.out.println("elapsedTime " + elapsedTime);\r
799     \r
800         System.out.println("gCount " + gCount);\r
801         ns = (int)(1000000 * elapsedTime / (gCount + 0.0));\r
802         System.out.println("Average time per CollationElementIterator.previous() nano seconds " + ns);\r
803     }\r
804     \r
805     \r
806     /**---------------------------------------------------------------------------------------\r
807      *\r
808      *    doIterTest()       Iteration test\r
809      *\r
810      *---------------------------------------------------------------------------------------\r
811      */\r
812     void doIterTest() {\r
813         doForwardIterTest();\r
814         doBackwardIterTest();\r
815     }\r
816     \r
817     void setOptions() {\r
818         \r
819         if (opt_java) {\r
820             opt_icu = false;\r
821         }\r
822         \r
823         if (opt_rules.length() != 0) {\r
824             try {\r
825                 icuCol = new com.ibm.icu.text.RuleBasedCollator(getCollationRules(opt_rules));\r
826             } catch (Exception e) {\r
827                 System.out.println("Cannot open rules:" + e.getMessage());\r
828                 System.exit(1);\r
829             }\r
830         } else {\r
831             icuCol = com.ibm.icu.text.Collator.getInstance(\r
832                                 LocaleUtility.getLocaleFromName(opt_locale));\r
833         }\r
834         \r
835         javaCol = java.text.Collator.getInstance(\r
836                                 LocaleUtility.getLocaleFromName(opt_locale));\r
837         \r
838         if (opt_norm) {\r
839             javaCol.setDecomposition(java.text.Collator.CANONICAL_DECOMPOSITION);\r
840             icuCol.setDecomposition(com.ibm.icu.text.Collator.CANONICAL_DECOMPOSITION);\r
841         }\r
842         \r
843         if (opt_french && opt_frenchoff) {\r
844             System.err.println("Error: specified both -french and -frenchoff options.");\r
845         }\r
846         \r
847         if (opt_french) {\r
848             ((com.ibm.icu.text.RuleBasedCollator)icuCol).setFrenchCollation(true);\r
849         }\r
850         if (opt_frenchoff) {\r
851             ((com.ibm.icu.text.RuleBasedCollator)icuCol).setFrenchCollation(false);\r
852         }\r
853         \r
854         if (opt_lower) {\r
855             ((com.ibm.icu.text.RuleBasedCollator)icuCol).setLowerCaseFirst(true);\r
856         }\r
857         \r
858         if (opt_upper) {\r
859             ((com.ibm.icu.text.RuleBasedCollator)icuCol).setUpperCaseFirst(true);\r
860         }\r
861         \r
862         if (opt_shifted) {\r
863             ((com.ibm.icu.text.RuleBasedCollator)icuCol).setAlternateHandlingShifted(true);\r
864         }\r
865         \r
866         if (opt_level != 0) {\r
867             switch (opt_level) {\r
868                 case 1 :\r
869                         javaCol.setStrength(java.text.Collator.PRIMARY);\r
870                         icuCol.setStrength(com.ibm.icu.text.Collator.PRIMARY);\r
871                         break;\r
872                 case 2 :\r
873                         javaCol.setStrength(java.text.Collator.SECONDARY);\r
874                         icuCol.setStrength(com.ibm.icu.text.Collator.SECONDARY);\r
875                         break;\r
876                 case 3 :\r
877                         javaCol.setStrength(java.text.Collator.TERTIARY);\r
878                         icuCol.setStrength(com.ibm.icu.text.Collator.TERTIARY);\r
879                         break;\r
880                 case 4 :\r
881                         icuCol.setStrength(com.ibm.icu.text.Collator.QUATERNARY);\r
882                         break;\r
883                 case 5 :\r
884                         javaCol.setStrength(java.text.Collator.IDENTICAL);\r
885                         icuCol.setStrength(com.ibm.icu.text.Collator.IDENTICAL);\r
886                         break;\r
887                 default:\r
888                     System.err.println("-level param must be between 1 and 5\n");\r
889                     System.exit(1);\r
890             }\r
891         }\r
892         // load classes at least once before starting\r
893         javaCol.compare("a", "b");\r
894         icuCol.compare("a", "b");\r
895     }\r
896     \r
897     static boolean processOptions(String[] args) {\r
898         int argNum;\r
899         for (argNum =0; argNum < args.length; argNum++) {\r
900             for (int i = 0; i < options.length; i++) {\r
901                 if (args[argNum].equalsIgnoreCase(options[i].name)) {\r
902                     switch (options[i].type) {\r
903                         case 0:\r
904                                 options[i].value.delete(0, options[i].value.capacity()).append("true");\r
905                                 break;\r
906                         case 1:\r
907                                 argNum++;\r
908                                 if ((argNum >= args.length) || (args[argNum].charAt(0)=='-')) {\r
909                                     System.err.println("value expected for"+ options[i].name +"option.\n");\r
910                                     return false;\r
911                                 }\r
912                                 try {\r
913                                    /* int value =*/ Integer.parseInt(args[argNum]);\r
914                                     options[i].value.delete(0, options[i].value.capacity()).append(args[argNum]);\r
915                                 } catch (NumberFormatException e) {\r
916                                     System.err.println("Expected: a number value");\r
917                                     return false;    \r
918                                 }\r
919                                 break;\r
920                         case 2:\r
921                                 argNum++;\r
922                                 if ((argNum >= args.length) || (args[argNum].charAt(0)=='-')) {\r
923                                     System.err.println("value expected for"+ options[i].name +"option.\n");\r
924                                     return false;\r
925                                 }\r
926                                 options[i].value.delete(0, options[i].value.capacity()).append(args[argNum]);\r
927                                 break;\r
928                         default:\r
929                                 System.err.println("Option type error: {FLAG=0, NUM=1, STRING=2}");\r
930                                 return false;\r
931                     }\r
932                 }\r
933             }\r
934         }\r
935         \r
936         opt_fName      = temp_opt_fName.toString();\r
937         opt_locale     = temp_opt_locale.toString();\r
938         opt_rules      = temp_opt_rules.toString();\r
939         if (temp_opt_help.toString().equalsIgnoreCase("true")) {\r
940             opt_help = true;\r
941         }\r
942         opt_loopCount  = Integer.parseInt(temp_opt_loopCount.toString());\r
943         opt_iLoopCount = Integer.parseInt(temp_opt_iLoopCount.toString());\r
944         if (temp_opt_terse.toString().equalsIgnoreCase("true")) {\r
945             opt_terse = true;\r
946         }\r
947         if (temp_opt_qsort.toString().equalsIgnoreCase("true")) {\r
948             opt_qsort = true;\r
949         }\r
950         if (temp_opt_binsearch.toString().equalsIgnoreCase("true")) {\r
951             opt_binsearch = true;\r
952         }\r
953         if (temp_opt_icu.toString().equalsIgnoreCase("true")) {\r
954             opt_icu = true;\r
955         }\r
956         if (temp_opt_usekeys.toString().equalsIgnoreCase("true")) {\r
957             opt_usekeys = true;\r
958         }\r
959         if (temp_opt_strcmp.toString().equalsIgnoreCase("true")) {\r
960             opt_strcmp = true;\r
961         }\r
962         if (temp_opt_strcmpCPO.toString().equalsIgnoreCase("true")) {\r
963             opt_strcmpCPO = true;\r
964         }\r
965         if (temp_opt_keygen.toString().equalsIgnoreCase("true")) {\r
966             opt_keygen = true;\r
967         }\r
968         if (temp_opt_norm.toString().equalsIgnoreCase("true")) {\r
969             opt_norm = true;\r
970         }\r
971         if (temp_opt_french.toString().equalsIgnoreCase("true")) {\r
972             opt_french = true;\r
973         }\r
974         if (temp_opt_frenchoff.toString().equalsIgnoreCase("true")) {\r
975             opt_frenchoff = true;\r
976         }\r
977         if (temp_opt_shifted.toString().equalsIgnoreCase("true")) {\r
978             opt_shifted = true;\r
979         }\r
980         if (temp_opt_lower.toString().equalsIgnoreCase("true")) {\r
981             opt_lower = true;\r
982         }\r
983         if (temp_opt_upper.toString().equalsIgnoreCase("true")) {\r
984             opt_upper = true;\r
985         }\r
986         if (temp_opt_case.toString().equalsIgnoreCase("true")) {\r
987             opt_case = true;\r
988         }\r
989         opt_level      = Integer.parseInt(temp_opt_level.toString());\r
990         if (temp_opt_keyhist.toString().equalsIgnoreCase("true")) {\r
991             opt_keyhist = true;\r
992         }\r
993         if (temp_opt_itertest.toString().equalsIgnoreCase("true")) {\r
994             opt_itertest = true;\r
995         }\r
996         if (temp_opt_dump.toString().equalsIgnoreCase("true")) {\r
997             opt_dump = true;\r
998         }\r
999         if (temp_opt_java.toString().equalsIgnoreCase("true")) {\r
1000             opt_java = true;\r
1001         }\r
1002         \r
1003         return true;\r
1004     }\r
1005     \r
1006     /**\r
1007      * Invoke the runtime's garbage collection procedure repeatedly\r
1008      * until the amount of free memory stabilizes to within 10%.\r
1009      */    \r
1010     private void callGC() {\r
1011         // From "Java Platform Performance".  This is the procedure\r
1012         // recommended by Javasoft.\r
1013         try {\r
1014             System.gc();\r
1015             Thread.sleep(100);\r
1016             System.runFinalization();\r
1017             Thread.sleep(100);\r
1018             \r
1019             System.gc();\r
1020             Thread.sleep(100);\r
1021             System.runFinalization();\r
1022             Thread.sleep(100);\r
1023         } catch (InterruptedException e) {}\r
1024     }\r
1025 \r
1026     //private boolean needCRLF = false;\r
1027     \r
1028     public int DOTMASK = 0x7FF;\r
1029  \r
1030     void dot(int i) {\r
1031         if ((i % DOTMASK) == 0) {\r
1032             //needCRLF = true;\r
1033             // I do not know why print the dot here\r
1034             //System.out.print('.');\r
1035         }\r
1036     }\r
1037     \r
1038     String readDataLine(BufferedReader br) throws Exception {\r
1039         String originalLine = "";\r
1040         String line = "";\r
1041         \r
1042         try {\r
1043             line = originalLine = br.readLine();\r
1044             if (line == null) return null;\r
1045             if (line.length() > 0 && line.charAt(0) == 0xFEFF) line = line.substring(1);\r
1046             int commentPos = line.indexOf('#');\r
1047             if (commentPos >= 0) line = line.substring(0, commentPos);\r
1048             line = line.trim();\r
1049         } catch (Exception e) {\r
1050             throw new Exception("Line \"{0}\",  \"{1}\"" + originalLine + " "\r
1051                                 + line + " " + e.toString());\r
1052         }\r
1053         return line;\r
1054     }\r
1055     \r
1056     void readDataLines() {\r
1057         // Read in  the input file.\r
1058         //   File assumed to be utf-16.\r
1059         //   Lines go onto heap buffers.  Global index array to line starts is created.\r
1060         //   Lines themselves are null terminated.\r
1061         //\r
1062         FileInputStream fis = null;\r
1063         InputStreamReader isr = null;\r
1064         BufferedReader br = null;\r
1065         try {\r
1066             fis = new FileInputStream(opt_fName);\r
1067             isr = new InputStreamReader(fis, "UTF-8");\r
1068             br= new BufferedReader(isr, 32*1024);\r
1069         } catch (Exception e) {\r
1070             System.err.println("Error: File access exception: " + e.getMessage() + "!");\r
1071             System.exit(2);\r
1072         }\r
1073         \r
1074         int counter = 0;\r
1075         \r
1076         list = new ArrayList();\r
1077         while (true) {\r
1078             String line = null;\r
1079             try {\r
1080                 line = readDataLine(br);\r
1081             } catch (Exception e) {\r
1082                 System.err.println("Read File Error" + e.getMessage() + "!");\r
1083                 System.exit(1);\r
1084             }\r
1085             \r
1086             if (line == null) break;\r
1087             if (line.length() == 0) continue;\r
1088             dot(counter++);\r
1089             list.add(line);\r
1090         }\r
1091         if (!opt_terse) {\r
1092             System.out.println("Read " + counter + " lines in file");\r
1093         }\r
1094         \r
1095         int size = list.size();\r
1096         tests = new String [size];\r
1097         \r
1098         for (int i = 0; i < size; ++i) {\r
1099             tests[i] = (String) list.get(i);\r
1100         }\r
1101     }\r
1102     \r
1103     /**\r
1104      * Get the Collator Rules\r
1105      * The Rule File format:\r
1106      * 1. leading and trailing whitespaces will be omitted\r
1107      * 2. lines with the leading character '#' will be treated as comments\r
1108      * 3. File encoding is ISO-8859-1\r
1109      */\r
1110     String getCollationRules(String ruleFileName) {\r
1111         FileInputStream fis = null;\r
1112         InputStreamReader isr = null;\r
1113         BufferedReader br = null;\r
1114         try {\r
1115             fis = new FileInputStream(opt_rules);\r
1116             isr = new InputStreamReader(fis,"ISO-8859-1");\r
1117             br= new BufferedReader(isr);\r
1118         } catch (Exception e) {\r
1119             System.err.println("Error: File access exception: " + e.getMessage() + "!");\r
1120             System.exit(2);\r
1121         }\r
1122         String rules = "";\r
1123         String line = "";\r
1124         while (true) {\r
1125             try {\r
1126                 line = br.readLine();\r
1127             } catch (IOException e) {\r
1128                 System.err.println("Read File Error" + e.getMessage() + "!");\r
1129                 System.exit(1);\r
1130             }\r
1131             if (line == null) {\r
1132                 break;\r
1133             }\r
1134             int commentPos = line.indexOf('#');\r
1135             if (commentPos >= 0) line = line.substring(0, commentPos);\r
1136             line = line.trim();\r
1137             rules = rules + line;\r
1138         }\r
1139         return rules;\r
1140     }\r
1141     \r
1142     //Implementing qsort\r
1143     void qSortImpl_java_usekeys(String src[], int fromIndex, int toIndex, java.text.Collator c) {\r
1144         int low = fromIndex;\r
1145         int high = toIndex;\r
1146         String middle = "";\r
1147         if (high > low) {\r
1148             middle = src[ (low + high) / 2 ];\r
1149             while(low <= high) {\r
1150                 while((low < toIndex) && (compare(c.getCollationKey(src[low]), c.getCollationKey(middle)) < 0)) {\r
1151                     ++low;\r
1152                 }\r
1153                 while((high > fromIndex) && (compare(c.getCollationKey(src[high]), c.getCollationKey(middle)) > 0)) {\r
1154                     --high;\r
1155                 }\r
1156                 if(low <= high) {\r
1157                     String swap = src[low];\r
1158                     src[low] = src[high];\r
1159                     src[high] = swap;\r
1160                     ++low;\r
1161                     --high;\r
1162                 }\r
1163             }\r
1164             if(fromIndex < high) {\r
1165                 qSortImpl_java_usekeys(src, fromIndex, high, c);\r
1166             }\r
1167             \r
1168             if(low < toIndex) {\r
1169                 qSortImpl_java_usekeys(src, low, toIndex, c);\r
1170             }\r
1171         }\r
1172     }\r
1173     \r
1174     void qSortImpl_icu_usekeys(String src[], int fromIndex, int toIndex, com.ibm.icu.text.Collator c) {\r
1175         int low = fromIndex;\r
1176         int high = toIndex;\r
1177         String middle = "";\r
1178         if (high > low) {\r
1179             middle = src[ (low + high) / 2 ];\r
1180             while(low <= high) {\r
1181                 while((low < toIndex) && (compare(c.getCollationKey(src[low]), c.getCollationKey(middle)) < 0)) {\r
1182                     ++low;\r
1183                 }\r
1184                 while((high > fromIndex) && (compare(c.getCollationKey(src[high]), c.getCollationKey(middle)) > 0)) {\r
1185                     --high;\r
1186                 }\r
1187                 if(low <= high) {\r
1188                     String swap = src[low];\r
1189                     src[low] = src[high];\r
1190                     src[high] = swap;\r
1191                     ++low;\r
1192                     --high;\r
1193                 }\r
1194             }\r
1195             if(fromIndex < high) {\r
1196                 qSortImpl_icu_usekeys(src, fromIndex, high, c);\r
1197             }\r
1198             \r
1199             if(low < toIndex) {\r
1200                 qSortImpl_icu_usekeys(src, low, toIndex, c);\r
1201             }\r
1202         }\r
1203     }\r
1204     \r
1205     void qSortImpl_nokeys(String src[], int fromIndex, int toIndex, Comparator c) {\r
1206         int low = fromIndex;\r
1207         int high = toIndex;\r
1208         String middle = "";\r
1209         if (high > low) {\r
1210             middle = src[ (low + high) / 2 ];\r
1211             while(low <= high) {\r
1212                 while((low < toIndex) && (compare(src[low], middle, c) < 0)) {\r
1213                     ++low;\r
1214                 }\r
1215                 while((high > fromIndex) && (compare(src[high], middle, c) > 0)) {\r
1216                     --high;\r
1217                 }\r
1218                 if(low <= high) {\r
1219                     String swap = src[low];\r
1220                     src[low] = src[high];\r
1221                     src[high] = swap;\r
1222                     ++low;\r
1223                     --high;\r
1224                 }\r
1225             }\r
1226             if(fromIndex < high) {\r
1227                 qSortImpl_nokeys(src, fromIndex, high, c);\r
1228             }\r
1229             \r
1230             if(low < toIndex) {\r
1231                 qSortImpl_nokeys(src, low, toIndex, c);\r
1232             }\r
1233         }\r
1234     }\r
1235     \r
1236     int compare(String source, String target, Comparator c) {\r
1237         globalCount++;\r
1238         return c.compare(source, target);\r
1239     }\r
1240     \r
1241     int compare(java.text.CollationKey source, java.text.CollationKey target) {\r
1242         globalCount++;\r
1243         return source.compareTo(target);\r
1244     }\r
1245     \r
1246     int compare(com.ibm.icu.text.CollationKey source, com.ibm.icu.text.CollationKey target) {\r
1247         globalCount++;\r
1248         return source.compareTo(target);\r
1249     } \r
1250     \r
1251     //Class for command line option\r
1252     static class OptionSpec {\r
1253         String name;\r
1254         int type;\r
1255         StringBuffer value;\r
1256         public OptionSpec(String name, int type, StringBuffer value) {\r
1257             this.name = name;\r
1258             this.type = type;\r
1259             this.value = value;\r
1260         }\r
1261     }\r
1262 }