-
Notifications
You must be signed in to change notification settings - Fork 13
/
AbstractTmfGraphBuilderModule.java
253 lines (212 loc) · 8.28 KB
/
AbstractTmfGraphBuilderModule.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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
/*******************************************************************************
* Copyright (c) 2015, 2024 École Polytechnique de Montréal and others
*
* 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.analysis.graph.core.building;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.graph.core.base.IGraphWorker;
import org.eclipse.tracecompass.analysis.graph.core.criticalpath.AbstractCriticalPathModule;
import org.eclipse.tracecompass.analysis.graph.core.criticalpath.ICriticalPathProvider;
import org.eclipse.tracecompass.analysis.graph.core.graph.ITmfGraph;
import org.eclipse.tracecompass.analysis.graph.core.graph.WorkerSerializer;
import org.eclipse.tracecompass.internal.analysis.graph.core.Activator;
import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
/**
* Base class for all modules building graphs
*
* @author Francis Giraldeau
* @author Geneviève Bastien
* @since 4.0
*/
public abstract class AbstractTmfGraphBuilderModule extends TmfAbstractAnalysisModule implements ICriticalPathProvider {
private @Nullable ITmfGraph fGraph;
private @Nullable ITmfEventRequest fRequest;
private final AbstractCriticalPathModule fCriticalPathModule;
/**
* Instantiate a new graph builder module which instantiates the critical path module.
*/
public AbstractTmfGraphBuilderModule() {
fCriticalPathModule = getCriticalPathModule();
}
/**
* Gets the graph provider to build this graph
*
* @return The graph provider
*/
protected abstract ITmfGraphProvider getGraphProvider();
protected abstract AbstractCriticalPathModule getCriticalPathModule();
/**
* @since 3.2
*/
protected abstract @Nullable ITmfGraph createGraphInstance(Path htFile, WorkerSerializer workerSerializer, long startTime, int version);
/**
* Gets the graph generated by the analysis
*
* @return The generated graph
* @since 3.2
*/
public @Nullable ITmfGraph getTmfGraph() {
return fGraph;
}
// ------------------------------------------------------------------------
// TmfAbstractAnalysisModule
// ------------------------------------------------------------------------
@Override
protected boolean executeAnalysis(final IProgressMonitor monitor) {
final ITmfGraphProvider provider = getGraphProvider();
/*
* TODO: This will eventually support multiple backends so we can
* save the graph on disk, like the state system, but for now, it is
* just in memory
*/
createGraph(provider);
return !monitor.isCanceled();
}
@Override
public boolean setTrace(@NonNull ITmfTrace trace) throws TmfAnalysisException {
boolean ret = super.setTrace(trace);
if (!ret) {
return ret;
}
ret = fCriticalPathModule.setTrace(trace);
return ret;
}
@Override
protected void canceling() {
ITmfEventRequest req = fRequest;
if ((req != null) && (!req.isCompleted())) {
req.cancel();
}
}
@Override
public void dispose() {
fCriticalPathModule.dispose();
super.dispose();
ITmfGraph graph = fGraph;
if (graph != null) {
graph.dispose();
}
fGraph = null;
}
// ------------------------------------------------------------------------
// Graph creation methods
// ------------------------------------------------------------------------
private void createGraph(ITmfGraphProvider provider) {
ITmfTrace trace = getTrace();
if (trace == null) {
throw new NullPointerException("The graph should not be created if there is no trace set"); //$NON-NLS-1$
}
String fileDirectory = TmfTraceManager.getSupplementaryFileDir(trace);
String id = getId();
Path htFile = Paths.get(fileDirectory + id + ".ht"); //$NON-NLS-1$
ITmfGraph graph = createGraphInstance(htFile, getWorkerSerializer(), provider.getStartTime(), provider.getGraphFileVersion());
fGraph = graph;
if (graph != null) {
provider.assignGraph(graph);
}
if (graph != null && graph.isDoneBuilding()) {
return;
}
build(provider, graph);
}
private static class DefaultWorkerSerializer implements WorkerSerializer {
@Override
public String serialize(IGraphWorker worker) {
return worker.toString();
}
@Override
public IGraphWorker deserialize(String serializedWorker) {
throw new UnsupportedOperationException("Implementatiosn nee");
}
}
/**
* Get the specific worker serializer for this analysis. The worker
* serializer is responsible to serialize/deserialize the worker map. Since
* each analysis can implement their own workers, it is also its
* responsibility to be able to write them to disk and read them afterwards.
* The default implementation of this method returns a worker serializer
* that does not serialize anything and deserializes an empty map.
*
* @return The worker serializer object
* @since 3.2
*/
public WorkerSerializer getWorkerSerializer() {
return new DefaultWorkerSerializer();
}
private void build(ITmfGraphProvider provider, ITmfGraph graph) {
/* Cancel any previous request */
ITmfEventRequest request = fRequest;
if ((request != null) && (!request.isCompleted())) {
request.cancel();
}
try {
request = new TmfGraphBuildRequest(provider, graph);
fRequest = request;
provider.getTrace().sendRequest(request);
request.waitForCompletion();
} catch (InterruptedException e) {
Activator.getInstance().logError("Request interrupted", e); //$NON-NLS-1$
Thread.currentThread().interrupt();
}
}
private static class TmfGraphBuildRequest extends TmfEventRequest {
private final ITmfGraphProvider fProvider;
private final ITmfGraph fBuilderGraph;
private long fLastEnd;
/**
* Constructor
*
* @param provider
* The graph provider
* @param graph
*/
public TmfGraphBuildRequest(ITmfGraphProvider provider, ITmfGraph graph) {
super(TmfEvent.class,
TmfTimeRange.ETERNITY,
0,
ITmfEventRequest.ALL_DATA,
ITmfEventRequest.ExecutionType.BACKGROUND);
fProvider = provider;
fBuilderGraph = graph;
}
@Override
public void handleData(final ITmfEvent event) {
super.handleData(event);
fProvider.processEvent(event);
fLastEnd = event.getTimestamp().getValue();
}
@Override
public synchronized void done() {
super.done();
fProvider.done();
fBuilderGraph.closeGraph(fLastEnd);
}
@Override
public void handleCancel() {
fProvider.handleCancel();
super.handleCancel();
}
}
@Override
public @Nullable ITmfGraph getCriticalPathGraph() {
return fCriticalPathModule.getCriticalPathGraph();
}
}