Commit | Line | Data |
---|---|---|
5d10d135 | 1 | /******************************************************************************* |
8827c197 | 2 | + * Copyright (c) 2009, 2010 Ericsson |
5d10d135 ASL |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made 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 | * Contributors: | |
10 | * Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | package org.eclipse.linuxtools.lttng.state.experiment; | |
13 | ||
550d787e FC |
14 | import java.util.HashMap; |
15 | import java.util.Map; | |
16 | ||
8827c197 FC |
17 | import org.eclipse.linuxtools.lttng.TraceDebug; |
18 | import org.eclipse.linuxtools.lttng.control.LttngCoreProviderFactory; | |
19 | import org.eclipse.linuxtools.lttng.control.LttngSyntheticEventProvider; | |
e31e01e8 | 20 | import org.eclipse.linuxtools.lttng.event.LttngEvent; |
550d787e FC |
21 | import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent; |
22 | import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd; | |
8827c197 | 23 | import org.eclipse.linuxtools.lttng.model.LTTngTreeNode; |
8827c197 FC |
24 | import org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener; |
25 | import org.eclipse.linuxtools.lttng.signal.StateExperimentListener; | |
8827c197 | 26 | import org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager; |
5d10d135 | 27 | import org.eclipse.linuxtools.tmf.event.TmfTimeRange; |
e31e01e8 | 28 | import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; |
550d787e FC |
29 | import org.eclipse.linuxtools.tmf.request.ITmfDataRequest; |
30 | import org.eclipse.linuxtools.tmf.request.ITmfEventRequest; | |
31 | import org.eclipse.linuxtools.tmf.request.TmfDataRequest; | |
32 | import org.eclipse.linuxtools.tmf.request.TmfEventRequest; | |
8827c197 FC |
33 | import org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal; |
34 | import org.eclipse.linuxtools.tmf.trace.ITmfTrace; | |
5d10d135 ASL |
35 | |
36 | /** | |
37 | * @author alvaro | |
38 | * | |
39 | */ | |
8827c197 FC |
40 | public class StateExperimentManager extends LTTngTreeNode implements |
41 | ILttExperimentSelectedListener, IStateExperimentManager { | |
5d10d135 ASL |
42 | |
43 | // ======================================================================== | |
44 | // Data | |
45 | // ======================================================================= | |
8827c197 FC |
46 | private LTTngTreeNode fSelectedExperiment = null; // one selected experiment |
47 | // supported | |
48 | private final StateExperimentListener fexperimentListener; | |
49 | private boolean fwaitForCompletion = false; | |
550d787e FC |
50 | /** |
51 | * Used to route incoming events to proper trace manager, during check point | |
52 | * building | |
53 | */ | |
54 | private final Map<String, IStateTraceManager> ftraceToManagerMap = new HashMap<String, IStateTraceManager>(); | |
55 | private LttngSyntheticEvent syntheticEvent = null; | |
56 | private ITmfEventRequest<LttngEvent> fStateCheckPointRequest = null; | |
8827c197 | 57 | |
5d10d135 ASL |
58 | |
59 | // ======================================================================== | |
60 | // Constructors | |
61 | // ======================================================================= | |
8827c197 FC |
62 | public StateExperimentManager(Long id, String name) { |
63 | super(id, null, name, null); | |
64 | fexperimentListener = new StateExperimentListener("Experiment Manager", | |
65 | this); | |
88144d4a | 66 | } |
5d10d135 | 67 | |
8827c197 | 68 | |
5d10d135 ASL |
69 | // ======================================================================== |
70 | // Methods | |
71 | // ======================================================================= | |
72 | ||
550d787e FC |
73 | // /* (non-Javadoc) |
74 | // * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperimentTimeWindow(org.eclipse.linuxtools.tmf.event.TmfTimeRange, java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener) | |
75 | // */ | |
76 | // public ILttngSyntEventRequest readExperimentTimeWindow(TmfTimeRange trange, | |
77 | // Object source, IRequestStatusListener listener, | |
78 | // ITransEventProcessor processor) { | |
79 | // | |
80 | // ILttngSyntEventRequest request = null; | |
81 | // | |
82 | // // validate | |
83 | // if (fSelectedExperiment != null) { | |
84 | // // Get all trace manager nodes | |
85 | // LTTngTreeNode[] traceMgrs = fSelectedExperiment.getChildren(); | |
86 | // | |
87 | // if (traceMgrs != null && traceMgrs.length > 0) { | |
88 | // IStateTraceManager traceManager; | |
89 | // // Trigger one request per trace | |
90 | // for (LTTngTreeNode traceNode : traceMgrs) { | |
91 | // traceManager = (IStateTraceManager) traceNode; | |
92 | // request = traceManager.executeDataRequest(trange, source, | |
93 | // listener, | |
94 | // processor); | |
95 | // } | |
96 | // } | |
97 | // } else { | |
98 | // if (fSelectedExperiment == null) { | |
99 | // TraceDebug.debug("No experiment selected"); | |
100 | // } | |
101 | // } | |
102 | // | |
103 | // return request; | |
104 | // } | |
5d10d135 | 105 | |
550d787e FC |
106 | // /* (non-Javadoc) |
107 | // * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperiment(java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener) | |
108 | // */ | |
109 | // @SuppressWarnings("unchecked") | |
110 | // public void readExperiment(Object source, IRequestStatusListener listener, | |
111 | // ITransEventProcessor processor) { | |
112 | // // validate | |
113 | // if (fSelectedExperiment != null) { | |
114 | // TmfExperiment<LttngEvent> experiment = (TmfExperiment<LttngEvent>) fSelectedExperiment | |
115 | // .getValue(); | |
116 | // TmfTimeRange trange = experiment.getTimeRange(); | |
117 | // readExperimentTimeWindow(trange, source, listener, processor); | |
118 | // } else { | |
119 | // TraceDebug.debug("No selected experiment available"); | |
120 | // } | |
121 | // } | |
88144d4a | 122 | |
8827c197 FC |
123 | |
124 | ||
5d10d135 ASL |
125 | /* |
126 | * (non-Javadoc) | |
127 | * | |
88144d4a | 128 | * @see |
8827c197 FC |
129 | * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager |
130 | * #experimentSelected_prep | |
131 | * (org.eclipse.linuxtools.tmf.experiment.TmfExperiment) | |
5d10d135 | 132 | */ |
8827c197 FC |
133 | public void experimentSelected_prep(TmfExperiment<LttngEvent> experiment) { |
134 | LTTngTreeNode experimentNode = null; | |
135 | if (experiment != null) { | |
136 | experimentNode = getChildByName(experiment.getName()); | |
137 | // keep experiment if already loaded with the same value | |
138 | if (experimentNode != null | |
139 | && experimentNode.getValue() != experiment) { | |
140 | // rebuild the experiment nodes from scratch | |
141 | removeChild(experimentNode); | |
142 | experimentNode = null; | |
143 | } | |
144 | ||
145 | // Make sure all traces involved have a corresponding state manager | |
146 | // and | |
147 | // state system to request its initial data | |
148 | if (experimentNode == null) { | |
149 | // Create the new experiment tree node | |
150 | experimentNode = new LTTngTreeNode(getNextUniqueId(), this, | |
151 | experiment.getName(), experiment); | |
152 | // add the new experiment to this children list | |
153 | addChild(experimentNode); | |
154 | } | |
155 | ||
156 | // Make sure the traces exists in the tree | |
157 | ITmfTrace[] rtraces = experiment.getTraces(); | |
158 | String traceName; | |
159 | LTTngTreeNode traceStateManagerNode; | |
160 | // StateStacksHandler | |
161 | for (ITmfTrace rtrace : rtraces) { | |
162 | traceName = rtrace.getName(); | |
163 | traceStateManagerNode = experimentNode.getChildByName(traceName); | |
164 | // Node does not exist for this experiment, so needs to be | |
165 | // created | |
166 | if (traceStateManagerNode == null) { | |
167 | traceStateManagerNode = StateManagerFactory.getManager( | |
168 | rtrace, experimentNode); | |
169 | experimentNode.addChild(traceStateManagerNode); | |
170 | } | |
171 | } | |
172 | ||
173 | // Reset event provider to handle requests for the new experiment | |
174 | LttngSyntheticEventProvider synEventProvider = LttngCoreProviderFactory | |
175 | .getEventProvider(); | |
176 | synEventProvider.reset(experimentNode); | |
177 | ||
178 | // preserve the selected experiment | |
179 | fSelectedExperiment = experimentNode; | |
88144d4a | 180 | } |
5d10d135 ASL |
181 | } |
182 | ||
8827c197 FC |
183 | /* |
184 | * (non-Javadoc) | |
88144d4a | 185 | * |
8827c197 FC |
186 | * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener# |
187 | * experimentSelected(java.lang.Object, | |
188 | * org.eclipse.linuxtools.tmf.experiment.TmfExperiment) | |
5d10d135 | 189 | */ |
8827c197 FC |
190 | public void experimentSelected(Object source, |
191 | TmfExperiment<LttngEvent> experiment) { | |
192 | // validate | |
550d787e FC |
193 | if (experiment == null) { |
194 | TraceDebug.debug("Received expriment is null"); | |
8827c197 FC |
195 | return; |
196 | } | |
197 | ||
550d787e FC |
198 | // If previous request is ongoing, cancel it before requesting a new |
199 | // one. | |
200 | if (fStateCheckPointRequest != null && !fStateCheckPointRequest.isCompleted()) { | |
201 | fStateCheckPointRequest.cancel(); | |
8827c197 | 202 | } |
550d787e FC |
203 | |
204 | // trigger data request to build the state system check points | |
205 | fStateCheckPointRequest = buildCheckPoints(experiment); | |
5d10d135 ASL |
206 | } |
207 | ||
8827c197 FC |
208 | /* |
209 | * (non-Javadoc) | |
210 | * | |
211 | * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener# | |
212 | * experimentUpdated | |
213 | * (org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal, boolean) | |
214 | */ | |
215 | public void experimentUpdated(TmfExperimentUpdatedSignal signal, boolean wait) { | |
216 | // NOTE: This represents the end of TMF indexing for a trace, however | |
217 | // the node was already existing and the state system check points are | |
218 | // already requested and built upon selection. | |
219 | // No action for the time being | |
220 | } | |
221 | ||
222 | ||
88144d4a | 223 | /** |
8827c197 FC |
224 | * @return the SelectedExperiment tree node |
225 | */ | |
226 | public LTTngTreeNode getSelectedExperiment() { | |
227 | return fSelectedExperiment; | |
228 | } | |
229 | ||
230 | /* (non-Javadoc) | |
231 | * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#getExperimentTimeRange() | |
5d10d135 | 232 | */ |
8827c197 | 233 | @SuppressWarnings("unchecked") |
5d10d135 ASL |
234 | public TmfTimeRange getExperimentTimeRange() { |
235 | TmfTimeRange timeRangeResult = null; | |
8827c197 FC |
236 | if (fSelectedExperiment != null) { |
237 | timeRangeResult = ((TmfExperiment<LttngEvent>) fSelectedExperiment | |
238 | .getValue()).getTimeRange(); | |
5d10d135 ASL |
239 | } |
240 | return timeRangeResult; | |
241 | } | |
242 | ||
8827c197 FC |
243 | /* |
244 | * (non-Javadoc) | |
245 | * | |
246 | * @see java.lang.Object#finalize() | |
247 | */ | |
550d787e | 248 | @Override |
8827c197 FC |
249 | protected void finalize() { |
250 | fexperimentListener.dispose(); | |
251 | } | |
252 | ||
253 | ||
254 | /* | |
255 | * (non-Javadoc) | |
256 | * | |
257 | * @see | |
258 | * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager | |
259 | * #waitForComplete(boolean) | |
260 | */ | |
261 | public void waitForCompletion(boolean wait) { | |
262 | fwaitForCompletion = wait; | |
263 | } | |
264 | ||
550d787e FC |
265 | private ITmfEventRequest<LttngEvent> buildCheckPoints(TmfExperiment<LttngEvent> experiment) { |
266 | // validate | |
267 | if (experiment == null) { | |
268 | TraceDebug.debug("Received expriment is null"); | |
269 | return null; | |
270 | } | |
271 | ||
272 | LTTngTreeNode experimentNode = getChildByName(experiment.getName()); | |
273 | if (experimentNode == null) { | |
274 | TraceDebug.debug("Expriment Node " + experiment.getName() + " does not exist"); | |
275 | return null; | |
276 | } | |
277 | ||
278 | // get the trace manager nodes associated to the experiment | |
279 | LTTngTreeNode[] traceNodes = experimentNode.getChildren(); | |
280 | synchronized (this) { | |
281 | ftraceToManagerMap.clear(); | |
282 | } | |
283 | ||
284 | ITmfTrace trace; | |
285 | for (LTTngTreeNode traceStateManagerNode : traceNodes) { | |
286 | IStateTraceManager traceManager; | |
287 | try { | |
288 | traceManager = (IStateTraceManager) traceStateManagerNode; | |
289 | } catch (ClassCastException e) { | |
290 | System.out.println(e.getStackTrace().toString()); | |
291 | return null; | |
292 | } | |
293 | ||
294 | // Clear all previously created check points as preparation to | |
295 | // re-build | |
296 | traceManager.clearCheckPoints(); | |
297 | ||
298 | // build the trace to manager mapping for event dispatching | |
299 | trace = traceManager.getTrace(); | |
300 | synchronized (this) { | |
301 | ftraceToManagerMap.put(getTraceKey(trace), traceManager); | |
302 | } | |
303 | } | |
304 | ||
305 | // if no trace mapping | |
306 | if (ftraceToManagerMap.size() < 1) { | |
307 | TraceDebug.debug("No traces associated to experiment " + experiment.getName()); | |
308 | return null; | |
309 | } | |
310 | ||
311 | // Prepare event data request to build state model | |
312 | ITmfEventRequest<LttngEvent> request = new TmfEventRequest<LttngEvent>( | |
313 | LttngEvent.class, TmfTimeRange.Eternity, | |
f6b14ce2 | 314 | TmfDataRequest.ALL_DATA, 1, ITmfDataRequest.ExecutionType.BACKGROUND) { |
550d787e FC |
315 | |
316 | Long nbEvents = 0L; | |
317 | ||
318 | /* | |
319 | * (non-Javadoc) | |
320 | * | |
321 | * @see | |
322 | * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleData() | |
323 | */ | |
324 | @Override | |
f9673903 FC |
325 | public void handleData(LttngEvent event) { |
326 | super.handleData(event); | |
327 | if (event != null) { | |
9b635e61 | 328 | // Tracer.trace("Chk: " + event.getTimestamp()); |
550d787e FC |
329 | ITmfTrace trace = event.getParentTrace(); |
330 | IStateTraceManager traceManager = ftraceToManagerMap.get(getTraceKey(trace)); | |
331 | if (traceManager != null) { | |
332 | // obtain synthetic event | |
333 | LttngSyntheticEvent synEvent = updateSynEvent(event, | |
334 | traceManager); | |
335 | // update state system, and save check points as needed | |
336 | traceManager.handleEvent(synEvent, nbEvents); | |
337 | } else { | |
338 | TraceDebug | |
339 | .debug("StateTraceManager not found for trace" | |
340 | + trace.getName()); | |
341 | } | |
342 | } | |
343 | } | |
344 | ||
345 | /* | |
346 | * (non-Javadoc) | |
347 | * | |
348 | * @see | |
349 | * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleFailure() | |
350 | */ | |
cb866e08 | 351 | @Override |
550d787e FC |
352 | public void handleFailure() { |
353 | printCompletedMessage(); | |
354 | } | |
355 | ||
356 | /* | |
357 | * (non-Javadoc) | |
358 | * | |
359 | * @see | |
360 | * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCancel() | |
361 | */ | |
cb866e08 | 362 | @Override |
550d787e FC |
363 | public void handleCancel() { |
364 | printCompletedMessage(); | |
365 | } | |
366 | ||
367 | /* | |
368 | * (non-Javadoc) | |
369 | * | |
370 | * @see | |
371 | * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleSuccess() | |
372 | */ | |
cb866e08 | 373 | @Override |
550d787e FC |
374 | public void handleSuccess() { |
375 | printCompletedMessage(); | |
376 | } | |
377 | ||
378 | /** | |
379 | * @param header | |
380 | */ | |
381 | private void printCompletedMessage() { | |
550d787e FC |
382 | if (TraceDebug.isDEBUG()) { |
383 | TraceDebug.debug("Trace check point building completed, number of events handled: " + nbEvents | |
384 | + "\n\t\t"); | |
385 | for (IStateTraceManager traceMgr : ftraceToManagerMap.values()) { | |
386 | TraceDebug.debug(traceMgr.toString() + "\n\t\t"); | |
387 | } | |
388 | } | |
389 | } | |
390 | }; | |
391 | ||
392 | // Execute event data request | |
393 | experiment.sendRequest(request); | |
394 | ||
395 | if (fwaitForCompletion) { | |
396 | try { | |
397 | request.waitForCompletion(); | |
398 | } catch (InterruptedException e) { | |
399 | e.printStackTrace(); | |
400 | } | |
401 | } | |
402 | ||
403 | return request; | |
404 | } | |
405 | ||
406 | /** | |
407 | * Simplified trace key used to identify trace within experiment | |
408 | * | |
409 | * @param trace | |
410 | * @return | |
411 | */ | |
412 | private String getTraceKey(ITmfTrace trace) { | |
413 | String traceKey = trace.getPath() + trace.getName(); | |
414 | return traceKey; | |
415 | } | |
416 | ||
417 | private LttngSyntheticEvent updateSynEvent(LttngEvent e, IStateTraceManager stateTraceManager) { | |
418 | if (syntheticEvent == null || syntheticEvent.getBaseEvent() != e) { | |
419 | syntheticEvent = new LttngSyntheticEvent(e); | |
420 | } | |
421 | ||
422 | // Trace model needed by application handlers | |
423 | syntheticEvent.setTraceModel(stateTraceManager.getStateModel()); | |
424 | syntheticEvent.setSequenceInd(SequenceInd.UPDATE); | |
425 | ||
426 | return syntheticEvent; | |
427 | } | |
428 | ||
e31e01e8 | 429 | } |