Bug 378402: Implementation of ControlFlow view and Resources view for
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / trace / TmfExperiment.java
CommitLineData
8c8bf09f 1/*******************************************************************************
0316808c 2 * Copyright (c) 2009, 2010, 2012 Ericsson
ce2388e0 3 *
8c8bf09f
ASL
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
ce2388e0 8 *
8c8bf09f
ASL
9 * Contributors:
10 * Francois Chouinard - Initial API and implementation
0316808c 11 * Francois Chouinard - Updated as per TMF Trace Model 1.0
8c8bf09f
ASL
12 *******************************************************************************/
13
9e0640dc 14package org.eclipse.linuxtools.tmf.core.trace;
8c8bf09f 15
a1091415 16import org.eclipse.core.resources.IFile;
12c155f5 17import org.eclipse.core.resources.IProject;
828e5592 18import org.eclipse.core.resources.IResource;
9e0640dc
FC
19import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentContext;
20import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentLocation;
21import org.eclipse.linuxtools.internal.tmf.core.trace.TmfLocationArray;
72f1e62a 22import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
4df4581d 23import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
6c13869b
FC
24import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
25import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
0316808c 26import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
1b70b6dc 27import org.eclipse.linuxtools.tmf.core.signal.TmfEndSynchSignal;
6c13869b
FC
28import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentDisposedSignal;
29import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal;
30import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;
31import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentUpdatedSignal;
32import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
c32744d6 33import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal;
8c8bf09f
ASL
34
35/**
9e0640dc 36 * TmfExperiment presents a time-ordered, unified view of a set of ITmfTrace:s
cbdacf03 37 * that are part of a tracing experiment.
8c8bf09f 38 */
0316808c 39public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements ITmfEventParser<T> {
8c8bf09f 40
c32744d6
FC
41 // ------------------------------------------------------------------------
42 // Constants
43 // ------------------------------------------------------------------------
44
9e0640dc
FC
45 /**
46 * The default index page size
47 */
48 public static final int DEFAULT_INDEX_PAGE_SIZE = 5000;
c32744d6 49
8c8bf09f
ASL
50 // ------------------------------------------------------------------------
51 // Attributes
52 // ------------------------------------------------------------------------
53
9e0640dc
FC
54 /**
55 * The currently selected experiment (null if none)
56 */
c32744d6 57 protected static TmfExperiment<?> fCurrentExperiment = null;
e31e01e8 58
9e0640dc
FC
59 /**
60 * The set of traces that constitute the experiment
61 */
c32744d6 62 protected ITmfTrace<T>[] fTraces;
8c8bf09f 63
9e0640dc
FC
64 /**
65 * The set of traces that constitute the experiment
66 */
67 private boolean fInitialized = false;
a1091415 68
9e0640dc
FC
69 /**
70 * The experiment bookmarks file
71 */
72 private IFile fBookmarksFile;
828e5592 73
8c8bf09f 74 // ------------------------------------------------------------------------
9e0640dc 75 // Construction
8c8bf09f
ASL
76 // ------------------------------------------------------------------------
77
9e0640dc
FC
78 /**
79 * @param type
80 * @param id
81 * @param traces
82 * @throws TmfTraceException
83 */
84 public TmfExperiment(final Class<T> type, final String id, final ITmfTrace<T>[] traces) {
85 this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE);
96c6806f
PT
86 }
87
8c8bf09f
ASL
88 /**
89 * @param type
90 * @param id
91 * @param traces
8c8bf09f 92 * @param indexPageSize
0316808c 93 * @throws TmfTraceException
8c8bf09f 94 */
0316808c 95 @SuppressWarnings({ "unchecked", "rawtypes" })
9e0640dc 96 public TmfExperiment(final Class<T> type, final String path, final ITmfTrace<T>[] traces, final int indexPageSize) {
0316808c
FC
97 setCacheSize(indexPageSize);
98 setStreamingInterval(0);
07671572 99 setIndexer(new TmfCheckpointIndexer(this, indexPageSize));
0316808c
FC
100 setParser(this);
101 try {
102 super.initialize(null, path, type);
103 } catch (TmfTraceException e) {
104 e.printStackTrace();
105 }
8c8bf09f 106
a79913eb 107 fTraces = traces;
a87cc4ef 108 setTimeRange(TmfTimeRange.NULL_RANGE);
8c8bf09f 109 }
a79913eb 110
8c8bf09f 111 /**
ff4ed569 112 * Clears the experiment
8c8bf09f
ASL
113 */
114 @Override
12c155f5 115 @SuppressWarnings("rawtypes")
a79913eb
FC
116 public synchronized void dispose() {
117
cbdacf03 118 final TmfExperimentDisposedSignal<T> signal = new TmfExperimentDisposedSignal<T>(this, this);
a79913eb 119 broadcast(signal);
9e0640dc
FC
120
121 if (fCurrentExperiment == this) {
09d11238 122 fCurrentExperiment = null;
9e0640dc 123 }
a79913eb
FC
124
125 if (fTraces != null) {
cbdacf03 126 for (final ITmfTrace trace : fTraces)
a79913eb 127 trace.dispose();
a79913eb
FC
128 fTraces = null;
129 }
2fb2eb37 130 super.dispose();
8c8bf09f
ASL
131 }
132
9e0640dc
FC
133 // ------------------------------------------------------------------------
134 // ITmfTrace - Initializers
135 // ------------------------------------------------------------------------
136
137 /* (non-Javadoc)
138 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(org.eclipse.core.resources.IProject, java.lang.String)
139 */
140 @Override
141 public boolean validate(final IProject project, final String path) {
142 return true;
143 }
144
145 /* (non-Javadoc)
146 * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#initTrace(org.eclipse.core.resources.IResource, java.lang.String, java.lang.Class)
147 */
148 @Override
149 public void initTrace(final IResource resource, final String path, final Class<T> type) {
150 }
151
8c8bf09f 152 // ------------------------------------------------------------------------
e31e01e8 153 // Accessors
8c8bf09f
ASL
154 // ------------------------------------------------------------------------
155
9e0640dc
FC
156 /**
157 * Selects the current, framework-wide, experiment
158 *
159 * @param experiment das experiment
160 */
cbdacf03 161 public static void setCurrentExperiment(final TmfExperiment<?> experiment) {
9e0640dc 162 if (fCurrentExperiment != null && fCurrentExperiment != experiment) {
09d11238 163 fCurrentExperiment.dispose();
9e0640dc 164 }
a79913eb 165 fCurrentExperiment = experiment;
f6b14ce2
FC
166 }
167
9e0640dc
FC
168 /**
169 * @return das experiment
170 */
e31e01e8 171 public static TmfExperiment<?> getCurrentExperiment() {
a79913eb 172 return fCurrentExperiment;
8c8bf09f
ASL
173 }
174
9e0640dc
FC
175 /**
176 * Get the list of traces. Handle with care...
177 *
178 * @return the experiment traces
179 */
12c155f5 180 public ITmfTrace<T>[] getTraces() {
a79913eb 181 return fTraces;
8c8bf09f
ASL
182 }
183
8c8bf09f 184 /**
cbdacf03
FC
185 * Returns the timestamp of the event at the requested index. If none,
186 * returns null.
a79913eb 187 *
0d9a6d76
FC
188 * @param index the event index (rank)
189 * @return the corresponding event timestamp
8c8bf09f 190 */
cbdacf03 191 public ITmfTimestamp getTimestamp(final int index) {
0316808c 192 final ITmfContext context = seekEvent(index);
c32744d6 193 final ITmfEvent event = getNext(context);
a79913eb 194 return (event != null) ? event.getTimestamp() : null;
8c8bf09f
ASL
195 }
196
9e0640dc
FC
197 /**
198 * Set the file to be used for bookmarks on this experiment
199 *
200 * @param file the bookmarks file
201 */
202 public void setBookmarksFile(final IFile file) {
203 fBookmarksFile = file;
204 }
07671572 205
9e0640dc
FC
206 /**
207 * Get the file used for bookmarks on this experiment
208 *
209 * @return the bookmarks file or null if none is set
210 */
211 public IFile getBookmarksFile() {
212 return fBookmarksFile;
a79913eb
FC
213 }
214
a79913eb 215 // ------------------------------------------------------------------------
9f584e4c
FC
216 // ITmfTrace trace positioning
217 // ------------------------------------------------------------------------
218
9e0640dc
FC
219 /* (non-Javadoc)
220 *
221 * Returns a brand new context based on the location provided and
222 * initializes the event queues
223 *
224 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools.tmf.core.trace.ITmfLocation)
225 */
a79913eb 226 @Override
9e0640dc 227 public synchronized ITmfContext seekEvent(final ITmfLocation<?> location) {
a79913eb 228 // Validate the location
9e0640dc 229 if (location != null && !(location instanceof TmfExperimentLocation)) {
a79913eb 230 return null; // Throw an exception?
9e0640dc
FC
231 }
232 // Make sure we have something to read from
233 if (fTraces == null) {
a79913eb 234 return null;
9e0640dc 235 }
8f50c396 236
a79913eb 237 // Instantiate the location
9e0640dc
FC
238 final TmfExperimentLocation expLocation = (location == null)
239 ? new TmfExperimentLocation(new TmfLocationArray(new ITmfLocation<?>[fTraces.length]))
240 : (TmfExperimentLocation) location.clone();
8f50c396 241
a79913eb 242 // Create and populate the context's traces contexts
0316808c 243 final TmfExperimentContext context = new TmfExperimentContext(new ITmfContext[fTraces.length]);
9b635e61 244
a79913eb
FC
245 for (int i = 0; i < fTraces.length; i++) {
246 // Get the relevant trace attributes
0316808c 247 final ITmfLocation<?> traceLocation = expLocation.getLocation().getLocations()[i];
7e6347b0 248 context.getContexts()[i] = fTraces[i].seekEvent(traceLocation);
0316808c 249 expLocation.getLocation().getLocations()[i] = context.getContexts()[i].getLocation().clone();
c32744d6 250 context.getEvents()[i] = fTraces[i].getNext(context.getContexts()[i]);
a79913eb 251 }
8f50c396 252
a79913eb
FC
253 // Finalize context
254 context.setLocation(expLocation);
255 context.setLastTrace(TmfExperimentContext.NO_TRACE);
0316808c 256 context.setRank(ITmfContext.UNKNOWN_RANK);
9e0640dc 257 return (ITmfContext) context;
a79913eb 258 }
9f584e4c 259
9e0640dc
FC
260 /* (non-Javadoc)
261 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(double)
262 */
c76c54bb 263 @Override
0316808c
FC
264 public ITmfContext seekEvent(final double ratio) {
265 final ITmfContext context = seekEvent((long) (ratio * getNbEvents()));
c76c54bb
FC
266 return context;
267 }
268
9e0640dc
FC
269 /* (non-Javadoc)
270 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getLocationRatio(org.eclipse.linuxtools.tmf.core.trace.ITmfLocation)
271 */
a79913eb 272 @Override
cbdacf03 273 public double getLocationRatio(final ITmfLocation<?> location) {
9e0640dc 274 if (location instanceof TmfExperimentLocation) {
7e6347b0 275 return (double) seekEvent(location).getRank() / getNbEvents();
9e0640dc
FC
276 }
277 return 0.0;
c76c54bb
FC
278 }
279
9e0640dc
FC
280 /* (non-Javadoc)
281 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
282 */
a79913eb
FC
283 @Override
284 public ITmfLocation<?> getCurrentLocation() {
a87cc4ef
FC
285 ITmfLocation<?>[] locations = new ITmfLocation<?>[fTraces.length];
286 for (int i = 0; i < fTraces.length; i++) {
287 locations[i] = fTraces[i].getCurrentLocation();
288 }
289 return new TmfExperimentLocation(new TmfLocationArray(locations));
a79913eb 290 }
c76c54bb 291
9e0640dc
FC
292 // ------------------------------------------------------------------------
293 // ITmfTrace trace positioning
294 // ------------------------------------------------------------------------
295
07671572 296 /* (non-Javadoc)
9e0640dc 297 * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#getNext(org.eclipse.linuxtools.tmf.core.trace.ITmfContext)
07671572
FC
298 */
299 @Override
c32744d6 300 public synchronized T getNext(final ITmfContext context) {
a0a4901e 301 final ITmfContext previousContext = (TmfExperimentContext) context.clone();
c32744d6 302 final T event = parseEvent(context);
07671572 303 if (event != null) {
a0a4901e 304 updateAttributes(previousContext, event.getTimestamp());
07671572
FC
305
306 TmfExperimentContext expContext = (TmfExperimentContext) context;
307 int trace = expContext.getLastTrace();
308 if (trace != TmfExperimentContext.NO_TRACE) {
309 TmfExperimentLocation location = (TmfExperimentLocation) expContext.getLocation();
310 location.getLocation().getLocations()[trace] = expContext.getContexts()[trace].getLocation();
311 }
312
313 context.increaseRank();
314 processEvent(event);
315 }
316 return event;
317 }
a79913eb 318
ce2388e0 319 /* (non-Javadoc)
9e0640dc 320 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser#parseEvent(org.eclipse.linuxtools.tmf.core.trace.ITmfContext)
a79913eb 321 */
0316808c
FC
322 @SuppressWarnings("unchecked")
323 @Override
a87cc4ef 324 public T parseEvent(ITmfContext context) {
a79913eb
FC
325
326 // Validate the context
9e0640dc 327 if (!(context instanceof TmfExperimentContext)) {
a79913eb 328 return null; // Throw an exception?
9e0640dc 329 }
a79913eb 330
a87cc4ef 331 TmfExperimentContext expContext = (TmfExperimentContext) context;
a79913eb 332
a87cc4ef 333 // If an event was consumed previously, first get the next one from that trace
cbdacf03 334 final int lastTrace = expContext.getLastTrace();
a79913eb 335 if (lastTrace != TmfExperimentContext.NO_TRACE) {
cbdacf03 336 final ITmfContext traceContext = expContext.getContexts()[lastTrace];
c32744d6 337 expContext.getEvents()[lastTrace] = fTraces[lastTrace].getNext(traceContext);
a79913eb 338 expContext.setLastTrace(TmfExperimentContext.NO_TRACE);
a79913eb
FC
339 }
340
341 // Scan the candidate events and identify the "next" trace to read from
342 int trace = TmfExperimentContext.NO_TRACE;
a4115405 343 ITmfTimestamp timestamp = TmfTimestamp.BIG_CRUNCH;
0316808c 344 for (int i = 0; i < fTraces.length; i++) {
cbdacf03 345 final ITmfEvent event = expContext.getEvents()[i];
a79913eb 346 if (event != null && event.getTimestamp() != null) {
cbdacf03 347 final ITmfTimestamp otherTS = event.getTimestamp();
a79913eb
FC
348 if (otherTS.compareTo(timestamp, true) < 0) {
349 trace = i;
350 timestamp = otherTS;
351 }
352 }
353 }
a87cc4ef
FC
354
355 T event = null;
07671572 356 if (trace != TmfExperimentContext.NO_TRACE) {
a87cc4ef 357 event = (T) expContext.getEvents()[trace];
07671572 358 }
a87cc4ef 359
a87cc4ef
FC
360 expContext.setLastTrace(trace);
361 return event;
a79913eb
FC
362 }
363
bcbea6a6 364 /* (non-Javadoc)
a79913eb
FC
365 * @see java.lang.Object#toString()
366 */
367 @Override
3b38ea61 368 @SuppressWarnings("nls")
a79913eb
FC
369 public String toString() {
370 return "[TmfExperiment (" + getName() + ")]";
371 }
8c8bf09f
ASL
372
373 // ------------------------------------------------------------------------
9e0640dc 374 // Streaming support
8c8bf09f
ASL
375 // ------------------------------------------------------------------------
376
1b70b6dc 377 private synchronized void initializeStreamingMonitor() {
9e0640dc
FC
378
379 if (fInitialized) {
828e5592 380 return;
9e0640dc 381 }
828e5592
PT
382 fInitialized = true;
383
1b70b6dc 384 if (getStreamingInterval() == 0) {
0316808c 385 final ITmfContext context = seekEvent(0);
cbdacf03
FC
386 final ITmfEvent event = getNext(context);
387 if (event == null)
1b70b6dc 388 return;
cbdacf03 389 final TmfTimeRange timeRange = new TmfTimeRange(event.getTimestamp().clone(), TmfTimestamp.BIG_CRUNCH);
828e5592
PT
390 final TmfExperimentRangeUpdatedSignal signal = new TmfExperimentRangeUpdatedSignal(this, this, timeRange);
391
392 // Broadcast in separate thread to prevent deadlock
393 new Thread() {
394 @Override
395 public void run() {
396 broadcast(signal);
397 }
398 }.start();
1b70b6dc
PT
399 return;
400 }
401
9e0640dc 402 final Thread thread = new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$
bcbea6a6
FC
403 private ITmfTimestamp safeTimestamp = null;
404 private TmfTimeRange timeRange = null;
1b70b6dc
PT
405
406 @Override
407 public void run() {
408 while (!fExecutor.isShutdown()) {
9e0640dc 409 if (!getIndexer().isIndexing()) {
a4115405
FC
410 ITmfTimestamp startTimestamp = TmfTimestamp.BIG_CRUNCH;
411 ITmfTimestamp endTimestamp = TmfTimestamp.BIG_BANG;
cbdacf03
FC
412 for (final ITmfTrace<T> trace : fTraces) {
413 if (trace.getStartTime().compareTo(startTimestamp) < 0)
1b70b6dc 414 startTimestamp = trace.getStartTime();
cbdacf03 415 if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0)
1b70b6dc 416 endTimestamp = trace.getEndTime();
1b70b6dc 417 }
cbdacf03 418 if (safeTimestamp != null && safeTimestamp.compareTo(getTimeRange().getEndTime(), false) > 0)
1b70b6dc 419 timeRange = new TmfTimeRange(startTimestamp, safeTimestamp);
cbdacf03 420 else
1b70b6dc 421 timeRange = null;
1b70b6dc
PT
422 safeTimestamp = endTimestamp;
423 if (timeRange != null) {
cbdacf03 424 final TmfExperimentRangeUpdatedSignal signal =
1b70b6dc
PT
425 new TmfExperimentRangeUpdatedSignal(TmfExperiment.this, TmfExperiment.this, timeRange);
426 broadcast(signal);
427 }
428 }
429 try {
430 Thread.sleep(getStreamingInterval());
cbdacf03 431 } catch (final InterruptedException e) {
1b70b6dc
PT
432 e.printStackTrace();
433 }
434 }
435 }
436 };
437 thread.start();
438 }
439
9e0640dc 440 /* (non-Javadoc)
1b70b6dc
PT
441 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getStreamingInterval()
442 */
443 @Override
444 public long getStreamingInterval() {
445 long interval = 0;
cbdacf03 446 for (final ITmfTrace<T> trace : fTraces)
1b70b6dc 447 interval = Math.max(interval, trace.getStreamingInterval());
1b70b6dc
PT
448 return interval;
449 }
450
8c8bf09f
ASL
451 // ------------------------------------------------------------------------
452 // Signal handlers
453 // ------------------------------------------------------------------------
454
9e0640dc 455 private Integer fEndSynchReference;
c32744d6 456
9e0640dc
FC
457 /**
458 * Signal handler for the TmfExperimentSelectedSignal signal
459 *
460 * @param signal
461 */
8c8bf09f 462 @TmfSignalHandler
cbdacf03
FC
463 public void experimentSelected(final TmfExperimentSelectedSignal<T> signal) {
464 final TmfExperiment<?> experiment = signal.getExperiment();
a79913eb
FC
465 if (experiment == this) {
466 setCurrentExperiment(experiment);
6e85c58d 467 fEndSynchReference = Integer.valueOf(signal.getReference());
a79913eb 468 }
8c8bf09f
ASL
469 }
470
9e0640dc
FC
471 /**
472 * Signal handler for the TmfEndSynchSignal signal
473 *
474 * @param signal
475 */
1b70b6dc 476 @TmfSignalHandler
cbdacf03 477 public void endSync(final TmfEndSynchSignal signal) {
1b70b6dc
PT
478 if (fEndSynchReference != null && fEndSynchReference.intValue() == signal.getReference()) {
479 fEndSynchReference = null;
480 initializeStreamingMonitor();
481 }
1b70b6dc
PT
482 }
483
828e5592 484 /**
9e0640dc 485 * Signal handler for the TmfTraceUpdatedSignal signal
cbdacf03 486 *
9e0640dc 487 * @param signal
828e5592 488 */
9e0640dc
FC
489 @TmfSignalHandler
490 public void traceUpdated(final TmfTraceUpdatedSignal signal) {
491 if (signal.getTrace() == this) {
492 broadcast(new TmfExperimentUpdatedSignal(this, this));
493 }
a1091415
PT
494 }
495
496 /**
9e0640dc 497 * Signal handler for the TmfExperimentRangeUpdatedSignal signal
cbdacf03 498 *
9e0640dc 499 * @param signal
a1091415 500 */
9e0640dc
FC
501 @TmfSignalHandler
502 public void experimentRangeUpdated(final TmfExperimentRangeUpdatedSignal signal) {
503 if (signal.getExperiment() == this) {
504 getIndexer().buildIndex(getNbEvents(), signal.getRange(), false);
505 }
a1091415
PT
506 }
507
4dc47e28 508}
This page took 0.082142 seconds and 5 git commands to generate.