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
;
53 * The function's name or address
55 * The function's duration
57 * The function's depth
59 * The aggregation tree's maximum depth
61 * The function's caller
63 public AggregatedCalledFunction(Object symbol
, long duration
, int depth
, int maxDepth
, @Nullable AggregatedCalledFunction parent
) {
70 fStatistics
= new AggregatedCalledFunctionStatistics(duration
, duration
);
74 * The function's symbol (address or name)
76 * @return The function's symbol
78 public Object
getSymbol() {
83 * The callees of the function
85 * @return The function's callees
87 public synchronized Collection
<AggregatedCalledFunction
> getChildren() {
88 return fChildren
.values();
92 * The function's caller
94 * @return The caller of a function
96 public @Nullable AggregatedCalledFunction
getParent() {
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.
106 * The callees of a function
108 public synchronized void addChild(AggregatedCalledFunction child
) {
109 AggregatedCalledFunction node
= fChildren
.get(child
.getSymbol());
111 fChildren
.put(child
.getSymbol(), child
);
114 fChildren
.replace(node
.getSymbol(), node
);
116 fSelfTime
-= child
.fDuration
;
117 fStatistics
.initializeMaxMinSelfTime(fSelfTime
);
121 * Modify the function's duration
124 * The amount to increment the duration by
126 private void addToDuration(long duration
) {
127 fDuration
+= duration
;
131 * Merge the callees of two functions.
134 * The first parent secondNode The second parent
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
);
145 AggregatedCalledFunction firstNodeChild
= aggregatedCalledFunction
;
146 merge(firstNodeChild
, secondNodeChild
);
147 firstNode
.fChildren
.replace(firstNodeChild
.getSymbol(), firstNodeChild
);
153 * Merge two functions, add durations, self times, increment the calls,
154 * update statistics and merge children.
157 * the node to merge to
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
);
172 * The function's duration
174 * @return The duration of the function
176 public long getDuration() {
181 * The function's depth
183 * @return The depth of the function
185 public int getDepth() {
190 * The depth of the aggregated tree
192 * @return The depth of the aggregated tree
194 public int getMaxDepth() {
199 * The number of calls of a function
201 * @return The number of calls of a function
203 public long getNbCalls() {
204 return fStatistics
.getNbSegments();
208 * The self time of an aggregated function
210 * @return The self time
212 public long getSelfTime() {
217 * Add to the self time of an aggregated function
220 * The amount of self time to add
222 public void addToSelfTime(long selfTime
) {
223 fSelfTime
+= selfTime
;
227 * Returns whether the function has callees.
231 public Boolean
hasChildren() {
232 return !fChildren
.isEmpty();
236 * The function's statistics
238 * @return The function's statistics
240 public AggregatedCalledFunctionStatistics
getFunctionStatistics() {