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