2010-10-26 Francois Chouinard <fchouinard@gmail.com> Contribution for Bug309042
[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 checkPointsLock = new Object();
69
70
71
72 // =======================================================================
73 // Constructor
74 // =======================================================================
75 /**
76 * @param id
77 * @param parent
78 * @param name
79 * @param trace
80 * @throws LttngStateException
81 */
82 public StateTraceManager(Long id, LTTngTreeNode parent, String name, ITmfTrace trace) throws LttngStateException {
83 super(id, parent, name, trace);
84
85 if (trace == null) {
86 throw new LttngStateException("No TmfTrace object available!");
87 }
88
89 fTrace = trace;
90 fStateUpdateProcessor = StateEventToHandlerFactory.getInstance();
91
92 init();
93
94 fStateModel = StateModelFactory.getStateEntryInstance(this);
95 fStateModel.init(this);
96
97 fCheckPointStateModel = StateModelFactory.getStateEntryInstance(this);
98 fCheckPointStateModel.init(this);
99 }
100
101 // =======================================================================
102 // Methods
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;
110 }
111
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();
117 }
118 }
119
120
121
122
123
124 /*
125 * (non-Javadoc)
126 *
127 * @see org.eclipse.linuxtools.lttng.state.IStateManager#getEventLog()
128 */
129 @Override
130 public ITmfTrace getTrace() {
131 return fTrace;
132 }
133
134 /**
135 * Save a checkpoint if it is needed at that point
136 * <p>
137 * The function will use "eventCount" internally to determine if a save was
138 * needed
139 *
140 * @param eventCounter
141 * The event "count" or event "id" so far
142 * @param eventTime
143 * The timestamp of this event
144 *
145 * @return boolean True if a checkpoint was saved, false otherwise
146 */
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();
153 }
154
155 TraceDebug.debug("Check point created here: " + eventCounter
156 + " -> " + eventTime.toString() + "************"
157 + getTrace().getName() + " >>>>> Thread: "
158 + Thread.currentThread().getId());
159
160 synchronized (checkPointsLock) {
161 // Save the checkpoint
162 stateCheckpointsList.put(eventCounter, stateCheckPoint);
163 // Save correlation between timestamp and checkpoint index
164
165 timestampCheckpointsList.add(new TmfCheckpoint(new TmfTimestamp(eventTime), new TmfLocation<Long>(
166 eventCounter)));
167 }
168 }
169 }
170
171 /**
172 * @return the lttng_check_point_interval
173 */
174 public long getCheckPointInterval() {
175 return fcheckPointInterval;
176 }
177
178 /**
179 * @param check_point_interval
180 * , the lttng_check_point_interval to set
181 */
182 public void setCheckPointInterval(long check_point_interval) {
183 this.fcheckPointInterval = check_point_interval;
184 }
185
186 /*
187 * (non-Javadoc)
188 *
189 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
190 * restoreCheckPointByTimestamp
191 * (org.eclipse.linuxtools.tmf.event.TmfTimestamp)
192 */
193 @Override
194 @SuppressWarnings("unchecked")
195 public TmfTimestamp restoreCheckPointByTimestamp(TmfTimestamp eventTime) {
196 TmfTimeRange experimentRange = fExperiment.getTimeRange();
197 TmfTimestamp nearestTimeStamp = fTrace.getStartTime();
198
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())) {
202 return null;
203 }
204
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();
209 }
210
211 Collections.sort(timestampCheckpointsList);
212 // Initiate the compare with a checkpoint containing the target time
213 // stamp to find
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
217 // not
218 // found
219 index = getPrevIndex(index);
220
221 LttngTraceState traceState;
222 if (index == 0) {
223 // No checkpoint restore is needed, start with a brand new
224 // TraceState
225 traceState = StateModelFactory.getStateEntryInstance(this);
226 } else {
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();
235 }
236 }
237
238 // Restore the stored traceState
239 synchronized (this) {
240 fStateModel = traceState;
241 }
242
243 return nearestTimeStamp;
244 }
245
246 /**
247 * Adjust the result from a binary search to the round down position
248 *
249 * @param position
250 * if Negative is: (-(insertion point) -1)
251 * @return position or if no match found, earlier than insertion point
252 */
253 private int getPrevIndex(int position) {
254 int roundDownPosition = position;
255 if (position < 0) {
256 roundDownPosition = -(position + 2);
257 }
258
259 roundDownPosition = roundDownPosition < 0 ? 0 : roundDownPosition;
260 return roundDownPosition;
261 }
262
263 // TODO: Remove this request type when the UI handle their own requests
264 /**
265 * Request Event data of a specified time range
266 *
267 * @param timeWindow
268 * @param listener
269 * @param processor
270 * @return ILttngEventRequest The request made
271 */
272 ILttngSyntEventRequest getDataRequestByTimeRange(TmfTimeRange timeWindow, IRequestStatusListener listener,
273 final ITransEventProcessor processor) {
274
275 ILttngSyntEventRequest request = new StateTraceManagerRequest(timeWindow, DEFAULT_OFFSET,
276 TmfDataRequest.ALL_DATA, DEFAULT_CHUNK, listener, getExperimentTimeWindow(), processor) {
277 };
278
279 return request;
280 }
281
282
283 /*
284 * (non-Javadoc)
285 *
286 * @see
287 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getStateModel
288 * ()
289 */
290 @Override
291 public LttngTraceState getStateModel() {
292 synchronized (fStateModel) {
293 return fStateModel;
294 }
295 }
296
297 /*
298 * (non-Javadoc)
299 *
300 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
301 * getCheckPointStateModel()
302 */
303 @Override
304 public LttngTraceState getCheckPointStateModel() {
305 synchronized (fStateModel) {
306 return fCheckPointStateModel;
307 }
308 }
309
310 /**
311 * @return the stateCheckpointsList
312 */
313 HashMap<Long, LttngTraceState> getStateCheckpointsList() {
314 return stateCheckpointsList;
315 }
316
317 /**
318 * @return the timestampCheckpointsList
319 */
320 Vector<TmfCheckpoint> getTimestampCheckpointsList() {
321 return timestampCheckpointsList;
322 }
323 // =======================================================================
324 // Inner Class
325 // =======================================================================
326 class StateTraceManagerRequest extends LttngSyntEventRequest {
327 // =======================================================================
328 // Data
329 // =======================================================================
330 final TmfEvent[] evt = new TmfEvent[1];
331 final ITransEventProcessor fprocessor;
332 LttngSyntheticEvent synEvent;
333 Long fCount = getSynEventCount();
334
335 // =======================================================================
336 // Constructor
337 // =======================================================================
338 public StateTraceManagerRequest(TmfTimeRange range, long offset, int nbEvents, int maxBlockSize,
339 IRequestStatusListener listener, TmfTimeRange experimentTimeRange, ITransEventProcessor processor) {
340
341 super(range, offset, nbEvents, maxBlockSize, listener, experimentTimeRange, processor);
342 fprocessor = processor;
343 TraceDebug.debug("Instance created for range: " + range.toString());
344 fCount = 0L;
345 }
346
347 // =======================================================================
348 // Methods
349 // =======================================================================
350 /*
351 * (non-Javadoc)
352 *
353 * @see
354 * org.eclipse.linuxtools.lttng.request.LttngSyntEventRequest#handleData
355 * ()
356 */
357 @Override
358 public void handleData(LttngSyntheticEvent event) {
359 super.handleData(event);
360 if (event != null) {
361 synEvent = 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"
365 // event
366 saveCheckPoint(fCount, synEvent.getTimestamp());
367 fCount++;
368
369 if (TraceDebug.isDEBUG()) {
370 if (fCount % 1000 == 0) {
371 TraceDebug.debug("handled: " + fCount + " sequence: " + synEvent.getSynType());
372 }
373 }
374 }
375 }
376 }
377
378 /**
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
382 *
383 * @param count
384 * @param time
385 */
386 public void saveCheckPoint(Long count, TmfTimestamp time) {
387
388 }
389 }
390
391 /*
392 * (non-Javadoc)
393 *
394 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
395 * getNumberOfCpus()
396 */
397 @Override
398 public int getNumberOfCpus() {
399 return fcpuNumber;
400 }
401
402 /*
403 * (non-Javadoc)
404 *
405 * @see org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#
406 * getTraceTimeWindow()
407 */
408 @Override
409 public TmfTimeRange getTraceTimeWindow() {
410 if (fTrace != null) {
411 return fTrace.getTimeRange();
412
413 }
414 return null;
415 }
416
417 /*
418 * (non-Javadoc)
419 *
420 * @see
421 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceId
422 * ()
423 */
424 @Override
425 public String getTraceId() {
426 if (fTrace != null) {
427 return fTrace.getName();
428 }
429 return null;
430 }
431
432 /*
433 * (non-Javadoc)
434 *
435 * @see org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#
436 * getExperimentTimeWindow()
437 */
438 @Override
439 public TmfTimeRange getExperimentTimeWindow() {
440 if (fExperiment != null) {
441 return fExperiment.getTimeRange();
442 }
443 return null;
444 }
445
446 /*
447 * (non-Javadoc)
448 *
449 * @see
450 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#getExperimentName
451 * ()
452 */
453 @Override
454 public String getExperimentName() {
455 return fExperiment.getName();
456 }
457
458 /*
459 * (non-Javadoc)
460 *
461 * @see
462 * org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext#getTraceIdRef
463 * ()
464 */
465 @Override
466 public ITmfTrace getTraceIdRef() {
467 return fTrace;
468 }
469
470 /*
471 * (non-Javadoc)
472 *
473 * @see
474 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#clearCheckPoints
475 * ()
476 */
477 @Override
478 public void clearCheckPoints() {
479 synchronized (checkPointsLock) {
480 stateCheckpointsList.clear();
481 timestampCheckpointsList.clear();
482
483 fCheckPointStateModel = StateModelFactory.getStateEntryInstance(this);
484 try {
485 fCheckPointStateModel.init(this);
486 } catch (LttngStateException e) {
487 e.printStackTrace();
488 }
489 }
490 }
491
492 /*
493 * (non-Javadoc)
494 *
495 * @see
496 * org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager#handleEvent
497 * (org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent, java.lang.Long)
498 */
499 @Override
500 public void handleEvent(LttngSyntheticEvent synEvent, Long eventCount) {
501 fStateUpdateProcessor.process(synEvent, fCheckPointStateModel);
502
503 // Save checkpoint as needed
504 saveCheckPointIfNeeded(eventCount - 1, synEvent.getTimestamp());
505 }
506
507 /*
508 * (non-Javadoc)
509 *
510 * @see java.lang.Object#toString()
511 */
512 @Override
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);
518
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());
526 }
527
528 return sb.toString();
529 }
530
531 }
This page took 0.0428 seconds and 5 git commands to generate.