001: //##header
002: /*
003: *******************************************************************************
004: * Copyright (C) 1996-2006, International Business Machines Corporation and *
005: * others. All Rights Reserved. *
006: *******************************************************************************
007: */
008: //#ifndef FOUNDATION
009: package com.ibm.icu.dev.test.util;
010:
011: import java.text.NumberFormat;
012: import java.util.ArrayList;
013: import java.util.Arrays;
014: import java.util.Collection;
015: import java.util.Comparator;
016: import java.util.HashMap;
017: import java.util.HashSet;
018: import java.util.Iterator;
019: import java.util.List;
020: import java.util.Map;
021: import java.util.Random;
022: import java.util.Set;
023: import java.util.SortedSet;
024: import java.util.TreeMap;
025: import java.util.TreeSet;
026:
027: import com.ibm.icu.dev.test.TestBoilerplate;
028: import com.ibm.icu.dev.test.TestFmwk;
029: import com.ibm.icu.impl.CollectionUtilities;
030: import com.ibm.icu.impl.Utility;
031: import com.ibm.icu.lang.UCharacter;
032: import com.ibm.icu.lang.UProperty;
033: import com.ibm.icu.text.UnicodeSet;
034:
035: public class TestUtilities extends TestFmwk {
036: static final int LIMIT = 0x15; // limit to make testing more realistic in terms of collisions
037: static final int ITERATIONS = 1000000;
038: static final boolean SHOW_PROGRESS = false;
039: static final boolean DEBUG = false;
040:
041: public static void main(String[] args) throws Exception {
042: new TestUtilities().run(args);
043: }
044:
045: UnicodeMap map1 = new UnicodeMap();
046: Map map2 = new HashMap();
047: Map map3 = new TreeMap();
048: SortedSet log = new TreeSet();
049: static String[] TEST_VALUES = { null, "A", "B", "C", "D", "E", "F" };
050: static Random random = new Random(12345);
051:
052: public void TestUnicodeMap() {
053: random.setSeed(12345);
054: // do random change to both, then compare
055: logln("Comparing against HashMap");
056: for (int counter = 0; counter < ITERATIONS; ++counter) {
057: int start = random.nextInt(LIMIT);
058: String value = TEST_VALUES[random
059: .nextInt(TEST_VALUES.length)];
060: String logline = Utility.hex(start) + "\t" + value;
061: if (SHOW_PROGRESS)
062: logln(counter + "\t" + logline);
063: log.add(logline);
064: if (DEBUG && counter == 144) {
065: System.out.println(" debug");
066: }
067: map1.put(start, value);
068: map2.put(new Integer(start), value);
069: check(counter);
070: }
071: checkNext(LIMIT);
072:
073: logln("Setting General Category");
074: map1 = new UnicodeMap();
075: map2 = new TreeMap();
076: for (int cp = 0; cp <= SET_LIMIT; ++cp) {
077: int enumValue = UCharacter
078: .getIntPropertyValue(cp, propEnum);
079: //if (enumValue <= 0) continue; // for smaller set
080: String value = UCharacter.getPropertyValueName(propEnum,
081: enumValue, UProperty.NameChoice.LONG);
082: map1.put(cp, value);
083: map2.put(new Integer(cp), value);
084: }
085: checkNext(Integer.MAX_VALUE);
086:
087: logln("Comparing General Category");
088: check(-1);
089: logln("Comparing Values");
090: Set values1 = (Set) map1.getAvailableValues(new TreeSet());
091: Set values2 = new TreeSet(map2.values());
092: Set temp;
093: if (!TestBoilerplate
094: .verifySetsIdentical(this , values1, values2)) {
095: throw new IllegalArgumentException("Halting");
096: }
097: logln("Comparing Sets");
098: for (Iterator it = values1.iterator(); it.hasNext();) {
099: Object value = it.next();
100: logln(value == null ? "null" : value.toString());
101: UnicodeSet set1 = map1.getSet(value);
102: UnicodeSet set2 = TestBoilerplate.getSet(map2, value);
103: if (!TestBoilerplate.verifySetsIdentical(this , set1, set2)) {
104: throw new IllegalArgumentException("Halting");
105: }
106: }
107:
108: logln("Getting Scripts");
109: UnicodeMap scripts = ICUPropertyFactory.make().getProperty(
110: "script").getUnicodeMap_internal();
111: UnicodeMap.Composer composer = new UnicodeMap.Composer() {
112: public Object compose(int codePoint, Object a, Object b) {
113: return a.toString() + "_" + b.toString();
114: }
115: };
116:
117: logln("Trying Compose");
118: UnicodeMap composed = ((UnicodeMap) scripts.cloneAsThawed())
119: .composeWith(map1, composer);
120: Object last = "";
121: for (int i = 0; i < 0x10FFFF; ++i) {
122: Object comp = composed.getValue(i);
123: Object gc = map1.getValue(i);
124: Object sc = scripts.getValue(i);
125: if (!comp.equals(composer.compose(i, gc, sc))) {
126: errln("Failed compose at: " + i);
127: }
128: if (!last.equals(comp)) {
129: logln(Utility.hex(i) + "\t" + comp);
130: last = comp;
131: }
132: }
133:
134: // check boilerplate
135: List argList = new ArrayList();
136: argList.add("TestMain");
137: if (params.nothrow)
138: argList.add("-nothrow");
139: if (params.verbose)
140: argList.add("-verbose");
141: String[] args = new String[argList.size()];
142: argList.toArray(args);
143: new UnicodeMapBoilerplate().run(args);
144: // TODO: the following is not being reached
145: new UnicodeSetBoilerplate().run(args);
146: }
147:
148: public void TestCollectionUtilitySpeed() {
149: HashSet hs1 = new HashSet();
150: HashSet hs2 = new HashSet();
151: int size = 100000;
152: int iterations = 100;
153: String prefix = "abcde";
154: String postfix = "abcde";
155: int start1 = 0; // 1 for some, 0 for all
156: for (int i = 0; i < size; i += 2)
157: hs1.add(prefix + String.valueOf(i) + postfix);
158: for (int i = start1; i < size; i += 2)
159: hs2.add(prefix + String.valueOf(i) + postfix);
160: TreeSet ts1 = new TreeSet(hs1);
161: TreeSet ts2 = new TreeSet(hs2);
162: CollectionUtilities.containsAll(hs1, hs2);
163: CollectionUtilities.containsAll(ts1, ts2);
164: long start, end;
165: boolean temp = false;
166: start = System.currentTimeMillis();
167: for (int i = 0; i < iterations; ++i)
168: temp = CollectionUtilities.containsAll(hs1, hs2);
169: end = System.currentTimeMillis();
170: logln(temp + " " + (end - start) / 1000.0);
171: start = System.currentTimeMillis();
172: for (int i = 0; i < iterations; ++i)
173: temp = CollectionUtilities.containsAll(ts1, ts2);
174: end = System.currentTimeMillis();
175: logln(temp + " " + (end - start) / 1000.0);
176: }
177:
178: public void TestCollectionUtilities() {
179: String[][] test = { { "a", "c", "e", "g", "h", "z" },
180: { "b", "d", "f", "h", "w" }, { "a", "b" },
181: { "a", "d" }, { "d" }, {} }; //
182: int resultMask = 0;
183: for (int i = 0; i < test.length; ++i) {
184: Collection a = new TreeSet(Arrays.asList(test[i]));
185: for (int j = 0; j < test.length; ++j) {
186: Collection b = new TreeSet(Arrays.asList(test[j]));
187: int relation = CollectionUtilities
188: .getContainmentRelation(a, b);
189: resultMask |= (1 << relation);
190: switch (relation) {
191: case CollectionUtilities.ALL_EMPTY:
192: checkContainment(a.size() == 0 && b.size() == 0, a,
193: relation, b);
194: break;
195: case CollectionUtilities.NOT_A_SUPERSET_B:
196: checkContainment(a.size() == 0 && b.size() != 0, a,
197: relation, b);
198: break;
199: case CollectionUtilities.NOT_A_DISJOINT_B:
200: checkContainment(a.equals(b) && a.size() != 0, a,
201: relation, b);
202: break;
203: case CollectionUtilities.NOT_A_SUBSET_B:
204: checkContainment(a.size() != 0 && b.size() == 0, a,
205: relation, b);
206: break;
207: case CollectionUtilities.A_PROPER_SUBSET_OF_B:
208: checkContainment(b.containsAll(a) && !a.equals(b),
209: a, relation, b);
210: break;
211: case CollectionUtilities.NOT_A_EQUALS_B:
212: checkContainment(!CollectionUtilities.containsSome(
213: a, b)
214: && a.size() != 0 && b.size() != 0, a,
215: relation, b);
216: break;
217: case CollectionUtilities.A_PROPER_SUPERSET_B:
218: checkContainment(a.containsAll(b) && !a.equals(b),
219: a, relation, b);
220: break;
221: case CollectionUtilities.A_PROPER_OVERLAPS_B:
222: checkContainment(!b.containsAll(a)
223: && !a.containsAll(b)
224: && CollectionUtilities.containsSome(a, b),
225: a, relation, b);
226: break;
227: }
228: }
229: }
230: if (resultMask != 0xFF) {
231: String missing = "";
232: for (int i = 0; i < 8; ++i) {
233: if ((resultMask & (1 << i)) == 0) {
234: if (missing.length() != 0)
235: missing += ", ";
236: missing += RelationName[i];
237: }
238: }
239: errln("Not all ContainmentRelations checked: " + missing);
240: }
241: }
242:
243: static final String[] RelationName = { "ALL_EMPTY",
244: "NOT_A_SUPERSET_B", "NOT_A_DISJOINT_B", "NOT_A_SUBSET_B",
245: "A_PROPER_SUBSET_OF_B", "A_PROPER_DISJOINT_B",
246: "A_PROPER_SUPERSET_B", "A_PROPER_OVERLAPS_B" };
247:
248: /**
249: *
250: */
251: private void checkContainment(boolean c, Collection a,
252: int relation, Collection b) {
253: if (!c) {
254: errln("Fails relation: " + a + " \t"
255: + RelationName[relation] + " \t" + b);
256: }
257: }
258:
259: private void checkNext(int limit) {
260: logln("Comparing nextRange");
261: UnicodeMap.MapIterator mi = new UnicodeMap.MapIterator(map1);
262: Map map3 = new TreeMap();
263: while (mi.nextRange()) {
264: logln(Utility.hex(mi.codepoint) + ".."
265: + Utility.hex(mi.codepointEnd) + " => " + mi.value);
266: for (int i = mi.codepoint; i <= mi.codepointEnd; ++i) {
267: if (i >= limit)
268: continue;
269: map3.put(new Integer(i), mi.value);
270: }
271: }
272: checkMap(map2, map3);
273:
274: logln("Comparing next");
275: mi.reset();
276: map3 = new TreeMap();
277: Object lastValue = new Object();
278: while (mi.next()) {
279: if (!UnicodeMap.areEqual(lastValue, mi.value)) {
280: // System.out.println("Change: " + Utility.hex(mi.codepoint) + " => " + mi.value);
281: lastValue = mi.value;
282: }
283: if (mi.codepoint >= limit)
284: continue;
285: map3.put(new Integer(mi.codepoint), mi.value);
286: }
287: checkMap(map2, map3);
288: }
289:
290: public void check(int counter) {
291: for (int i = 0; i < LIMIT; ++i) {
292: Object value1 = map1.getValue(i);
293: Object value2 = map2.get(new Integer(i));
294: if (!UnicodeMap.areEqual(value1, value2)) {
295: errln(counter + " Difference at " + Utility.hex(i)
296: + "\t UnicodeMap: " + value1 + "\t HashMap: "
297: + value2);
298: errln("UnicodeMap: " + map1);
299: errln("Log: " + TestBoilerplate.show(log));
300: errln("HashMap: " + TestBoilerplate.show(map2));
301: }
302: }
303: }
304:
305: void checkMap(Map m1, Map m2) {
306: if (m1.equals(m2))
307: return;
308: StringBuffer buffer = new StringBuffer();
309: Set m1entries = m1.entrySet();
310: Set m2entries = m2.entrySet();
311: getEntries("\r\nIn First, and not Second", m1entries,
312: m2entries, buffer, 20);
313: getEntries("\r\nIn Second, and not First", m2entries,
314: m1entries, buffer, 20);
315: errln(buffer.toString());
316: }
317:
318: static Comparator ENTRY_COMPARATOR = new Comparator() {
319: public int compare(Object o1, Object o2) {
320: if (o1 == o2)
321: return 0;
322: if (o1 == null)
323: return -1;
324: if (o2 == null)
325: return 1;
326: Map.Entry a = (Map.Entry) o1;
327: Map.Entry b = (Map.Entry) o2;
328: int result = compare2(a.getKey(), b.getKey());
329: if (result != 0)
330: return result;
331: return compare2(a.getValue(), b.getValue());
332: }
333:
334: private int compare2(Object o1, Object o2) {
335: if (o1 == o2)
336: return 0;
337: if (o1 == null)
338: return -1;
339: if (o2 == null)
340: return 1;
341: return ((Comparable) o1).compareTo(o2);
342: }
343: };
344:
345: private void getEntries(String title, Set m1entries, Set m2entries,
346: StringBuffer buffer, int limit) {
347: Set m1_m2 = new TreeSet(ENTRY_COMPARATOR);
348: m1_m2.addAll(m1entries);
349: m1_m2.removeAll(m2entries);
350: buffer.append(title + ": " + m1_m2.size() + "\r\n");
351: for (Iterator it = m1_m2.iterator(); it.hasNext();) {
352: if (limit-- < 0)
353: return;
354: Map.Entry entry = (Map.Entry) it.next();
355: buffer.append(entry.getKey()).append(" => ").append(
356: entry.getValue()).append("\r\n");
357: }
358: }
359:
360: static final int SET_LIMIT = 0x10FFFF;
361: static final int CHECK_LIMIT = 0xFFFF;
362: static final NumberFormat pf = NumberFormat.getPercentInstance();
363: static final NumberFormat nf = NumberFormat.getInstance();
364:
365: public void TestTime() {
366: double hashTime, umTime, icuTime, treeTime;
367: umTime = checkSetTime(20, 0);
368: hashTime = checkSetTime(20, 1);
369: logln("Percentage: " + pf.format(hashTime / umTime));
370: treeTime = checkSetTime(20, 3);
371: logln("Percentage: " + pf.format(treeTime / umTime));
372: //logln(map1.toString());
373:
374: umTime = checkGetTime(1000, 0);
375: hashTime = checkGetTime(1000, 1);
376: logln("Percentage: " + pf.format(hashTime / umTime));
377: icuTime = checkGetTime(1000, 2);
378: logln("Percentage: " + pf.format(icuTime / umTime));
379: treeTime = checkGetTime(1000, 3);
380: logln("Percentage: " + pf.format(treeTime / umTime));
381: }
382:
383: int propEnum = UProperty.GENERAL_CATEGORY;
384:
385: double checkSetTime(int iterations, int type) {
386: _checkSetTime(1, type);
387: double result = _checkSetTime(iterations, type);
388: logln((type == 0 ? "UnicodeMap" : type == 1 ? "HashMap"
389: : type == 2 ? "ICU" : "TreeMap")
390: + "\t" + nf.format(result));
391: return result;
392: }
393:
394: double _checkSetTime(int iterations, int type) {
395: map1 = new UnicodeMap();
396: map2 = new HashMap();
397: System.gc();
398: double start = System.currentTimeMillis();
399: for (int j = 0; j < iterations; ++j)
400: for (int cp = 0; cp <= SET_LIMIT; ++cp) {
401: int enumValue = UCharacter.getIntPropertyValue(cp,
402: propEnum);
403: if (enumValue <= 0)
404: continue; // for smaller set
405: String value = UCharacter.getPropertyValueName(
406: propEnum, enumValue, UProperty.NameChoice.LONG);
407: switch (type) {
408: case 0:
409: map1.put(cp, value);
410: break;
411: case 1:
412: map2.put(new Integer(cp), value);
413: break;
414: case 3:
415: map3.put(new Integer(cp), value);
416: break;
417: }
418: }
419: double end = System.currentTimeMillis();
420: return (end - start) / 1000 / iterations;
421: }
422:
423: double checkGetTime(int iterations, int type) {
424: _checkGetTime(1, type);
425: double result = _checkGetTime(iterations, type);
426: logln((type == 0 ? "UnicodeMap" : type == 1 ? "HashMap"
427: : type == 2 ? "ICU" : "TreeMap")
428: + "\t" + nf.format(result));
429: return result;
430: }
431:
432: double _checkGetTime(int iterations, int type) {
433: System.gc();
434: double start = System.currentTimeMillis();
435: for (int j = 0; j < iterations; ++j)
436: for (int cp = 0; cp < CHECK_LIMIT; ++cp) {
437: switch (type) {
438: case 0:
439: map1.getValue(cp);
440: break;
441: case 1:
442: map2.get(new Integer(cp));
443: break;
444: case 2:
445: int enumValue = UCharacter.getIntPropertyValue(cp,
446: propEnum);
447: //if (enumValue <= 0) continue;
448: String value = UCharacter.getPropertyValueName(
449: propEnum, enumValue,
450: UProperty.NameChoice.LONG);
451: break;
452: case 3:
453: map3.get(new Integer(cp));
454: break;
455: }
456: }
457: double end = System.currentTimeMillis();
458: return (end - start) / 1000 / iterations;
459: }
460:
461: static class UnicodeMapBoilerplate extends TestBoilerplate {
462:
463: /*
464: * @see com.ibm.icu.dev.test.TestBoilerplate#_hasSameBehavior(java.lang.Object, java.lang.Object)
465: */
466: protected boolean _hasSameBehavior(Object a, Object b) {
467: // we are pretty confident in the equals method, so won't bother with this right now.
468: return true;
469: }
470:
471: /*
472: * @see com.ibm.icu.dev.test.TestBoilerplate#_createTestObject()
473: */
474: protected boolean _addTestObject(List list) {
475: if (list.size() > 30)
476: return false;
477: UnicodeMap result = new UnicodeMap();
478: for (int i = 0; i < 50; ++i) {
479: int start = random.nextInt(25);
480: String value = TEST_VALUES[random
481: .nextInt(TEST_VALUES.length)];
482: result.put(start, value);
483: }
484: list.add(result);
485: return true;
486: }
487: }
488:
489: static class StringBoilerplate extends TestBoilerplate {
490:
491: /*
492: * @see com.ibm.icu.dev.test.TestBoilerplate#_hasSameBehavior(java.lang.Object, java.lang.Object)
493: */
494: protected boolean _hasSameBehavior(Object a, Object b) {
495: // we are pretty confident in the equals method, so won't bother with this right now.
496: return true;
497: }
498:
499: /*
500: * @see com.ibm.icu.dev.test.TestBoilerplate#_createTestObject()
501: */
502: protected boolean _addTestObject(List list) {
503: if (list.size() > 31)
504: return false;
505: StringBuffer result = new StringBuffer();
506: for (int i = 0; i < 10; ++i) {
507: result.append((char) random.nextInt(0xFF));
508: }
509: list.add(result.toString());
510: return true;
511: }
512: }
513:
514: static class UnicodeSetBoilerplate extends TestBoilerplate {
515:
516: /*
517: * @see com.ibm.icu.dev.test.TestBoilerplate#_hasSameBehavior(java.lang.Object, java.lang.Object)
518: */
519: protected boolean _hasSameBehavior(Object a, Object b) {
520: // we are pretty confident in the equals method, so won't bother with this right now.
521: return true;
522: }
523:
524: /*
525: * @see com.ibm.icu.dev.test.TestBoilerplate#_createTestObject()
526: */
527: protected boolean _addTestObject(List list) {
528: if (list.size() > 32)
529: return false;
530: UnicodeSet result = new UnicodeSet();
531: for (int i = 0; i < 50; ++i) {
532: result.add(random.nextInt(100));
533: }
534: list.add(result.toString());
535: return true;
536: }
537: }
538:
539: }
540: //#endif
|