TMF: Make the ITmfEvent#getTimestamp() return NonNull
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / trace / experiment / TmfExperiment.java
CommitLineData
8c8bf09f 1/*******************************************************************************
deaae6e1 2 * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal
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
e73a4ba5 14 * Geneviève Bastien - Added support of experiment synchronization
b3dd2736 15 * Added the initExperiment method and default constructor
d77f31da 16 * Bernd Hufmann - Updated for added interfaces to ITmfEventProvider
8c8bf09f
ASL
17 *******************************************************************************/
18
5c5fa260 19package org.eclipse.tracecompass.tmf.core.trace.experiment;
8c8bf09f 20
e73a4ba5 21import java.io.File;
032ecd45 22import java.nio.ByteBuffer;
4d2a4a2c 23import java.util.Collections;
fa62dc1d 24import java.util.List;
4d2a4a2c
GB
25import java.util.concurrent.locks.Lock;
26import java.util.concurrent.locks.ReentrantLock;
e73a4ba5 27
12c155f5 28import org.eclipse.core.resources.IProject;
828e5592 29import org.eclipse.core.resources.IResource;
e73a4ba5 30import org.eclipse.core.runtime.CoreException;
a94410d9 31import org.eclipse.core.runtime.IStatus;
9928ddeb 32import org.eclipse.core.runtime.MultiStatus;
a94410d9 33import org.eclipse.core.runtime.Status;
4178260e 34import org.eclipse.jdt.annotation.Nullable;
2bdf0193 35import org.eclipse.tracecompass.internal.tmf.core.Activator;
5c5fa260
AM
36import org.eclipse.tracecompass.internal.tmf.core.trace.experiment.TmfExperimentContext;
37import org.eclipse.tracecompass.internal.tmf.core.trace.experiment.TmfExperimentLocation;
38import org.eclipse.tracecompass.internal.tmf.core.trace.experiment.TmfLocationArray;
2bdf0193
AM
39import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
40import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
41import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
42import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
43import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
44import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
45import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal;
46import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSynchronizedSignal;
47import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationAlgorithm;
48import org.eclipse.tracecompass.tmf.core.synchronization.SynchronizationManager;
49import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
50import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
51import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
5c5fa260 52import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
5c5fa260
AM
53import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
54import org.eclipse.tracecompass.tmf.core.trace.TmfTrace;
55import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
2bdf0193
AM
56import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable;
57import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer;
58import org.eclipse.tracecompass.tmf.core.trace.indexer.TmfBTreeTraceIndexer;
59import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
8c8bf09f
ASL
60
61/**
9e0640dc 62 * TmfExperiment presents a time-ordered, unified view of a set of ITmfTrace:s
cbdacf03 63 * that are part of a tracing experiment.
4b7b3670
FC
64 *
65 * @version 1.0
66 * @author Francois Chouinard
8c8bf09f 67 */
5733be39 68public class TmfExperiment extends TmfTrace implements ITmfPersistentlyIndexable {
8c8bf09f 69
c32744d6
FC
70 // ------------------------------------------------------------------------
71 // Constants
72 // ------------------------------------------------------------------------
73
e73a4ba5
GB
74 /**
75 * The file name of the Synchronization
76 *
77 * @since 3.0
7f38b742
GB
78 * @deprecated This file name shouldn't be used directly anymore. All
79 * synchronization files have been moved to a folder and you
80 * should use the {@link #getSynchronizationFolder(boolean)}
81 * method to return the path to this folder.
e73a4ba5 82 */
04ba3554 83 @Deprecated
7f38b742 84 public static final String SYNCHRONIZATION_FILE_NAME = "synchronization.bin"; //$NON-NLS-1$
e73a4ba5 85
04ba3554
GB
86 /**
87 * The name of the directory containing trace synchronization data. This
88 * directory typically will be preserved when traces are synchronized.
89 * Analysis involved in synchronization can put their supplementary files in
90 * there so they are not deleted when synchronized traces are copied.
04ba3554 91 */
7f38b742 92 private static final String SYNCHRONIZATION_DIRECTORY = "sync_data"; //$NON-NLS-1$
04ba3554 93
9e0640dc
FC
94 /**
95 * The default index page size
96 */
97 public static final int DEFAULT_INDEX_PAGE_SIZE = 5000;
c32744d6 98
8c8bf09f
ASL
99 // ------------------------------------------------------------------------
100 // Attributes
101 // ------------------------------------------------------------------------
102
9e0640dc
FC
103 /**
104 * The set of traces that constitute the experiment
105 */
106 private boolean fInitialized = false;
a1091415 107
4d2a4a2c
GB
108 /**
109 * Lock for synchronization methods. These methods cannot be 'synchronized'
110 * since it makes it impossible to use an event request on the experiment
111 * during synchronization (the request thread would block)
112 */
113 private final Lock fSyncLock = new ReentrantLock();
4178260e 114
8c8bf09f 115 // ------------------------------------------------------------------------
9e0640dc 116 // Construction
8c8bf09f
ASL
117 // ------------------------------------------------------------------------
118
9e0640dc 119 /**
4178260e
AM
120 * Default constructor. Should not be used directly, but is needed for
121 * extension points.
04ba3554 122 *
4178260e 123 * @deprecated Do not call this directly (but do not remove it either!)
b3dd2736 124 */
4178260e 125 @Deprecated
b3dd2736
GB
126 public TmfExperiment() {
127 super();
128 }
129
130 /**
4178260e 131 * Constructor of an experiment, taking the type, path, traces,
99504bb8
GB
132 * indexPageSize and resource
133 *
134 * @param type
4178260e 135 * The event type
99504bb8 136 * @param path
4178260e 137 * The experiment path
99504bb8 138 * @param traces
4178260e 139 * The experiment set of traces
99504bb8 140 * @param indexPageSize
4178260e
AM
141 * The experiment index page size. You can use
142 * {@link TmfExperiment#DEFAULT_INDEX_PAGE_SIZE} for a default
143 * value.
99504bb8 144 * @param resource
4178260e
AM
145 * The resource associated to the experiment. You can use 'null'
146 * for no resources (tests, etc.)
99504bb8 147 */
4178260e
AM
148 public TmfExperiment(final Class<? extends ITmfEvent> type,
149 final String path,
150 final ITmfTrace[] traces,
151 final int indexPageSize,
152 final @Nullable IResource resource) {
b3dd2736 153 initExperiment(type, path, traces, indexPageSize, resource);
8c8bf09f 154 }
a79913eb 155
032ecd45
MAL
156 @Override
157 protected ITmfTraceIndexer createIndexer(int interval) {
158 if (getCheckpointSize() > 0) {
159 return new TmfBTreeTraceIndexer(this, interval);
160 }
161 return super.createIndexer(interval);
162 }
163
8c8bf09f 164 /**
ff4ed569 165 * Clears the experiment
8c8bf09f
ASL
166 */
167 @Override
a79913eb
FC
168 public synchronized void dispose() {
169
77551cc2
FC
170 // Clean up the index if applicable
171 if (getIndexer() != null) {
172 getIndexer().dispose();
173 }
b5ee6881 174
2fb2eb37 175 super.dispose();
8c8bf09f
ASL
176 }
177
9e0640dc
FC
178 // ------------------------------------------------------------------------
179 // ITmfTrace - Initializers
180 // ------------------------------------------------------------------------
181
9e0640dc 182 @Override
6256d8ad 183 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) {
4178260e 184 /* Do nothing for experiments */
9e0640dc
FC
185 }
186
b3dd2736
GB
187 /**
188 * Initialization of an experiment, taking the type, path, traces,
189 * indexPageSize and resource
190 *
191 * @param type
192 * the event type
193 * @param path
194 * the experiment path
195 * @param traces
196 * the experiment set of traces
197 * @param indexPageSize
198 * the experiment index page size
199 * @param resource
200 * the resource associated to the experiment
201 * @since 3.0
202 */
4178260e
AM
203 public void initExperiment(final Class<? extends ITmfEvent> type,
204 final String path,
205 final ITmfTrace[] traces,
206 final int indexPageSize,
207 final @Nullable IResource resource) {
208
b3dd2736
GB
209 setCacheSize(indexPageSize);
210 setStreamingInterval(0);
d77f31da 211
7976315b 212 // traces have to be set before super.initialize()
d77f31da
BH
213 if (traces != null) {
214 // initialize
d77f31da
BH
215 for (ITmfTrace trace : traces) {
216 if (trace != null) {
217 addChild(trace);
218 }
219 }
220 }
221
b3dd2736
GB
222 try {
223 super.initialize(resource, path, type);
224 } catch (TmfTraceException e) {
225 Activator.logError("Error initializing experiment", e); //$NON-NLS-1$
226 }
227
b3dd2736 228 if (resource != null) {
04ba3554 229 this.synchronizeTraces();
b3dd2736
GB
230 }
231 }
232
a94410d9
MK
233 /**
234 * @since 2.0
235 */
9e0640dc 236 @Override
a94410d9
MK
237 public IStatus validate(final IProject project, final String path) {
238 return Status.OK_STATUS;
9e0640dc
FC
239 }
240
8c8bf09f 241 // ------------------------------------------------------------------------
e31e01e8 242 // Accessors
8c8bf09f
ASL
243 // ------------------------------------------------------------------------
244
f0c0d2c2
AM
245 /**
246 * Get the traces contained in this experiment.
247 *
248 * @return The array of contained traces
249 */
fa62dc1d
BH
250 public List<ITmfTrace> getTraces() {
251 return getChildren(ITmfTrace.class);
8c8bf09f
ASL
252 }
253
8c8bf09f 254 /**
cbdacf03
FC
255 * Returns the timestamp of the event at the requested index. If none,
256 * returns null.
9b749023 257 *
e73a4ba5
GB
258 * @param index
259 * the event index (rank)
0d9a6d76 260 * @return the corresponding event timestamp
3bd46eef 261 * @since 2.0
8c8bf09f 262 */
cbdacf03 263 public ITmfTimestamp getTimestamp(final int index) {
0316808c 264 final ITmfContext context = seekEvent(index);
c32744d6 265 final ITmfEvent event = getNext(context);
4c9f2944 266 context.dispose();
a79913eb 267 return (event != null) ? event.getTimestamp() : null;
8c8bf09f
ASL
268 }
269
49e2f79a
FC
270 // ------------------------------------------------------------------------
271 // Request management
272 // ------------------------------------------------------------------------
273
e6809677
PT
274 /**
275 * @since 2.0
3bd44ac8 276 */
49e2f79a 277 @Override
fd3f1eff 278 public synchronized ITmfContext armRequest(final ITmfEventRequest request) {
9b749023 279
6a953367 280 // Make sure we have something to read from
fa62dc1d 281 if (getChildren().isEmpty()) {
6a953367
BH
282 return null;
283 }
9b749023 284
fd3f1eff
AM
285 if (!TmfTimestamp.BIG_BANG.equals(request.getRange().getStartTime())
286 && request.getIndex() == 0) {
287 final ITmfContext context = seekEvent(request.getRange().getStartTime());
288 request.setStartIndex((int) context.getRank());
49e2f79a 289 return context;
5419a136 290
49e2f79a
FC
291 }
292
5419a136 293 return seekEvent(request.getIndex());
49e2f79a
FC
294 }
295
a79913eb 296 // ------------------------------------------------------------------------
9f584e4c
FC
297 // ITmfTrace trace positioning
298 // ------------------------------------------------------------------------
299
a3db8436
AM
300 /**
301 * @since 3.0
302 */
a79913eb 303 @Override
1e1bef82 304 public synchronized ITmfContext seekEvent(final ITmfLocation location) {
a79913eb 305 // Validate the location
9e0640dc 306 if (location != null && !(location instanceof TmfExperimentLocation)) {
a79913eb 307 return null; // Throw an exception?
9e0640dc 308 }
d77f31da 309
fa62dc1d 310 int length = getNbChildren();
8f50c396 311
ea271da6
PT
312 // Initialize the location array if necessary
313 TmfLocationArray locationArray = ((location == null) ?
fa62dc1d 314 new TmfLocationArray(length) :
ea271da6
PT
315 ((TmfExperimentLocation) location).getLocationInfo());
316
317 ITmfLocation[] locations = locationArray.getLocations();
318 long[] ranks = locationArray.getRanks();
319
a79913eb 320 // Create and populate the context's traces contexts
fa62dc1d 321 final TmfExperimentContext context = new TmfExperimentContext(length);
9b635e61 322
d62bb185 323 // Position the traces
ea271da6 324 long rank = 0;
fa62dc1d 325 for (int i = 0; i < length; i++) {
a79913eb 326 // Get the relevant trace attributes
fa62dc1d 327 final ITmfContext traceContext = ((ITmfTrace) getChild(i)).seekEvent(locations[i]);
07ef7847 328 context.setContext(i, traceContext);
ea271da6 329 traceContext.setRank(ranks[i]);
7f38b742
GB
330 // update location after seek
331 locations[i] = traceContext.getLocation();
fa62dc1d 332 context.setEvent(i, ((ITmfTrace) getChild(i)).getNext(traceContext));
ea271da6 333 rank += ranks[i];
a79913eb 334 }
8f50c396 335
a79913eb 336 // Finalize context
ea271da6 337 context.setLocation(new TmfExperimentLocation(new TmfLocationArray(locations, ranks)));
a79913eb 338 context.setLastTrace(TmfExperimentContext.NO_TRACE);
ea271da6 339 context.setRank(rank);
49e2f79a 340
9b749023 341 return context;
a79913eb 342 }
9f584e4c 343
3bd44ac8
FC
344 // ------------------------------------------------------------------------
345 // ITmfTrace - SeekEvent operations (returning a trace context)
346 // ------------------------------------------------------------------------
347
c76c54bb 348 @Override
0316808c 349 public ITmfContext seekEvent(final double ratio) {
91f6e587 350 final ITmfContext context = seekEvent(Math.round(ratio * getNbEvents()));
c76c54bb
FC
351 return context;
352 }
353
a3db8436
AM
354 /**
355 * @since 3.0
356 */
a79913eb 357 @Override
1e1bef82 358 public double getLocationRatio(final ITmfLocation location) {
9e0640dc 359 if (location instanceof TmfExperimentLocation) {
ea271da6
PT
360 long rank = 0;
361 TmfLocationArray locationArray = ((TmfExperimentLocation) location).getLocationInfo();
362 for (int i = 0; i < locationArray.size(); i++) {
363 rank += locationArray.getRank(i);
364 }
365 return (double) rank / getNbEvents();
9e0640dc
FC
366 }
367 return 0.0;
c76c54bb
FC
368 }
369
a3db8436
AM
370 /**
371 * @since 3.0
372 */
a79913eb 373 @Override
1e1bef82 374 public ITmfLocation getCurrentLocation() {
ea271da6
PT
375 // never used
376 return null;
a79913eb 377 }
c76c54bb 378
9e0640dc
FC
379 // ------------------------------------------------------------------------
380 // ITmfTrace trace positioning
381 // ------------------------------------------------------------------------
382
07671572 383 @Override
6256d8ad 384 public synchronized ITmfEvent parseEvent(final ITmfContext context) {
ea271da6
PT
385 final ITmfContext tmpContext = seekEvent(context.getLocation());
386 final ITmfEvent event = getNext(tmpContext);
07671572
FC
387 return event;
388 }
a79913eb 389
0316808c 390 @Override
6256d8ad 391 public synchronized ITmfEvent getNext(ITmfContext context) {
a79913eb
FC
392
393 // Validate the context
9e0640dc 394 if (!(context instanceof TmfExperimentContext)) {
a79913eb 395 return null; // Throw an exception?
9e0640dc 396 }
0e8c76f8 397
fa62dc1d
BH
398 int length = getNbChildren();
399
0e8c76f8 400 // Make sure that we have something to read from
fa62dc1d 401 if (length == 0) {
0e8c76f8
BH
402 return null;
403 }
404
a87cc4ef 405 TmfExperimentContext expContext = (TmfExperimentContext) context;
a79913eb 406
e73a4ba5
GB
407 // If an event was consumed previously, first get the next one from that
408 // trace
cbdacf03 409 final int lastTrace = expContext.getLastTrace();
a79913eb 410 if (lastTrace != TmfExperimentContext.NO_TRACE) {
07ef7847 411 final ITmfContext traceContext = expContext.getContext(lastTrace);
fa62dc1d 412 expContext.setEvent(lastTrace, ((ITmfTrace) getChild(lastTrace)).getNext(traceContext));
a79913eb 413 expContext.setLastTrace(TmfExperimentContext.NO_TRACE);
a79913eb
FC
414 }
415
416 // Scan the candidate events and identify the "next" trace to read from
417 int trace = TmfExperimentContext.NO_TRACE;
a4115405 418 ITmfTimestamp timestamp = TmfTimestamp.BIG_CRUNCH;
fa62dc1d 419 for (int i = 0; i < length; i++) {
07ef7847 420 final ITmfEvent event = expContext.getEvent(i);
fa62dc1d 421
cbf0057c 422 if (event != null) {
cbdacf03 423 final ITmfTimestamp otherTS = event.getTimestamp();
065cc19b 424 if (otherTS.compareTo(timestamp) < 0) {
a79913eb
FC
425 trace = i;
426 timestamp = otherTS;
427 }
428 }
429 }
a87cc4ef 430
6256d8ad 431 ITmfEvent event = null;
07671572 432 if (trace != TmfExperimentContext.NO_TRACE) {
07ef7847 433 event = expContext.getEvent(trace);
408e65d2
FC
434 if (event != null) {
435 updateAttributes(expContext, event.getTimestamp());
408e65d2
FC
436 expContext.increaseRank();
437 expContext.setLastTrace(trace);
07ef7847
AM
438 final ITmfContext traceContext = expContext.getContext(trace);
439 if (traceContext == null) {
440 throw new IllegalStateException();
441 }
17324c9a 442
ea271da6
PT
443 // Update the experiment location
444 TmfLocationArray locationArray = new TmfLocationArray(
445 ((TmfExperimentLocation) expContext.getLocation()).getLocationInfo(),
446 trace, traceContext.getLocation(), traceContext.getRank());
447 expContext.setLocation(new TmfExperimentLocation(locationArray));
408e65d2 448 }
07671572 449 }
a87cc4ef 450
a87cc4ef 451 return event;
a79913eb
FC
452 }
453
66262ad8
BH
454 /**
455 * @since 2.0
456 */
457 @Override
458 public ITmfTimestamp getInitialRangeOffset() {
d77f31da 459
fa62dc1d
BH
460 List<ITmfTrace> children = getChildren(ITmfTrace.class);
461
462 if (children.isEmpty()) {
66262ad8
BH
463 return super.getInitialRangeOffset();
464 }
465
466 ITmfTimestamp initTs = TmfTimestamp.BIG_CRUNCH;
fa62dc1d
BH
467 for (ITmfTrace trace : children) {
468 ITmfTimestamp ts = (trace).getInitialRangeOffset();
66262ad8
BH
469 if (ts.compareTo(initTs) < 0) {
470 initTs = ts;
471 }
472 }
473 return initTs;
474 }
475
04ba3554
GB
476 /**
477 * Get the path to the folder in the supplementary file where
478 * synchronization-related data can be kept so they are not deleted when the
7f38b742
GB
479 * experiment is synchronized. Analysis involved in synchronization can put
480 * their supplementary files in there so they are preserved after
481 * synchronization.
04ba3554 482 *
7f38b742
GB
483 * If the directory does not exist, it will be created. A return value of
484 * <code>null</code> means either the trace resource does not exist or
485 * supplementary resources cannot be kept.
486 *
487 * @param absolute
488 * If <code>true</code>, it returns the absolute path in the file
489 * system, including the supplementary file path. Otherwise, it
490 * returns only the directory name.
04ba3554
GB
491 * @return The path to the folder where synchronization-related
492 * supplementary files can be kept or <code>null</code> if not
493 * available.
a465519a 494 * @since 3.2
04ba3554 495 */
7f38b742 496 public String getSynchronizationFolder(boolean absolute) {
04ba3554
GB
497 /* Set up the path to the synchronization file we'll use */
498 IResource resource = this.getResource();
499 String syncDirectory = null;
500
501 try {
502 /* get the directory where the file will be stored. */
503 if (resource != null) {
7f38b742 504 String fullDirectory = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER);
04ba3554 505 /* Create the synchronization data directory if not present */
7f38b742
GB
506 if (fullDirectory != null) {
507 fullDirectory = fullDirectory + File.separator + SYNCHRONIZATION_DIRECTORY;
508 File syncDir = new File(fullDirectory);
04ba3554
GB
509 syncDir.mkdirs();
510 }
7f38b742
GB
511 if (absolute) {
512 syncDirectory = fullDirectory;
513 } else {
514 syncDirectory = SYNCHRONIZATION_DIRECTORY;
515 }
04ba3554
GB
516 }
517 } catch (CoreException e) {
518 return null;
519 }
520
521 return syncDirectory;
522 }
523
e73a4ba5
GB
524 /**
525 * Synchronizes the traces of an experiment. By default it only tries to
526 * read a synchronization file if it exists
527 *
528 * @return The synchronization object
e73a4ba5
GB
529 * @since 3.0
530 */
4d2a4a2c 531 public SynchronizationAlgorithm synchronizeTraces() {
e73a4ba5
GB
532 return synchronizeTraces(false);
533 }
534
535 /**
536 * Synchronizes the traces of an experiment.
537 *
538 * @param doSync
539 * Whether to actually synchronize or just try opening a sync
540 * file
541 * @return The synchronization object
e73a4ba5
GB
542 * @since 3.0
543 */
4d2a4a2c
GB
544 public SynchronizationAlgorithm synchronizeTraces(boolean doSync) {
545 fSyncLock.lock();
e73a4ba5 546
4d2a4a2c
GB
547 try {
548 String syncDirectory = getSynchronizationFolder(true);
e73a4ba5 549
4d2a4a2c 550 final File syncFile = (syncDirectory != null) ? new File(syncDirectory + File.separator + SYNCHRONIZATION_FILE_NAME) : null;
e73a4ba5 551
4d2a4a2c 552 final SynchronizationAlgorithm syncAlgo = SynchronizationManager.synchronizeTraces(syncFile, Collections.<ITmfTrace> singleton(this), doSync);
e73a4ba5 553
4d2a4a2c 554 final TmfTraceSynchronizedSignal signal = new TmfTraceSynchronizedSignal(this, syncAlgo);
e73a4ba5 555
4d2a4a2c
GB
556 /* Broadcast in separate thread to prevent deadlock */
557 new Thread() {
558 @Override
559 public void run() {
560 broadcast(signal);
561 }
562 }.start();
e73a4ba5 563
4d2a4a2c
GB
564 return syncAlgo;
565 } finally {
566 fSyncLock.unlock();
567 }
e73a4ba5
GB
568 }
569
a79913eb 570 @Override
3b38ea61 571 @SuppressWarnings("nls")
5419a136 572 public synchronized String toString() {
a79913eb
FC
573 return "[TmfExperiment (" + getName() + ")]";
574 }
8c8bf09f
ASL
575
576 // ------------------------------------------------------------------------
9e0640dc 577 // Streaming support
8c8bf09f
ASL
578 // ------------------------------------------------------------------------
579
1b70b6dc 580 private synchronized void initializeStreamingMonitor() {
9e0640dc
FC
581
582 if (fInitialized) {
828e5592 583 return;
9e0640dc 584 }
828e5592
PT
585 fInitialized = true;
586
1b70b6dc 587 if (getStreamingInterval() == 0) {
0316808c 588 final ITmfContext context = seekEvent(0);
cbdacf03 589 final ITmfEvent event = getNext(context);
4c9f2944 590 context.dispose();
9b749023 591 if (event == null) {
1b70b6dc 592 return;
9b749023 593 }
4593bd5b 594 final TmfTimeRange timeRange = new TmfTimeRange(event.getTimestamp(), TmfTimestamp.BIG_CRUNCH);
faa38350 595 final TmfTraceRangeUpdatedSignal signal = new TmfTraceRangeUpdatedSignal(this, this, timeRange);
828e5592
PT
596
597 // Broadcast in separate thread to prevent deadlock
598 new Thread() {
599 @Override
600 public void run() {
601 broadcast(signal);
602 }
603 }.start();
1b70b6dc
PT
604 return;
605 }
606
9e0640dc 607 final Thread thread = new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$
bcbea6a6 608 private ITmfTimestamp safeTimestamp = null;
6be2d5cc 609 private ITmfTimestamp lastSafeTimestamp = null;
bcbea6a6 610 private TmfTimeRange timeRange = null;
1b70b6dc
PT
611
612 @Override
613 public void run() {
fc7cd0be 614 while (!executorIsShutdown()) {
9e0640dc 615 if (!getIndexer().isIndexing()) {
a4115405
FC
616 ITmfTimestamp startTimestamp = TmfTimestamp.BIG_CRUNCH;
617 ITmfTimestamp endTimestamp = TmfTimestamp.BIG_BANG;
fa62dc1d
BH
618
619 for (final ITmfTrace trace : getChildren(ITmfTrace.class)) {
9b749023 620 if (trace.getStartTime().compareTo(startTimestamp) < 0) {
1b70b6dc 621 startTimestamp = trace.getStartTime();
9b749023
AM
622 }
623 if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0) {
1b70b6dc 624 endTimestamp = trace.getEndTime();
9b749023 625 }
1b70b6dc 626 }
065cc19b 627 if (safeTimestamp != null && (lastSafeTimestamp == null || safeTimestamp.compareTo(lastSafeTimestamp) > 0)) {
1b70b6dc 628 timeRange = new TmfTimeRange(startTimestamp, safeTimestamp);
6be2d5cc 629 lastSafeTimestamp = safeTimestamp;
9b749023 630 } else {
1b70b6dc 631 timeRange = null;
9b749023 632 }
1b70b6dc
PT
633 safeTimestamp = endTimestamp;
634 if (timeRange != null) {
faa38350
PT
635 final TmfTraceRangeUpdatedSignal signal =
636 new TmfTraceRangeUpdatedSignal(TmfExperiment.this, TmfExperiment.this, timeRange);
1b70b6dc
PT
637 broadcast(signal);
638 }
639 }
640 try {
641 Thread.sleep(getStreamingInterval());
cbdacf03 642 } catch (final InterruptedException e) {
1b70b6dc
PT
643 e.printStackTrace();
644 }
645 }
646 }
647 };
648 thread.start();
649 }
650
1b70b6dc
PT
651 @Override
652 public long getStreamingInterval() {
653 long interval = 0;
fa62dc1d 654 for (final ITmfTrace trace : getChildren(ITmfTrace.class)) {
1b70b6dc 655 interval = Math.max(interval, trace.getStreamingInterval());
9b749023 656 }
1b70b6dc
PT
657 return interval;
658 }
659
8c8bf09f
ASL
660 // ------------------------------------------------------------------------
661 // Signal handlers
662 // ------------------------------------------------------------------------
663
faa38350 664 @Override
9e0640dc 665 @TmfSignalHandler
faa38350 666 public void traceOpened(TmfTraceOpenedSignal signal) {
9e0640dc 667 if (signal.getTrace() == this) {
faa38350 668 initializeStreamingMonitor();
9928ddeb
GB
669
670 /* Initialize the analysis */
671 MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
672 status.add(executeAnalysis());
673 if (!status.isOK()) {
674 Activator.log(status);
675 }
b5e8ee95 676 TmfTraceManager.refreshSupplementaryFiles(this);
9e0640dc 677 }
a1091415
PT
678 }
679
c4767854
AM
680 /**
681 * @since 3.0
682 */
032ecd45
MAL
683 @Override
684 public synchronized int getCheckpointSize() {
685 int totalCheckpointSize = 0;
686 try {
fa62dc1d
BH
687 List<ITmfTrace> children = getChildren(ITmfTrace.class);
688 for (ITmfTrace trace : children) {
689 if (!(trace instanceof ITmfPersistentlyIndexable)) {
690 return 0;
691 }
032ecd45 692
fa62dc1d
BH
693 ITmfPersistentlyIndexable persistableIndexTrace = (ITmfPersistentlyIndexable) trace;
694 int currentTraceCheckpointSize = persistableIndexTrace.getCheckpointSize();
695 if (currentTraceCheckpointSize <= 0) {
696 return 0;
032ecd45 697 }
fa62dc1d
BH
698 totalCheckpointSize += currentTraceCheckpointSize;
699 // each entry in the TmfLocationArray has a rank in addition
700 // of the location
701 totalCheckpointSize += 8;
032ecd45
MAL
702 }
703 } catch (UnsupportedOperationException e) {
704 return 0;
705 }
706
707 return totalCheckpointSize;
708 }
709
c4767854
AM
710 /**
711 * @since 3.0
712 */
032ecd45
MAL
713 @Override
714 public ITmfLocation restoreLocation(ByteBuffer bufferIn) {
fa62dc1d
BH
715 List<ITmfTrace> children = getChildren(ITmfTrace.class);
716 int length = children.size();
717 ITmfLocation[] locations = new ITmfLocation[length];
718 long[] ranks = new long[length];
719 for (int i = 0; i < length; ++i) {
720 final ITmfTrace trace = children.get(i);
032ecd45
MAL
721 locations[i] = ((ITmfPersistentlyIndexable) trace).restoreLocation(bufferIn);
722 ranks[i] = bufferIn.getLong();
723 }
724 TmfLocationArray arr = new TmfLocationArray(locations, ranks);
725 TmfExperimentLocation l = new TmfExperimentLocation(arr);
726 return l;
727 }
4dc47e28 728}
This page took 0.131923 seconds and 5 git commands to generate.