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