2010-11-09 Francois Chouinard <fchouinard@gmail.com> Contribution for Bug315307
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng / src / org / eclipse / linuxtools / lttng / state / trace / StateTraceManager.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 *******************************************************************************/
12 package org.eclipse.linuxtools.lttng.state.trace;
13
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.Vector;
17
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;
43
44 public class StateTraceManager extends LTTngTreeNode implements IStateTraceManager, ILttngStateContext {
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
51 private static final long LTTNG_CHECK_POINT_INTERVAL = 15000L;
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;
65 private LttngTraceState fCheckPointStateModel;
66
67 // locks
68 private Object fCheckPointsLock = new Object();
69 private Object fStateModelLock = new Object();
70
71
72
73 // =======================================================================
74 // Constructor
75 // =======================================================================
76 /**
77 * @param id
78 * @param parent
79 * @param name
80 * @param trace
81 * @throws LttngStateException
82 */
83 public StateTraceManager(Long id, LTTngTreeNode parent, String name, ITmfTrace trace) throws LttngStateException {
84 super(id, parent, name, trace);
85
86 if (trace == null) {
87 throw new LttngStateException("No TmfTrace object available!");
88 }
89
90 fTrace = trace;
91 fStateUpdateProcessor = StateEventToHandlerFactory.getInstance();
92
93 init();
94
95 fStateModel = StateModelFactory.getStateEntryInstance(this);
96 fStateModel.init(this);
97
98 fCheckPointStateModel = StateModelFactory.getStateEntryInstance(this);
99 fCheckPointStateModel.init(this);
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 }
120
121
122
123
124
125 /*
126 * (non-Javadoc)
127 *
128 * @see org.eclipse.linuxtools.lttng.state.IStateManager#getEventLog()
129 */
130 @Override
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 */
148 private void saveCheckPointIfNeeded(Long eventCounter, TmfTimestamp eventTime) {
149 // Save a checkpoint every LTTNG_STATE_SAVE_INTERVAL event
150 if ((eventCounter.longValue() % fcheckPointInterval) == 0) {
151
152 LttngTraceState stateCheckPoint;
153 synchronized (fCheckPointsLock) {
154 stateCheckPoint = fCheckPointStateModel.clone();
155 }
156
157 TraceDebug.debug("Check point created here: " + eventCounter
158 + " -> " + eventTime.toString() + "************"
159 + getTrace().getName() + " >>>>> Thread: "
160 + Thread.currentThread().getId());
161
162 synchronized (fCheckPointsLock) {
163 // Save the checkpoint
164 stateCheckpointsList.put(eventCounter, stateCheckPoint);
165 // Save correlation between timestamp and checkpoint index
166
167 timestampCheckpointsList.add(new TmfCheckpoint(new TmfTimestamp(eventTime), new TmfLocation<Long>(
168 eventCounter)));
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
188 /*
189 * (non-Javadoc)
190 *
191 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
192 * restoreCheckPointByTimestamp
193 * (org.eclipse.linuxtools.tmf.event.TmfTimestamp)
194 */
195 @Override
196 @SuppressWarnings("unchecked")
197 public TmfTimestamp restoreCheckPointByTimestamp(TmfTimestamp eventTime) {
198 TmfTimeRange experimentRange = fExperiment.getTimeRange();
199 TmfTimestamp nearestTimeStamp = fTrace.getStartTime();
200
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())) {
204 return null;
205 }
206
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();
211 }
212
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
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();
238 }
239
240 }
241
242 // Restore the stored traceState
243 synchronized (fStateModelLock) {
244 fStateModel = traceState;
245 }
246
247 return nearestTimeStamp;
248 }
249
250 /**
251 * Adjust the result from a binary search to the round down position
252 *
253 * @param position
254 * if Negative is: (-(insertion point) -1)
255 * @return position or if no match found, earlier than insertion point
256 */
257 private int getPrevIndex(int position) {
258 int roundDownPosition = position;
259 if (position < 0) {
260 roundDownPosition = -(position + 2);
261 }
262
263 roundDownPosition = roundDownPosition < 0 ? 0 : roundDownPosition;
264 return roundDownPosition;
265 }
266
267 // TODO: Remove this request type when the UI handle their own requests
268 /**
269 * Request Event data of a specified time range
270 *
271 * @param timeWindow
272 * @param listener
273 * @param processor
274 * @return ILttngEventRequest The request made
275 */
276 ILttngSyntEventRequest getDataRequestByTimeRange(TmfTimeRange timeWindow, IRequestStatusListener listener,
277 final ITransEventProcessor processor) {
278
279 ILttngSyntEventRequest request = new StateTraceManagerRequest(timeWindow, DEFAULT_OFFSET,
280 TmfDataRequest.ALL_DATA, DEFAULT_CHUNK, listener, getExperimentTimeWindow(), processor) {
281 };
282
283 return request;
284 }
285
286
287 /*
288 * (non-Javadoc)
289 *
290 * @see
291 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getStateModel
292 * ()
293 */
294 @Override
295 public LttngTraceState getStateModel() {
296 LttngTraceState stateModel = null;
297 synchronized (fStateModelLock) {
298 stateModel = fStateModel;
299 }
300 return stateModel;
301 }
302
303 /*
304 * (non-Javadoc)
305 *
306 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
307 * getCheckPointStateModel()
308 */
309 @Override
310 public LttngTraceState getCheckPointStateModel() {
311 LttngTraceState checkPointStateModel = null;
312 synchronized (fCheckPointsLock) {
313 checkPointStateModel = fCheckPointStateModel;
314 }
315 return checkPointStateModel;
316 }
317
318 /**
319 * @return the stateCheckpointsList
320 */
321 HashMap<Long, LttngTraceState> getStateCheckpointsList() {
322 return stateCheckpointsList;
323 }
324
325 /**
326 * @return the timestampCheckpointsList
327 */
328 Vector<TmfCheckpoint> getTimestampCheckpointsList() {
329 return timestampCheckpointsList;
330 }
331 // =======================================================================
332 // Inner Class
333 // =======================================================================
334 class StateTraceManagerRequest extends LttngSyntEventRequest {
335 // =======================================================================
336 // Data
337 // =======================================================================
338 final TmfEvent[] evt = new TmfEvent[1];
339 final ITransEventProcessor fprocessor;
340 LttngSyntheticEvent synEvent;
341 Long fCount = getSynEventCount();
342
343 // =======================================================================
344 // Constructor
345 // =======================================================================
346 public StateTraceManagerRequest(TmfTimeRange range, long offset, int nbEvents, int maxBlockSize,
347 IRequestStatusListener listener, TmfTimeRange experimentTimeRange, ITransEventProcessor processor) {
348
349 super(range, offset, nbEvents, maxBlockSize, listener, experimentTimeRange, processor);
350 fprocessor = processor;
351 TraceDebug.debug("Instance created for range: " + range.toString());
352 fCount = 0L;
353 }
354
355 // =======================================================================
356 // Methods
357 // =======================================================================
358 /*
359 * (non-Javadoc)
360 *
361 * @see
362 * org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData
363 * ()
364 */
365 @Override
366 public void handleData(LttngSyntheticEvent event) {
367 super.handleData(event);
368 if (event != null) {
369 synEvent = 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"
373 // event
374 saveCheckPoint(fCount, synEvent.getTimestamp());
375 fCount++;
376
377 if (TraceDebug.isDEBUG()) {
378 if (fCount % 1000 == 0) {
379 TraceDebug.debug("handled: " + fCount + " sequence: " + synEvent.getSynType());
380 }
381 }
382 }
383 }
384 }
385
386 /**
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
390 *
391 * @param count
392 * @param time
393 */
394 public void saveCheckPoint(Long count, TmfTimestamp time) {
395
396 }
397 }
398
399 /*
400 * (non-Javadoc)
401 *
402 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
403 * getNumberOfCpus()
404 */
405 @Override
406 public int getNumberOfCpus() {
407 return fcpuNumber;
408 }
409
410 /*
411 * (non-Javadoc)
412 *
413 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
414 * getTraceTimeWindow()
415 */
416 @Override
417 public TmfTimeRange getTraceTimeWindow() {
418 if (fTrace != null) {
419 return fTrace.getTimeRange();
420
421 }
422 return null;
423 }
424
425 /*
426 * (non-Javadoc)
427 *
428 * @see
429 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceId
430 * ()
431 */
432 @Override
433 public String getTraceId() {
434 if (fTrace != null) {
435 return fTrace.getName();
436 }
437 return null;
438 }
439
440 /*
441 * (non-Javadoc)
442 *
443 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
444 * getExperimentTimeWindow()
445 */
446 @Override
447 public TmfTimeRange getExperimentTimeWindow() {
448 if (fExperiment != null) {
449 return fExperiment.getTimeRange();
450 }
451 return null;
452 }
453
454 /*
455 * (non-Javadoc)
456 *
457 * @see
458 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getExperimentName
459 * ()
460 */
461 @Override
462 public String getExperimentName() {
463 return fExperiment.getName();
464 }
465
466 /*
467 * (non-Javadoc)
468 *
469 * @see
470 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceIdRef
471 * ()
472 */
473 @Override
474 public ITmfTrace getTraceIdRef() {
475 return fTrace;
476 }
477
478 /*
479 * (non-Javadoc)
480 *
481 * @see
482 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#clearCheckPoints
483 * ()
484 */
485 @Override
486 public void clearCheckPoints() {
487 synchronized (fCheckPointsLock) {
488 stateCheckpointsList.clear();
489 timestampCheckpointsList.clear();
490
491 fCheckPointStateModel = StateModelFactory.getStateEntryInstance(this);
492
493 try {
494 fCheckPointStateModel.init(this);
495 } catch (LttngStateException e) {
496 e.printStackTrace();
497 }
498 }
499 }
500
501 /*
502 * (non-Javadoc)
503 *
504 * @see
505 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#handleEvent
506 * (org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent, java.lang.Long)
507 */
508 @Override
509 public void handleEvent(LttngSyntheticEvent synEvent, Long eventCount) {
510 fStateUpdateProcessor.process(synEvent, fCheckPointStateModel);
511
512 // Save checkpoint as needed
513 saveCheckPointIfNeeded(eventCount - 1, synEvent.getTimestamp());
514 }
515
516 /*
517 * (non-Javadoc)
518 *
519 * @see java.lang.Object#toString()
520 */
521 @Override
522 @SuppressWarnings("nls")
523 public String toString() {
524 StringBuilder sb = new StringBuilder(super.toString());
525 sb.append("\n\tTotal number of processes in the Shared State model: " + fStateModel.getProcesses().length
526 + "\n\t" + "Total number of processes in the Check point State model: "
527 + fCheckPointStateModel.getProcesses().length);
528
529 TmfTimeRange traceTRange = fTrace.getTimeRange();
530 sb.append("\n\tTrace time interval for trace " + fTrace.getName() + "\n\t"
531 + new LttngTimestamp(traceTRange.getStartTime()));
532 sb.append(" - " + new LttngTimestamp(traceTRange.getEndTime()));
533 sb.append("\n\tCheckPoints available at: ");
534 for (TmfCheckpoint cpoint : timestampCheckpointsList) {
535 sb.append("\n\t" + "Location: " + cpoint.getLocation() + " - " + cpoint.getTimestamp());
536 }
537
538 return sb.toString();
539 }
540
541 }
This page took 0.041342 seconds and 5 git commands to generate.