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 }