1 /*******************************************************************************
2 * Copyright (c) 2009, 2010 Ericsson
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
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
;
15 import java
.util
.HashMap
;
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
;
41 public class StateExperimentManager
extends LTTngTreeNode
implements
42 ILttExperimentSelectedListener
, IStateExperimentManager
{
44 // ========================================================================
46 // =======================================================================
47 private LTTngTreeNode fSelectedExperiment
= null; // one selected experiment
49 private final StateExperimentListener fexperimentListener
;
50 private boolean fwaitForCompletion
= false;
52 * Used to route incoming events to proper trace manager, during check point
55 private final Map
<ITmfTrace
, StateTraceHelper
> ftraceToManagerMap
= new HashMap
<ITmfTrace
, StateTraceHelper
>();
57 private LttngSyntheticEvent syntheticEvent
= null;
58 private ITmfEventRequest
<LttngEvent
> fStateCheckPointRequest
= null;
61 // ========================================================================
63 // =======================================================================
64 public StateExperimentManager(Long id
, String name
) {
65 super(id
, null, name
, null);
66 fexperimentListener
= new StateExperimentListener("Experiment Manager", this);
70 // ========================================================================
72 // =======================================================================
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)
77 // public ILttngSyntEventRequest readExperimentTimeWindow(TmfTimeRange trange,
78 // Object source, IRequestStatusListener listener,
79 // ITransEventProcessor processor) {
81 // ILttngSyntEventRequest request = null;
84 // if (fSelectedExperiment != null) {
85 // // Get all trace manager nodes
86 // LTTngTreeNode[] traceMgrs = fSelectedExperiment.getChildren();
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,
99 // if (fSelectedExperiment == null) {
100 // TraceDebug.debug("No experiment selected");
108 // * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperiment(java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener)
110 // @SuppressWarnings("unchecked")
111 // public void readExperiment(Object source, IRequestStatusListener listener,
112 // ITransEventProcessor processor) {
114 // if (fSelectedExperiment != null) {
115 // TmfExperiment<LttngEvent> experiment = (TmfExperiment<LttngEvent>) fSelectedExperiment
117 // TmfTimeRange trange = experiment.getTimeRange();
118 // readExperimentTimeWindow(trange, source, listener, processor);
120 // TraceDebug.debug("No selected experiment available");
130 * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager
131 * #experimentSelected_prep
132 * (org.eclipse.linuxtools.tmf.experiment.TmfExperiment)
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;
147 // Make sure all traces involved have a corresponding state manager
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
);
158 // Make sure the traces exists in the tree
159 ITmfTrace
[] rtraces
= experiment
.getTraces();
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
168 if (traceStateManagerNode
== null) {
169 traceStateManagerNode
= StateManagerFactory
.getManager(
170 rtrace
, experimentNode
);
171 experimentNode
.addChild(traceStateManagerNode
);
175 // Reset event provider to handle requests for the new experiment
176 LttngCoreProviderFactory
.reset(experimentNode
);
178 // preserve the selected experiment
179 fSelectedExperiment
= experimentNode
;
186 * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener#
187 * experimentSelected(java.lang.Object,
188 * org.eclipse.linuxtools.tmf.experiment.TmfExperiment)
191 public void experimentSelected(Object source
,
192 TmfExperiment
<LttngEvent
> experiment
) {
194 if (experiment
== null) {
195 TraceDebug
.debug("Received expriment is null");
199 // If previous request is ongoing, cancel it before requesting a new
201 if (fStateCheckPointRequest
!= null && !fStateCheckPointRequest
.isCompleted()) {
202 fStateCheckPointRequest
.cancel();
205 // trigger data request to build the state system check points
206 fStateCheckPointRequest
= buildCheckPoints(experiment
);
212 * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener#
214 * (org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal, boolean)
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
226 * @return the SelectedExperiment tree node
229 public LTTngTreeNode
getSelectedExperiment() {
230 return fSelectedExperiment
;
234 * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#getExperimentTimeRange()
237 @SuppressWarnings("unchecked")
238 public TmfTimeRange
getExperimentTimeRange() {
239 TmfTimeRange timeRangeResult
= null;
240 if (fSelectedExperiment
!= null) {
241 timeRangeResult
= ((TmfExperiment
<LttngEvent
>) fSelectedExperiment
242 .getValue()).getTimeRange();
244 return timeRangeResult
;
250 * @see java.lang.Object#finalize()
253 protected void finalize() {
254 fexperimentListener
.dispose();
262 * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager
263 * #waitForComplete(boolean)
266 public void waitForCompletion(boolean wait
) {
267 fwaitForCompletion
= wait
;
270 private ITmfEventRequest
<LttngEvent
> buildCheckPoints(TmfExperiment
<LttngEvent
> experiment
) {
272 if (experiment
== null) {
273 TraceDebug
.debug("Received expriment is null");
277 LTTngTreeNode experimentNode
= getChildByName(experiment
.getName());
278 if (experimentNode
== null) {
279 TraceDebug
.debug("Expriment Node " + experiment
.getName() + " does not exist");
283 // get the trace manager nodes associated to the experiment
284 LTTngTreeNode
[] traceNodes
= experimentNode
.getChildren();
285 synchronized (this) {
286 ftraceToManagerMap
.clear();
290 for (LTTngTreeNode traceStateManagerNode
: traceNodes
) {
291 IStateTraceManager traceManager
;
293 traceManager
= (IStateTraceManager
) traceStateManagerNode
;
294 } catch (ClassCastException e
) {
295 System
.out
.println(e
.getStackTrace().toString());
299 // Clear all previously created check points as preparation to
301 traceManager
.clearCheckPoints();
303 // build the trace to manager mapping for event dispatching
304 trace
= traceManager
.getTrace();
305 synchronized (this) {
306 ftraceToManagerMap
.put(trace
, new StateTraceHelper(traceManager
));
310 // if no trace mapping
311 if (ftraceToManagerMap
.size() < 1) {
312 TraceDebug
.debug("No traces associated to experiment " + experiment
.getName());
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
) {
321 long nbEventsHandled
= 0;
327 * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleData()
330 public void handleData(LttngEvent event
) {
331 super.handleData(event
);
333 // Tracer.trace("Chk: " + event.getTimestamp());
335 ITmfTrace trace
= event
.getParentTrace();
337 StateTraceHelper helper
= ftraceToManagerMap
.get(trace
);
339 if (helper
!= null) {
340 helper
.incrementNumberRead();
342 // obtain synthetic event
343 LttngSyntheticEvent synEvent
= updateSynEvent(event
, helper
.getTraceModel());
345 // update state system, and save check points as needed
346 helper
.getStateManager().handleEvent(synEvent
, helper
.getNumberRead());
348 TraceDebug
.debug("StateTraceManager not found for trace"
358 * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleFailure()
361 public void handleFailure() {
362 printCompletedMessage();
369 * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCancel()
372 public void handleCancel() {
373 printCompletedMessage();
380 * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleSuccess()
383 public void handleSuccess() {
384 printCompletedMessage();
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");
400 // Execute event data request
401 experiment
.sendRequest(request
);
403 if (fwaitForCompletion
) {
405 request
.waitForCompletion();
406 } catch (InterruptedException e
) {
414 private LttngSyntheticEvent
updateSynEvent(LttngEvent e
, LttngTraceState stateModel
) {
415 if (syntheticEvent
== null || syntheticEvent
.getBaseEvent() != e
) {
416 syntheticEvent
= new LttngSyntheticEvent(e
);
419 // Trace model needed by application handlers
420 syntheticEvent
.setTraceModel(stateModel
);
421 syntheticEvent
.setSequenceInd(SequenceInd
.UPDATE
);
423 return syntheticEvent
;
427 * Helper class that wraps the StateTraceManager, the current
428 * LTTngTraceState and the number of read events
433 private class StateTraceHelper
{
435 IStateTraceManager stateTraceManager
= null;
436 long numberEventsRead
= 0;
437 LttngTraceState stateTraceModel
= null;
442 * @param stateManager
443 * The StateTraceManager the helper is for
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();
454 * Returns the StateTraceManager
456 * @return IStateTraceManager
458 public IStateTraceManager
getStateManager() {
459 return stateTraceManager
;
463 * Returns the number of read events
467 public long getNumberRead() {
468 return numberEventsRead
;
472 * Increments the number of read events
474 public void incrementNumberRead() {
479 * Returns the current LTTngTraceState
481 * @return LttngTraceState
483 public LttngTraceState
getTraceModel() {
484 return stateTraceModel
;