001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.lib.util.concurrent;
020:
021: import java.util.ArrayList;
022: import java.util.Collections;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026: import java.util.Set;
027: import java.util.TreeSet;
028:
029: import junit.framework.TestCase;
030: import org.apache.openjpa.lib.util.ReferenceMap;
031:
032: /**
033: * Tests the methods of {@link ConcurrentMap}.
034: *
035: * @author Abe White
036: */
037: public class TestConcurrentMap extends TestCase {
038:
039: private static final int ENTRIES = 333;
040: private static final int SLEEP = 3;
041:
042: private ConcurrentMap[] _maps = new ConcurrentMap[] {
043: new ConcurrentHashMap(),
044: new ConcurrentReferenceHashMap(ReferenceMap.HARD,
045: ReferenceMap.HARD), };
046:
047: public void setUp() {
048: for (int i = 0; i < ENTRIES; i++) {
049: for (int j = 0; j < _maps.length; j++) {
050: int key = j * ENTRIES + i;
051: _maps[j].put(new Integer(key), "v" + key);
052: }
053: }
054: }
055:
056: public void testRemoveRandom() {
057: Set keys = new TreeSet();
058: for (int i = 0; i < ENTRIES; i++)
059: for (int j = 0; j < _maps.length; j++)
060: assertTrue(removeRandom(_maps[j], keys));
061: postRemoveTest(keys);
062: }
063:
064: private static boolean removeRandom(ConcurrentMap map, Set keys) {
065: Map.Entry rem = map.removeRandom();
066: return rem != null && rem.getValue().equals("v" + rem.getKey())
067: && keys.add(rem.getKey());
068: }
069:
070: private void postRemoveTest(Set keys) {
071: for (int i = 0; i < _maps.length; i++) {
072: assertTrue(_maps[i].isEmpty());
073: assertTrue(!_maps[i].containsKey(new Integer(ENTRIES * i
074: + i)));
075: }
076: assertEquals(keys.toString(), ENTRIES * _maps.length, keys
077: .size());
078: }
079:
080: public synchronized void testRemoveRandomThreaded()
081: throws InterruptedException {
082: Set keys = Collections.synchronizedSet(new TreeSet());
083: RemoveRandomRunnable[] runs = new RemoveRandomRunnable[ENTRIES
084: * _maps.length];
085: for (int i = 0; i < ENTRIES; i++)
086: for (int j = 0; j < _maps.length; j++)
087: runs[j * ENTRIES + i] = new RemoveRandomRunnable(
088: _maps[j], keys);
089: for (int i = 0; i < runs.length; i++)
090: new Thread(runs[i]).start();
091: Thread.currentThread().sleep(SLEEP * ENTRIES * _maps.length);
092: for (int i = 0; i < runs.length; i++) {
093: assertTrue(String.valueOf(i), !runs[i].error);
094: if (runs[i].interrupted)
095: throw new InterruptedException(String.valueOf(i));
096: }
097: postRemoveTest(keys);
098: }
099:
100: public void testIterate() {
101: iterationTest(false);
102: }
103:
104: private List iterationTest(boolean random) {
105: Set keys = new TreeSet();
106: List ordered = new ArrayList(200);
107: for (int i = 0; i < _maps.length; i++) {
108: Iterator itr = (random) ? _maps[i].randomEntryIterator()
109: : _maps[i].entrySet().iterator();
110: while (itr.hasNext()) {
111: Map.Entry entry = (Map.Entry) itr.next();
112: assertEquals("v" + entry.getKey(), entry.getValue());
113: assertTrue(keys + ":: " + _maps[i].getClass() + "::"
114: + entry.getKey() + "::" + entry.getValue(),
115: keys.add(entry.getKey()));
116: ordered.add(entry.getKey());
117: }
118: }
119: assertEquals(keys.toString(), ENTRIES * _maps.length, keys
120: .size());
121: return ordered;
122: }
123:
124: public void testRandomIterate() {
125: List l1 = iterationTest(true);
126: List l2 = iterationTest(true);
127: assertTrue(!l1.equals(l2));
128: }
129:
130: private static class RemoveRandomRunnable implements Runnable {
131:
132: public boolean error = false;
133: public boolean interrupted = false;
134:
135: private final ConcurrentMap _map;
136: private final Set _keys;
137:
138: public RemoveRandomRunnable(ConcurrentMap map, Set keys) {
139: _map = map;
140: _keys = keys;
141: }
142:
143: public synchronized void run() {
144: try {
145: Thread.currentThread().sleep(
146: (long) (Math.random() * SLEEP));
147: } catch (InterruptedException ie) {
148: interrupted = true;
149: }
150: error = !removeRandom(_map, _keys);
151: }
152: }
153: }
|