1 4 package com.tctest.longrunning; 5 6 import com.tc.exception.TCRuntimeException; 7 import com.tc.object.config.ConfigVisitor; 8 import com.tc.object.config.DSOClientConfigHelper; 9 import com.tc.object.config.TransparencyClassSpec; 10 import com.tc.objectserver.control.ServerControl; 11 import com.tc.simulator.app.Application; 12 import com.tc.simulator.app.ApplicationConfig; 13 import com.tc.simulator.app.ApplicationConfigBuilder; 14 import com.tc.simulator.container.ContainerBuilderConfig; 15 import com.tc.simulator.listener.ListenerProvider; 16 import com.tc.simulator.listener.ResultsListener; 17 import com.tc.util.Assert; 18 19 import java.text.DateFormat ; 20 import java.text.SimpleDateFormat ; 21 import java.util.ArrayList ; 22 import java.util.Arrays ; 23 import java.util.Collection ; 24 import java.util.Date ; 25 import java.util.HashMap ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Map ; 29 import java.util.Random ; 30 31 public class LargeGraphTestApp implements Application, ApplicationConfigBuilder { 32 33 private static final DateFormat df = new SimpleDateFormat ("yyyy-MM=dd HH:mm:ss,SSS Z"); 34 35 private final String appId; 36 private final ResultsListener resultsListener; 37 private final Random random = new Random (); 38 private int idCounter; 39 40 private final Map graph = new HashMap (); 41 private final Collection references; 42 private final Map referencesByNodeID; 43 private final Map nodesByNodeID; 44 private final List objectCount = new ArrayList (1); 45 46 private ConfigVisitor visitor; 47 48 51 public LargeGraphTestApp(ContainerBuilderConfig containerBuilderConfig) { 52 this("", null, null); 53 visitor = new ConfigVisitor(); 54 } 55 56 59 public LargeGraphTestApp(String appId, ApplicationConfig cfg, ListenerProvider listeners) { 60 this.appId = appId; 61 if (listeners != null) this.resultsListener = listeners.getResultsListener(); 62 else this.resultsListener = null; 63 64 if (doVerify()) { 65 referencesByNodeID = new HashMap (); 66 nodesByNodeID = new HashMap (); 67 references = new ArrayList (); 68 } else { 69 referencesByNodeID = null; 70 nodesByNodeID = null; 71 references = null; 72 } 73 } 74 75 public static void visitL1DSOConfig(ConfigVisitor visitor, DSOClientConfigHelper config) { 76 String testClassName = LargeGraphTestApp.class.getName(); 77 TransparencyClassSpec spec = config.getOrCreateSpec(testClassName); 78 79 spec.addRoot("graph", testClassName + ".graph"); 80 spec.addRoot("objectCount", testClassName + ".objectCount"); 81 if (doVerify()) { 82 spec.addRoot("references", testClassName + ".references"); 83 spec.addRoot("referencesByNodeID", testClassName + ".referencesByNodeID"); 84 spec.addRoot("nodesByNodeID", testClassName + ".nodesByNodeID"); 85 } 86 87 config.addWriteAutolock("public void " + testClassName + ".growGraph(int, int)"); 88 config.addWriteAutolock("private void " + testClassName + ".incrementObjectCount()"); 89 config.addWriteAutolock("* " + testClassName + ".newGraphNode()"); 90 config.addReadAutolock("* " + testClassName + ".getObjectCount()"); 91 config.addReadAutolock("* " + testClassName + ".verifyGraph()"); 92 config.addReadAutolock("* " + testClassName + ".verifyReferences()"); 93 config.addReadAutolock("* " + testClassName + ".touchGraph()"); 94 95 spec.addTransient("resultsListener"); 96 spec.addTransient("outputListener"); 97 spec.addTransient("appId"); 98 spec.addTransient("random"); 99 spec.addTransient("idCounter"); 100 101 config.getOrCreateSpec(GraphNode.class.getName()); 102 config.getOrCreateSpec(NodeReference.class.getName()); 103 } 104 105 public String getApplicationId() { 106 return this.appId; 107 } 108 109 public boolean interpretResult(Object result) { 110 return ((Boolean ) result).booleanValue(); 111 } 112 113 static boolean doVerify() { 114 return false; 115 } 116 117 public void run() { 118 try { 119 int iteration = 0; 120 while (true) { 121 int batchSize = random.nextInt(1000); 122 println("About to grow graph by " + batchSize + " nodes..."); 123 growGraph(batchSize, 50); 124 if (random.nextInt(10) > 5) { 125 touchGraph(); 126 } 127 if (doVerify()) { 128 verifyGraph(); 129 verifyReferences(); 130 } 131 println("completed " + (++iteration) + " iteration(s); There are now " + getObjectCount() + " objects."); 132 } 133 } catch (Throwable t) { 134 t.printStackTrace(); 135 resultsListener.notifyResult(Boolean.FALSE); 136 throw new TCRuntimeException(t); 137 } 138 } 139 140 private void println(Object o) { 141 System.out.println(df.format(new Date ()) + ": " + Thread.currentThread() + "[" + appId + "] " + o); 142 } 143 144 147 public void touchGraph() throws Exception { 148 println("About to touch graph..."); 149 synchronized (graph) { 150 GraphNode node = (GraphNode) graph.get(appId); 151 if (node != null) { 152 println("root node has: " + node.getReferenceCount() + " references."); 153 for (int i = 0; i < node.getReferenceCount(); i++) { 154 GraphNode child = node.getReference(i); 155 println("Child " + i + ": " + child); 156 } 157 } else { 158 println("No starting node for: " + appId); 159 } 160 } 161 } 162 163 166 public void growGraph(int theObjectCount, int bushyness) throws Exception { 167 Assert.eval("Bushyness should be between zero and 100, inclusive.", bushyness <= 100 && bushyness >= 0); 168 GraphNode node = null; 169 synchronized (graph) { 170 try { 171 println("Growing graph: objectCount=" + theObjectCount + ", bushyness=" + bushyness + "..."); 172 node = (GraphNode) graph.get(appId); 173 if (node == null) { 174 node = newGraphNode(); 175 theObjectCount--; 176 graph.put(appId, node); 177 incrementObjectCount(); 178 } 179 180 Collection newRoots = new ArrayList (); 181 newRoots.add(node); 182 183 while (theObjectCount > 0) { 184 newRoots = growGraph(theObjectCount, newRoots, bushyness); 185 theObjectCount -= newRoots.size(); 186 } 187 } catch (Throwable t) { 188 t.printStackTrace(); 189 throw new TCRuntimeException(t); 190 } 191 } 192 println("Done growing graph."); 193 } 194 195 private Collection growGraph(int theObjectCount, Collection roots, int bushyness) { 196 Collection newRoots = new ArrayList (); 197 for (Iterator i = roots.iterator(); i.hasNext();) { 198 GraphNode root = (GraphNode) i.next(); 199 boolean first = true; 200 while (first || (beBushy(bushyness)) && theObjectCount > 0) { 201 first = false; 202 GraphNode newNode = newGraphNode(); 203 theObjectCount--; 204 root.addReference(references, referencesByNodeID, newNode); 205 incrementObjectCount(); 206 newRoots.add(newNode); 207 } 208 if (theObjectCount == 0) break; 209 } 210 return newRoots; 211 } 212 213 private boolean beBushy(int bushyness) { 214 return random.nextInt(100) <= bushyness; 215 } 216 217 220 private GraphNode newGraphNode() { 221 String id = nextID(); 222 GraphNode node = new GraphNode(id); 223 if (doVerify()) { 224 List l = new ArrayList (); 225 synchronized (referencesByNodeID) { 226 referencesByNodeID.put(id, l); 227 } 228 synchronized (nodesByNodeID) { 229 nodesByNodeID.put(id, node); 230 } 231 } 232 return node; 233 } 234 235 private synchronized String nextID() { 236 return appId + ":" + idCounter++; 237 } 238 239 242 public int getObjectCount() { 243 synchronized (objectCount) { 244 try { 245 if (objectCount.size() > 0) { 246 return ((Integer ) objectCount.get(0)).intValue(); 247 } else { 248 return 0; 249 } 250 } catch (Throwable t) { 251 t.printStackTrace(); 252 throw new TCRuntimeException(t); 253 } 254 } 255 } 256 257 private void incrementObjectCount() { 258 synchronized (objectCount) { 259 try { 260 Integer newValue = new Integer (getObjectCount() + 1); 261 if (objectCount.size() == 0) { 262 objectCount.add(newValue); 263 } else { 264 objectCount.set(0, newValue); 265 } 266 } catch (Throwable t) { 267 t.printStackTrace(); 268 } 269 } 270 } 271 272 275 public void verifyGraph() throws VerifyException { 276 if (!doVerify()) return; 277 Collection newRoots = null; 278 synchronized (graph) { 279 println("Starting to verify graph..."); 280 newRoots = graph.values(); 281 while (true) { 282 newRoots = verifyGraph(newRoots); 283 if (newRoots.size() == 0) { 284 println("Done verifying graph."); 285 return; 286 } 287 } 288 } 289 } 290 291 private Collection verifyGraph(Collection roots) throws VerifyException { 292 Collection newRoots = new ArrayList (); 293 for (Iterator i = roots.iterator(); i.hasNext();) { 294 visitNode((GraphNode) i.next(), newRoots); 295 } 296 return newRoots; 297 } 298 299 private void visitNode(GraphNode node, Collection newRoots) throws VerifyException { 300 List nodeReferences = (List ) referencesByNodeID.get(node.getID()); 301 302 for (int i = 0; i < node.getReferenceCount(); i++) { 303 GraphNode child = node.getReference(i); 304 if (nodeReferences.size() < i + 1) { throw new VerifyException("There are not enough references for this node: " 305 + child + "; nodeReferences.size(): " 306 + nodeReferences.size()); } 307 NodeReference reference = (NodeReference) nodeReferences.get(i); 308 Assert.eval(node.getID().equals(reference.getReferrerID())); 309 Assert.assertNotNull("Child at " + i + " for node: " + node + " was null!", child); 310 Assert.assertNotNull("Reference at " + i + " for node: " + node + " was null!", reference); 311 if (!child.getID().equals(reference.getReferredID())) { 312 String message = "Child id: " + child.getID() + " not equal to reference.getReferredID(): " 313 + reference.getReferredID(); 314 throw new VerifyException(message); 315 } 316 newRoots.add(child); 317 } 318 } 319 320 323 public void verifyReferences() throws VerifyException { 324 if (!doVerify()) return; 325 synchronized (graph) { 326 println("Starting to verify references..."); 327 for (Iterator i = references.iterator(); i.hasNext();) { 328 NodeReference reference = (NodeReference) i.next(); 329 GraphNode referrer = (GraphNode) nodesByNodeID.get(reference.getReferrerID()); 330 GraphNode referred = referrer.getReference(reference.index()); 331 if (!reference.getReferredID().equals(referred.getID())) { 332 String message = "reference.getRefferedID(): " + reference.getReferredID() 333 + " is not equal to referred.getID(): " + referred.getID(); 334 throw new VerifyException(message); 335 } 336 } 337 println("Done verifying references..."); 338 } 339 } 340 341 public static class GraphNode { 342 private final String id; 343 344 private GraphNode[] children = new GraphNode[0]; 345 346 public GraphNode(String id) { 347 this.id = id; 348 } 349 350 public String toString() { 351 return "GraphNode[id=" + id + ", children=" + enumerateChildren(new StringBuffer ()); 352 } 353 354 private StringBuffer enumerateChildren(StringBuffer buf) { 355 buf.append("["); 356 if (children == null) { 357 buf.append("null"); 358 } else { 359 for (int i = 0; i < children.length; i++) { 360 if (i > 0) { 361 buf.append(","); 362 } 363 if (children[i] != null) buf.append(children[i].getID()); 364 else buf.append("null"); 365 } 366 } 367 buf.append("]"); 368 return buf; 369 } 370 371 public String getID() { 372 return this.id; 373 } 374 375 public synchronized void addReference(Collection references, Map index, GraphNode referred) { 376 377 List l = new ArrayList (Arrays.asList(children)); 378 l.add(referred); 379 children = new GraphNode[l.size()]; 380 for (int i = 0; i < children.length; i++) { 383 children[i] = (GraphNode) l.get(i); 384 } 385 if (doVerify()) { 386 NodeReference rv = new NodeReference(this, referred, children.length - 1); 387 references.add(rv); 388 l = (List ) index.get(getID()); 389 l.add(rv); 390 } 391 } 392 393 public synchronized int getReferenceCount() { 394 return children.length; 395 } 396 397 public synchronized GraphNode getReference(int index) { 398 return children[index]; 399 } 400 401 } 402 403 public static class VerifyException extends Exception { 404 VerifyException(String m) { 405 super(m); 406 } 407 } 408 409 public static class NodeReference { 410 private final String referrer; 411 private final String referred; 412 private final int index; 413 414 public NodeReference(GraphNode referrer, GraphNode referred, int index) { 415 this.index = index; 416 this.referrer = referrer.getID(); 417 this.referred = referred.getID(); 418 } 419 420 public String getReferrerID() { 421 return referrer; 422 } 423 424 public int index() { 425 return this.index; 426 } 427 428 public String getReferredID() { 429 return referred; 430 } 431 432 } 433 434 437 public void visitClassLoaderConfig(DSOClientConfigHelper config) { 438 this.visitor.visit(config, getClass()); 439 } 440 441 public ApplicationConfig newApplicationConfig() { 442 return new ApplicationConfig() { 443 444 public String getApplicationClassname() { 445 return LargeGraphTestApp.class.getName(); 446 } 447 448 public void setAttribute(String key, String value) { 449 } 451 452 public String getAttribute(String key) { 453 return null; 454 } 455 456 public int getIntensity() { 457 throw new AssertionError (); 458 } 459 460 public int getGlobalParticipantCount() { 461 throw new AssertionError (); 462 } 463 464 public ApplicationConfig copy() { 465 throw new AssertionError (); 466 } 467 468 public ServerControl getServerControl() { 469 throw new AssertionError (); 470 } 471 472 }; 473 } 474 } | Popular Tags |