Contribution for Bug353020
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng / src / org / eclipse / linuxtools / lttng / state / trace / StateTraceManager.java
CommitLineData
5d10d135
ASL
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 *******************************************************************************/
12package org.eclipse.linuxtools.lttng.state.trace;
13
14import java.util.Collections;
15import java.util.HashMap;
16import java.util.Vector;
17
18import org.eclipse.linuxtools.lttng.TraceDebug;
19import org.eclipse.linuxtools.lttng.event.LttngEvent;
20import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent;
21import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd;
22import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
23import org.eclipse.linuxtools.lttng.model.LTTngTreeNode;
24import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest;
25import org.eclipse.linuxtools.lttng.request.IRequestStatusListener;
26import org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest;
27import org.eclipse.linuxtools.lttng.state.LttngStateException;
28import org.eclipse.linuxtools.lttng.state.evProcessor.ITransEventProcessor;
29import org.eclipse.linuxtools.lttng.state.evProcessor.state.StateEventToHandlerFactory;
30import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
31import org.eclipse.linuxtools.lttng.state.model.StateModelFactory;
32import org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext;
33import org.eclipse.linuxtools.lttng.trace.LTTngTextTrace;
34import org.eclipse.linuxtools.lttng.trace.LTTngTrace;
5d10d135
ASL
35import org.eclipse.linuxtools.tmf.event.TmfEvent;
36import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
37import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
38import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
39import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
5d10d135
ASL
40import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
41import org.eclipse.linuxtools.tmf.trace.TmfCheckpoint;
42import org.eclipse.linuxtools.tmf.trace.TmfLocation;
43
550d787e 44public class StateTraceManager extends LTTngTreeNode implements IStateTraceManager, ILttngStateContext {
5d10d135
ASL
45
46 // constants
47 private static final long DEFAULT_OFFSET = 0L;
48 private static final int DEFAULT_CHUNK = 1;
49
50 // configurable check point interval
b12f4544 51 private static final long LTTNG_CHECK_POINT_INTERVAL = 50000L;
5d10d135
ASL
52 private long fcheckPointInterval = LTTNG_CHECK_POINT_INTERVAL;
53
54 private TmfExperiment<LttngEvent> fExperiment = null;
55
56 // immutable Objects
57 private final ITmfTrace fTrace;
58 private int fcpuNumber = -1;
59 private final ITransEventProcessor fStateUpdateProcessor;
60
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;
550d787e 65 private LttngTraceState fCheckPointStateModel;
5d10d135
ASL
66
67 // locks
c1c69938
FC
68 private Object fCheckPointsLock = new Object();
69 private Object fStateModelLock = new Object();
5d10d135 70
5d10d135
ASL
71
72
73 // =======================================================================
74 // Constructor
75 // =======================================================================
76 /**
77 * @param id
78 * @param parent
79 * @param name
80 * @param trace
5d10d135
ASL
81 * @throws LttngStateException
82 */
550d787e 83 public StateTraceManager(Long id, LTTngTreeNode parent, String name, ITmfTrace trace) throws LttngStateException {
5d10d135
ASL
84 super(id, parent, name, trace);
85
86 if (trace == null) {
9c4eb5f7 87 throw new LttngStateException("No TmfTrace object available!"); //$NON-NLS-1$
5d10d135
ASL
88 }
89
90 fTrace = trace;
5d10d135 91 fStateUpdateProcessor = StateEventToHandlerFactory.getInstance();
550d787e 92
5d10d135 93 init();
550d787e
FC
94
95 fStateModel = StateModelFactory.getStateEntryInstance(this);
96 fStateModel.init(this);
97
98 fCheckPointStateModel = StateModelFactory.getStateEntryInstance(this);
99 fCheckPointStateModel.init(this);
5d10d135
ASL
100 }
101
102 // =======================================================================
103 // Methods
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;
111 }
112
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();
118 }
119 }
550d787e 120
5d10d135 121
8827c197 122
8827c197 123
5d10d135
ASL
124
125 /*
126 * (non-Javadoc)
127 *
128 * @see org.eclipse.linuxtools.lttng.state.IStateManager#getEventLog()
129 */
d4011df2 130 @Override
5d10d135
ASL
131 public ITmfTrace getTrace() {
132 return fTrace;
133 }
134
135 /**
136 * Save a checkpoint if it is needed at that point
137 * <p>
138 * The function will use "eventCount" internally to determine if a save was
139 * needed
140 *
141 * @param eventCounter
142 * The event "count" or event "id" so far
143 * @param eventTime
144 * The timestamp of this event
145 *
146 * @return boolean True if a checkpoint was saved, false otherwise
147 */
550d787e 148 private void saveCheckPointIfNeeded(Long eventCounter, TmfTimestamp eventTime) {
5d10d135
ASL
149 // Save a checkpoint every LTTNG_STATE_SAVE_INTERVAL event
150 if ((eventCounter.longValue() % fcheckPointInterval) == 0) {
c1c69938 151
5d10d135 152 LttngTraceState stateCheckPoint;
c1c69938 153 synchronized (fCheckPointsLock) {
550d787e 154 stateCheckPoint = fCheckPointStateModel.clone();
5d10d135
ASL
155 }
156
9c4eb5f7
FC
157 TraceDebug.debug("Check point created here: " + eventCounter //$NON-NLS-1$
158 + " -> " + eventTime.toString() + "************" //$NON-NLS-1$ //$NON-NLS-2$
159 + getTrace().getName() + " >>>>> Thread: " //$NON-NLS-1$
5d10d135
ASL
160 + Thread.currentThread().getId());
161
c1c69938 162 synchronized (fCheckPointsLock) {
5d10d135
ASL
163 // Save the checkpoint
164 stateCheckpointsList.put(eventCounter, stateCheckPoint);
165 // Save correlation between timestamp and checkpoint index
166
550d787e
FC
167 timestampCheckpointsList.add(new TmfCheckpoint(new TmfTimestamp(eventTime), new TmfLocation<Long>(
168 eventCounter)));
5d10d135
ASL
169 }
170 }
171 }
172
173 /**
174 * @return the lttng_check_point_interval
175 */
176 public long getCheckPointInterval() {
177 return fcheckPointInterval;
178 }
179
180 /**
181 * @param check_point_interval
182 * , the lttng_check_point_interval to set
183 */
184 public void setCheckPointInterval(long check_point_interval) {
185 this.fcheckPointInterval = check_point_interval;
186 }
187
736aecd5
ASL
188 /*
189 * (non-Javadoc)
190 *
550d787e
FC
191 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
192 * restoreCheckPointByTimestamp
736aecd5 193 * (org.eclipse.linuxtools.tmf.event.TmfTimestamp)
5d10d135 194 */
d4011df2 195 @Override
5d10d135 196 @SuppressWarnings("unchecked")
a79913eb 197 public TmfCheckpoint restoreCheckPointByTimestamp(TmfTimestamp eventTime) {
736aecd5 198 TmfTimeRange experimentRange = fExperiment.getTimeRange();
a79913eb 199 TmfCheckpoint checkpoint = new TmfCheckpoint(fTrace.getStartTime(), new TmfLocation<Long>(0L));
5d10d135
ASL
200
201 // The GUI can have time limits higher than this log, since GUI can
202 // handle multiple logs
550d787e 203 if ((eventTime.getValue() < 0) || (eventTime.getValue() > experimentRange.getEndTime().getValue())) {
5d10d135
ASL
204 return null;
205 }
206
736aecd5
ASL
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();
5dbe4d3b 211 }
736aecd5 212
c1c69938
FC
213 LttngTraceState traceState;
214 synchronized (fCheckPointsLock) {
215 Collections.sort(timestampCheckpointsList);
216 // Initiate the compare with a checkpoint containing the target time
217 // stamp to find
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
221 // not
222 // found
223 index = getPrevIndex(index);
224
225 if (index == 0) {
226 // No checkpoint restore is needed, start with a brand new
227 // TraceState
228 traceState = StateModelFactory.getStateEntryInstance(this);
229 } else {
230
231 // Useful CheckPoint found
a79913eb 232 checkpoint = timestampCheckpointsList.get(index);
c1c69938
FC
233 // get the location associated with the checkpoint
234 TmfLocation<Long> location = (TmfLocation<Long>) checkpoint.getLocation();
235 // reference a new copy of the checkpoint template
236 traceState = stateCheckpointsList.get(location.getLocation()).clone();
237 }
238
5dbe4d3b 239 }
5d10d135 240
5dbe4d3b 241 // Restore the stored traceState
c1c69938 242 synchronized (fStateModelLock) {
5dbe4d3b 243 fStateModel = traceState;
5d10d135
ASL
244 }
245
a79913eb
FC
246 return checkpoint;
247 }
248
249 /* (non-Javadoc)
250 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#restoreCheckPointByIndex(long)
251 */
252 @Override
253 public TmfCheckpoint restoreCheckPointByIndex(long eventIndex) {
254 TmfCheckpoint checkpoint = new TmfCheckpoint(fTrace.getStartTime(), new TmfLocation<Long>(0L));
255
256 LttngTraceState traceState;
257 synchronized (fCheckPointsLock) {
258 Collections.sort(timestampCheckpointsList);
259 // Initiate the compare with a checkpoint containing the target time
260 // stamp to find
261 int index = Collections.binarySearch(timestampCheckpointsList, new TmfCheckpoint(null,
262 new TmfLocation<Long>(eventIndex)));
263 // adjust index to round down to earlier checkpoint when exact match not found
264 index = getPrevIndex(index);
265
266 if (index == 0) {
267 // No checkpoint restore is needed, start with a brand new
268 // TraceState
269 traceState = StateModelFactory.getStateEntryInstance(this);
270 } else {
271
272 // Useful CheckPoint found
273 checkpoint = timestampCheckpointsList.get(index);
274 // get the location associated with the checkpoint
275 @SuppressWarnings("unchecked")
276 TmfLocation<Long> location = (TmfLocation<Long>) checkpoint.getLocation();
277 // reference a new copy of the checkpoint template
278 traceState = stateCheckpointsList.get(location.getLocation()).clone();
279 }
280
281 }
282
283 // Restore the stored traceState
284 synchronized (fStateModelLock) {
285 fStateModel = traceState;
286 }
287
288 return checkpoint;
5d10d135
ASL
289 }
290
291 /**
292 * Adjust the result from a binary search to the round down position
293 *
294 * @param position
295 * if Negative is: (-(insertion point) -1)
296 * @return position or if no match found, earlier than insertion point
297 */
298 private int getPrevIndex(int position) {
299 int roundDownPosition = position;
300 if (position < 0) {
301 roundDownPosition = -(position + 2);
302 }
303
304 roundDownPosition = roundDownPosition < 0 ? 0 : roundDownPosition;
305 return roundDownPosition;
306 }
307
5d10d135
ASL
308 // TODO: Remove this request type when the UI handle their own requests
309 /**
310 * Request Event data of a specified time range
311 *
312 * @param timeWindow
313 * @param listener
314 * @param processor
315 * @return ILttngEventRequest The request made
316 */
550d787e 317 ILttngSyntEventRequest getDataRequestByTimeRange(TmfTimeRange timeWindow, IRequestStatusListener listener,
5d10d135
ASL
318 final ITransEventProcessor processor) {
319
550d787e
FC
320 ILttngSyntEventRequest request = new StateTraceManagerRequest(timeWindow, DEFAULT_OFFSET,
321 TmfDataRequest.ALL_DATA, DEFAULT_CHUNK, listener, getExperimentTimeWindow(), processor) {
5d10d135
ASL
322 };
323
324 return request;
325 }
326
5d10d135
ASL
327
328 /*
329 * (non-Javadoc)
330 *
331 * @see
332 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getStateModel
333 * ()
334 */
d4011df2 335 @Override
c1c69938
FC
336 public LttngTraceState getStateModel() {
337 LttngTraceState stateModel = null;
338 synchronized (fStateModelLock) {
339 stateModel = fStateModel;
5d10d135 340 }
c1c69938 341 return stateModel;
5d10d135
ASL
342 }
343
550d787e
FC
344 /*
345 * (non-Javadoc)
346 *
347 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
348 * getCheckPointStateModel()
349 */
d4011df2 350 @Override
c1c69938
FC
351 public LttngTraceState getCheckPointStateModel() {
352 LttngTraceState checkPointStateModel = null;
353 synchronized (fCheckPointsLock) {
354 checkPointStateModel = fCheckPointStateModel;
550d787e 355 }
c1c69938 356 return checkPointStateModel;
550d787e
FC
357 }
358
5d10d135
ASL
359 /**
360 * @return the stateCheckpointsList
361 */
362 HashMap<Long, LttngTraceState> getStateCheckpointsList() {
363 return stateCheckpointsList;
364 }
365
366 /**
367 * @return the timestampCheckpointsList
368 */
369 Vector<TmfCheckpoint> getTimestampCheckpointsList() {
370 return timestampCheckpointsList;
371 }
372 // =======================================================================
373 // Inner Class
374 // =======================================================================
375 class StateTraceManagerRequest extends LttngSyntEventRequest {
376 // =======================================================================
377 // Data
378 // =======================================================================
379 final TmfEvent[] evt = new TmfEvent[1];
380 final ITransEventProcessor fprocessor;
381 LttngSyntheticEvent synEvent;
382 Long fCount = getSynEventCount();
383
384 // =======================================================================
385 // Constructor
386 // =======================================================================
550d787e
FC
387 public StateTraceManagerRequest(TmfTimeRange range, long offset, int nbEvents, int maxBlockSize,
388 IRequestStatusListener listener, TmfTimeRange experimentTimeRange, ITransEventProcessor processor) {
5d10d135 389
550d787e 390 super(range, offset, nbEvents, maxBlockSize, listener, experimentTimeRange, processor);
5d10d135 391 fprocessor = processor;
9c4eb5f7 392 TraceDebug.debug("Instance created for range: " + range.toString()); //$NON-NLS-1$
5d10d135
ASL
393 fCount = 0L;
394 }
395
396 // =======================================================================
397 // Methods
398 // =======================================================================
399 /*
400 * (non-Javadoc)
401 *
402 * @see
403 * org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData
404 * ()
405 */
406 @Override
f9673903
FC
407 public void handleData(LttngSyntheticEvent event) {
408 super.handleData(event);
409 if (event != null) {
410 synEvent = event;
5d10d135
ASL
411 if (synEvent.getSynType() == SequenceInd.AFTER) {
412 // Note : We call this function before incrementing
413 // eventCount to save a default check point at the "0th"
414 // event
415 saveCheckPoint(fCount, synEvent.getTimestamp());
416 fCount++;
417
418 if (TraceDebug.isDEBUG()) {
419 if (fCount % 1000 == 0) {
9c4eb5f7 420 TraceDebug.debug("handled: " + fCount + " sequence: " + synEvent.getSynType()); //$NON-NLS-1$ //$NON-NLS-2$
5d10d135
ASL
421 }
422 }
423 }
424 }
425 }
426
427 /**
428 * To be overridden by active save e.g. check points, this no action
429 * default is used for requests which do not require rebuilding of
430 * checkpoints e.g. requiring data of a new time range selection
431 *
432 * @param count
433 * @param time
434 */
435 public void saveCheckPoint(Long count, TmfTimestamp time) {
436
437 }
438 }
439
440 /*
441 * (non-Javadoc)
442 *
443 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
444 * getNumberOfCpus()
445 */
d4011df2 446 @Override
5d10d135
ASL
447 public int getNumberOfCpus() {
448 return fcpuNumber;
449 }
450
451 /*
452 * (non-Javadoc)
453 *
454 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
455 * getTraceTimeWindow()
456 */
d4011df2 457 @Override
5d10d135
ASL
458 public TmfTimeRange getTraceTimeWindow() {
459 if (fTrace != null) {
460 return fTrace.getTimeRange();
461
462 }
463 return null;
464 }
465
466 /*
467 * (non-Javadoc)
468 *
469 * @see
470 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceId
471 * ()
472 */
d4011df2 473 @Override
5d10d135
ASL
474 public String getTraceId() {
475 if (fTrace != null) {
476 return fTrace.getName();
477 }
478 return null;
479 }
480
481 /*
482 * (non-Javadoc)
483 *
484 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
485 * getExperimentTimeWindow()
486 */
d4011df2 487 @Override
5d10d135
ASL
488 public TmfTimeRange getExperimentTimeWindow() {
489 if (fExperiment != null) {
490 return fExperiment.getTimeRange();
491 }
492 return null;
493 }
494
495 /*
496 * (non-Javadoc)
497 *
498 * @see
499 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getExperimentName
500 * ()
501 */
d4011df2 502 @Override
5d10d135
ASL
503 public String getExperimentName() {
504 return fExperiment.getName();
505 }
506
507 /*
508 * (non-Javadoc)
509 *
510 * @see
511 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceIdRef
512 * ()
513 */
d4011df2 514 @Override
5d10d135
ASL
515 public ITmfTrace getTraceIdRef() {
516 return fTrace;
517 }
550d787e
FC
518
519 /*
520 * (non-Javadoc)
521 *
522 * @see
523 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#clearCheckPoints
524 * ()
525 */
d4011df2 526 @Override
c1c69938
FC
527 public void clearCheckPoints() {
528 synchronized (fCheckPointsLock) {
550d787e
FC
529 stateCheckpointsList.clear();
530 timestampCheckpointsList.clear();
531
532 fCheckPointStateModel = StateModelFactory.getStateEntryInstance(this);
c1c69938 533
550d787e
FC
534 try {
535 fCheckPointStateModel.init(this);
536 } catch (LttngStateException e) {
537 e.printStackTrace();
538 }
539 }
540 }
541
542 /*
543 * (non-Javadoc)
544 *
545 * @see
546 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#handleEvent
547 * (org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent, java.lang.Long)
548 */
d4011df2 549 @Override
550d787e
FC
550 public void handleEvent(LttngSyntheticEvent synEvent, Long eventCount) {
551 fStateUpdateProcessor.process(synEvent, fCheckPointStateModel);
552
553 // Save checkpoint as needed
554 saveCheckPointIfNeeded(eventCount - 1, synEvent.getTimestamp());
555 }
556
557 /*
558 * (non-Javadoc)
559 *
560 * @see java.lang.Object#toString()
561 */
cb866e08 562 @Override
3b38ea61 563 @SuppressWarnings("nls")
550d787e
FC
564 public String toString() {
565 StringBuilder sb = new StringBuilder(super.toString());
566 sb.append("\n\tTotal number of processes in the Shared State model: " + fStateModel.getProcesses().length
567 + "\n\t" + "Total number of processes in the Check point State model: "
568 + fCheckPointStateModel.getProcesses().length);
569
570 TmfTimeRange traceTRange = fTrace.getTimeRange();
571 sb.append("\n\tTrace time interval for trace " + fTrace.getName() + "\n\t"
572 + new LttngTimestamp(traceTRange.getStartTime()));
573 sb.append(" - " + new LttngTimestamp(traceTRange.getEndTime()));
574 sb.append("\n\tCheckPoints available at: ");
575 for (TmfCheckpoint cpoint : timestampCheckpointsList) {
576 sb.append("\n\t" + "Location: " + cpoint.getLocation() + " - " + cpoint.getTimestamp());
577 }
578
579 return sb.toString();
580 }
581
b12f4544
FC
582 /*
583 * (non-Javadoc)
584 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getIdentifier()
585 */
586 @Override
587 public long getIdentifier() {
588 return getId().longValue();
589 }
590
550d787e 591}
This page took 0.054285 seconds and 5 git commands to generate.