001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tctest;
005:
006: import com.tc.object.bytecode.Manageable;
007: import com.tc.object.bytecode.ManagerUtil;
008: import com.tc.object.config.ConfigVisitor;
009: import com.tc.object.config.DSOClientConfigHelper;
010: import com.tc.object.config.TransparencyClassSpec;
011: import com.tc.simulator.app.ApplicationConfig;
012: import com.tc.simulator.listener.ListenerProvider;
013: import com.tc.util.Assert;
014: import com.tc.util.DebugUtil;
015: import com.tctest.runner.AbstractTransparentApp;
016:
017: import java.util.HashMap;
018: import java.util.Iterator;
019: import java.util.Map;
020: import java.util.Set;
021: import java.util.Map.Entry;
022: import java.util.concurrent.ConcurrentHashMap;
023: import java.util.concurrent.CyclicBarrier;
024:
025: public class ConcurrentHashMapLoadTestApp extends
026: AbstractTransparentApp {
027: private static final int NUM_OF_PUT = 1000;
028:
029: private final DataKey[] keyRoots = new DataKey[] { new DataKey(1),
030: new DataKey(2), new DataKey(3), new DataKey(4) };
031: private final DataValue[] valueRoots = new DataValue[] {
032: new DataValue(10), new DataValue(20), new DataValue(30),
033: new DataValue(40) };
034:
035: private final CyclicBarrier barrier;
036: private final ConcurrentHashMap mapRoot = new ConcurrentHashMap();
037: private final SharedObject sharedRoot = new SharedObject();
038:
039: public ConcurrentHashMapLoadTestApp(String appId,
040: ApplicationConfig cfg, ListenerProvider listenerProvider) {
041: super (appId, cfg, listenerProvider);
042: barrier = new CyclicBarrier(getParticipantCount());
043: }
044:
045: public void run() {
046: try {
047: int index = barrier.await();
048:
049: testUnsharedToShared1(index);
050: testUnsharedToShared2(index);
051: testUnsharedToShared3(index);
052: testUnsharedToShared4(index);
053:
054: testContainsKey1(index);
055: testContainsKey2(index);
056: testGet(index);
057: testRemove(index);
058: testReplace(index);
059:
060: testPutMany(index);
061: testPutAndRemoveMany(index);
062: } catch (Throwable t) {
063: notifyError(t);
064: }
065: }
066:
067: private void testUnsharedToShared1(int index) throws Exception {
068: if (index == 0) {
069: ConcurrentHashMap newMap = new ConcurrentHashMap();
070: newMap.put(keyRoots[0], valueRoots[0]);
071: newMap.put(keyRoots[1], valueRoots[1]);
072: newMap.put(keyRoots[2], valueRoots[2]);
073: newMap.put(keyRoots[3], valueRoots[3]);
074:
075: synchronized (sharedRoot) {
076: sharedRoot.setMap(newMap);
077: }
078: }
079:
080: barrier.await();
081:
082: Map newMap = new HashMap();
083: newMap.put(keyRoots[0], valueRoots[0]);
084: newMap.put(keyRoots[1], valueRoots[1]);
085: newMap.put(keyRoots[2], valueRoots[2]);
086: newMap.put(keyRoots[3], valueRoots[3]);
087:
088: Map sharedMap = sharedRoot.getMap();
089: assertMappingsEqual(newMap, sharedMap);
090:
091: barrier.await();
092: }
093:
094: private void testUnsharedToShared2(int index) throws Exception {
095: if (index == 0) {
096: ConcurrentHashMap newMap = new ConcurrentHashMap();
097: newMap.put(keyRoots[0], valueRoots[0]);
098: newMap.put(keyRoots[1], valueRoots[1]);
099: newMap.put(keyRoots[2], valueRoots[2]);
100:
101: mapRoot.put("newMap", newMap);
102: mapRoot.put(keyRoots[0], keyRoots[1]);
103: }
104:
105: barrier.await();
106:
107: Map newMap = new HashMap();
108: newMap.put(keyRoots[0], valueRoots[0]);
109: newMap.put(keyRoots[1], valueRoots[1]);
110: newMap.put(keyRoots[2], valueRoots[2]);
111:
112: Map sharedMap = (Map) mapRoot.get("newMap");
113: assertMappingsEqual(newMap, sharedMap);
114:
115: barrier.await();
116:
117: if (index == 1) {
118: Map m = (Map) mapRoot.get("newMap");
119: m.put(keyRoots[3], valueRoots[3]);
120: }
121:
122: barrier.await();
123:
124: newMap.put(keyRoots[3], valueRoots[3]);
125:
126: sharedMap = (Map) mapRoot.get("newMap");
127: assertMappingsEqual(newMap, sharedMap);
128:
129: barrier.await();
130: }
131:
132: private void testUnsharedToShared3(int index) throws Exception {
133: if (index == 0) {
134: ConcurrentHashMap newMap = new ConcurrentHashMap();
135: DataKey key1 = new DataKey(1);
136: DataKey key2 = new DataKey(2);
137: DataValue val1 = new DataValue(10);
138: DataValue val2 = new DataValue(20);
139: newMap.put(key1, val1);
140: newMap.put(key2, val2);
141:
142: Assert.assertNull(((Manageable) key1).__tc_managed());
143:
144: mapRoot.put("newMap", newMap);
145:
146: Assert.assertNotNull(((Manageable) key1).__tc_managed());
147: }
148:
149: barrier.await();
150: }
151:
152: private void testUnsharedToShared4(int index) throws Exception {
153: clearMapRoot(index);
154: if (index == 0) {
155: ConcurrentHashMap newMap = new ConcurrentHashMap();
156: HashKey key1 = new HashKey(1);
157: HashKey key2 = new HashKey(2);
158: HashValue val1 = new HashValue(10);
159: HashValue val2 = new HashValue(20);
160: newMap.put(key1, val1);
161: newMap.put(key2, val2);
162:
163: mapRoot.put(newMap, "newMap");
164: }
165:
166: barrier.await();
167:
168: Assert.assertEquals(1, mapRoot.size());
169:
170: Set keys = mapRoot.keySet();
171: Iterator keyIterator = keys.iterator();
172: Map map = (Map) keyIterator.next();
173: map.containsKey(new HashKey(1));
174: map.containsKey(new HashKey(2));
175: map.containsValue(new HashValue(10));
176: map.containsValue(new HashValue(20));
177:
178: Object o = mapRoot.get(map);
179: Assert.assertEquals("newMap", o);
180:
181: barrier.await();
182:
183: if (index == 1) {
184: map.put(new HashKey(3), new HashValue(30));
185: }
186:
187: barrier.await();
188:
189: Assert.assertEquals(new HashValue(30), map.get(new HashKey(3)));
190:
191: barrier.await();
192: }
193:
194: private void testContainsKey1(int index) throws Exception {
195: if (index == 0) {
196: DataKey key1 = new DataKey(1);
197: DataKey key2 = new DataKey(1);
198:
199: DataValue val1 = new DataValue(10);
200: DataValue val2 = new DataValue(10);
201:
202: Assert.assertNull(((Manageable) key1).__tc_managed());
203: Assert.assertNull(((Manageable) key2).__tc_managed());
204: Assert.assertNull(((Manageable) val1).__tc_managed());
205: Assert.assertNull(((Manageable) val2).__tc_managed());
206:
207: mapRoot.put(key1, val1);
208: Assert.assertNotNull(((Manageable) key1).__tc_managed());
209: Assert.assertNotNull(((Manageable) val1).__tc_managed());
210:
211: Assert.assertTrue(mapRoot.containsKey(key1));
212: Assert.assertFalse(mapRoot.containsKey(key2));
213:
214: Assert.assertNull(((Manageable) key2).__tc_managed());
215:
216: Assert.assertTrue(mapRoot.contains(val1));
217: Assert.assertFalse(mapRoot.contains(val2));
218:
219: Assert.assertNull(((Manageable) val2).__tc_managed());
220: }
221:
222: barrier.await();
223: }
224:
225: private void testContainsKey2(int index) throws Exception {
226: if (index == 0) {
227: HashKey key1 = new HashKey(1);
228: HashKey key2 = new HashKey(1);
229:
230: HashValue val1 = new HashValue(10);
231: HashValue val2 = new HashValue(10);
232:
233: Assert.assertNull(((Manageable) key1).__tc_managed());
234: Assert.assertNull(((Manageable) key2).__tc_managed());
235: Assert.assertNull(((Manageable) val1).__tc_managed());
236: Assert.assertNull(((Manageable) val2).__tc_managed());
237:
238: mapRoot.put(key1, val1);
239:
240: Assert.assertNotNull(((Manageable) key1).__tc_managed());
241: Assert.assertNotNull(((Manageable) val1).__tc_managed());
242:
243: Assert.assertTrue(mapRoot.containsKey(key1));
244: Assert.assertTrue(mapRoot.containsKey(key2));
245:
246: Assert.assertNull(((Manageable) key2).__tc_managed());
247:
248: Assert.assertTrue(mapRoot.contains(val1));
249: Assert.assertTrue(mapRoot.contains(val2));
250:
251: Assert.assertNull(((Manageable) val2).__tc_managed());
252: }
253:
254: barrier.await();
255: }
256:
257: private void testGet(int index) throws Exception {
258: if (index == 0) {
259: DataKey key1 = new DataKey(1);
260: DataKey key2 = new DataKey(1);
261:
262: DataValue val1 = new DataValue(10);
263: DataValue val2 = new DataValue(10);
264:
265: Assert.assertNull(((Manageable) key1).__tc_managed());
266: Assert.assertNull(((Manageable) key2).__tc_managed());
267: Assert.assertNull(((Manageable) val1).__tc_managed());
268: Assert.assertNull(((Manageable) val2).__tc_managed());
269:
270: mapRoot.put(key1, val1);
271:
272: Assert.assertNotNull(((Manageable) key1).__tc_managed());
273: Assert.assertNotNull(((Manageable) val1).__tc_managed());
274:
275: Assert.assertNotNull(mapRoot.get(key1));
276: Assert.assertNull(mapRoot.get(key2));
277:
278: Assert.assertNull(((Manageable) key2).__tc_managed());
279: }
280:
281: barrier.await();
282: }
283:
284: private void testRemove(int index) throws Exception {
285: if (index == 0) {
286: DataKey key1 = new DataKey(1);
287: DataKey key2 = new DataKey(1);
288:
289: DataValue val1 = new DataValue(10);
290: DataValue val2 = new DataValue(10);
291:
292: Assert.assertNull(((Manageable) key1).__tc_managed());
293: Assert.assertNull(((Manageable) key2).__tc_managed());
294: Assert.assertNull(((Manageable) val1).__tc_managed());
295: Assert.assertNull(((Manageable) val2).__tc_managed());
296:
297: mapRoot.put(key1, val1);
298:
299: Assert.assertNotNull(((Manageable) key1).__tc_managed());
300: Assert.assertNotNull(((Manageable) val1).__tc_managed());
301:
302: Assert.assertNull(mapRoot.remove(key2));
303:
304: Assert.assertNull(((Manageable) key2).__tc_managed());
305: }
306:
307: barrier.await();
308: }
309:
310: private void testReplace(int index) throws Exception {
311: if (index == 0) {
312: DataKey key1 = new DataKey(1);
313: DataKey key2 = new DataKey(1);
314:
315: DataValue val1 = new DataValue(10);
316: DataValue val2 = new DataValue(10);
317:
318: Assert.assertNull(((Manageable) key1).__tc_managed());
319: Assert.assertNull(((Manageable) key2).__tc_managed());
320: Assert.assertNull(((Manageable) val1).__tc_managed());
321: Assert.assertNull(((Manageable) val2).__tc_managed());
322:
323: mapRoot.put(key1, val1);
324:
325: Assert.assertNotNull(((Manageable) key1).__tc_managed());
326: Assert.assertNotNull(((Manageable) val1).__tc_managed());
327:
328: Assert.assertNull(mapRoot.replace(key2, val2));
329:
330: Assert.assertNull(((Manageable) key2).__tc_managed());
331: }
332:
333: barrier.await();
334: }
335:
336: private void testPutMany(int index) throws Exception {
337: if (index == 0) {
338: for (int i = 0; i < NUM_OF_PUT; i++) {
339: mapRoot.put(new HashKey(i), new HashValue(i));
340: }
341: }
342:
343: barrier.await();
344:
345: if (DebugUtil.DEBUG) {
346: System.err.println("Index: " + index + ", map size: "
347: + mapRoot.size());
348: System.err.println("Index: " + index + ", map: " + mapRoot);
349: }
350:
351: for (int i = 0; i < NUM_OF_PUT; i++) {
352: Assert.assertEquals(new HashValue(i), mapRoot
353: .get(new HashKey(i)));
354: }
355:
356: if (DebugUtil.DEBUG) {
357: System.err.println("Index: " + index + ", map size: "
358: + mapRoot.size());
359: System.err.println("Index: " + index
360: + " exiting last barrier in testPutMany.");
361: }
362:
363: barrier.await();
364: }
365:
366: private void testPutAndRemoveMany(int index) throws Exception {
367: DebugUtil.DEBUG = true;
368: clearMapRoot(index);
369:
370: if (index == 0) {
371: for (int i = 0; i < NUM_OF_PUT; i++) {
372: System.out.println("Put: " + i);
373: mapRoot.put(new HashKey(i), new HashValue(i));
374: }
375: } else if (index == 1) {
376: for (int i = 0; i < NUM_OF_PUT; i++) {
377: Object o = null;
378: while (o == null) {
379: o = mapRoot.remove(new HashKey(i));
380: }
381:
382: Assert.assertEquals(o, new HashValue(i));
383: System.out.println("Remove: " + i);
384: }
385: }
386:
387: barrier.await();
388:
389: if (DebugUtil.DEBUG) {
390: System.err.println("Node id: " + ManagerUtil.getClientID()
391: + " -- " + index + ", size of concurrentHashMap: "
392: + mapRoot.size());
393: }
394: Assert.assertTrue(mapRoot.isEmpty());
395:
396: barrier.await();
397:
398: DebugUtil.DEBUG = false;
399: }
400:
401: private void clearMapRoot(int index) throws Exception {
402: if (index == 0) {
403: System.err.println("In clearMapRoot");
404:
405: mapRoot.clear();
406: }
407: barrier.await();
408: }
409:
410: void assertMappingsEqual(Map expect, Map actual) {
411: Assert.assertEquals(expect.size(), actual.size());
412:
413: Set expectEntries = expect.entrySet();
414: Set actualEntries = actual.entrySet();
415:
416: for (Iterator i = expectEntries.iterator(); i.hasNext();) {
417: Entry entry = (Entry) i.next();
418: Assert.assertEquals(
419: ((DataValue) entry.getValue()).getInt(),
420: ((DataValue) actual.get(entry.getKey())).getInt());
421: }
422:
423: for (Iterator i = actualEntries.iterator(); i.hasNext();) {
424: Entry entry = (Entry) i.next();
425: Assert.assertEquals(
426: ((DataValue) entry.getValue()).getInt(),
427: ((DataValue) expect.get(entry.getKey())).getInt());
428: }
429: }
430:
431: public static void visitL1DSOConfig(ConfigVisitor visitor,
432: DSOClientConfigHelper config) {
433: String testClass = ConcurrentHashMapLoadTestApp.class.getName();
434: TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
435:
436: config.addIncludePattern(testClass + "$*", false, false, true);
437:
438: String methodExpression = "* " + testClass + "*.*(..)";
439: config.addWriteAutolock(methodExpression);
440:
441: spec.addRoot("barrier", "barrier");
442: spec.addRoot("mapRoot", "mapRoot");
443: spec.addRoot("sharedRoot", "sharedRoot");
444: spec.addRoot("keyRoots", "keyRoots");
445: spec.addRoot("valueRoots", "valueRoots");
446: }
447:
448: private static class DataKey {
449: private int i;
450:
451: public DataKey(int i) {
452: super ();
453: this .i = i;
454: }
455:
456: public int getInt() {
457: return this .i;
458: }
459:
460: public String toString() {
461: return super .toString() + ", i: " + i;
462: }
463: }
464:
465: private static class DataValue {
466: private int i;
467:
468: public DataValue(int i) {
469: super ();
470: this .i = i;
471: }
472:
473: public int getInt() {
474: return this .i;
475: }
476:
477: public String toString() {
478: return super .toString() + ", i: " + i;
479: }
480: }
481:
482: private static class HashKey {
483: private int i;
484:
485: public HashKey(int i) {
486: super ();
487: this .i = i;
488: }
489:
490: public int getInt() {
491: return this .i;
492: }
493:
494: public int hashCode() {
495: return i;
496: }
497:
498: public boolean equals(Object obj) {
499: if (obj == null)
500: return false;
501: if (!(obj instanceof HashKey))
502: return false;
503: return ((HashKey) obj).i == i;
504: }
505:
506: public String toString() {
507: return super .toString() + ", i: " + i;
508: }
509: }
510:
511: private static class HashValue {
512: private int i;
513:
514: public HashValue(int i) {
515: super ();
516: this .i = i;
517: }
518:
519: public int getInt() {
520: return this .i;
521: }
522:
523: public int hashCode() {
524: return i;
525: }
526:
527: public boolean equals(Object obj) {
528: if (obj == null)
529: return false;
530: if (!(obj instanceof HashValue))
531: return false;
532: return ((HashValue) obj).i == i;
533: }
534:
535: public String toString() {
536: return super .toString() + ", i: " + i;
537: }
538: }
539:
540: private static class SharedObject {
541: private ConcurrentHashMap map;
542:
543: public SharedObject() {
544: super ();
545: }
546:
547: public ConcurrentHashMap getMap() {
548: return map;
549: }
550:
551: public void setMap(ConcurrentHashMap map) {
552: this.map = map;
553: }
554:
555: }
556:
557: }
|