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 checkPointsLock
= new Object();
72 // =======================================================================
74 // =======================================================================
80 * @throws LttngStateException
82 public StateTraceManager(Long id
, LTTngTreeNode parent
, String name
, ITmfTrace trace
) throws LttngStateException
{
83 super(id
, parent
, name
, trace
);
86 throw new LttngStateException("No TmfTrace object available!");
90 fStateUpdateProcessor
= StateEventToHandlerFactory
.getInstance();
94 fStateModel
= StateModelFactory
.getStateEntryInstance(this);
95 fStateModel
.init(this);
97 fCheckPointStateModel
= StateModelFactory
.getStateEntryInstance(this);
98 fCheckPointStateModel
.init(this);
101 // =======================================================================
103 // =======================================================================
104 @SuppressWarnings("unchecked")
105 private void init() {
106 // resolve the experiment
107 Object obj
= getParent().getValue();
108 if (obj
!= null && obj
instanceof TmfExperiment
<?
>) {
109 fExperiment
= (TmfExperiment
<LttngEvent
>) obj
;
112 // initialize the number of cpus
113 if (fTrace
instanceof LTTngTrace
) {
114 fcpuNumber
= ((LTTngTrace
) fTrace
).getCpuNumber();
115 } else if (fTrace
instanceof LTTngTextTrace
) {
116 fcpuNumber
= ((LTTngTextTrace
) fTrace
).getCpuNumber();
127 * @see org.eclipse.linuxtools.lttng.state.IStateManager#getEventLog()
130 public ITmfTrace
getTrace() {
135 * Save a checkpoint if it is needed at that point
137 * The function will use "eventCount" internally to determine if a save was
140 * @param eventCounter
141 * The event "count" or event "id" so far
143 * The timestamp of this event
145 * @return boolean True if a checkpoint was saved, false otherwise
147 private void saveCheckPointIfNeeded(Long eventCounter
, TmfTimestamp eventTime
) {
148 // Save a checkpoint every LTTNG_STATE_SAVE_INTERVAL event
149 if ((eventCounter
.longValue() % fcheckPointInterval
) == 0) {
150 LttngTraceState stateCheckPoint
;
151 synchronized (fCheckPointStateModel
) {
152 stateCheckPoint
= fCheckPointStateModel
.clone();
155 TraceDebug
.debug("Check point created here: " + eventCounter
156 + " -> " + eventTime
.toString() + "************"
157 + getTrace().getName() + " >>>>> Thread: "
158 + Thread
.currentThread().getId());
160 synchronized (checkPointsLock
) {
161 // Save the checkpoint
162 stateCheckpointsList
.put(eventCounter
, stateCheckPoint
);
163 // Save correlation between timestamp and checkpoint index
165 timestampCheckpointsList
.add(new TmfCheckpoint(new TmfTimestamp(eventTime
), new TmfLocation
<Long
>(
172 * @return the lttng_check_point_interval
174 public long getCheckPointInterval() {
175 return fcheckPointInterval
;
179 * @param check_point_interval
180 * , the lttng_check_point_interval to set
182 public void setCheckPointInterval(long check_point_interval
) {
183 this.fcheckPointInterval
= check_point_interval
;
189 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
190 * restoreCheckPointByTimestamp
191 * (org.eclipse.linuxtools.tmf.event.TmfTimestamp)
194 @SuppressWarnings("unchecked")
195 public TmfTimestamp
restoreCheckPointByTimestamp(TmfTimestamp eventTime
) {
196 TmfTimeRange experimentRange
= fExperiment
.getTimeRange();
197 TmfTimestamp nearestTimeStamp
= fTrace
.getStartTime();
199 // The GUI can have time limits higher than this log, since GUI can
200 // handle multiple logs
201 if ((eventTime
.getValue() < 0) || (eventTime
.getValue() > experimentRange
.getEndTime().getValue())) {
205 // The GUI can have time limits lower than this trace, since experiment
206 // can handle multiple traces
207 if ((eventTime
.getValue() < fTrace
.getStartTime().getValue())) {
208 eventTime
= fTrace
.getStartTime();
211 Collections
.sort(timestampCheckpointsList
);
212 // Initiate the compare with a checkpoint containing the target time
214 int index
= Collections
.binarySearch(timestampCheckpointsList
, new TmfCheckpoint(eventTime
,
215 new TmfLocation
<Long
>(0L)));
216 // adjust index to round down to earlier checkpoint when exact match
219 index
= getPrevIndex(index
);
221 LttngTraceState traceState
;
223 // No checkpoint restore is needed, start with a brand new
225 traceState
= StateModelFactory
.getStateEntryInstance(this);
227 synchronized (checkPointsLock
) {
228 // Useful CheckPoint found
229 TmfCheckpoint checkpoint
= timestampCheckpointsList
.get(index
);
230 nearestTimeStamp
= checkpoint
.getTimestamp();
231 // get the location associated with the checkpoint
232 TmfLocation
<Long
> location
= (TmfLocation
<Long
>) checkpoint
.getLocation();
233 // reference a new copy of the checkpoint template
234 traceState
= stateCheckpointsList
.get(location
.getLocation()).clone();
238 // Restore the stored traceState
239 synchronized (this) {
240 fStateModel
= traceState
;
243 return nearestTimeStamp
;
247 * Adjust the result from a binary search to the round down position
250 * if Negative is: (-(insertion point) -1)
251 * @return position or if no match found, earlier than insertion point
253 private int getPrevIndex(int position
) {
254 int roundDownPosition
= position
;
256 roundDownPosition
= -(position
+ 2);
259 roundDownPosition
= roundDownPosition
< 0 ?
0 : roundDownPosition
;
260 return roundDownPosition
;
263 // TODO: Remove this request type when the UI handle their own requests
265 * Request Event data of a specified time range
270 * @return ILttngEventRequest The request made
272 ILttngSyntEventRequest
getDataRequestByTimeRange(TmfTimeRange timeWindow
, IRequestStatusListener listener
,
273 final ITransEventProcessor processor
) {
275 ILttngSyntEventRequest request
= new StateTraceManagerRequest(timeWindow
, DEFAULT_OFFSET
,
276 TmfDataRequest
.ALL_DATA
, DEFAULT_CHUNK
, listener
, getExperimentTimeWindow(), processor
) {
287 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getStateModel
291 public LttngTraceState
getStateModel() {
292 synchronized (fStateModel
) {
300 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
301 * getCheckPointStateModel()
304 public LttngTraceState
getCheckPointStateModel() {
305 synchronized (fStateModel
) {
306 return fCheckPointStateModel
;
311 * @return the stateCheckpointsList
313 HashMap
<Long
, LttngTraceState
> getStateCheckpointsList() {
314 return stateCheckpointsList
;
318 * @return the timestampCheckpointsList
320 Vector
<TmfCheckpoint
> getTimestampCheckpointsList() {
321 return timestampCheckpointsList
;
323 // =======================================================================
325 // =======================================================================
326 class StateTraceManagerRequest
extends LttngSyntEventRequest
{
327 // =======================================================================
329 // =======================================================================
330 final TmfEvent
[] evt
= new TmfEvent
[1];
331 final ITransEventProcessor fprocessor
;
332 LttngSyntheticEvent synEvent
;
333 Long fCount
= getSynEventCount();
335 // =======================================================================
337 // =======================================================================
338 public StateTraceManagerRequest(TmfTimeRange range
, long offset
, int nbEvents
, int maxBlockSize
,
339 IRequestStatusListener listener
, TmfTimeRange experimentTimeRange
, ITransEventProcessor processor
) {
341 super(range
, offset
, nbEvents
, maxBlockSize
, listener
, experimentTimeRange
, processor
);
342 fprocessor
= processor
;
343 TraceDebug
.debug("Instance created for range: " + range
.toString());
347 // =======================================================================
349 // =======================================================================
354 * org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData
358 public void handleData(LttngSyntheticEvent event
) {
359 super.handleData(event
);
362 if (synEvent
.getSynType() == SequenceInd
.AFTER
) {
363 // Note : We call this function before incrementing
364 // eventCount to save a default check point at the "0th"
366 saveCheckPoint(fCount
, synEvent
.getTimestamp());
369 if (TraceDebug
.isDEBUG()) {
370 if (fCount
% 1000 == 0) {
371 TraceDebug
.debug("handled: " + fCount
+ " sequence: " + synEvent
.getSynType());
379 * To be overridden by active save e.g. check points, this no action
380 * default is used for requests which do not require rebuilding of
381 * checkpoints e.g. requiring data of a new time range selection
386 public void saveCheckPoint(Long count
, TmfTimestamp time
) {
394 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
398 public int getNumberOfCpus() {
405 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
406 * getTraceTimeWindow()
409 public TmfTimeRange
getTraceTimeWindow() {
410 if (fTrace
!= null) {
411 return fTrace
.getTimeRange();
421 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceId
425 public String
getTraceId() {
426 if (fTrace
!= null) {
427 return fTrace
.getName();
435 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
436 * getExperimentTimeWindow()
439 public TmfTimeRange
getExperimentTimeWindow() {
440 if (fExperiment
!= null) {
441 return fExperiment
.getTimeRange();
450 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getExperimentName
454 public String
getExperimentName() {
455 return fExperiment
.getName();
462 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceIdRef
466 public ITmfTrace
getTraceIdRef() {
474 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#clearCheckPoints
478 public void clearCheckPoints() {
479 synchronized (checkPointsLock
) {
480 stateCheckpointsList
.clear();
481 timestampCheckpointsList
.clear();
483 fCheckPointStateModel
= StateModelFactory
.getStateEntryInstance(this);
485 fCheckPointStateModel
.init(this);
486 } catch (LttngStateException e
) {
496 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#handleEvent
497 * (org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent, java.lang.Long)
500 public void handleEvent(LttngSyntheticEvent synEvent
, Long eventCount
) {
501 fStateUpdateProcessor
.process(synEvent
, fCheckPointStateModel
);
503 // Save checkpoint as needed
504 saveCheckPointIfNeeded(eventCount
- 1, synEvent
.getTimestamp());
510 * @see java.lang.Object#toString()
513 public String
toString() {
514 StringBuilder sb
= new StringBuilder(super.toString());
515 sb
.append("\n\tTotal number of processes in the Shared State model: " + fStateModel
.getProcesses().length
516 + "\n\t" + "Total number of processes in the Check point State model: "
517 + fCheckPointStateModel
.getProcesses().length
);
519 TmfTimeRange traceTRange
= fTrace
.getTimeRange();
520 sb
.append("\n\tTrace time interval for trace " + fTrace
.getName() + "\n\t"
521 + new LttngTimestamp(traceTRange
.getStartTime()));
522 sb
.append(" - " + new LttngTimestamp(traceTRange
.getEndTime()));
523 sb
.append("\n\tCheckPoints available at: ");
524 for (TmfCheckpoint cpoint
: timestampCheckpointsList
) {
525 sb
.append("\n\t" + "Location: " + cpoint
.getLocation() + " - " + cpoint
.getTimestamp());
528 return sb
.toString();