5610407cf6ad1454024eeca9aab5f500f5613085
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.timing.core / src / org / eclipse / tracecompass / internal / analysis / timing / core / callgraph / AggregatedCalledFunction.java
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
10 package org.eclipse.tracecompass.internal.analysis.timing.core.callgraph;
11
12 import java.util.Collection;
13 import java.util.HashMap;
14 import java.util.Map;
15
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.eclipse.tracecompass.common.core.NonNullUtils;
18
19 /**
20 * This class represents a function call in a certain level in the call stack.
21 * It's used to build an aggregation segment tree (aggregated by depth and
22 * callers). Per example,the two calls to the function A() in the call graph
23 * below will be combined into one node in the generated tree:
24 *
25 * <pre>
26 * (Depth=0) main main
27 * ↓↑ ↓↑ ↓↑ => ↓↑ ↓↑
28 * (Depth=1) A() B() A() A() B()
29 * </pre>
30 *
31 * @author Sonia Farrah
32 *
33 */
34 public class AggregatedCalledFunction {
35
36 // ------------------------------------------------------------------------
37 // Attributes
38 // ------------------------------------------------------------------------
39
40 private final Object fSymbol;
41 private final int fDepth;
42 private final int fMaxDepth;
43 private final Map<Object, AggregatedCalledFunction> fChildren = new HashMap<>();
44 private final @Nullable AggregatedCalledFunction fParent;
45 private final AggregatedCalledFunctionStatistics fStatistics;
46 private long fDuration;
47 private long fSelfTime;
48
49 /**
50 * Constructor
51 *
52 * @param symbol
53 * The function's name or address
54 * @param duration
55 * The function's duration
56 * @param depth
57 * The function's depth
58 * @param maxDepth
59 * The aggregation tree's maximum depth
60 * @param parent
61 * The function's caller
62 */
63 public AggregatedCalledFunction(Object symbol, long duration, int depth, int maxDepth, @Nullable AggregatedCalledFunction parent) {
64 fSymbol = symbol;
65 fDuration = duration;
66 fSelfTime = duration;
67 fDepth = depth;
68 fMaxDepth = maxDepth;
69 fParent = parent;
70 fStatistics = new AggregatedCalledFunctionStatistics(duration, duration);
71 }
72
73 /**
74 * The function's symbol (address or name)
75 *
76 * @return The function's symbol
77 */
78 public Object getSymbol() {
79 return fSymbol;
80 }
81
82 /**
83 * The callees of the function
84 *
85 * @return The function's callees
86 */
87 public synchronized Collection<AggregatedCalledFunction> getChildren() {
88 return fChildren.values();
89 }
90
91 /**
92 * The function's caller
93 *
94 * @return The caller of a function
95 */
96 public @Nullable AggregatedCalledFunction getParent() {
97 return fParent;
98 }
99
100 /**
101 * Add a new callee into the Callees list. If the function exists in the
102 * callees list, the new callee's duration will be added to its duration and
103 * it'll combine their callees.
104 *
105 * @param child
106 * The callees of a function
107 */
108 public synchronized void addChild(AggregatedCalledFunction child) {
109 AggregatedCalledFunction node = fChildren.get(child.getSymbol());
110 if (node == null) {
111 fChildren.put(child.getSymbol(), child);
112 } else {
113 merge(node, child);
114 fChildren.replace(node.getSymbol(), node);
115 }
116 fSelfTime -= child.fDuration;
117 fStatistics.initializeMaxMinSelfTime(fSelfTime);
118 }
119
120 /**
121 * Modify the function's duration
122 *
123 * @param duration
124 * The amount to increment the duration by
125 */
126 private void addToDuration(long duration) {
127 fDuration += duration;
128 }
129
130 /**
131 * Merge the callees of two functions.
132 *
133 * @param firstNode
134 * The first parent secondNode The second parent
135 */
136 private static void mergeChildren(AggregatedCalledFunction firstNode, AggregatedCalledFunction secondNode) {
137 for (Map.Entry<Object, AggregatedCalledFunction> FunctionEntry : secondNode.fChildren.entrySet()) {
138 Object childSymbol = NonNullUtils.checkNotNull(FunctionEntry.getKey());
139 AggregatedCalledFunction secondNodeChild = NonNullUtils.checkNotNull(FunctionEntry.getValue());
140 AggregatedCalledFunction aggregatedCalledFunction = firstNode.fChildren.get(childSymbol);
141 if (aggregatedCalledFunction == null) {
142 firstNode.fChildren.put(secondNodeChild.getSymbol(), secondNodeChild);
143 } else {
144 // combine children
145 AggregatedCalledFunction firstNodeChild = aggregatedCalledFunction;
146 merge(firstNodeChild, secondNodeChild);
147 firstNode.fChildren.replace(firstNodeChild.getSymbol(), firstNodeChild);
148 }
149 }
150 }
151
152 /**
153 * Merge two functions, add durations, self times, increment the calls,
154 * update statistics and merge children.
155 *
156 * @param destination
157 * the node to merge to
158 * @param source
159 * the node to merge
160 */
161 private static void merge(AggregatedCalledFunction destination, AggregatedCalledFunction source) {
162 long sourceDuration = source.getDuration();
163 long sourceSelfTime = source.getSelfTime();
164 destination.addToDuration(sourceDuration);
165 destination.addToSelfTime(sourceSelfTime);
166 destination.fStatistics.update(sourceDuration, sourceSelfTime);
167 // merge the children callees.
168 mergeChildren(destination, source);
169 }
170
171 /**
172 * The function's duration
173 *
174 * @return The duration of the function
175 */
176 public long getDuration() {
177 return fDuration;
178 }
179
180 /**
181 * The function's depth
182 *
183 * @return The depth of the function
184 */
185 public int getDepth() {
186 return fDepth;
187 }
188
189 /**
190 * The depth of the aggregated tree
191 *
192 * @return The depth of the aggregated tree
193 */
194 public int getMaxDepth() {
195 return fMaxDepth;
196 }
197
198 /**
199 * The number of calls of a function
200 *
201 * @return The number of calls of a function
202 */
203 public long getNbCalls() {
204 return fStatistics.getNbSegments();
205 }
206
207 /**
208 * The self time of an aggregated function
209 *
210 * @return The self time
211 */
212 public long getSelfTime() {
213 return fSelfTime;
214 }
215
216 /**
217 * Add to the self time of an aggregated function
218 *
219 * @param selfTime
220 * The amount of self time to add
221 */
222 public void addToSelfTime(long selfTime) {
223 fSelfTime += selfTime;
224 }
225
226 /**
227 * Returns whether the function has callees.
228 *
229 * @return Boolean
230 */
231 public Boolean hasChildren() {
232 return !fChildren.isEmpty();
233 }
234
235 /**
236 * The function's statistics
237 *
238 * @return The function's statistics
239 */
240 public AggregatedCalledFunctionStatistics getFunctionStatistics() {
241 return fStatistics;
242 }
243 }
This page took 0.076732 seconds and 4 git commands to generate.