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.config.ConfigVisitor;
007: import com.tc.object.config.DSOClientConfigHelper;
008: import com.tc.object.config.TransparencyClassSpec;
009: import com.tc.simulator.app.ApplicationConfig;
010: import com.tc.simulator.listener.ListenerProvider;
011: import com.tc.util.Assert;
012: import com.tctest.runner.AbstractTransparentApp;
013:
014: import java.util.Random;
015: import java.util.UUID;
016: import java.util.concurrent.ConcurrentHashMap;
017: import java.util.concurrent.CyclicBarrier;
018:
019: public class ConcurrentHashMapMultipleNodesTestApp extends
020: AbstractTransparentApp {
021: private static final int CACHE_CONCURRENCY_LEVEL = 12;
022: private static final int NUM_OF_OBJECTS = 800;
023: private static final int MAX_OBJECTS = 400;
024: private static final boolean OP_SUCCEEDED = true;
025: private static final boolean OP_FAILED = false;
026: private static final int DURATION = 300000;
027:
028: private final CyclicBarrier barrier;
029: private final SessionCache cache = new SessionCache();
030:
031: public ConcurrentHashMapMultipleNodesTestApp(String appId,
032: ApplicationConfig cfg, ListenerProvider listenerProvider) {
033: super (appId, cfg, listenerProvider);
034: barrier = new CyclicBarrier(getParticipantCount());
035: }
036:
037: public void run() {
038: try {
039: int index = barrier.await();
040:
041: if (index == 0) {
042: loadData();
043: }
044:
045: barrier.await();
046:
047: if (index != 0) {
048: runTest();
049: }
050:
051: barrier.await();
052:
053: } catch (Throwable t) {
054: notifyError(t);
055: }
056: }
057:
058: private void runTest() throws Throwable {
059: System.err.println("Start Running Test");
060: long currentTime = System.currentTimeMillis();
061: long spentTime = 0;
062: int count = 0;
063: while (spentTime < DURATION) {
064: System.err.println("Running " + (++count));
065: runReadTest();
066: runInsertTest();
067: long endTime = System.currentTimeMillis();
068: spentTime = spentTime + (endTime - currentTime);
069: }
070: System.err.println("Test FINISHED");
071: }
072:
073: private void runReadTest() throws Throwable {
074: UUID uuid = UUID.randomUUID();
075: Random random = new Random(uuid.getLeastSignificantBits());
076: int id = (int) (random.nextGaussian() * MAX_OBJECTS);
077:
078: if (id < 0 || id >= MAX_OBJECTS) {
079: System.err.println("Skipping non existent user id" + id);
080: return;
081: }
082:
083: UserIdCacheKey key = new UserIdCacheKey(id);
084: System.err.println("Getting session for user id"
085: + key.getUserId());
086: TerracottaSession session = cache.getSession(key);
087: if (session == null) {
088: System.err.println("Skipping non existent user id" + id);
089: return;
090: }
091: System.err.println("Got session user id" + key.getUserId());
092: Assert.assertEquals(key.getUserId(), session.getI());
093: System.err.flush();
094: }
095:
096: private void runInsertTest() throws Throwable {
097: UUID uuid = UUID.randomUUID();
098: Random random = new Random(uuid.getLeastSignificantBits());
099: int id = (int) (random.nextGaussian() * MAX_OBJECTS);
100:
101: if (id < 0 || id >= MAX_OBJECTS) {
102: return;
103: }
104:
105: UserIdCacheKey key = new UserIdCacheKey(id);
106: TerracottaSession session = cache.getSession(key);
107: if (session == null) {
108: session = new TerracottaSession(key.getUserId());
109: cache.insertSession(key, session);
110: }
111: }
112:
113: private void loadData() {
114: for (int i = 0; i < NUM_OF_OBJECTS; i++) {
115: System.err.println("Loading object " + i);
116: UserIdCacheKey key = new UserIdCacheKey(i);
117: TerracottaSession session = new TerracottaSession(key
118: .getUserId());
119:
120: cache.insertSession(key, session);
121: }
122: }
123:
124: public static void visitL1DSOConfig(ConfigVisitor visitor,
125: DSOClientConfigHelper config) {
126: String testClass = ConcurrentHashMapMultipleNodesTestApp.class
127: .getName();
128: TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
129:
130: config.addIncludePattern(testClass + "$*", false, false, true);
131:
132: String methodExpression = "* " + testClass + "*.*(..)";
133: config.addWriteAutolock(methodExpression);
134:
135: spec.addRoot("barrier", "barrier");
136: spec.addRoot("cache", "cache");
137: }
138:
139: private static class SessionCache {
140: private final ConcurrentHashMap cache = new ConcurrentHashMap(
141: NUM_OF_OBJECTS, 0.75f, CACHE_CONCURRENCY_LEVEL);
142:
143: public TerracottaSession getSession(UserIdCacheKey key) {
144: TerracottaSession session = null;
145: session = (TerracottaSession) cache.get(key);
146: return session;
147: }
148:
149: public boolean insertSession(UserIdCacheKey key,
150: TerracottaSession value) {
151: TerracottaSession session = null;
152: session = (TerracottaSession) cache.put(key, value);
153: if (session != null) {
154: System.err
155: .println("Found TerracottaSession with user id: "
156: + key.getUserId()
157: + " already. Duplicate insert");
158: return OP_FAILED;
159: }
160: return OP_SUCCEEDED;
161: }
162: }
163:
164: private static class TerracottaSession {
165: private final int i;
166:
167: public TerracottaSession(int i) {
168: this .i = i;
169: }
170:
171: public int getI() {
172: return i;
173: }
174: }
175:
176: private static class UserIdCacheKey {
177: private int userId;
178:
179: public UserIdCacheKey(int u) {
180: userId = u;
181: }
182:
183: public boolean equals(Object other) {
184: if (null == other)
185: return false;
186: if (!(other instanceof UserIdCacheKey))
187: return false;
188:
189: return userId == ((UserIdCacheKey) other).userId;
190: }
191:
192: public int hashCode() {
193: return userId;
194: }
195:
196: public String toString() {
197: return Integer.toString(userId);
198: }
199:
200: public int getUserId() {
201: return userId;
202: }
203: }
204: }
|