001: /***
002: * Retrotranslator: a Java bytecode transformer that translates Java classes
003: * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
004: *
005: * Copyright (c) 2005 - 2008 Taras Puchko
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * 3. Neither the name of the copyright holders nor the names of its
017: * contributors may be used to endorse or promote products derived from
018: * this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
022: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
023: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
024: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
025: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
026: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
027: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
028: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
029: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
030: * THE POSSIBILITY OF SUCH DAMAGE.
031: */package net.sf.retrotranslator.runtime.impl;
032:
033: import java.util.*;
034: import java.util.concurrent.*;
035: import net.sf.retrotranslator.tests.TestCaseBase;
036:
037: /**
038: * @author Taras Puchko
039: */
040: public class WeakIdentityTableTestCase extends TestCaseBase {
041:
042: private static class StringWeakIdentityTable extends
043: WeakIdentityTable<String, String> {
044: protected String initialValue() {
045: return new String();
046: }
047: }
048:
049: public void testSequential() throws Exception {
050: StringWeakIdentityTable table = new StringWeakIdentityTable();
051: String k1 = new String("k");
052: assertNull(table.lookup(k1));
053: assertEquals(0, table.size());
054: String v1 = table.obtain(k1);
055: assertNotNull(v1);
056: assertEquals(1, table.size());
057: assertSame(v1, table.lookup(k1));
058: assertSame(v1, table.obtain(k1));
059: assertEquals(1, table.size());
060: String v1x = "";
061: table.putIfAbsent(k1, v1x);
062: assertEquals(1, table.size());
063: assertSame(v1, table.lookup(k1));
064: assertNotSame(v1, v1x);
065:
066: String k2 = new String("k");
067: assertNull(table.lookup(k2));
068: assertEquals(1, table.size());
069: String v2 = "";
070: table.putIfAbsent(k2, v2);
071: assertEquals(2, table.size());
072: assertSame(v2, table.lookup(k2));
073: assertSame(v2, table.obtain(k2));
074: assertEquals(2, table.size());
075:
076: System.gc();
077: assertSame(v1, table.lookup(k1));
078: assertSame(v2, table.lookup(k2));
079: assertNotSame(v1, v2);
080: k1 = null;
081: gc(table, 1);
082: assertEquals(1, table.size());
083: assertSame(v2, table.lookup(k2));
084: k2 = null;
085: gc(table, 0);
086: assertEquals(0, table.size());
087: }
088:
089: public void testParallel() throws Exception {
090: final StringWeakIdentityTable table = new StringWeakIdentityTable();
091: ExecutorService service = Executors.newCachedThreadPool();
092: List<Future> list = new ArrayList<Future>();
093: final int iterations = 1000;
094: final CyclicBarrier barrier = new CyclicBarrier(20);
095: for (int i = 0; i < barrier.getParties(); i++) {
096: list.add(service.submit(new Callable() {
097: public Object call() throws Exception {
098: barrier.await();
099: for (int j = 0; j < iterations; j++) {
100: String k = new String("k");
101: assertNull(table.lookup(k));
102: String v = table.obtain(k);
103: assertNotNull(v);
104: table.putIfAbsent(k, new String("x"));
105: assertSame(v, table.lookup(k));
106: assertSame(v, table.obtain(k));
107: String k2 = new String("k2");
108: String v2 = "v2";
109: table.putIfAbsent(k2, v2);
110: assertSame(v2, table.lookup(k2));
111: }
112: return null;
113: }
114: }));
115: }
116: for (Future future : list) {
117: future.get();
118: }
119: gc(table, 0);
120: int size = table.size();
121: assertTrue("Table must be empty but contains " + size
122: + " entries.", size < 10);
123: }
124:
125: private void gc(final WeakIdentityTable table, final int size)
126: throws Exception {
127: gc(new Callable<Boolean>() {
128: public Boolean call() throws Exception {
129: return table.size() > size;
130: }
131: });
132: }
133:
134: }
|