1 /*******************************************************************************
2 * Copyright (c) 2016 Ericsson
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 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.analysis
.timing
.core
.callgraph
;
12 import java
.util
.Collection
;
13 import java
.util
.HashMap
;
16 import org
.eclipse
.jdt
.annotation
.Nullable
;
17 import org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
;
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:
28 * (Depth=1) A() B() A() A() B()
31 * @author Sonia Farrah
34 public class AggregatedCalledFunction
{
36 // ------------------------------------------------------------------------
38 // ------------------------------------------------------------------------
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 private final int fProcessId
;
51 * Constructor, parent is not null
53 * @param calledFunction
59 public AggregatedCalledFunction(AbstractCalledFunction calledFunction
, AggregatedCalledFunction parent
) {
60 fSymbol
= calledFunction
.getSymbol();
61 fDuration
= calledFunction
.getLength();
62 fSelfTime
= calledFunction
.getLength();
63 fDepth
= calledFunction
.getDepth();
64 fProcessId
= calledFunction
.getProcessId();
65 fMaxDepth
= parent
.getMaxDepth();
67 fStatistics
= new AggregatedCalledFunctionStatistics(calledFunction
, calledFunction
);
71 * Root constructor, parent is null
73 * @param calledFunction
78 public AggregatedCalledFunction(AbstractCalledFunction calledFunction
, int maxDepth
) {
79 fSymbol
= calledFunction
.getSymbol();
80 fDuration
= calledFunction
.getLength();
81 fSelfTime
= calledFunction
.getLength();
82 fDepth
= calledFunction
.getDepth();
83 fProcessId
= calledFunction
.getProcessId();
86 fStatistics
= new AggregatedCalledFunctionStatistics(calledFunction
, calledFunction
);
90 * The function's symbol (address or name)
92 * @return The function's symbol
94 public Object
getSymbol() {
99 * The callees of the function
101 * @return The function's callees
103 public synchronized Collection
<AggregatedCalledFunction
> getChildren() {
104 return fChildren
.values();
108 * The function's caller
110 * @return The caller of a function
112 public @Nullable AggregatedCalledFunction
getParent() {
117 * Add a new callee into the Callees list. If the function exists in the
118 * callees list, the new callee's duration will be added to its duration and
119 * it'll combine their callees.
122 * The callees of a function
124 public synchronized void addChild(AggregatedCalledFunction child
) {
125 AggregatedCalledFunction node
= fChildren
.get(child
.getSymbol());
127 fChildren
.put(child
.getSymbol(), child
);
130 fChildren
.replace(node
.getSymbol(), node
);
132 fSelfTime
-= child
.fDuration
;
133 fStatistics
.initializeMaxMinSelfTime(fSelfTime
);
137 * Modify the function's duration
140 * The amount to increment the duration by
142 private void addToDuration(long duration
) {
143 fDuration
+= duration
;
147 * Merge the callees of two functions.
150 * The first parent secondNode The second parent
152 private static void mergeChildren(AggregatedCalledFunction firstNode
, AggregatedCalledFunction secondNode
) {
153 for (Map
.Entry
<Object
, AggregatedCalledFunction
> FunctionEntry
: secondNode
.fChildren
.entrySet()) {
154 Object childSymbol
= NonNullUtils
.checkNotNull(FunctionEntry
.getKey());
155 AggregatedCalledFunction secondNodeChild
= NonNullUtils
.checkNotNull(FunctionEntry
.getValue());
156 AggregatedCalledFunction aggregatedCalledFunction
= firstNode
.fChildren
.get(childSymbol
);
157 if (aggregatedCalledFunction
== null) {
158 firstNode
.fChildren
.put(secondNodeChild
.getSymbol(), secondNodeChild
);
161 AggregatedCalledFunction firstNodeChild
= aggregatedCalledFunction
;
162 merge(firstNodeChild
, secondNodeChild
);
163 firstNode
.fChildren
.replace(firstNodeChild
.getSymbol(), firstNodeChild
);
169 * Merge two functions, add durations, self times, increment the calls,
170 * update statistics and merge children.
173 * the node to merge to
177 private static void merge(AggregatedCalledFunction destination
, AggregatedCalledFunction source
) {
178 long sourceDuration
= source
.getDuration();
179 long sourceSelfTime
= source
.getSelfTime();
180 destination
.addToDuration(sourceDuration
);
181 destination
.addToSelfTime(sourceSelfTime
);
182 destination
.getFunctionStatistics().update(source
.getFunctionStatistics(), sourceDuration
, sourceSelfTime
);
183 // merge the children callees.
184 mergeChildren(destination
, source
);
188 * The function's duration
190 * @return The duration of the function
192 public long getDuration() {
197 * The function's depth
199 * @return The depth of the function
201 public int getDepth() {
206 * The depth of the aggregated tree
208 * @return The depth of the aggregated tree
210 public int getMaxDepth() {
215 * The number of calls of a function
217 * @return The number of calls of a function
219 public long getNbCalls() {
220 return fStatistics
.getNbSegments();
224 * The self time of an aggregated function
226 * @return The self time
228 public long getSelfTime() {
233 * Add to the self time of an aggregated function
236 * The amount of self time to add
238 public void addToSelfTime(long selfTime
) {
239 fSelfTime
+= selfTime
;
243 * The process ID of the trace application.
244 * @return The process Id
246 public int getProcessId() {
251 * Returns whether the function has callees.
255 public Boolean
hasChildren() {
256 return !fChildren
.isEmpty();
260 * The function's statistics
262 * @return The function's statistics
264 public AggregatedCalledFunctionStatistics
getFunctionStatistics() {