package se.krka.kahlua.profiler;
import java.util.*;
import java.io.PrintWriter;
public class StacktraceNode {
private final long time;
private final StacktraceElement element;
private final List<StacktraceNode> children;
public StacktraceNode(StacktraceElement element, List<StacktraceNode> children, long time) {
this.element = element;
this.children = children;
this.time = time;
}
public static StacktraceNode createFrom(StacktraceCounter counter,
StacktraceElement element,
int maxDepth,
double minTimeRatio,
int maxChildren) {
StacktraceNode returnValue = new StacktraceNode(element,
new ArrayList<StacktraceNode>(),
counter.getTime());
if (maxDepth > 0) {
Map<StacktraceElement,StacktraceCounter> map = counter.getChildren();
List<Map.Entry<StacktraceElement, StacktraceCounter>> childArray = new ArrayList<Map.Entry<StacktraceElement, StacktraceCounter>>(map.entrySet());
Collections.sort(childArray, new Comparator<Map.Entry<StacktraceElement, StacktraceCounter>>() {
@Override
public int compare(Map.Entry<StacktraceElement, StacktraceCounter> o1, Map.Entry<StacktraceElement, StacktraceCounter> o2) {
return Long.signum(o2.getValue().getTime() - o1.getValue().getTime());
}
});
for (int i = childArray.size() - 1; i >= maxChildren; i--) {
childArray.remove(i);
}
for (Map.Entry<StacktraceElement, StacktraceCounter> entry : childArray) {
StacktraceElement e = entry.getKey();
StacktraceCounter childCounter = entry.getValue();
if (childCounter.getTime() >= minTimeRatio * counter.getTime()) {
StacktraceNode childNode = createFrom(childCounter, e,
maxDepth - 1,
minTimeRatio,
maxChildren);
returnValue.children.add(childNode);
}
}
}
return returnValue;
}
public void output(PrintWriter writer) {
output(writer, "", time, time);
}
public void output(PrintWriter writer, String indent, long parentTime, long rootTime) {
writer.println(String.format("%-40s %4d ms %5.1f%% of parent %5.1f%% of total",
indent + element.name() + " (" + element.type() + ")",
time,
100.0 * time / parentTime,
100.0 * time / rootTime));
String nextIndent = indent + " ";
for (StacktraceNode child : children) {
child.output(writer, nextIndent, time, rootTime);
}
}
}