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