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); | |
206 | ||
207 | // LTTngTreeNode experimentNode = getChildByName(experiment.getName()); | |
208 | // if (experimentNode != null) { | |
209 | // // get the trace manager nodes | |
210 | // LTTngTreeNode[] traceNodes = experimentNode.getChildren(); | |
211 | // for (LTTngTreeNode traceStateManagerNode : traceNodes) { | |
212 | // // The trace node needs to perform its first data request | |
213 | // // for this experiment with the main goal of building its | |
214 | // // checkpoints | |
215 | // if (traceStateManagerNode instanceof ILttExperimentSelectedListener) { | |
216 | // // no need to provide the trace to the trace manager | |
217 | // ((ILttExperimentSelectedListener) traceStateManagerNode).experimentUpdated( | |
218 | // new TmfExperimentUpdatedSignal(source, experiment, null), fwaitForCompletion); | |
219 | // } | |
220 | // } | |
221 | // } | |
5d10d135 ASL |
222 | } |
223 | ||
8827c197 FC |
224 | /* |
225 | * (non-Javadoc) | |
226 | * | |
227 | * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener# | |
228 | * experimentUpdated | |
229 | * (org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal, boolean) | |
230 | */ | |
231 | public void experimentUpdated(TmfExperimentUpdatedSignal signal, boolean wait) { | |
232 | // NOTE: This represents the end of TMF indexing for a trace, however | |
233 | // the node was already existing and the state system check points are | |
234 | // already requested and built upon selection. | |
235 | // No action for the time being | |
236 | } | |
237 | ||
238 | ||
88144d4a | 239 | /** |
8827c197 FC |
240 | * @return the SelectedExperiment tree node |
241 | */ | |
242 | public LTTngTreeNode getSelectedExperiment() { | |
243 | return fSelectedExperiment; | |
244 | } | |
245 | ||
246 | /* (non-Javadoc) | |
247 | * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#getExperimentTimeRange() | |
5d10d135 | 248 | */ |
8827c197 | 249 | @SuppressWarnings("unchecked") |
5d10d135 ASL |
250 | public TmfTimeRange getExperimentTimeRange() { |
251 | TmfTimeRange timeRangeResult = null; | |
8827c197 FC |
252 | if (fSelectedExperiment != null) { |
253 | timeRangeResult = ((TmfExperiment<LttngEvent>) fSelectedExperiment | |
254 | .getValue()).getTimeRange(); | |
5d10d135 ASL |
255 | } |
256 | return timeRangeResult; | |
257 | } | |
258 | ||
8827c197 FC |
259 | /* |
260 | * (non-Javadoc) | |
261 | * | |
262 | * @see java.lang.Object#finalize() | |
263 | */ | |
550d787e | 264 | @Override |
8827c197 FC |
265 | protected void finalize() { |
266 | fexperimentListener.dispose(); | |
267 | } | |
268 | ||
269 | ||
270 | /* | |
271 | * (non-Javadoc) | |
272 | * | |
273 | * @see | |
274 | * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager | |
275 | * #waitForComplete(boolean) | |
276 | */ | |
277 | public void waitForCompletion(boolean wait) { | |
278 | fwaitForCompletion = wait; | |
279 | } | |
280 | ||
550d787e FC |
281 | private ITmfEventRequest<LttngEvent> buildCheckPoints(TmfExperiment<LttngEvent> experiment) { |
282 | // validate | |
283 | if (experiment == null) { | |
284 | TraceDebug.debug("Received expriment is null"); | |
285 | return null; | |
286 | } | |
287 | ||
288 | LTTngTreeNode experimentNode = getChildByName(experiment.getName()); | |
289 | if (experimentNode == null) { | |
290 | TraceDebug.debug("Expriment Node " + experiment.getName() + " does not exist"); | |
291 | return null; | |
292 | } | |
293 | ||
294 | // get the trace manager nodes associated to the experiment | |
295 | LTTngTreeNode[] traceNodes = experimentNode.getChildren(); | |
296 | synchronized (this) { | |
297 | ftraceToManagerMap.clear(); | |
298 | } | |
299 | ||
300 | ITmfTrace trace; | |
301 | for (LTTngTreeNode traceStateManagerNode : traceNodes) { | |
302 | IStateTraceManager traceManager; | |
303 | try { | |
304 | traceManager = (IStateTraceManager) traceStateManagerNode; | |
305 | } catch (ClassCastException e) { | |
306 | System.out.println(e.getStackTrace().toString()); | |
307 | return null; | |
308 | } | |
309 | ||
310 | // Clear all previously created check points as preparation to | |
311 | // re-build | |
312 | traceManager.clearCheckPoints(); | |
313 | ||
314 | // build the trace to manager mapping for event dispatching | |
315 | trace = traceManager.getTrace(); | |
316 | synchronized (this) { | |
317 | ftraceToManagerMap.put(getTraceKey(trace), traceManager); | |
318 | } | |
319 | } | |
320 | ||
321 | // if no trace mapping | |
322 | if (ftraceToManagerMap.size() < 1) { | |
323 | TraceDebug.debug("No traces associated to experiment " + experiment.getName()); | |
324 | return null; | |
325 | } | |
326 | ||
327 | // Prepare event data request to build state model | |
328 | ITmfEventRequest<LttngEvent> request = new TmfEventRequest<LttngEvent>( | |
329 | LttngEvent.class, TmfTimeRange.Eternity, | |
330 | TmfDataRequest.ALL_DATA, 1, ITmfDataRequest.ExecutionType.LONG) { | |
331 | ||
332 | Long nbEvents = 0L; | |
333 | ||
334 | /* | |
335 | * (non-Javadoc) | |
336 | * | |
337 | * @see | |
338 | * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleData() | |
339 | */ | |
340 | @Override | |
341 | public void handleData() { | |
cb866e08 | 342 | LttngEvent[] events = getData(); |
550d787e FC |
343 | if (events.length > 0) { |
344 | nbEvents++; | |
345 | ||
346 | LttngEvent event = (LttngEvent) events[0]; | |
347 | ITmfTrace trace = event.getParentTrace(); | |
348 | IStateTraceManager traceManager = ftraceToManagerMap.get(getTraceKey(trace)); | |
349 | if (traceManager != null) { | |
350 | // obtain synthetic event | |
351 | LttngSyntheticEvent synEvent = updateSynEvent(event, | |
352 | traceManager); | |
353 | // update state system, and save check points as needed | |
354 | traceManager.handleEvent(synEvent, nbEvents); | |
355 | } else { | |
356 | TraceDebug | |
357 | .debug("StateTraceManager not found for trace" | |
358 | + trace.getName()); | |
359 | } | |
360 | } | |
361 | } | |
362 | ||
363 | /* | |
364 | * (non-Javadoc) | |
365 | * | |
366 | * @see | |
367 | * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleFailure() | |
368 | */ | |
cb866e08 | 369 | @Override |
550d787e FC |
370 | public void handleFailure() { |
371 | printCompletedMessage(); | |
372 | } | |
373 | ||
374 | /* | |
375 | * (non-Javadoc) | |
376 | * | |
377 | * @see | |
378 | * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCancel() | |
379 | */ | |
cb866e08 | 380 | @Override |
550d787e FC |
381 | public void handleCancel() { |
382 | printCompletedMessage(); | |
383 | } | |
384 | ||
385 | /* | |
386 | * (non-Javadoc) | |
387 | * | |
388 | * @see | |
389 | * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleSuccess() | |
390 | */ | |
cb866e08 | 391 | @Override |
550d787e FC |
392 | public void handleSuccess() { |
393 | printCompletedMessage(); | |
394 | } | |
395 | ||
396 | /** | |
397 | * @param header | |
398 | */ | |
399 | private void printCompletedMessage() { | |
400 | // super.handleCompleted(); | |
401 | if (TraceDebug.isDEBUG()) { | |
402 | TraceDebug.debug("Trace check point building completed, number of events handled: " + nbEvents | |
403 | + "\n\t\t"); | |
404 | for (IStateTraceManager traceMgr : ftraceToManagerMap.values()) { | |
405 | TraceDebug.debug(traceMgr.toString() + "\n\t\t"); | |
406 | } | |
407 | } | |
408 | } | |
409 | }; | |
410 | ||
411 | // Execute event data request | |
412 | experiment.sendRequest(request); | |
413 | ||
414 | if (fwaitForCompletion) { | |
415 | try { | |
416 | request.waitForCompletion(); | |
417 | } catch (InterruptedException e) { | |
418 | e.printStackTrace(); | |
419 | } | |
420 | } | |
421 | ||
422 | return request; | |
423 | } | |
424 | ||
425 | /** | |
426 | * Simplified trace key used to identify trace within experiment | |
427 | * | |
428 | * @param trace | |
429 | * @return | |
430 | */ | |
431 | private String getTraceKey(ITmfTrace trace) { | |
432 | String traceKey = trace.getPath() + trace.getName(); | |
433 | return traceKey; | |
434 | } | |
435 | ||
436 | private LttngSyntheticEvent updateSynEvent(LttngEvent e, IStateTraceManager stateTraceManager) { | |
437 | if (syntheticEvent == null || syntheticEvent.getBaseEvent() != e) { | |
438 | syntheticEvent = new LttngSyntheticEvent(e); | |
439 | } | |
440 | ||
441 | // Trace model needed by application handlers | |
442 | syntheticEvent.setTraceModel(stateTraceManager.getStateModel()); | |
443 | syntheticEvent.setSequenceInd(SequenceInd.UPDATE); | |
444 | ||
445 | return syntheticEvent; | |
446 | } | |
447 | ||
e31e01e8 | 448 | } |