timing: Fix duration of flamegraph view
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.timing.ui / src / org / eclipse / tracecompass / internal / analysis / timing / ui / flamegraph / FlameGraphContentProvider.java
CommitLineData
74ccf789
SF
1/*******************************************************************************
2 * Copyright (c) 2016 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9
10package org.eclipse.tracecompass.internal.analysis.timing.ui.flamegraph;
11
e162d9ae
BH
12import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
13
74ccf789
SF
14import java.util.ArrayDeque;
15import java.util.ArrayList;
16import java.util.Comparator;
17import java.util.Deque;
18import java.util.List;
19
e162d9ae 20import org.eclipse.jdt.annotation.NonNull;
74ccf789 21import org.eclipse.jface.viewers.Viewer;
e162d9ae 22
74ccf789 23import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.AggregatedCalledFunction;
b3282dcf 24import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.ThreadNode;
74ccf789
SF
25import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
26import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
27import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphContentProvider;
28import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
29import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
30
74ccf789
SF
31/**
32 * Content provider for the flame graph view
33 *
34 * @author Sonia Farrah
35 *
36 */
37public class FlameGraphContentProvider implements ITimeGraphContentProvider {
38
4aab9e1d 39 private final List<FlamegraphDepthEntry> fFlameGraphEntries = new ArrayList<>();
74ccf789 40 private ITmfTrace fActiveTrace;
e162d9ae
BH
41 private SortOption fSortOption = SortOption.BY_NAME;
42 private @NonNull Comparator<FlamegraphDepthEntry> fThreadComparator = new ThreadNameComparator();
43
74ccf789
SF
44
45 /**
46 * Parse the aggregated tree created by the callGraphAnalysis and creates
47 * the event list (functions) for each entry (depth)
48 *
49 * @param firstNode
50 * The first node of the aggregation tree
51 * @param childrenEntries
52 * The list of entries for one thread
53 * @param timestampStack
54 * A stack used to save the functions timeStamps
55 */
56 private void setData(AggregatedCalledFunction firstNode, List<FlamegraphDepthEntry> childrenEntries, Deque<Long> timestampStack) {
4aab9e1d 57 long lastEnd = timestampStack.peek();
74ccf789
SF
58 for (int i = 0; i < firstNode.getMaxDepth(); i++) {
59 if (i >= childrenEntries.size()) {
4aab9e1d 60 FlamegraphDepthEntry entry = new FlamegraphDepthEntry(String.valueOf(i), 0, firstNode.getDuration(), i, i);
74ccf789
SF
61 childrenEntries.add(entry);
62 }
4aab9e1d 63 childrenEntries.get(i).updateEndTime(lastEnd + firstNode.getDuration());
74ccf789 64 }
e162d9ae 65 FlamegraphDepthEntry firstEntry = checkNotNull(childrenEntries.get(0));
4aab9e1d 66 firstEntry.addEvent(new FlamegraphEvent(firstEntry, lastEnd, firstNode));
74ccf789
SF
67 // Build the event list for next entries (next depth)
68 addEvent(firstNode, childrenEntries, timestampStack);
4aab9e1d 69 timestampStack.pop();
74ccf789
SF
70 }
71
72 /**
73 * Build the events list for an entry (depth), then creates recursively the
74 * events for the next entries. This parses the aggregation tree starting
75 * from the bottom. This uses a stack to save the timestamp for each
76 * function. Once we save a function's timestamp we'll use it to create the
77 * callees events.
78 *
79 * @param node
80 * The node of the aggregation tree
81 * @param childrenEntries
82 * The list of entries for one thread
83 * @param timestampStack
84 * A stack used to save the functions timeStamps
85 */
86 private void addEvent(AggregatedCalledFunction node, List<FlamegraphDepthEntry> childrenEntries, Deque<Long> timestampStack) {
87 if (node.hasChildren()) {
88 node.getChildren().stream()
89 .sorted(Comparator.comparingLong(AggregatedCalledFunction::getDuration))
90 .forEach(child -> {
91 addEvent(child, childrenEntries, timestampStack);
92 });
74ccf789
SF
93 node.getChildren().stream().forEach(child -> {
94 timestampStack.pop();
95 });
96 }
e162d9ae 97 FlamegraphDepthEntry entry = checkNotNull(childrenEntries.get(node.getDepth()));
74ccf789
SF
98 // Create the event corresponding to the function using the caller's
99 // timestamp
0b06f3bc 100 entry.addEvent(new FlamegraphEvent(entry, timestampStack.peek(), node));
74ccf789
SF
101 timestampStack.push(timestampStack.peek() + node.getDuration());
102 }
103
104 @Override
105 public boolean hasChildren(Object element) {
106 return !fFlameGraphEntries.isEmpty();
107 }
108
109 @Override
110 public ITimeGraphEntry[] getElements(Object inputElement) {
111 fFlameGraphEntries.clear();
112 // Get the root of each thread
113 fActiveTrace = TmfTraceManager.getInstance().getActiveTrace();
114 if (fActiveTrace == null) {
115 return new ITimeGraphEntry[0];
116 }
117
118 if (inputElement instanceof List<?>) {
119 List<?> threadNodes = (List<?>) inputElement;
120 for (Object object : threadNodes) {
b3282dcf
SF
121 if (object instanceof ThreadNode) {
122 buildChildrenEntries((ThreadNode) object);
74ccf789
SF
123 }
124 }
125 }
e162d9ae
BH
126 // Sort the threads
127 fFlameGraphEntries.sort(fThreadComparator);
74ccf789
SF
128 return fFlameGraphEntries.toArray(new ITimeGraphEntry[fFlameGraphEntries.size()]);
129 }
130
131 /**
132 * Build the entry list for one thread
133 *
134 * @param threadNode
135 * The node of the aggregation tree
136 */
b3282dcf 137 private void buildChildrenEntries(ThreadNode threadNode) {
4aab9e1d 138 FlamegraphDepthEntry threadEntry = new FlamegraphDepthEntry("", 0, 0, fFlameGraphEntries.size(), threadNode.getId()); //$NON-NLS-1$
74ccf789 139 List<FlamegraphDepthEntry> childrenEntries = new ArrayList<>();
4aab9e1d
GB
140 Deque<Long> timestampStack = new ArrayDeque<>();
141 timestampStack.push(0L);
74ccf789
SF
142 // Sort children by duration
143 threadNode.getChildren().stream()
144 .sorted(Comparator.comparingLong(AggregatedCalledFunction::getDuration))
145 .forEach(rootFunction -> {
74ccf789 146 setData(rootFunction, childrenEntries, timestampStack);
4aab9e1d
GB
147 long currentThreadDuration = timestampStack.pop() + rootFunction.getDuration();
148 timestampStack.push(currentThreadDuration);
74ccf789
SF
149 });
150 childrenEntries.forEach(child -> {
151 if (child != null) {
152 threadEntry.addChild(child);
153 }
154 });
4aab9e1d 155 threadEntry.updateEndTime(timestampStack.pop());
74ccf789
SF
156 threadEntry.setName(threadNode.getSymbol().toString());
157 fFlameGraphEntries.add(threadEntry);
158 }
159
160 @Override
161 public ITimeGraphEntry[] getChildren(Object parentElement) {
162 return fFlameGraphEntries.toArray(new TimeGraphEntry[fFlameGraphEntries.size()]);
163 }
164
165 @Override
166 public ITimeGraphEntry getParent(Object element) {
167 // Do nothing
168 return null;
169 }
170
171 @Override
172 public void dispose() {
173 // Do nothing
174 }
175
176 @Override
177 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
178 // Do nothing
179 }
180
e162d9ae
BH
181
182 /**
183 * Get the sort option
184 *
185 * @return the sort option.
186 */
187 public SortOption getSortOption() {
188 return fSortOption;
189 }
190
191 /**
192 * Set the sort option for sorting the thread entries
193 *
194 * @param sortOption
195 * the sort option to set
196 *
197 */
198 public void setSortOption(SortOption sortOption) {
199 fSortOption = sortOption;
200 switch (sortOption) {
201 case BY_NAME:
202 fThreadComparator = new ThreadNameComparator();
203 break;
204 case BY_NAME_REV:
205 fThreadComparator = checkNotNull(new ThreadNameComparator().reversed());
206 break;
207 case BY_ID:
208 fThreadComparator = new ThreadIdComparator();
209 break;
210 case BY_ID_REV:
211 fThreadComparator = checkNotNull(new ThreadIdComparator().reversed());
212 break;
213 default:
214 break;
215 }
216 }
74ccf789 217}
This page took 0.034247 seconds and 5 git commands to generate.