]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-52_1/main/tests/translit/src/com/ibm/icu/dev/test/util/TestUtilities.java
Upgrade ICU4J.
[Dictionary.git] / jars / icu4j-52_1 / main / tests / translit / src / com / ibm / icu / dev / test / util / TestUtilities.java
1 /*
2  *******************************************************************************
3  * Copyright (C) 1996-2012, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 package com.ibm.icu.dev.test.util;
8
9 import java.text.NumberFormat;
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.Collection;
13 import java.util.Comparator;
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Random;
19 import java.util.Set;
20 import java.util.SortedSet;
21 import java.util.TreeMap;
22 import java.util.TreeSet;
23
24 import com.ibm.icu.dev.test.TestBoilerplate;
25 import com.ibm.icu.dev.test.TestFmwk;
26 import com.ibm.icu.dev.util.CollectionUtilities;
27 import com.ibm.icu.dev.util.ICUPropertyFactory;
28 import com.ibm.icu.dev.util.UnicodeMap;
29 import com.ibm.icu.dev.util.UnicodeMapIterator;
30 import com.ibm.icu.impl.Utility;
31 import com.ibm.icu.lang.UCharacter;
32 import com.ibm.icu.lang.UProperty;
33 import com.ibm.icu.text.UnicodeSet;
34
35 public class TestUtilities extends TestFmwk {
36     static final int LIMIT = 0x15; // limit to make testing more realistic in terms of collisions
37     static final int ITERATIONS = 1000000;
38     static final boolean SHOW_PROGRESS = false;
39     static final boolean DEBUG = false;
40     
41     public static void main(String[] args) throws Exception {
42         new TestUtilities().run(args);
43     }
44     
45     UnicodeMap map1 = new UnicodeMap();
46     Map map2 = new HashMap();
47     Map map3 = new TreeMap();
48     SortedSet log = new TreeSet();
49     static String[] TEST_VALUES = {null, "A", "B", "C", "D", "E", "F"};
50     static Random random = new Random(12345);
51     
52     public void TestUnicodeMap() {
53         random.setSeed(12345);
54         // do random change to both, then compare
55         logln("Comparing against HashMap");
56         for (int counter = 0; counter < ITERATIONS; ++counter) {
57             int start = random.nextInt(LIMIT);
58             String value = TEST_VALUES[random.nextInt(TEST_VALUES.length)];
59             String logline = Utility.hex(start) + "\t" + value;
60             if (SHOW_PROGRESS) logln(counter + "\t" + logline);
61             log.add(logline);
62             if (DEBUG && counter == 144) {
63                 System.out.println(" debug");
64             }
65             map1.put(start, value);
66             map2.put(new Integer(start), value);
67             check(counter);
68         }
69         checkNext(LIMIT);
70         
71         logln("Setting General Category");
72         map1 = new UnicodeMap();
73         map2 = new TreeMap();
74         for (int cp = 0; cp <= SET_LIMIT; ++cp) {
75               int enumValue = UCharacter.getIntPropertyValue(cp, propEnum);
76               //if (enumValue <= 0) continue; // for smaller set
77               String value = UCharacter.getPropertyValueName(propEnum,enumValue, UProperty.NameChoice.LONG);
78               map1.put(cp, value);
79               map2.put(new Integer(cp), value);
80         }       
81         checkNext(Integer.MAX_VALUE);
82
83
84         logln("Comparing General Category");
85         check(-1);
86         logln("Comparing Values");
87         Set values1 = (Set) map1.getAvailableValues(new TreeSet());
88         Set values2 = new TreeSet(map2.values());
89         if (!TestBoilerplate.verifySetsIdentical(this, values1, values2)) {
90             throw new IllegalArgumentException("Halting");
91         }
92         logln("Comparing Sets");
93         for (Iterator it = values1.iterator(); it.hasNext();) {
94             Object value = it.next();
95             logln(value == null ? "null" : value.toString());
96             UnicodeSet set1 = map1.keySet(value);
97             UnicodeSet set2 = TestBoilerplate.getSet(map2, value);
98             if (!TestBoilerplate.verifySetsIdentical(this, set1, set2)) {
99                 throw new IllegalArgumentException("Halting");
100             }
101         } 
102         
103         logln("Getting Scripts");
104         UnicodeMap scripts = ICUPropertyFactory.make().getProperty("script").getUnicodeMap_internal();
105         UnicodeMap.Composer composer = new UnicodeMap.Composer() {
106             public Object compose(int codepoint, String string, Object a, Object b) {
107                 return a.toString() + "_" + b.toString();
108             }
109         };
110         
111         logln("Trying Compose");
112         UnicodeMap composed = ((UnicodeMap)scripts.cloneAsThawed()).composeWith(map1, composer);
113         Object last = "";
114         for (int i = 0; i < 0x10FFFF; ++i) {
115             Object comp = composed.getValue(i);
116             Object gc = map1.getValue(i);
117             Object sc = scripts.getValue(i);
118             if (!comp.equals(composer.compose(i, null, gc, sc))) {
119                 errln("Failed compose at: " + i);
120             }
121             if (!last.equals(comp)) {
122                 logln(Utility.hex(i) + "\t" + comp);
123                 last = comp;
124             }
125         }
126
127         // check boilerplate
128         List argList = new ArrayList();
129         argList.add("TestMain");
130         if (params.nothrow) argList.add("-nothrow");
131         if (params.verbose) argList.add("-verbose");
132         String[] args = new String[argList.size()];
133         argList.toArray(args);
134         new UnicodeMapBoilerplate().run(args);
135          // TODO: the following is not being reached
136         new UnicodeSetBoilerplate().run(args);       
137     }
138     
139     public void TestCollectionUtilitySpeed() {
140         TreeSet ts1 = new TreeSet();
141         TreeSet ts2 = new TreeSet();
142         int size = 1000;
143         int iterations = 1000;
144         String prefix =  "abc";
145         String postfix = "nop";
146         for (int i = 0; i < size; ++i) {
147             ts1.add(prefix + String.valueOf(i) + postfix);
148             ts2.add(prefix + String.valueOf(i) + postfix);
149         }
150         // warm up
151         CollectionUtilities.containsAll(ts1, ts2);
152         ts1.containsAll(ts2);
153
154         timeAndCompare(ts1, ts2, iterations, true, .75);
155         // now different sets
156         ts1.add("Able");
157         timeAndCompare(ts1, ts2, iterations, true, .75);
158         timeAndCompare(ts2, ts1, iterations*100, false, 1.05);
159     }
160
161     private void timeAndCompare(TreeSet ts1, TreeSet ts2, int iterations, boolean expected, double factorOfStandard) {
162         double utilityTimeSorted = timeUtilityContainsAll(iterations, ts1, ts2, expected)/(double)iterations;
163         double standardTimeSorted = timeStandardContainsAll(iterations, ts1, ts2, expected)/(double)iterations;
164         
165         if (utilityTimeSorted < standardTimeSorted*factorOfStandard) {
166             logln("Sorted: Utility time (" + utilityTimeSorted + ") << Standard duration (" + standardTimeSorted + "); " + 100*(utilityTimeSorted/standardTimeSorted) + "%");
167         } else {
168             errln("Sorted: Utility time (" + utilityTimeSorted + ") !<< Standard duration (" + standardTimeSorted + "); " + 100*(utilityTimeSorted/standardTimeSorted) + "%");
169         }
170     }
171
172     private long timeStandardContainsAll(int iterations, Set hs1, Set hs2, boolean expected) {
173         long standardTime;
174         {
175             long start, end;
176             boolean temp = false;
177
178             start = System.currentTimeMillis();
179             for (int i = 0; i < iterations; ++i) {
180                 temp = hs1.containsAll(hs2);
181                 if (temp != expected) {
182                     errln("Bad result");
183                 }
184             }
185             end = System.currentTimeMillis();
186             standardTime = end - start;
187         }
188         return standardTime;
189     }
190
191     private long timeUtilityContainsAll(int iterations, Set hs1, Set hs2, boolean expected) {
192         long utilityTime;
193         {
194             long start, end;
195             boolean temp = false;
196             start = System.currentTimeMillis();
197             for (int i = 0; i < iterations; ++i) {
198                 temp = CollectionUtilities.containsAll(hs1, hs2);
199                 if (temp != expected) {
200                     errln("Bad result");
201                 }
202             }
203             end = System.currentTimeMillis();
204             utilityTime = end - start;
205         }
206         return utilityTime;
207     }
208     
209     public void TestCollectionUtilities() {
210         String[][] test = {{"a", "c", "e", "g", "h", "z"}, {"b", "d", "f", "h", "w"}, { "a", "b" }, { "a", "d" }, {"d"}, {}}; // 
211         int resultMask = 0;
212         for (int i = 0; i < test.length; ++i) {
213             Collection a = new TreeSet(Arrays.asList(test[i]));
214             for (int j = 0; j < test.length; ++j) {
215                 Collection b = new TreeSet(Arrays.asList(test[j]));
216                 int relation = CollectionUtilities.getContainmentRelation(a, b);
217                 resultMask |= (1 << relation);
218                 switch (relation) {
219                 case CollectionUtilities.ALL_EMPTY:
220                     checkContainment(a.size() == 0 && b.size() == 0, a, relation, b);
221                     break;
222                 case CollectionUtilities.NOT_A_SUPERSET_B:
223                     checkContainment(a.size() == 0 && b.size() != 0, a, relation, b);
224                     break;
225                 case CollectionUtilities.NOT_A_DISJOINT_B:
226                     checkContainment(a.equals(b) && a.size() != 0, a, relation, b);
227                     break;
228                 case CollectionUtilities.NOT_A_SUBSET_B:
229                     checkContainment(a.size() != 0 && b.size() == 0, a, relation, b);
230                     break;
231                 case CollectionUtilities.A_PROPER_SUBSET_OF_B:
232                     checkContainment(b.containsAll(a) && !a.equals(b), a, relation, b);
233                     break;
234                 case CollectionUtilities.NOT_A_EQUALS_B:
235                     checkContainment(!CollectionUtilities.containsSome(a, b) && a.size() != 0 && b.size() != 0, a, relation, b);
236                     break;
237                 case CollectionUtilities.A_PROPER_SUPERSET_B:
238                     checkContainment(a.containsAll(b) && !a.equals(b), a, relation, b);
239                 break;
240                 case CollectionUtilities.A_PROPER_OVERLAPS_B:
241                     checkContainment(!b.containsAll(a) && !a.containsAll(b) && CollectionUtilities.containsSome(a, b), a, relation, b);
242                 break;
243                 }
244             }
245         }
246         if (resultMask != 0xFF) {
247             String missing = "";
248             for (int i = 0; i < 8; ++i) {
249                 if ((resultMask & (1 << i)) == 0) {
250                     if (missing.length() != 0) missing += ", ";
251                     missing += RelationName[i];
252                 }
253             }
254             errln("Not all ContainmentRelations checked: " + missing);
255         }
256     }
257
258     static final String[] RelationName = {"ALL_EMPTY",
259             "NOT_A_SUPERSET_B",
260             "NOT_A_DISJOINT_B",
261             "NOT_A_SUBSET_B",
262             "A_PROPER_SUBSET_OF_B",
263             "A_PROPER_DISJOINT_B",
264             "A_PROPER_SUPERSET_B",
265             "A_PROPER_OVERLAPS_B"};
266
267     /**
268      *  
269      */
270     private void checkContainment(boolean c, Collection a, int relation, Collection b) {
271         if (!c) {
272             errln("Fails relation: " + a + " \t" + RelationName[relation] + " \t" + b);
273         }
274     }
275
276     private void checkNext(int limit) {
277         logln("Comparing nextRange");
278         UnicodeMapIterator mi = new UnicodeMapIterator(map1);
279         Map localMap = new TreeMap();
280         while (mi.nextRange()) {
281             logln(Utility.hex(mi.codepoint) + ".." + Utility.hex(mi.codepointEnd) + " => " + mi.value);
282             for (int i = mi.codepoint; i <= mi.codepointEnd; ++i) {
283                 if (i >= limit) continue;
284                 localMap.put(new Integer(i), mi.value);
285             }
286         }
287         checkMap(map2, localMap);
288         
289         logln("Comparing next");
290         mi.reset();
291         localMap = new TreeMap();
292         Object lastValue = new Object();
293         while (mi.next()) {
294             if (!UnicodeMap.areEqual(lastValue, mi.value)) {
295                 // System.out.println("Change: " + Utility.hex(mi.codepoint) + " => " + mi.value);
296                 lastValue = mi.value;
297             }
298             if (mi.codepoint >= limit) continue;
299             localMap.put(new Integer(mi.codepoint), mi.value);
300         }
301         checkMap(map2, localMap);
302     }
303     
304     public void check(int counter) {
305         for (int i = 0; i < LIMIT; ++i) {
306             Object value1 = map1.getValue(i);
307             Object value2 = map2.get(new Integer(i));
308             if (!UnicodeMap.areEqual(value1, value2)) {
309                 errln(counter + " Difference at " + Utility.hex(i)
310                      + "\t UnicodeMap: " + value1
311                      + "\t HashMap: " + value2);
312                 errln("UnicodeMap: " + map1);
313                 errln("Log: " + TestBoilerplate.show(log));
314                 errln("HashMap: " + TestBoilerplate.show(map2));
315             }
316         }
317     }
318     
319     void checkMap(Map m1, Map m2) {
320         if (m1.equals(m2)) return;
321         StringBuffer buffer = new StringBuffer();
322         Set m1entries = m1.entrySet();
323         Set m2entries = m2.entrySet();
324         getEntries("\r\nIn First, and not Second", m1entries, m2entries, buffer, 20);
325         getEntries("\r\nIn Second, and not First", m2entries, m1entries, buffer, 20);
326         errln(buffer.toString());
327     }
328     
329     static Comparator ENTRY_COMPARATOR = new Comparator() {
330         public int compare(Object o1, Object o2) {
331             if (o1 == o2) return 0;
332             if (o1 == null) return -1;
333             if (o2 == null) return 1;
334             Map.Entry a = (Map.Entry) o1;
335             Map.Entry b = (Map.Entry) o2;
336             int result = compare2(a.getKey(), b.getKey());
337             if (result != 0) return result;
338             return compare2(a.getValue(), b.getValue());
339         }
340         private int compare2(Object o1, Object o2) {
341             if (o1 == o2) return 0;
342             if (o1 == null) return -1;
343             if (o2 == null) return 1;
344             return ((Comparable)o1).compareTo(o2);
345         }
346     };
347
348     private void getEntries(String title, Set m1entries, Set m2entries, StringBuffer buffer, int limit) {
349         Set m1_m2 = new TreeSet(ENTRY_COMPARATOR);
350         m1_m2.addAll(m1entries);
351         m1_m2.removeAll(m2entries);
352         buffer.append(title + ": " + m1_m2.size() + "\r\n");
353         for (Iterator it = m1_m2.iterator(); it.hasNext();) {
354             if (limit-- < 0) return;
355             Map.Entry entry = (Map.Entry) it.next();
356             buffer.append(entry.getKey()).append(" => ")
357              .append(entry.getValue()).append("\r\n");
358         }
359     }
360     
361     static final int SET_LIMIT = 0x10FFFF;
362     static final int CHECK_LIMIT = 0xFFFF;
363     static final NumberFormat pf = NumberFormat.getPercentInstance();
364     static final NumberFormat nf = NumberFormat.getInstance();
365     
366     public void TestTime() {
367         double hashTime, umTime, icuTime, treeTime;
368         umTime = checkSetTime(20, 0);
369         hashTime = checkSetTime(20, 1);
370         logln("Percentage: " + pf.format(hashTime/umTime));
371         treeTime = checkSetTime(20, 3);
372         logln("Percentage: " + pf.format(treeTime/umTime));
373         //logln(map1.toString());
374         
375         umTime = checkGetTime(1000, 0);
376         hashTime = checkGetTime(1000, 1);
377         logln("Percentage: " + pf.format(hashTime/umTime));
378         icuTime = checkGetTime(1000, 2);
379         logln("Percentage: " + pf.format(icuTime/umTime));
380         treeTime = checkGetTime(1000, 3);
381         logln("Percentage: " + pf.format(treeTime/umTime));
382     }
383     
384     int propEnum = UProperty.GENERAL_CATEGORY;
385     
386     double checkSetTime(int iterations, int type) {
387         _checkSetTime(1,type);
388         double result = _checkSetTime(iterations, type);
389         logln((type == 0 ? "UnicodeMap" : type == 1 ? "HashMap" : type == 2 ? "ICU" : "TreeMap") + "\t" + nf.format(result));
390         return result;
391     }
392     double _checkSetTime(int iterations, int type) {
393         map1 = new UnicodeMap();
394         map2 = new HashMap();
395         System.gc();
396         double start = System.currentTimeMillis();
397         for (int j = 0; j < iterations; ++j)
398           for (int cp = 0; cp <= SET_LIMIT; ++cp) {
399             int enumValue = UCharacter.getIntPropertyValue(cp, propEnum);
400             if (enumValue <= 0) continue; // for smaller set
401             String value = UCharacter.getPropertyValueName(propEnum,enumValue, UProperty.NameChoice.LONG);
402             switch(type) {
403             case 0: map1.put(cp, value); break;
404             case 1: map2.put(new Integer(cp), value); break;
405             case 3: map3.put(new Integer(cp), value); break;
406             }
407         }
408         double end = System.currentTimeMillis();
409         return (end-start)/1000/iterations;
410     }
411     
412     double checkGetTime(int iterations, int type) {
413         _checkGetTime(1,type);
414         double result = _checkGetTime(iterations, type);
415         logln((type == 0 ? "UnicodeMap" : type == 1 ? "HashMap" : type == 2 ? "ICU" : "TreeMap") + "\t" + nf.format(result));
416         return result;
417     }
418     double _checkGetTime(int iterations, int type) {
419         System.gc();
420         double start = System.currentTimeMillis();
421         for (int j = 0; j < iterations; ++j)
422           for (int cp = 0; cp < CHECK_LIMIT; ++cp) {
423             switch (type) {
424             case 0: map1.getValue(cp); break;
425             case 1: map2.get(new Integer(cp)); break;
426             case 2:
427                 int enumValue = UCharacter.getIntPropertyValue(cp, propEnum);
428                 //if (enumValue <= 0) continue;
429                 UCharacter.getPropertyValueName(propEnum,enumValue, UProperty.NameChoice.LONG);
430                 break;                
431             case 3: map3.get(new Integer(cp)); break;
432             }
433         }
434         double end = System.currentTimeMillis();
435         return (end-start)/1000/iterations;
436     }
437     
438     static class UnicodeMapBoilerplate extends TestBoilerplate {
439
440         /* 
441          * @see com.ibm.icu.dev.test.TestBoilerplate#_hasSameBehavior(java.lang.Object, java.lang.Object)
442          */
443         protected boolean _hasSameBehavior(Object a, Object b) {
444             // we are pretty confident in the equals method, so won't bother with this right now.
445             return true;
446         }
447
448         /*
449          * @see com.ibm.icu.dev.test.TestBoilerplate#_createTestObject()
450          */
451         protected boolean _addTestObject(List list) {
452             if (list.size() > 30) return false;
453             UnicodeMap result = new UnicodeMap();
454             for (int i = 0; i < 50; ++i) {
455                 int start = random.nextInt(25);
456                 String value = TEST_VALUES[random.nextInt(TEST_VALUES.length)];
457                 result.put(start, value);
458             }
459             list.add(result);
460             return true;
461         }
462     }
463     
464     static class StringBoilerplate extends TestBoilerplate {
465
466         /* 
467          * @see com.ibm.icu.dev.test.TestBoilerplate#_hasSameBehavior(java.lang.Object, java.lang.Object)
468          */
469         protected boolean _hasSameBehavior(Object a, Object b) {
470             // we are pretty confident in the equals method, so won't bother with this right now.
471             return true;
472         }
473
474         /*
475          * @see com.ibm.icu.dev.test.TestBoilerplate#_createTestObject()
476          */
477         protected boolean _addTestObject(List list) {
478             if (list.size() > 31) return false;
479             StringBuffer result = new StringBuffer();
480             for (int i = 0; i < 10; ++i) {
481                 result.append((char)random.nextInt(0xFF));
482             }
483             list.add(result.toString());
484             return true;
485         }
486     }
487     
488     static class UnicodeSetBoilerplate extends TestBoilerplate {
489
490         /* 
491          * @see com.ibm.icu.dev.test.TestBoilerplate#_hasSameBehavior(java.lang.Object, java.lang.Object)
492          */
493         protected boolean _hasSameBehavior(Object a, Object b) {
494             // we are pretty confident in the equals method, so won't bother with this right now.
495             return true;
496         }
497
498         /*
499          * @see com.ibm.icu.dev.test.TestBoilerplate#_createTestObject()
500          */
501         protected boolean _addTestObject(List list) {
502             if (list.size() > 32) return false;
503             UnicodeSet result = new UnicodeSet();
504             for (int i = 0; i < 50; ++i) {
505                 result.add(random.nextInt(100));
506             }
507             list.add(result.toString());
508             return true;
509         }
510     }
511
512 }