-
Notifications
You must be signed in to change notification settings - Fork 10
/
CallStackScriptingModule.java
167 lines (159 loc) · 7.64 KB
/
CallStackScriptingModule.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*******************************************************************************
* Copyright (c) 2019 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.incubator.scripting.core.callstack;
import org.eclipse.ease.modules.ScriptParameter;
import org.eclipse.ease.modules.WrapToScript;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeGroupDescriptor;
import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeProvider;
import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeSet;
import org.eclipse.tracecompass.analysis.profiling.core.tree.WeightedTree;
import org.eclipse.tracecompass.analysis.profiling.core.tree.WeightedTreeGroupBy;
import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTreeProvider;
import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.WeightedTreeUtils;
import org.eclipse.tracecompass.incubator.internal.scripting.core.data.provider.ScriptingDataProviderManager;
import org.eclipse.tracecompass.internal.analysis.profiling.core.flamegraph.FlameGraphDataProvider;
import org.eclipse.tracecompass.internal.analysis.profiling.core.tree.AllGroupDescriptor;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
/**
* Provide an API to manipulate callstacks and weighted trees. This modules uses
* objects of class {@link IWeightedTreeProvider} that can be obtained from a
* trace by requesting an analysis that implements the interface.
* <p>
* For example, the following scriptlet would get the LTTng-UST CallStack
* analysis, which implements the weighted tree provider, for the active LTTng
* UST trace. The object can then be used as parameter for the methods of this
* module.
* </p>
*
* <pre>
* trace = getActiveTrace()
* wtProvider = getTraceAnalysis(trace, "org.eclipse.tracecompass.lttng2.ust.core.analysis.callstack");
* </pre>
*
* @author Geneviève Bastien
*/
public class CallStackScriptingModule {
/**
* Group the trees of the provider's main treeset, up to the requested
* level. For example, if a treeset's elements are grouped in a hierarchical
* manner with the following element hierarchy:
*
* <pre>
* element 1
* {@literal -->} element 2
* {@literal -->} element 3
* element 4
* {@literal -->} element 5
* </pre>
*
* this method with a level of <code>1</code> would result in a treeset with
* 2 elements: <code>element 1</code> and <code>element 4</code>, each
* containing a merge of the weighted trees of their respective children
* elements.
*
* @param <N>
* The type of objects represented by each node in the tree
* @param <E>
* The type of elements used to group the trees
* @param provider
* The {@link IWeightedTreeProvider} object containing the
* treeset for which to group trees.
* @param level
* The hierarchical level after which the elements' trees will be
* merged together. A value of <code>0</code> would group all the
* weighted trees together in a single element.
* @return The weighted tree set with weighted grouped at the requested
* level.
*/
@WrapToScript
public <@NonNull N, E> IWeightedTreeSet<N, ?, WeightedTree<N>> groupTreesBy(IWeightedTreeProvider<N, E, WeightedTree<N>> provider, int level) {
IWeightedTreeSet<N, E, WeightedTree<N>> treeSet = provider.getTreeSet();
IWeightedTreeGroupDescriptor groupDescriptor = getGroupDescriptor(provider, level);
if (groupDescriptor != null) {
return WeightedTreeGroupBy.groupWeightedTreeBy(groupDescriptor, treeSet, provider);
}
return treeSet;
}
private static <@NonNull N> @Nullable IWeightedTreeGroupDescriptor getGroupDescriptor(IWeightedTreeProvider<N, ?, WeightedTree<N>> provider, int level) {
IWeightedTreeGroupDescriptor groupDescriptor = provider.getGroupDescriptor();
if (level == 0) {
return AllGroupDescriptor.getInstance();
}
int i = 1;
while (groupDescriptor != null && i < level) {
groupDescriptor = groupDescriptor.getNextGroup();
i++;
}
return groupDescriptor;
}
/**
* Differentiates 2 treesets
*
* @param provider
* The original weighted tree provider, whose values will be used
* for the metrics, palettes, etc
* @param first
* The base treeset for comparison
* @param second
* The treeset to compare to
* @param minSignificantValue
* The value as a percentage (between 0 and 100), under which is
* difference should not be highlighted
* @param maxSignificantValue
* The value as a percentage (between 0 and 100), above which the
* difference should be highlighted at the maximal value.
* @param <N>
* The type of data that goes in the trees
* @return The resulting differential weighted tree provider containing the
* result of the difference between the 2 trees
*/
@WrapToScript
public <@NonNull N> @Nullable DifferentialWeightedTreeProvider<N> diffTreeSets(IWeightedTreeProvider<N, ?, WeightedTree<N>> provider,
IWeightedTreeSet<N, @NonNull ?, WeightedTree<N>> first,
IWeightedTreeSet<N, @NonNull ?, WeightedTree<N>> second,
@ScriptParameter(defaultValue = "-1") int minSignificantValue,
@ScriptParameter(defaultValue = "-1") int maxSignificantValue) {
DifferentialWeightedTreeProvider<@NonNull N> diffTrees = WeightedTreeUtils.diffTreeSets(provider, first, second);
if (diffTrees != null && minSignificantValue >= 0) {
diffTrees.setHeatThresholds(minSignificantValue, maxSignificantValue);
}
return diffTrees;
}
/**
* Get a flame graph data provider for a weighted tree provider. The
* weighted tree provider can be the result of the {@link #diffTreeSets}
* method
*
* @param <N>
* The type of data that goes in the trees
* @param <E>
* The type of elements used to group the trees
* @param <T>
* The type of the tree provided
* @param trace
* The trace for which to get the data provider. It is required
* for the data provider base class.
* @param provider
* The weighted tree provider that will provide the data
* @param id
* The ID of the data provider
* @return The resulting flame graph data provider
*/
@SuppressWarnings("restriction")
@WrapToScript
public <@NonNull N, E, @NonNull T extends WeightedTree<N>> FlameGraphDataProvider<N, E, T> getFlameGraphDataProvider(ITmfTrace trace, IWeightedTreeProvider<N, E, T> provider, String id) {
FlameGraphDataProvider<@NonNull N, E, @NonNull T> dataProvider = new FlameGraphDataProvider<>(trace, provider, ScriptingDataProviderManager.PROVIDER_ID + ':' + id);
ScriptingDataProviderManager.getInstance().registerDataProvider(trace, dataProvider);
return dataProvider;
}
}