VisClient/org/hfbk/vis/visnode/VisProfiler.java

Go to the documentation of this file.
00001 package org.hfbk.vis.visnode;
00002 
00003 import java.util.Map;
00004 
00005 import org.dronus.gl.GLFont;
00006 import org.dronus.gl.GLSphereRenderer;
00007 import org.dronus.gl.GLTextPanel;
00008 import org.dronus.gl.GLUtil;
00009 import org.dronus.graph.Edge;
00010 import org.dronus.graph.Graph;
00011 import org.dronus.graph.Node;
00012 import org.hfbk.util.Counter;
00013 import org.hfbk.util.Sleeper;
00014 import org.lwjgl.opengl.GL11;
00015 import org.lwjgl.util.vector.Vector3f;
00016 
00029 public class VisProfiler extends VisSet {
00030         
00032 //      final int DELAY=10;  
00033         final int DELAY=1000;  
00034         
00036         Graph profile=new Graph();
00037 
00039         Counter<Integer> callCounter=new Counter<Integer>();
00040         
00041         //if something was sampled but not yet visualised.
00042         boolean dirty=true;
00043         
00045         class VisCallBall extends VisNodeDraggable {
00046                 int dl;
00047                 GLTextPanel helpText;           
00048                 Node node;
00049                 boolean isTriggered=true; 
00050                 
00051                 VisCallBall(Node n, Vector3f position) {
00052                         super(n, position);
00053                         this.node=n;
00054                         w=h=radius=1.6f;
00055                         helpText=new GLTextPanel(n.text,0,0);
00056                 }
00057                 
00058                 void renderSelf() {
00059                         Integer count=callCounter.get(node.id);
00060                         if (count!=null){
00061                                 radius=.3f+10*(float)Math.sqrt(count/(float)callCounter.total);
00062                                 w=h=2*radius;
00063                         }
00064                         if (isHoovered || isTriggered)                          
00065                                 GL11.glColor3f(1,1,1);
00066                         else if (node.type.equals("Thread"))
00067                                 GL11.glColor3f(1,1,.4f);                        
00068                         else if (node.type.equals("Call")){
00069                                 boolean isOur=node.text.startsWith("org.dronus")||node.text.startsWith("org.hfbk");
00070                                 GL11.glColor4f(1,0,0,(isOur ? 1 : .5f ));
00071                         }
00072                                 
00073                         GLSphereRenderer.renderSphere(radius);
00074                         
00075                         //if (isHoovered || radius>=1.6f) { //describe "fat" calls unhoovered also              
00076                         if (isHoovered) {
00077                                 GL11.glTranslatef(radius,radius,0);
00078                                 GLUtil.billboardCylinder();
00079                                 GL11.glScalef(1,2,1);
00080                                 GLFont.getDefault().render();                           
00081                                 helpText.render();
00082                                 GL11.glDisable(GL11.GL_TEXTURE_2D);
00083                         }
00084                         
00085                         isTriggered=false;
00086                 }
00087         }
00088         
00090         VisNode create(Node node, Vector3f pos) {
00091                 return new VisCallBall(node, pos);
00092         }
00093         
00095         public VisProfiler(Node dummy, Vector3f position) {     
00096                 super(null, position);
00097                                 
00098                 profile.addNode(new Node("0","Vis/Client","Set"));
00099                 
00100                 Thread profiler=new Thread(){                   
00101                         public void run() {
00102                                 setName("VisProfiler");
00103                                 while(true){
00104                                         synchronized(VisProfiler.this){ profile();      };
00105                                         Sleeper.sleep(DELAY);
00106                                 }
00107                         }
00108                 };                              
00109                 profiler.start();
00110         }
00111         
00116         void profile(){
00117                 Node rootset=profile.getRoot();
00118                 
00119                 //for all existing threads...
00120                 for(Map.Entry<Thread,StackTraceElement[]> trace : Thread.getAllStackTraces().entrySet()){
00121                         
00122                         String threadName=trace.getKey().getName();
00123                         int threadId=threadName.hashCode();
00124                         Node threadNode=profile.findNode(threadId);
00125                         if(threadNode==null) {
00126                                 threadNode=new Node(threadId, threadName, "Thread");
00127                                 profile.addNode(threadNode);
00128                                 profile.addEdge(new Edge(threadNode,rootset, null, "in"));                                      
00129                         }
00130                         StackTraceElement[] stes=trace.getValue();
00131                         
00132                         //reverse stack trace
00133                         for (int i=0; i<stes.length/2; i++){
00134                                 StackTraceElement tmp=stes[i];
00135                                 stes[i]=stes[stes.length-i-1];
00136                                 stes[stes.length-i-1]=tmp;
00137                         }
00138                         
00139                         //for all elements of current thread's call stack...
00140                         Node last=null;
00141                         for (StackTraceElement ste: stes){
00142                                 //id by thread too to show threads independently
00143                                 int id=threadId^ste.getClassName().hashCode()^ste.getMethodName().hashCode();
00144                                 
00145                                 callCounter.add(id); //count method sample
00146                                 
00147                                 Node n=profile.findNode(id); //know this method already?
00148                                 
00149                                 if (n==null){
00150                                         n=new Node(id, ste.getClassName()+"."+ste.getMethodName(),"Call");
00151                                         profile.addNode(n);                                     
00152                                         dirty=true; //mark for update
00153                                 }       
00154                                 profile.addEdge(new Edge(n,rootset, null, "in"));
00155                                 
00156                                 if (last!=null) //link to caller method 
00157                                         profile.addEdge(new Edge(last,n, null, ""));
00158                                 else
00159                                         profile.addEdge(new Edge(n,threadNode, null, "in"));
00160                                 last=n;
00161                         }       
00162                         
00163                         // flash active node
00164                         VisNode vn=nodes.get(last);
00165                         if (vn instanceof VisCallBall)
00166                                 ((VisCallBall)vn).isTriggered=true;
00167                 }
00168         }
00169         
00170         void renderSelf() {
00171                 super.renderSelf();
00172                 //everytime the profiler added something to
00173                 //profile graph, we update the visualisation.
00174                 if (dirty) synchronized(this){
00175                         Node root=profile.getRoot();
00176                         update(root);
00177                         
00178                         dirty=false;
00179                 }
00180         }
00181 }

Generated on Tue Apr 7 17:57:22 2009 for visclient by  doxygen 1.5.1