Use the NonNull utility methods where we can
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / trace / TmfTrace.java
CommitLineData
8c8bf09f 1/*******************************************************************************
089a4872 2 * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal
0bfb7d06 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
0bfb7d06 8 *
8c8bf09f 9 * Contributors:
20658947
FC
10 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Updated as per TMF Trace Model 1.0
ea271da6 12 * Patrick Tasse - Updated for removal of context clone
e73a4ba5
GB
13 * Geneviève Bastien - Added timestamp transforms, its saving to file and
14 * timestamp creation functions
8c8bf09f
ASL
15 *******************************************************************************/
16
2bdf0193 17package org.eclipse.tracecompass.tmf.core.trace;
8c8bf09f 18
5db5a3a4
AM
19import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
20
6f4a1d2b 21import java.io.File;
b04903a2 22import java.util.Collection;
35c160d9 23import java.util.Collections;
ff3f02c8 24import java.util.HashSet;
35c160d9 25import java.util.LinkedHashMap;
a51b2b9f 26import java.util.Map;
ff3f02c8 27import java.util.Set;
8c8bf09f 28
828e5592 29import org.eclipse.core.resources.IResource;
42459d24 30import org.eclipse.core.runtime.IStatus;
b22a582a 31import org.eclipse.core.runtime.MultiStatus;
032ecd45 32import org.eclipse.core.runtime.Path;
42459d24 33import org.eclipse.core.runtime.Status;
ba27dd38 34import org.eclipse.jdt.annotation.NonNull;
2bdf0193
AM
35import org.eclipse.tracecompass.internal.tmf.core.Activator;
36import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
37import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
38import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
39import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider;
40import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
b04903a2 41import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
2bdf0193
AM
42import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
43import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
44import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
45import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
46import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
47import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
48import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal;
49import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal;
50import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform;
51import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory;
52import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
53import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
54import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
55import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
56import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer;
57import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer;
58import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
8c8bf09f 59
b04903a2
AM
60import com.google.common.collect.ImmutableList;
61
8c8bf09f 62/**
09e86496
FC
63 * Abstract implementation of ITmfTrace.
64 * <p>
13cb5f43
FC
65 * Since the concept of 'location' is trace specific, the concrete classes have
66 * to provide the related methods, namely:
67 * <ul>
68 * <li> public ITmfLocation<?> getCurrentLocation()
69 * <li> public double getLocationRatio(ITmfLocation<?> location)
70 * <li> public ITmfContext seekEvent(ITmfLocation<?> location)
71 * <li> public ITmfContext seekEvent(double ratio)
da1a4b39 72 * <li> public IStatus validate(IProject project, String path)
13cb5f43
FC
73 * </ul>
74 * A concrete trace must provide its corresponding parser. A common way to
75 * accomplish this is by making the concrete class extend TmfTrace and
76 * implement ITmfEventParser.
77 * <p>
6b44794a
MK
78 * When constructing an event, the concrete trace should use the trace's
79 * timestamp transform to create the timestamp, by either transforming the
80 * parsed time value directly or by using the method createTimestamp().
81 * <p>
13cb5f43
FC
82 * The concrete class can either specify its own indexer or use the provided
83 * TmfCheckpointIndexer (default). In this case, the trace cache size will be
84 * used as checkpoint interval.
0bfb7d06 85 *
f7703ed6
FC
86 * @version 1.0
87 * @author Francois Chouinard
88 *
f7703ed6
FC
89 * @see ITmfEvent
90 * @see ITmfTraceIndexer
91 * @see ITmfEventParser
8c8bf09f 92 */
6fd3c6e9 93public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace, ITmfTraceCompleteness {
62d1696a 94
e31e01e8 95 // ------------------------------------------------------------------------
b04903a2
AM
96 // Class attributes
97 // ------------------------------------------------------------------------
98
99 /**
100 * Basic aspects that should be valid for all trace types.
101 */
8192209b 102 public static final @NonNull Collection<ITmfEventAspect> BASE_ASPECTS =
5db5a3a4 103 checkNotNull(ImmutableList.of(
b04903a2
AM
104 ITmfEventAspect.BaseAspects.TIMESTAMP,
105 ITmfEventAspect.BaseAspects.EVENT_TYPE,
106 ITmfEventAspect.BaseAspects.CONTENTS
5db5a3a4 107 ));
b04903a2
AM
108
109 // ------------------------------------------------------------------------
110 // Instance attributes
e31e01e8 111 // ------------------------------------------------------------------------
8c8bf09f 112
09e86496
FC
113 // The resource used for persistent properties for this trace
114 private IResource fResource;
115
b0a282fb 116 // The trace path
12c155f5 117 private String fPath;
b0a282fb 118
0316808c
FC
119 // The trace cache page size
120 private int fCacheSize = ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
62d1696a 121
0316808c 122 // The number of events collected (so far)
e9a6e38e 123 private volatile long fNbEvents = 0;
62d1696a
FC
124
125 // The time span of the event stream
9cbe7899 126 private ITmfTimestamp fStartTime = TmfTimestamp.BIG_BANG;
a4115405 127 private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG;
62d1696a 128
0316808c
FC
129 // The trace streaming interval (0 = no streaming)
130 private long fStreamingInterval = 0;
085d898f 131
0316808c 132 // The trace indexer
6256d8ad 133 private ITmfTraceIndexer fIndexer;
20658947 134
0316808c 135 // The trace parser
6256d8ad 136 private ITmfEventParser fParser;
7e6347b0 137
e73a4ba5
GB
138 private ITmfTimestampTransform fTsTransform;
139
ff3f02c8
AM
140 private final Map<String, IAnalysisModule> fAnalysisModules =
141 Collections.synchronizedMap(new LinkedHashMap<String, IAnalysisModule>());
c068a752 142
e31e01e8 143 // ------------------------------------------------------------------------
3791b5df 144 // Construction
e31e01e8 145 // ------------------------------------------------------------------------
8c8bf09f 146
62d1696a 147 /**
3791b5df 148 * The default, parameterless, constructor
62d1696a 149 */
3791b5df
FC
150 public TmfTrace() {
151 super();
ab186fbb 152 fIndexer = createIndexer(DEFAULT_BLOCK_SIZE);
05bd3318
FC
153 }
154
155 /**
8cf330ae 156 * Full constructor.
0bfb7d06 157 *
8cf330ae
AM
158 * @param resource
159 * The resource associated to the trace
160 * @param type
161 * The type of events that will be read from this trace
162 * @param path
163 * The path to the trace on the filesystem
164 * @param cacheSize
165 * The trace cache size. Pass '-1' to use the default specified
166 * in {@link ITmfTrace#DEFAULT_TRACE_CACHE_SIZE}
167 * @param interval
168 * The trace streaming interval. You can use '0' for post-mortem
169 * traces.
8cf330ae
AM
170 * @param parser
171 * The trace event parser. Use 'null' if (and only if) the trace
172 * object itself is also the ITmfEventParser to be used.
173 * @throws TmfTraceException
174 * If something failed during the opening
20658947 175 */
8cf330ae
AM
176 protected TmfTrace(final IResource resource,
177 final Class<? extends ITmfEvent> type,
178 final String path,
179 final int cacheSize,
180 final long interval,
8cf330ae
AM
181 final ITmfEventParser parser)
182 throws TmfTraceException {
00641a97 183 super();
0316808c 184 fCacheSize = (cacheSize > 0) ? cacheSize : ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
3791b5df 185 fStreamingInterval = interval;
13cb5f43 186 fParser = parser;
09e86496 187 initialize(resource, path, type);
8c8bf09f
ASL
188 }
189
3791b5df
FC
190 /**
191 * Copy constructor
0bfb7d06 192 *
3791b5df 193 * @param trace the original trace
063f0d27 194 * @throws TmfTraceException Should not happen usually
3791b5df 195 */
6256d8ad 196 public TmfTrace(final TmfTrace trace) throws TmfTraceException {
3791b5df 197 super();
0316808c 198 if (trace == null) {
3791b5df 199 throw new IllegalArgumentException();
0316808c 200 }
20658947
FC
201 fCacheSize = trace.getCacheSize();
202 fStreamingInterval = trace.getStreamingInterval();
13cb5f43
FC
203 fParser = trace.fParser;
204 initialize(trace.getResource(), trace.getPath(), trace.getEventType());
3791b5df
FC
205 }
206
032ecd45
MAL
207 /**
208 * Creates the indexer instance. Classes extending this class can override
209 * this to provide a different indexer implementation.
210 *
211 * @param interval the checkpoints interval
212 *
213 * @return the indexer
214 * @since 3.0
215 */
216 protected ITmfTraceIndexer createIndexer(int interval) {
217 return new TmfCheckpointIndexer(this, interval);
218 }
219
7e6347b0
FC
220 // ------------------------------------------------------------------------
221 // ITmfTrace - Initializers
222 // ------------------------------------------------------------------------
223
339d539c
PT
224 @Override
225 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type, String name) throws TmfTraceException {
6d8922ce
GB
226 if (name == null) {
227 throw new IllegalArgumentException();
228 }
339d539c
PT
229 setName(name);
230 initTrace(resource, path, type);
231 }
232
7e6347b0 233 @Override
6256d8ad 234 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException {
7e6347b0 235 initialize(resource, path, type);
7e6347b0
FC
236 }
237
09e86496 238 /**
1703b536 239 * Initialize the trace common attributes and the base component.
0bfb7d06
MK
240 *
241 * @param resource the Eclipse resource (trace)
1703b536
FC
242 * @param path the trace path
243 * @param type the trace event type
0bfb7d06 244 *
6f4e8ec0 245 * @throws TmfTraceException If something failed during the initialization
3791b5df 246 */
248af329
AM
247 protected void initialize(final IResource resource,
248 final String path,
249 final Class<? extends ITmfEvent> type)
250 throws TmfTraceException {
0316808c 251 if (path == null) {
b4f71e4a 252 throw new TmfTraceException("Invalid trace path"); //$NON-NLS-1$
0316808c 253 }
3791b5df 254 fPath = path;
1703b536 255 fResource = resource;
339d539c 256 String traceName = getName();
d40ddf8a 257 if (traceName.isEmpty()) {
339d539c 258 traceName = (resource != null) ? resource.getName() : new Path(path).lastSegment();
1703b536 259 }
2352aed9
FC
260 if (fParser == null) {
261 if (this instanceof ITmfEventParser) {
6256d8ad 262 fParser = (ITmfEventParser) this;
2352aed9
FC
263 } else {
264 throw new TmfTraceException("Invalid trace parser"); //$NON-NLS-1$
265 }
266 }
3791b5df 267 super.init(traceName, type);
fec1ac0b
BH
268 // register as VIP after super.init() because TmfComponent registers to signal manager there
269 TmfSignalManager.registerVIP(this);
1a3f1ec3
GB
270 if (fIndexer != null) {
271 fIndexer.dispose();
272 }
ab186fbb 273 fIndexer = createIndexer(fCacheSize);
3791b5df
FC
274 }
275
2352aed9
FC
276 /**
277 * Indicates if the path points to an existing file/directory
0bfb7d06 278 *
2352aed9
FC
279 * @param path the path to test
280 * @return true if the file/directory exists
3791b5df 281 */
2352aed9 282 protected boolean fileExists(final String path) {
085d898f 283 final File file = new File(path);
3791b5df
FC
284 return file.exists();
285 }
286
c7e1020d 287 /**
51e75066 288 * @since 2.0
c7e1020d 289 */
51e75066
AM
290 @Override
291 public void indexTrace(boolean waitForCompletion) {
9e0640dc 292 getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, waitForCompletion);
c7e1020d
FC
293 }
294
c068a752
GB
295 /**
296 * Instantiate the applicable analysis modules and executes the analysis
297 * modules that are meant to be automatically executed
298 *
299 * @return An IStatus indicating whether the analysis could be run
300 * successfully or not
301 * @since 3.0
302 */
303 protected IStatus executeAnalysis() {
304 MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
ba27dd38 305
5db5a3a4 306 Class<? extends TmfTrace> className = checkNotNull(this.getClass());
ba27dd38 307 Map<String, IAnalysisModuleHelper> modules = TmfAnalysisManager.getAnalysisModules(className);
c068a752
GB
308 for (IAnalysisModuleHelper helper : modules.values()) {
309 try {
310 IAnalysisModule module = helper.newModule(this);
311 fAnalysisModules.put(module.getId(), module);
312 if (module.isAutomatic()) {
313 status.add(module.schedule());
314 }
315 } catch (TmfAnalysisException e) {
26683871 316 status.add(new Status(IStatus.WARNING, Activator.PLUGIN_ID, e.getMessage()));
c068a752
GB
317 }
318 }
319 return status;
320 }
321
c4767854
AM
322 /**
323 * @since 3.0
324 */
c068a752 325 @Override
ff3f02c8 326 public IAnalysisModule getAnalysisModule(String analysisId) {
c068a752
GB
327 return fAnalysisModules.get(analysisId);
328 }
329
ff3f02c8
AM
330
331 /**
332 * @since 3.0
333 */
334 @Override
335 public Iterable<IAnalysisModule> getAnalysisModules() {
336 synchronized (fAnalysisModules) {
337 Set<IAnalysisModule> modules = new HashSet<>(fAnalysisModules.values());
338 return modules;
339 }
340 }
341
b04903a2
AM
342 @Override
343 public Iterable<ITmfEventAspect> getEventAspects() {
344 /* By default we provide only the base aspects valid for all trace types */
345 return BASE_ASPECTS;
346 }
347
b5ee6881
FC
348 /**
349 * Clears the trace
350 */
351 @Override
352 public synchronized void dispose() {
1a4205d9 353 /* Clean up the index if applicable */
77551cc2
FC
354 if (getIndexer() != null) {
355 getIndexer().dispose();
356 }
1a4205d9 357
a1529f38 358 /* Clean up the analysis modules */
ff3f02c8
AM
359 synchronized (fAnalysisModules) {
360 for (IAnalysisModule module : fAnalysisModules.values()) {
361 module.dispose();
362 }
6ef5ae35 363 fAnalysisModules.clear();
a1529f38
AM
364 }
365
b5ee6881
FC
366 super.dispose();
367 }
368
3791b5df 369 // ------------------------------------------------------------------------
09e86496 370 // ITmfTrace - Basic getters
e31e01e8 371 // ------------------------------------------------------------------------
8c8bf09f 372
25e48683 373 @Override
0f89d4ba
AM
374 public Class<? extends ITmfEvent> getEventType() {
375 return super.getType();
25e48683
FC
376 }
377
d4011df2 378 @Override
09e86496
FC
379 public IResource getResource() {
380 return fResource;
8c8bf09f
ASL
381 }
382
d4011df2 383 @Override
09e86496
FC
384 public String getPath() {
385 return fPath;
8c8bf09f
ASL
386 }
387
20658947
FC
388 @Override
389 public int getCacheSize() {
390 return fCacheSize;
391 }
392
20658947
FC
393 @Override
394 public long getStreamingInterval() {
395 return fStreamingInterval;
396 }
397
0316808c
FC
398 /**
399 * @return the trace indexer
a3db8436 400 * @since 3.0
0316808c 401 */
6256d8ad 402 protected ITmfTraceIndexer getIndexer() {
0316808c
FC
403 return fIndexer;
404 }
405
406 /**
407 * @return the trace parser
408 */
6256d8ad 409 protected ITmfEventParser getParser() {
0316808c
FC
410 return fParser;
411 }
412
09e86496
FC
413 // ------------------------------------------------------------------------
414 // ITmfTrace - Trace characteristics getters
415 // ------------------------------------------------------------------------
416
d4011df2 417 @Override
e9a6e38e 418 public long getNbEvents() {
3791b5df 419 return fNbEvents;
b0a282fb
FC
420 }
421
3bd46eef
AM
422 /**
423 * @since 2.0
62d1696a 424 */
d4011df2 425 @Override
12c155f5 426 public TmfTimeRange getTimeRange() {
cb866e08 427 return new TmfTimeRange(fStartTime, fEndTime);
8c8bf09f
ASL
428 }
429
3bd46eef
AM
430 /**
431 * @since 2.0
e31e01e8 432 */
d4011df2 433 @Override
4df4581d 434 public ITmfTimestamp getStartTime() {
4593bd5b 435 return fStartTime;
146a887c
FC
436 }
437
3bd46eef
AM
438 /**
439 * @since 2.0
e31e01e8 440 */
d4011df2 441 @Override
4df4581d 442 public ITmfTimestamp getEndTime() {
4593bd5b 443 return fEndTime;
20658947
FC
444 }
445
d7ee91bb 446 /**
d7ee91bb
PT
447 * @since 2.0
448 */
66262ad8
BH
449 @Override
450 public ITmfTimestamp getInitialRangeOffset() {
d7ee91bb
PT
451 final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec
452 return new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE);
453 }
454
bb52f9bc
GB
455 /**
456 * @since 3.0
457 */
458 @Override
459 public String getHostId() {
460 return this.getName();
461 }
462
20658947 463 // ------------------------------------------------------------------------
d7ee91bb 464 // Convenience setters
20658947
FC
465 // ------------------------------------------------------------------------
466
0316808c
FC
467 /**
468 * Set the trace cache size. Must be done at initialization time.
0bfb7d06 469 *
0316808c
FC
470 * @param cacheSize The trace cache size
471 */
472 protected void setCacheSize(final int cacheSize) {
473 fCacheSize = cacheSize;
474 }
475
476 /**
477 * Set the trace known number of events. This can be quite dynamic
478 * during indexing or for live traces.
0bfb7d06 479 *
0316808c
FC
480 * @param nbEvents The number of events
481 */
482 protected synchronized void setNbEvents(final long nbEvents) {
483 fNbEvents = (nbEvents > 0) ? nbEvents : 0;
484 }
485
20658947
FC
486 /**
487 * Update the trace events time range
0bfb7d06 488 *
20658947 489 * @param range the new time range
3bd46eef 490 * @since 2.0
20658947
FC
491 */
492 protected void setTimeRange(final TmfTimeRange range) {
4593bd5b
AM
493 fStartTime = range.getStartTime();
494 fEndTime = range.getEndTime();
20658947
FC
495 }
496
497 /**
498 * Update the trace chronologically first event timestamp
0bfb7d06 499 *
20658947 500 * @param startTime the new first event timestamp
3bd46eef 501 * @since 2.0
20658947
FC
502 */
503 protected void setStartTime(final ITmfTimestamp startTime) {
4593bd5b 504 fStartTime = startTime;
20658947
FC
505 }
506
507 /**
508 * Update the trace chronologically last event timestamp
0bfb7d06 509 *
20658947 510 * @param endTime the new last event timestamp
3bd46eef 511 * @since 2.0
20658947
FC
512 */
513 protected void setEndTime(final ITmfTimestamp endTime) {
4593bd5b 514 fEndTime = endTime;
20658947
FC
515 }
516
517 /**
0316808c 518 * Set the polling interval for live traces (default = 0 = no streaming).
0bfb7d06 519 *
20658947
FC
520 * @param interval the new trace streaming interval
521 */
522 protected void setStreamingInterval(final long interval) {
1703b536 523 fStreamingInterval = (interval > 0) ? interval : 0;
146a887c
FC
524 }
525
0316808c
FC
526 /**
527 * Set the trace parser. Must be done at initialization time.
0bfb7d06 528 *
0316808c
FC
529 * @param parser the new trace parser
530 */
6256d8ad 531 protected void setParser(final ITmfEventParser parser) {
0316808c
FC
532 fParser = parser;
533 }
534
09e86496 535 // ------------------------------------------------------------------------
7e6347b0 536 // ITmfTrace - SeekEvent operations (returning a trace context)
09e86496
FC
537 // ------------------------------------------------------------------------
538
1b70b6dc 539 @Override
7e6347b0 540 public synchronized ITmfContext seekEvent(final long rank) {
09e86496 541
7e6347b0 542 // A rank <= 0 indicates to seek the first event
2352aed9 543 if (rank <= 0) {
1e1bef82 544 ITmfContext context = seekEvent((ITmfLocation) null);
2352aed9
FC
545 context.setRank(0);
546 return context;
547 }
09e86496 548
09e86496 549 // Position the trace at the checkpoint
7e6347b0 550 final ITmfContext context = fIndexer.seekIndex(rank);
09e86496
FC
551
552 // And locate the requested event context
7e6347b0
FC
553 long pos = context.getRank();
554 if (pos < rank) {
c32744d6 555 ITmfEvent event = getNext(context);
0bfb7d06 556 while ((event != null) && (++pos < rank)) {
c32744d6 557 event = getNext(context);
7e6347b0 558 }
09e86496
FC
559 }
560 return context;
1b70b6dc
PT
561 }
562
3bd46eef
AM
563 /**
564 * @since 2.0
09e86496
FC
565 */
566 @Override
7e6347b0 567 public synchronized ITmfContext seekEvent(final ITmfTimestamp timestamp) {
09e86496 568
7e6347b0 569 // A null timestamp indicates to seek the first event
2352aed9 570 if (timestamp == null) {
1e1bef82 571 ITmfContext context = seekEvent((ITmfLocation) null);
2352aed9
FC
572 context.setRank(0);
573 return context;
574 }
09e86496 575
1703b536 576 // Position the trace at the checkpoint
408e65d2 577 ITmfContext context = fIndexer.seekIndex(timestamp);
09e86496
FC
578
579 // And locate the requested event context
ea271da6
PT
580 ITmfLocation previousLocation = context.getLocation();
581 long previousRank = context.getRank();
582 ITmfEvent event = getNext(context);
065cc19b 583 while (event != null && event.getTimestamp().compareTo(timestamp) < 0) {
ea271da6
PT
584 previousLocation = context.getLocation();
585 previousRank = context.getRank();
586 event = getNext(context);
09e86496 587 }
0316808c
FC
588 if (event == null) {
589 context.setLocation(null);
590 context.setRank(ITmfContext.UNKNOWN_RANK);
ea271da6
PT
591 } else {
592 context.dispose();
593 context = seekEvent(previousLocation);
594 context.setRank(previousRank);
0316808c 595 }
09e86496
FC
596 return context;
597 }
0283f7ff 598
09e86496
FC
599 // ------------------------------------------------------------------------
600 // ITmfTrace - Read operations (returning an actual event)
601 // ------------------------------------------------------------------------
602
d4011df2 603 @Override
6256d8ad 604 public synchronized ITmfEvent getNext(final ITmfContext context) {
09e86496 605 // parseEvent() does not update the context
6256d8ad 606 final ITmfEvent event = fParser.parseEvent(context);
09e86496 607 if (event != null) {
d337369a 608 updateAttributes(context, event.getTimestamp());
09e86496
FC
609 context.setLocation(getCurrentLocation());
610 context.increaseRank();
611 processEvent(event);
612 }
613 return event;
614 }
615
616 /**
d337369a 617 * Hook for special event processing by the concrete class
7e6347b0 618 * (called by TmfTrace.getEvent())
0bfb7d06 619 *
d337369a 620 * @param event the event
09e86496
FC
621 */
622 protected void processEvent(final ITmfEvent event) {
d337369a 623 // Do nothing
09e86496
FC
624 }
625
d337369a
FC
626 /**
627 * Update the trace attributes
0bfb7d06 628 *
d337369a 629 * @param context the current trace context
2848c377 630 * @param timestamp the corresponding timestamp
3bd46eef 631 * @since 2.0
d337369a
FC
632 */
633 protected synchronized void updateAttributes(final ITmfContext context, final ITmfTimestamp timestamp) {
065cc19b 634 if (fStartTime.equals(TmfTimestamp.BIG_BANG) || (fStartTime.compareTo(timestamp) > 0)) {
4593bd5b 635 fStartTime = timestamp;
09e86496 636 }
065cc19b 637 if (fEndTime.equals(TmfTimestamp.BIG_CRUNCH) || (fEndTime.compareTo(timestamp) < 0)) {
4593bd5b 638 fEndTime = timestamp;
09e86496
FC
639 }
640 if (context.hasValidRank()) {
d337369a 641 long rank = context.getRank();
09e86496
FC
642 if (fNbEvents <= rank) {
643 fNbEvents = rank + 1;
644 }
200789b3
AM
645 if (fIndexer != null) {
646 fIndexer.updateIndex(context, timestamp);
647 }
09e86496 648 }
abfad0aa
FC
649 }
650
3791b5df 651 // ------------------------------------------------------------------------
d337369a 652 // TmfDataProvider
3791b5df
FC
653 // ------------------------------------------------------------------------
654
77c4a6df
AM
655 /**
656 * @since 2.0
d337369a 657 */
3791b5df 658 @Override
fd3f1eff 659 public synchronized ITmfContext armRequest(final ITmfEventRequest request) {
faa38350
PT
660 if (executorIsShutdown()) {
661 return null;
662 }
fd3f1eff
AM
663 if (!TmfTimestamp.BIG_BANG.equals(request.getRange().getStartTime())
664 && (request.getIndex() == 0)) {
665 final ITmfContext context = seekEvent(request.getRange().getStartTime());
666 request.setStartIndex((int) context.getRank());
8584dc20 667 return context;
8584dc20 668
5419a136
AM
669 }
670 return seekEvent(request.getIndex());
3791b5df
FC
671 }
672
faa38350
PT
673 // ------------------------------------------------------------------------
674 // Signal handlers
675 // ------------------------------------------------------------------------
676
677 /**
678 * Handler for the Trace Opened signal
679 *
680 * @param signal
681 * The incoming signal
682 * @since 2.0
683 */
684 @TmfSignalHandler
685 public void traceOpened(TmfTraceOpenedSignal signal) {
b9a5bf8f
AM
686 boolean signalIsForUs = false;
687 for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) {
688 if (trace == this) {
689 signalIsForUs = true;
fe0c44c4 690 break;
faa38350
PT
691 }
692 }
faa38350 693
b9a5bf8f 694 if (!signalIsForUs) {
fe0c44c4
AM
695 return;
696 }
697
698 /*
b9a5bf8f 699 * The signal is either for this trace, or for an experiment containing
fe0c44c4
AM
700 * this trace.
701 */
be4a197a 702 IStatus status = executeAnalysis();
b22a582a
AM
703 if (!status.isOK()) {
704 Activator.log(status);
fe0c44c4
AM
705 }
706
b5e8ee95 707 TmfTraceManager.refreshSupplementaryFiles(this);
fe0c44c4 708
faa38350 709 if (signal.getTrace() == this) {
f8fc4a3a 710 /* Additionally, the signal is directly for this trace. */
faa38350
PT
711 if (getNbEvents() == 0) {
712 return;
713 }
714
f8fc4a3a
PT
715 /* For a streaming trace, the range updated signal should be sent
716 * by the subclass when a new safe time is determined.
717 */
718 if (getStreamingInterval() > 0) {
719 return;
720 }
721
6fd3c6e9
MAL
722 if (isComplete()) {
723 final TmfTimeRange timeRange = new TmfTimeRange(getStartTime(), TmfTimestamp.BIG_CRUNCH);
724 final TmfTraceRangeUpdatedSignal rangeUpdatedsignal = new TmfTraceRangeUpdatedSignal(this, this, timeRange);
faa38350 725
6fd3c6e9
MAL
726 // Broadcast in separate thread to prevent deadlock
727 broadcastAsync(rangeUpdatedsignal);
728 }
faa38350
PT
729 return;
730 }
731 }
732
733 /**
734 * Signal handler for the TmfTraceRangeUpdatedSignal signal
735 *
736 * @param signal The incoming signal
737 * @since 2.0
738 */
739 @TmfSignalHandler
740 public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal) {
741 if (signal.getTrace() == this) {
742 getIndexer().buildIndex(getNbEvents(), signal.getRange(), false);
743 }
744 }
745
032ecd45
MAL
746 /**
747 * Signal handler for the TmfTraceUpdatedSignal signal
748 *
749 * @param signal The incoming signal
c4767854 750 * @since 3.0
032ecd45
MAL
751 */
752 @TmfSignalHandler
753 public void traceUpdated(final TmfTraceUpdatedSignal signal) {
754 if (signal.getSource() == getIndexer()) {
755 fNbEvents = signal.getNbEvents();
756 fStartTime = signal.getRange().getStartTime();
757 fEndTime = signal.getRange().getEndTime();
758 }
759 }
760
e73a4ba5
GB
761 // ------------------------------------------------------------------------
762 // Timestamp transformation functions
763 // ------------------------------------------------------------------------
764
765 /**
766 * @since 3.0
767 */
768 @Override
769 public ITmfTimestampTransform getTimestampTransform() {
770 if (fTsTransform == null) {
6b44794a 771 fTsTransform = TimestampTransformFactory.getTimestampTransform(getResource());
e73a4ba5
GB
772 }
773 return fTsTransform;
774 }
775
776 /**
777 * @since 3.0
778 */
779 @Override
780 public void setTimestampTransform(final ITmfTimestampTransform tt) {
781 fTsTransform = tt;
6b44794a 782 TimestampTransformFactory.setTimestampTransform(getResource(), tt);
e73a4ba5
GB
783 }
784
785 /**
786 * @since 3.0
787 */
788 @Override
789 public ITmfTimestamp createTimestamp(long ts) {
b2c463c5 790 return new TmfNanoTimestamp(getTimestampTransform().transform(ts));
e73a4ba5
GB
791 }
792
3791b5df 793 // ------------------------------------------------------------------------
09e86496 794 // toString
3791b5df
FC
795 // ------------------------------------------------------------------------
796
12c155f5 797 @Override
09e86496 798 @SuppressWarnings("nls")
5419a136 799 public synchronized String toString() {
20658947
FC
800 return "TmfTrace [fPath=" + fPath + ", fCacheSize=" + fCacheSize
801 + ", fNbEvents=" + fNbEvents + ", fStartTime=" + fStartTime
802 + ", fEndTime=" + fEndTime + ", fStreamingInterval=" + fStreamingInterval + "]";
12c155f5
FC
803 }
804
6fd3c6e9
MAL
805 /**
806 * @since 3.1
807 */
808 @Override
809 public boolean isComplete() {
810 /*
811 * Be default, all traces are "complete" which means no more data will
812 * be added later
813 */
814 return true;
815 }
816
817 /**
818 * @since 3.1
819 */
820 @Override
821 public void setComplete(boolean isComplete) {
822 /*
823 * This should be overridden by trace classes that can support live
824 * reading (traces in an incomplete state)
825 */
826 }
8c8bf09f 827}
This page took 0.131927 seconds and 5 git commands to generate.