001 package org.shiftone.jrat.provider.tree.ui; 002 003 004 import org.shiftone.jrat.core.Accumulator; 005 import org.shiftone.jrat.core.MethodKey; 006 import org.shiftone.jrat.provider.tree.TreeNode; 007 import org.shiftone.jrat.util.collection.ArrayEnumeration; 008 import org.shiftone.jrat.util.log.Logger; 009 010 import java.util.Arrays; 011 import java.util.Comparator; 012 import java.util.Enumeration; 013 import java.util.List; 014 015 016 /** 017 * @author jeff@shiftone.org (Jeff Drost) 018 */ 019 public class TraceTreeNode implements javax.swing.tree.TreeNode { 020 021 private static final Logger LOG = Logger.getLogger(TraceTreeNode.class); 022 023 private final MethodKey methodKey; 024 private final Accumulator accumulator; 025 026 private final Double averageMethodDuration; 027 private final long totalMethodDuration; 028 029 private final int depth; 030 private final TraceTreeNode[] childArray; 031 private final TraceTreeNode parent; 032 private double pctOfAvgRootDuration; 033 private double pctOfAvgParentDuration; 034 035 private int totalChildren; // total # of children and all children's children 036 private int maxDepth; // depth deepest child 037 038 039 public TraceTreeNode(TreeNode node) { 040 this(node, 0, null, null); 041 } 042 043 044 private TraceTreeNode(TreeNode node, int depth, TraceTreeNode parent, TraceTreeNode root) { 045 046 this.methodKey = node.getMethodKey(); 047 this.accumulator = node.getAccumulator(); 048 this.depth = depth; 049 this.parent = parent; 050 051 052 if ((parent != null) && (getTotalExits() > 0)) { 053 054 long parentTotalDuration = parent.getTotalDuration(); 055 056 if (parentTotalDuration > 0) { 057 pctOfAvgParentDuration = (100.0 * getTotalDuration()) / parentTotalDuration; 058 } 059 060 } 061 062 if ((root != null) && (getTotalExits() > 0)) { 063 064 long rootTotalDuration = root.getTotalDuration(); 065 066 if (rootTotalDuration > 0) { 067 pctOfAvgRootDuration = (100.0 * getTotalDuration()) / rootTotalDuration; 068 } 069 070 } 071 072 List c = node.getChildren(); // <TreeNode> 073 074 this.childArray = new TraceTreeNode[c.size()]; 075 076 077 for (int i = 0; i < childArray.length; i++) { 078 079 TreeNode childNode = (TreeNode) c.get(i); 080 TraceTreeNode childStackTreeNode = new TraceTreeNode(childNode, depth + 1, this, root); 081 082 totalChildren += (1 + childStackTreeNode.totalChildren); 083 maxDepth = Math.max(maxDepth, 1 + childStackTreeNode.maxDepth); 084 085 childArray[i] = childStackTreeNode; 086 } 087 088 Arrays.sort(childArray, TotalChildrenComparator.INSTANCE); 089 090 091 { // total method duration 092 093 long duration = getTotalDuration(); 094 095 for (int i = 0; i < childArray.length; i++) { 096 duration -= childArray[i].getTotalDuration(); 097 } 098 099 totalMethodDuration = duration; 100 } 101 102 { // average method duration 103 104 if (getTotalExits() == 0) { 105 averageMethodDuration = null; 106 } else { 107 averageMethodDuration = new Double(totalMethodDuration / getTotalExits()); 108 } 109 } 110 111 // this.rootAverageDurationNanos = (childOfRoot) 112 // ? this.averageDurationNanos 113 // : parent.rootAverageDurationNanos; 114 // 115 // // 116 // this.rootTotalDurationNanos = (childOfRoot) 117 // ? node.getTotalDuration() 118 // : parent.rootTotalDurationNanos; 119 // 120 // if (rootAverageDurationNanos > 0) { 121 // pctOfAvgRootDuration = (100.0 * averageDurationNanos) / rootAverageDurationNanos; 122 // } 123 // 124 // if (rootTotalDurationNanos > 0) { 125 // pctOfRootTotalDuration = ((100.0 * node.getTotalDuration()) / rootTotalDurationNanos); 126 // } 127 } 128 129 130 public int getMaxDepth() { 131 return maxDepth; 132 } 133 134 public int getDepth() { 135 return depth; 136 } 137 138 139 public double getPctOfAvgParentDuration() { 140 return pctOfAvgParentDuration; 141 } 142 143 144 public double getPctOfAvgRootDuration() { 145 return pctOfAvgRootDuration; 146 } 147 148 public Double getAverageMethodDuration() { 149 return averageMethodDuration; 150 } 151 152 public long getTotalMethodDuration() { 153 return totalMethodDuration; 154 } 155 156 // ---------------------------------------------------------- 157 158 159 public int getMaxConcurrentThreads() { 160 return accumulator.getMaxConcurrentThreads(); 161 } 162 163 public long getSumOfSquares() { 164 return accumulator.getSumOfSquares(); 165 } 166 167 public Accumulator getAccumulator() { 168 return accumulator; 169 } 170 171 public MethodKey getMethodKey() { 172 return methodKey; 173 } 174 175 public Double getAverageDuration() { 176 return accumulator.getAverageDuration(); 177 } 178 179 public Double getStdDeviation() { 180 return accumulator.getStdDeviation(); 181 } 182 183 public long getTotalDuration() { 184 return accumulator.getTotalDuration(); 185 } 186 187 public int getConcurrentThreads() { 188 return accumulator.getConcurrentThreads(); 189 } 190 191 public long getTotalErrors() { 192 return accumulator.getTotalErrors(); 193 } 194 195 public long getTotalEnters() { 196 return accumulator.getTotalEnters(); 197 } 198 199 public long getTotalExits() { 200 return accumulator.getTotalExits(); 201 } 202 203 public long getMinDuration() { 204 return accumulator.getMinDuration(); 205 } 206 207 208 public long getMaxDuration() { 209 return accumulator.getMaxDuration(); 210 } 211 212 public boolean isRootNode() { 213 return methodKey == null; 214 } 215 216 217 // ------------------------------------------------------------- 218 public String toString() { 219 220 return (isRootNode()) 221 ? "Root" 222 : methodKey.getMethodName(); 223 } 224 225 226 public Enumeration children() { 227 return new ArrayEnumeration(childArray); 228 } 229 230 231 public boolean getAllowsChildren() { 232 return true; 233 } 234 235 236 public javax.swing.tree.TreeNode getChildAt(int childIndex) { 237 return childArray[childIndex]; 238 } 239 240 public TraceTreeNode getChildNodeAt(int childIndex) { 241 return childArray[childIndex]; 242 } 243 244 public int getChildCount() { 245 return childArray.length; 246 } 247 248 249 public javax.swing.tree.TreeNode getParent() { 250 return parent; 251 } 252 253 public TraceTreeNode getParentNode() { 254 return parent; 255 } 256 257 public int getIndex(javax.swing.tree.TreeNode node) { 258 for (int i = 0; i < childArray.length; i++) { 259 if (node == childArray[i]) { 260 return i; 261 } 262 } 263 return -1; 264 } 265 266 267 public boolean isLeaf() { 268 return (getChildCount() == 0); 269 } 270 271 272 private static class TotalChildrenComparator implements Comparator { 273 274 private static final Comparator INSTANCE = new TotalChildrenComparator(); 275 276 public int compare(Object o1, Object o2) { 277 278 TraceTreeNode stn1 = (TraceTreeNode) o1; 279 TraceTreeNode stn2 = (TraceTreeNode) o2; 280 int diff = stn1.totalChildren - stn2.totalChildren; 281 282 return (diff == 0) 283 ? 0 284 : (diff < 0) 285 ? 1 286 : -1; 287 } 288 } 289 290 291 }