001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2006, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.util;
017:
018: // J2SE dependencies
019: import java.util.HashMap;
020: import java.util.HashSet;
021: import java.util.Iterator;
022: import java.util.Map;
023: import java.util.Random;
024: import java.util.ConcurrentModificationException;
025:
026: // JUnit dependencies
027: import junit.framework.Test;
028: import junit.framework.TestCase;
029: import junit.framework.TestSuite;
030:
031: /**
032: * Tests {@link SoftValueHashMap}.
033: *
034: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/test/java/org/geotools/util/SoftValueHashMapTest.java $
035: * @version $Id: SoftValueHashMapTest.java 27848 2007-11-12 13:10:32Z desruisseaux $
036: * @author Martin Desruisseaux
037: */
038: public final class SoftValueHashMapTest extends TestCase {
039: /**
040: * The size of the test sets to be created.
041: */
042: private static final int SAMPLE_SIZE = 200;
043:
044: /**
045: * Run the suit from the command line.
046: */
047: public static void main(final String[] args) {
048: org.geotools.util.logging.Logging.GEOTOOLS
049: .forceMonolineConsoleOutput();
050: junit.textui.TestRunner.run(suite());
051: }
052:
053: /**
054: * Returns the test suite.
055: */
056: public static Test suite() {
057: return new TestSuite(SoftValueHashMapTest.class);
058: }
059:
060: /**
061: * Constructs a test case with the given name.
062: */
063: public SoftValueHashMapTest(final String name) {
064: super (name);
065: }
066:
067: /**
068: * Tests the {@link SoftValueHashMap} using strong references. The tested
069: * {@link SoftValueHashMap} should behave like a standard {@link Map} object.
070: */
071: public void testStrongReferences() {
072: final Random random = new Random();
073: for (int pass = 0; pass < 4; pass++) {
074: final SoftValueHashMap softMap = new SoftValueHashMap();
075: final HashMap strongMap = new HashMap();
076: for (int i = 0; i < SAMPLE_SIZE; i++) {
077: final Integer key = new Integer(random
078: .nextInt(SAMPLE_SIZE));
079: final Integer value = new Integer(random
080: .nextInt(SAMPLE_SIZE));
081: assertEquals("containsKey:",
082: strongMap.containsKey(key), softMap
083: .containsKey(key));
084: assertEquals("containsValue:", strongMap
085: .containsValue(value), softMap
086: .containsValue(value));
087: assertSame("get:", strongMap.get(key), softMap.get(key));
088: if (random.nextBoolean()) {
089: // Test addition.
090: assertSame("put:", strongMap.put(key, value),
091: softMap.put(key, value));
092: } else {
093: // Test remove
094: assertSame("remove:", strongMap.remove(key),
095: softMap.remove(key));
096: }
097: assertEquals("equals:", strongMap, softMap);
098: }
099: }
100: }
101:
102: /**
103: * Tests the {@link SoftValueHashMap} using soft references.
104: * In this test, we have to keep in mind than some elements
105: * in {@code softMap} may disaspear at any time.
106: */
107: public void testSoftReferences() throws InterruptedException {
108: final Random random = new Random();
109: final SoftValueHashMap softMap = new SoftValueHashMap();
110: final HashMap strongMap = new HashMap();
111: for (int pass = 0; pass < 2; pass++) {
112: int count = 0;
113: softMap.clear();
114: strongMap.clear();
115: for (int i = 0; i < SAMPLE_SIZE; i++) {
116: final Integer key = new Integer(random
117: .nextInt(SAMPLE_SIZE));
118: final Integer value = new Integer(random
119: .nextInt(SAMPLE_SIZE));
120: if (random.nextBoolean()) {
121: /*
122: * Test addition.
123: */
124: final Object softPrevious = softMap.put(key, value);
125: final Object strongPrevious = strongMap.put(key,
126: value);
127: if (softPrevious == null) {
128: // If the element was not in the SoftValueHashMap (i.e. if the garbage
129: // collector has cleared it), then it must not been in HashMap neither
130: // (otherwise GC should not have cleared it).
131: assertNull("put:", strongPrevious);
132: count++; // Count only the new values.
133: } else {
134: assertNotSame(value, softPrevious);
135: }
136: if (strongPrevious != null) {
137: // Note: If 'strongPrevious==null', 'softPrevious' may not
138: // be null if GC has not collected its entry yet.
139: assertSame("put:", strongPrevious, softPrevious);
140: }
141: } else {
142: /*
143: * Test remove
144: */
145: final Object softPrevious = softMap.get(key);
146: final Object strongPrevious = strongMap.remove(key);
147: if (strongPrevious != null) {
148: assertSame("remove:", strongPrevious,
149: softPrevious);
150: }
151: }
152: assertTrue("containsAll:", softMap.entrySet()
153: .containsAll(strongMap.entrySet()));
154: }
155: // Do our best to lets GC finish its work.
156: for (int i = 0; i < 4; i++) {
157: Thread.sleep(50);
158: System.gc();
159: }
160: assertTrue(softMap.isValid());
161: assertTrue("size:", softMap.size() <= count);
162: /*
163: * Make sure that all values are of the correct type. More specifically, we
164: * want to make sure that we didn't forget to convert some Reference object.
165: */
166: for (final Iterator it = softMap.values().iterator(); it
167: .hasNext();) {
168: final Object value;
169: try {
170: value = it.next();
171: } catch (ConcurrentModificationException e) {
172: break;
173: }
174: assertTrue(value instanceof Integer);
175: assertNotNull(value);
176: }
177: }
178: }
179: }
|