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 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.lttng
.state
.trace
;
14 import java
.util
.Collections
;
15 import java
.util
.HashMap
;
16 import java
.util
.Vector
;
18 import org
.eclipse
.linuxtools
.lttng
.TraceDebug
;
19 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEvent
;
20 import org
.eclipse
.linuxtools
.lttng
.event
.LttngSyntheticEvent
;
21 import org
.eclipse
.linuxtools
.lttng
.event
.LttngSyntheticEvent
.SequenceInd
;
22 import org
.eclipse
.linuxtools
.lttng
.event
.LttngTimestamp
;
23 import org
.eclipse
.linuxtools
.lttng
.model
.LTTngTreeNode
;
24 import org
.eclipse
.linuxtools
.lttng
.request
.ILttngSyntEventRequest
;
25 import org
.eclipse
.linuxtools
.lttng
.request
.IRequestStatusListener
;
26 import org
.eclipse
.linuxtools
.lttng
.request
.LttngSyntEventRequest
;
27 import org
.eclipse
.linuxtools
.lttng
.state
.LttngStateException
;
28 import org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.ITransEventProcessor
;
29 import org
.eclipse
.linuxtools
.lttng
.state
.evProcessor
.state
.StateEventToHandlerFactory
;
30 import org
.eclipse
.linuxtools
.lttng
.state
.model
.LttngTraceState
;
31 import org
.eclipse
.linuxtools
.lttng
.state
.model
.StateModelFactory
;
32 import org
.eclipse
.linuxtools
.lttng
.state
.resource
.ILttngStateContext
;
33 import org
.eclipse
.linuxtools
.lttng
.trace
.LTTngTextTrace
;
34 import org
.eclipse
.linuxtools
.lttng
.trace
.LTTngTrace
;
35 import org
.eclipse
.linuxtools
.tmf
.event
.TmfEvent
;
36 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
37 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimestamp
;
38 import org
.eclipse
.linuxtools
.tmf
.experiment
.TmfExperiment
;
39 import org
.eclipse
.linuxtools
.tmf
.request
.TmfDataRequest
;
40 import org
.eclipse
.linuxtools
.tmf
.trace
.ITmfTrace
;
41 import org
.eclipse
.linuxtools
.tmf
.trace
.TmfCheckpoint
;
42 import org
.eclipse
.linuxtools
.tmf
.trace
.TmfLocation
;
44 public class StateTraceManager
extends LTTngTreeNode
implements IStateTraceManager
, ILttngStateContext
{
47 private static final long DEFAULT_OFFSET
= 0L;
48 private static final int DEFAULT_CHUNK
= 1;
50 // configurable check point interval
51 private static final long LTTNG_CHECK_POINT_INTERVAL
= 15000L;
52 private long fcheckPointInterval
= LTTNG_CHECK_POINT_INTERVAL
;
54 private TmfExperiment
<LttngEvent
> fExperiment
= null;
57 private final ITmfTrace fTrace
;
58 private int fcpuNumber
= -1;
59 private final ITransEventProcessor fStateUpdateProcessor
;
61 // potentially thread shared
62 private final HashMap
<Long
, LttngTraceState
> stateCheckpointsList
= new HashMap
<Long
, LttngTraceState
>();
63 private final Vector
<TmfCheckpoint
> timestampCheckpointsList
= new Vector
<TmfCheckpoint
>();
64 private LttngTraceState fStateModel
;
65 private LttngTraceState fCheckPointStateModel
;
68 private Object fCheckPointsLock
= new Object();
69 private Object fStateModelLock
= new Object();
73 // =======================================================================
75 // =======================================================================
81 * @throws LttngStateException
83 public StateTraceManager(Long id
, LTTngTreeNode parent
, String name
, ITmfTrace trace
) throws LttngStateException
{
84 super(id
, parent
, name
, trace
);
87 throw new LttngStateException("No TmfTrace object available!");
91 fStateUpdateProcessor
= StateEventToHandlerFactory
.getInstance();
95 fStateModel
= StateModelFactory
.getStateEntryInstance(this);
96 fStateModel
.init(this);
98 fCheckPointStateModel
= StateModelFactory
.getStateEntryInstance(this);
99 fCheckPointStateModel
.init(this);
102 // =======================================================================
104 // =======================================================================
105 @SuppressWarnings("unchecked")
106 private void init() {
107 // resolve the experiment
108 Object obj
= getParent().getValue();
109 if (obj
!= null && obj
instanceof TmfExperiment
<?
>) {
110 fExperiment
= (TmfExperiment
<LttngEvent
>) obj
;
113 // initialize the number of cpus
114 if (fTrace
instanceof LTTngTrace
) {
115 fcpuNumber
= ((LTTngTrace
) fTrace
).getCpuNumber();
116 } else if (fTrace
instanceof LTTngTextTrace
) {
117 fcpuNumber
= ((LTTngTextTrace
) fTrace
).getCpuNumber();
128 * @see org.eclipse.linuxtools.lttng.state.IStateManager#getEventLog()
131 public ITmfTrace
getTrace() {
136 * Save a checkpoint if it is needed at that point
138 * The function will use "eventCount" internally to determine if a save was
141 * @param eventCounter
142 * The event "count" or event "id" so far
144 * The timestamp of this event
146 * @return boolean True if a checkpoint was saved, false otherwise
148 private void saveCheckPointIfNeeded(Long eventCounter
, TmfTimestamp eventTime
) {
149 // Save a checkpoint every LTTNG_STATE_SAVE_INTERVAL event
150 if ((eventCounter
.longValue() % fcheckPointInterval
) == 0) {
152 LttngTraceState stateCheckPoint
;
153 synchronized (fCheckPointsLock
) {
154 stateCheckPoint
= fCheckPointStateModel
.clone();
157 TraceDebug
.debug("Check point created here: " + eventCounter
158 + " -> " + eventTime
.toString() + "************"
159 + getTrace().getName() + " >>>>> Thread: "
160 + Thread
.currentThread().getId());
162 synchronized (fCheckPointsLock
) {
163 // Save the checkpoint
164 stateCheckpointsList
.put(eventCounter
, stateCheckPoint
);
165 // Save correlation between timestamp and checkpoint index
167 timestampCheckpointsList
.add(new TmfCheckpoint(new TmfTimestamp(eventTime
), new TmfLocation
<Long
>(
174 * @return the lttng_check_point_interval
176 public long getCheckPointInterval() {
177 return fcheckPointInterval
;
181 * @param check_point_interval
182 * , the lttng_check_point_interval to set
184 public void setCheckPointInterval(long check_point_interval
) {
185 this.fcheckPointInterval
= check_point_interval
;
191 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
192 * restoreCheckPointByTimestamp
193 * (org.eclipse.linuxtools.tmf.event.TmfTimestamp)
196 @SuppressWarnings("unchecked")
197 public TmfTimestamp
restoreCheckPointByTimestamp(TmfTimestamp eventTime
) {
198 TmfTimeRange experimentRange
= fExperiment
.getTimeRange();
199 TmfTimestamp nearestTimeStamp
= fTrace
.getStartTime();
201 // The GUI can have time limits higher than this log, since GUI can
202 // handle multiple logs
203 if ((eventTime
.getValue() < 0) || (eventTime
.getValue() > experimentRange
.getEndTime().getValue())) {
207 // The GUI can have time limits lower than this trace, since experiment
208 // can handle multiple traces
209 if ((eventTime
.getValue() < fTrace
.getStartTime().getValue())) {
210 eventTime
= fTrace
.getStartTime();
213 LttngTraceState traceState
;
214 synchronized (fCheckPointsLock
) {
215 Collections
.sort(timestampCheckpointsList
);
216 // Initiate the compare with a checkpoint containing the target time
218 int index
= Collections
.binarySearch(timestampCheckpointsList
, new TmfCheckpoint(eventTime
,
219 new TmfLocation
<Long
>(0L)));
220 // adjust index to round down to earlier checkpoint when exact match
223 index
= getPrevIndex(index
);
226 // No checkpoint restore is needed, start with a brand new
228 traceState
= StateModelFactory
.getStateEntryInstance(this);
231 // Useful CheckPoint found
232 TmfCheckpoint checkpoint
= timestampCheckpointsList
.get(index
);
233 nearestTimeStamp
= checkpoint
.getTimestamp();
234 // get the location associated with the checkpoint
235 TmfLocation
<Long
> location
= (TmfLocation
<Long
>) checkpoint
.getLocation();
236 // reference a new copy of the checkpoint template
237 traceState
= stateCheckpointsList
.get(location
.getLocation()).clone();
242 // Restore the stored traceState
243 synchronized (fStateModelLock
) {
244 fStateModel
= traceState
;
247 return nearestTimeStamp
;
251 * Adjust the result from a binary search to the round down position
254 * if Negative is: (-(insertion point) -1)
255 * @return position or if no match found, earlier than insertion point
257 private int getPrevIndex(int position
) {
258 int roundDownPosition
= position
;
260 roundDownPosition
= -(position
+ 2);
263 roundDownPosition
= roundDownPosition
< 0 ?
0 : roundDownPosition
;
264 return roundDownPosition
;
267 // TODO: Remove this request type when the UI handle their own requests
269 * Request Event data of a specified time range
274 * @return ILttngEventRequest The request made
276 ILttngSyntEventRequest
getDataRequestByTimeRange(TmfTimeRange timeWindow
, IRequestStatusListener listener
,
277 final ITransEventProcessor processor
) {
279 ILttngSyntEventRequest request
= new StateTraceManagerRequest(timeWindow
, DEFAULT_OFFSET
,
280 TmfDataRequest
.ALL_DATA
, DEFAULT_CHUNK
, listener
, getExperimentTimeWindow(), processor
) {
291 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getStateModel
295 public LttngTraceState
getStateModel() {
296 LttngTraceState stateModel
= null;
297 synchronized (fStateModelLock
) {
298 stateModel
= fStateModel
;
306 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
307 * getCheckPointStateModel()
310 public LttngTraceState
getCheckPointStateModel() {
311 LttngTraceState checkPointStateModel
= null;
312 synchronized (fCheckPointsLock
) {
313 checkPointStateModel
= fCheckPointStateModel
;
315 return checkPointStateModel
;
319 * @return the stateCheckpointsList
321 HashMap
<Long
, LttngTraceState
> getStateCheckpointsList() {
322 return stateCheckpointsList
;
326 * @return the timestampCheckpointsList
328 Vector
<TmfCheckpoint
> getTimestampCheckpointsList() {
329 return timestampCheckpointsList
;
331 // =======================================================================
333 // =======================================================================
334 class StateTraceManagerRequest
extends LttngSyntEventRequest
{
335 // =======================================================================
337 // =======================================================================
338 final TmfEvent
[] evt
= new TmfEvent
[1];
339 final ITransEventProcessor fprocessor
;
340 LttngSyntheticEvent synEvent
;
341 Long fCount
= getSynEventCount();
343 // =======================================================================
345 // =======================================================================
346 public StateTraceManagerRequest(TmfTimeRange range
, long offset
, int nbEvents
, int maxBlockSize
,
347 IRequestStatusListener listener
, TmfTimeRange experimentTimeRange
, ITransEventProcessor processor
) {
349 super(range
, offset
, nbEvents
, maxBlockSize
, listener
, experimentTimeRange
, processor
);
350 fprocessor
= processor
;
351 TraceDebug
.debug("Instance created for range: " + range
.toString());
355 // =======================================================================
357 // =======================================================================
362 * org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData
366 public void handleData(LttngSyntheticEvent event
) {
367 super.handleData(event
);
370 if (synEvent
.getSynType() == SequenceInd
.AFTER
) {
371 // Note : We call this function before incrementing
372 // eventCount to save a default check point at the "0th"
374 saveCheckPoint(fCount
, synEvent
.getTimestamp());
377 if (TraceDebug
.isDEBUG()) {
378 if (fCount
% 1000 == 0) {
379 TraceDebug
.debug("handled: " + fCount
+ " sequence: " + synEvent
.getSynType());
387 * To be overridden by active save e.g. check points, this no action
388 * default is used for requests which do not require rebuilding of
389 * checkpoints e.g. requiring data of a new time range selection
394 public void saveCheckPoint(Long count
, TmfTimestamp time
) {
402 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
406 public int getNumberOfCpus() {
413 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
414 * getTraceTimeWindow()
417 public TmfTimeRange
getTraceTimeWindow() {
418 if (fTrace
!= null) {
419 return fTrace
.getTimeRange();
429 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceId
433 public String
getTraceId() {
434 if (fTrace
!= null) {
435 return fTrace
.getName();
443 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
444 * getExperimentTimeWindow()
447 public TmfTimeRange
getExperimentTimeWindow() {
448 if (fExperiment
!= null) {
449 return fExperiment
.getTimeRange();
458 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getExperimentName
462 public String
getExperimentName() {
463 return fExperiment
.getName();
470 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceIdRef
474 public ITmfTrace
getTraceIdRef() {
482 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#clearCheckPoints
486 public void clearCheckPoints() {
487 synchronized (fCheckPointsLock
) {
488 stateCheckpointsList
.clear();
489 timestampCheckpointsList
.clear();
491 fCheckPointStateModel
= StateModelFactory
.getStateEntryInstance(this);
494 fCheckPointStateModel
.init(this);
495 } catch (LttngStateException e
) {
505 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#handleEvent
506 * (org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent, java.lang.Long)
509 public void handleEvent(LttngSyntheticEvent synEvent
, Long eventCount
) {
510 fStateUpdateProcessor
.process(synEvent
, fCheckPointStateModel
);
512 // Save checkpoint as needed
513 saveCheckPointIfNeeded(eventCount
- 1, synEvent
.getTimestamp());
519 * @see java.lang.Object#toString()
522 public String
toString() {
523 StringBuilder sb
= new StringBuilder(super.toString());
524 sb
.append("\n\tTotal number of processes in the Shared State model: " + fStateModel
.getProcesses().length
525 + "\n\t" + "Total number of processes in the Check point State model: "
526 + fCheckPointStateModel
.getProcesses().length
);
528 TmfTimeRange traceTRange
= fTrace
.getTimeRange();
529 sb
.append("\n\tTrace time interval for trace " + fTrace
.getName() + "\n\t"
530 + new LttngTimestamp(traceTRange
.getStartTime()));
531 sb
.append(" - " + new LttngTimestamp(traceTRange
.getEndTime()));
532 sb
.append("\n\tCheckPoints available at: ");
533 for (TmfCheckpoint cpoint
: timestampCheckpointsList
) {
534 sb
.append("\n\t" + "Location: " + cpoint
.getLocation() + " - " + cpoint
.getTimestamp());
537 return sb
.toString();