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
1 /*******************************************************************************
2 * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Updated as per TMF Trace Model 1.0
12 * Patrick Tasse - Updated for removal of context clone
13 * Geneviève Bastien - Added timestamp transforms, its saving to file and
14 * timestamp creation functions
15 *******************************************************************************/
16
17 package org.eclipse.tracecompass.tmf.core.trace;
18
19 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
20
21 import java.io.File;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.LinkedHashMap;
26 import java.util.Map;
27 import java.util.Set;
28
29 import org.eclipse.core.resources.IResource;
30 import org.eclipse.core.runtime.IStatus;
31 import org.eclipse.core.runtime.MultiStatus;
32 import org.eclipse.core.runtime.Path;
33 import org.eclipse.core.runtime.Status;
34 import org.eclipse.jdt.annotation.NonNull;
35 import org.eclipse.tracecompass.internal.tmf.core.Activator;
36 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
37 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModuleHelper;
38 import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisManager;
39 import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider;
40 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
41 import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
42 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
43 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
44 import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
45 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
46 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
47 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
48 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceRangeUpdatedSignal;
49 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceUpdatedSignal;
50 import org.eclipse.tracecompass.tmf.core.synchronization.ITmfTimestampTransform;
51 import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory;
52 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
53 import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
54 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
55 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
56 import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfTraceIndexer;
57 import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer;
58 import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
59
60 import com.google.common.collect.ImmutableList;
61
62 /**
63 * Abstract implementation of ITmfTrace.
64 * <p>
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)
72 * <li> public IStatus validate(IProject project, String path)
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>
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>
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.
85 *
86 * @version 1.0
87 * @author Francois Chouinard
88 *
89 * @see ITmfEvent
90 * @see ITmfTraceIndexer
91 * @see ITmfEventParser
92 */
93 public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace, ITmfTraceCompleteness {
94
95 // ------------------------------------------------------------------------
96 // Class attributes
97 // ------------------------------------------------------------------------
98
99 /**
100 * Basic aspects that should be valid for all trace types.
101 */
102 public static final @NonNull Collection<ITmfEventAspect> BASE_ASPECTS =
103 checkNotNull(ImmutableList.of(
104 ITmfEventAspect.BaseAspects.TIMESTAMP,
105 ITmfEventAspect.BaseAspects.EVENT_TYPE,
106 ITmfEventAspect.BaseAspects.CONTENTS
107 ));
108
109 // ------------------------------------------------------------------------
110 // Instance attributes
111 // ------------------------------------------------------------------------
112
113 // The resource used for persistent properties for this trace
114 private IResource fResource;
115
116 // The trace path
117 private String fPath;
118
119 // The trace cache page size
120 private int fCacheSize = ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
121
122 // The number of events collected (so far)
123 private volatile long fNbEvents = 0;
124
125 // The time span of the event stream
126 private ITmfTimestamp fStartTime = TmfTimestamp.BIG_BANG;
127 private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG;
128
129 // The trace streaming interval (0 = no streaming)
130 private long fStreamingInterval = 0;
131
132 // The trace indexer
133 private ITmfTraceIndexer fIndexer;
134
135 // The trace parser
136 private ITmfEventParser fParser;
137
138 private ITmfTimestampTransform fTsTransform;
139
140 private final Map<String, IAnalysisModule> fAnalysisModules =
141 Collections.synchronizedMap(new LinkedHashMap<String, IAnalysisModule>());
142
143 // ------------------------------------------------------------------------
144 // Construction
145 // ------------------------------------------------------------------------
146
147 /**
148 * The default, parameterless, constructor
149 */
150 public TmfTrace() {
151 super();
152 fIndexer = createIndexer(DEFAULT_BLOCK_SIZE);
153 }
154
155 /**
156 * Full constructor.
157 *
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.
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
175 */
176 protected TmfTrace(final IResource resource,
177 final Class<? extends ITmfEvent> type,
178 final String path,
179 final int cacheSize,
180 final long interval,
181 final ITmfEventParser parser)
182 throws TmfTraceException {
183 super();
184 fCacheSize = (cacheSize > 0) ? cacheSize : ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
185 fStreamingInterval = interval;
186 fParser = parser;
187 initialize(resource, path, type);
188 }
189
190 /**
191 * Copy constructor
192 *
193 * @param trace the original trace
194 * @throws TmfTraceException Should not happen usually
195 */
196 public TmfTrace(final TmfTrace trace) throws TmfTraceException {
197 super();
198 if (trace == null) {
199 throw new IllegalArgumentException();
200 }
201 fCacheSize = trace.getCacheSize();
202 fStreamingInterval = trace.getStreamingInterval();
203 fParser = trace.fParser;
204 initialize(trace.getResource(), trace.getPath(), trace.getEventType());
205 }
206
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
220 // ------------------------------------------------------------------------
221 // ITmfTrace - Initializers
222 // ------------------------------------------------------------------------
223
224 @Override
225 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type, String name) throws TmfTraceException {
226 if (name == null) {
227 throw new IllegalArgumentException();
228 }
229 setName(name);
230 initTrace(resource, path, type);
231 }
232
233 @Override
234 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException {
235 initialize(resource, path, type);
236 }
237
238 /**
239 * Initialize the trace common attributes and the base component.
240 *
241 * @param resource the Eclipse resource (trace)
242 * @param path the trace path
243 * @param type the trace event type
244 *
245 * @throws TmfTraceException If something failed during the initialization
246 */
247 protected void initialize(final IResource resource,
248 final String path,
249 final Class<? extends ITmfEvent> type)
250 throws TmfTraceException {
251 if (path == null) {
252 throw new TmfTraceException("Invalid trace path"); //$NON-NLS-1$
253 }
254 fPath = path;
255 fResource = resource;
256 String traceName = getName();
257 if (traceName.isEmpty()) {
258 traceName = (resource != null) ? resource.getName() : new Path(path).lastSegment();
259 }
260 if (fParser == null) {
261 if (this instanceof ITmfEventParser) {
262 fParser = (ITmfEventParser) this;
263 } else {
264 throw new TmfTraceException("Invalid trace parser"); //$NON-NLS-1$
265 }
266 }
267 super.init(traceName, type);
268 // register as VIP after super.init() because TmfComponent registers to signal manager there
269 TmfSignalManager.registerVIP(this);
270 if (fIndexer != null) {
271 fIndexer.dispose();
272 }
273 fIndexer = createIndexer(fCacheSize);
274 }
275
276 /**
277 * Indicates if the path points to an existing file/directory
278 *
279 * @param path the path to test
280 * @return true if the file/directory exists
281 */
282 protected boolean fileExists(final String path) {
283 final File file = new File(path);
284 return file.exists();
285 }
286
287 /**
288 * @since 2.0
289 */
290 @Override
291 public void indexTrace(boolean waitForCompletion) {
292 getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, waitForCompletion);
293 }
294
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);
305
306 Class<? extends TmfTrace> className = checkNotNull(this.getClass());
307 Map<String, IAnalysisModuleHelper> modules = TmfAnalysisManager.getAnalysisModules(className);
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) {
316 status.add(new Status(IStatus.WARNING, Activator.PLUGIN_ID, e.getMessage()));
317 }
318 }
319 return status;
320 }
321
322 /**
323 * @since 3.0
324 */
325 @Override
326 public IAnalysisModule getAnalysisModule(String analysisId) {
327 return fAnalysisModules.get(analysisId);
328 }
329
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
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
348 /**
349 * Clears the trace
350 */
351 @Override
352 public synchronized void dispose() {
353 /* Clean up the index if applicable */
354 if (getIndexer() != null) {
355 getIndexer().dispose();
356 }
357
358 /* Clean up the analysis modules */
359 synchronized (fAnalysisModules) {
360 for (IAnalysisModule module : fAnalysisModules.values()) {
361 module.dispose();
362 }
363 fAnalysisModules.clear();
364 }
365
366 super.dispose();
367 }
368
369 // ------------------------------------------------------------------------
370 // ITmfTrace - Basic getters
371 // ------------------------------------------------------------------------
372
373 @Override
374 public Class<? extends ITmfEvent> getEventType() {
375 return super.getType();
376 }
377
378 @Override
379 public IResource getResource() {
380 return fResource;
381 }
382
383 @Override
384 public String getPath() {
385 return fPath;
386 }
387
388 @Override
389 public int getCacheSize() {
390 return fCacheSize;
391 }
392
393 @Override
394 public long getStreamingInterval() {
395 return fStreamingInterval;
396 }
397
398 /**
399 * @return the trace indexer
400 * @since 3.0
401 */
402 protected ITmfTraceIndexer getIndexer() {
403 return fIndexer;
404 }
405
406 /**
407 * @return the trace parser
408 */
409 protected ITmfEventParser getParser() {
410 return fParser;
411 }
412
413 // ------------------------------------------------------------------------
414 // ITmfTrace - Trace characteristics getters
415 // ------------------------------------------------------------------------
416
417 @Override
418 public long getNbEvents() {
419 return fNbEvents;
420 }
421
422 /**
423 * @since 2.0
424 */
425 @Override
426 public TmfTimeRange getTimeRange() {
427 return new TmfTimeRange(fStartTime, fEndTime);
428 }
429
430 /**
431 * @since 2.0
432 */
433 @Override
434 public ITmfTimestamp getStartTime() {
435 return fStartTime;
436 }
437
438 /**
439 * @since 2.0
440 */
441 @Override
442 public ITmfTimestamp getEndTime() {
443 return fEndTime;
444 }
445
446 /**
447 * @since 2.0
448 */
449 @Override
450 public ITmfTimestamp getInitialRangeOffset() {
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
455 /**
456 * @since 3.0
457 */
458 @Override
459 public String getHostId() {
460 return this.getName();
461 }
462
463 // ------------------------------------------------------------------------
464 // Convenience setters
465 // ------------------------------------------------------------------------
466
467 /**
468 * Set the trace cache size. Must be done at initialization time.
469 *
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.
479 *
480 * @param nbEvents The number of events
481 */
482 protected synchronized void setNbEvents(final long nbEvents) {
483 fNbEvents = (nbEvents > 0) ? nbEvents : 0;
484 }
485
486 /**
487 * Update the trace events time range
488 *
489 * @param range the new time range
490 * @since 2.0
491 */
492 protected void setTimeRange(final TmfTimeRange range) {
493 fStartTime = range.getStartTime();
494 fEndTime = range.getEndTime();
495 }
496
497 /**
498 * Update the trace chronologically first event timestamp
499 *
500 * @param startTime the new first event timestamp
501 * @since 2.0
502 */
503 protected void setStartTime(final ITmfTimestamp startTime) {
504 fStartTime = startTime;
505 }
506
507 /**
508 * Update the trace chronologically last event timestamp
509 *
510 * @param endTime the new last event timestamp
511 * @since 2.0
512 */
513 protected void setEndTime(final ITmfTimestamp endTime) {
514 fEndTime = endTime;
515 }
516
517 /**
518 * Set the polling interval for live traces (default = 0 = no streaming).
519 *
520 * @param interval the new trace streaming interval
521 */
522 protected void setStreamingInterval(final long interval) {
523 fStreamingInterval = (interval > 0) ? interval : 0;
524 }
525
526 /**
527 * Set the trace parser. Must be done at initialization time.
528 *
529 * @param parser the new trace parser
530 */
531 protected void setParser(final ITmfEventParser parser) {
532 fParser = parser;
533 }
534
535 // ------------------------------------------------------------------------
536 // ITmfTrace - SeekEvent operations (returning a trace context)
537 // ------------------------------------------------------------------------
538
539 @Override
540 public synchronized ITmfContext seekEvent(final long rank) {
541
542 // A rank <= 0 indicates to seek the first event
543 if (rank <= 0) {
544 ITmfContext context = seekEvent((ITmfLocation) null);
545 context.setRank(0);
546 return context;
547 }
548
549 // Position the trace at the checkpoint
550 final ITmfContext context = fIndexer.seekIndex(rank);
551
552 // And locate the requested event context
553 long pos = context.getRank();
554 if (pos < rank) {
555 ITmfEvent event = getNext(context);
556 while ((event != null) && (++pos < rank)) {
557 event = getNext(context);
558 }
559 }
560 return context;
561 }
562
563 /**
564 * @since 2.0
565 */
566 @Override
567 public synchronized ITmfContext seekEvent(final ITmfTimestamp timestamp) {
568
569 // A null timestamp indicates to seek the first event
570 if (timestamp == null) {
571 ITmfContext context = seekEvent((ITmfLocation) null);
572 context.setRank(0);
573 return context;
574 }
575
576 // Position the trace at the checkpoint
577 ITmfContext context = fIndexer.seekIndex(timestamp);
578
579 // And locate the requested event context
580 ITmfLocation previousLocation = context.getLocation();
581 long previousRank = context.getRank();
582 ITmfEvent event = getNext(context);
583 while (event != null && event.getTimestamp().compareTo(timestamp) < 0) {
584 previousLocation = context.getLocation();
585 previousRank = context.getRank();
586 event = getNext(context);
587 }
588 if (event == null) {
589 context.setLocation(null);
590 context.setRank(ITmfContext.UNKNOWN_RANK);
591 } else {
592 context.dispose();
593 context = seekEvent(previousLocation);
594 context.setRank(previousRank);
595 }
596 return context;
597 }
598
599 // ------------------------------------------------------------------------
600 // ITmfTrace - Read operations (returning an actual event)
601 // ------------------------------------------------------------------------
602
603 @Override
604 public synchronized ITmfEvent getNext(final ITmfContext context) {
605 // parseEvent() does not update the context
606 final ITmfEvent event = fParser.parseEvent(context);
607 if (event != null) {
608 updateAttributes(context, event.getTimestamp());
609 context.setLocation(getCurrentLocation());
610 context.increaseRank();
611 processEvent(event);
612 }
613 return event;
614 }
615
616 /**
617 * Hook for special event processing by the concrete class
618 * (called by TmfTrace.getEvent())
619 *
620 * @param event the event
621 */
622 protected void processEvent(final ITmfEvent event) {
623 // Do nothing
624 }
625
626 /**
627 * Update the trace attributes
628 *
629 * @param context the current trace context
630 * @param timestamp the corresponding timestamp
631 * @since 2.0
632 */
633 protected synchronized void updateAttributes(final ITmfContext context, final ITmfTimestamp timestamp) {
634 if (fStartTime.equals(TmfTimestamp.BIG_BANG) || (fStartTime.compareTo(timestamp) > 0)) {
635 fStartTime = timestamp;
636 }
637 if (fEndTime.equals(TmfTimestamp.BIG_CRUNCH) || (fEndTime.compareTo(timestamp) < 0)) {
638 fEndTime = timestamp;
639 }
640 if (context.hasValidRank()) {
641 long rank = context.getRank();
642 if (fNbEvents <= rank) {
643 fNbEvents = rank + 1;
644 }
645 if (fIndexer != null) {
646 fIndexer.updateIndex(context, timestamp);
647 }
648 }
649 }
650
651 // ------------------------------------------------------------------------
652 // TmfDataProvider
653 // ------------------------------------------------------------------------
654
655 /**
656 * @since 2.0
657 */
658 @Override
659 public synchronized ITmfContext armRequest(final ITmfEventRequest request) {
660 if (executorIsShutdown()) {
661 return null;
662 }
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());
667 return context;
668
669 }
670 return seekEvent(request.getIndex());
671 }
672
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) {
686 boolean signalIsForUs = false;
687 for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) {
688 if (trace == this) {
689 signalIsForUs = true;
690 break;
691 }
692 }
693
694 if (!signalIsForUs) {
695 return;
696 }
697
698 /*
699 * The signal is either for this trace, or for an experiment containing
700 * this trace.
701 */
702 IStatus status = executeAnalysis();
703 if (!status.isOK()) {
704 Activator.log(status);
705 }
706
707 TmfTraceManager.refreshSupplementaryFiles(this);
708
709 if (signal.getTrace() == this) {
710 /* Additionally, the signal is directly for this trace. */
711 if (getNbEvents() == 0) {
712 return;
713 }
714
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
722 if (isComplete()) {
723 final TmfTimeRange timeRange = new TmfTimeRange(getStartTime(), TmfTimestamp.BIG_CRUNCH);
724 final TmfTraceRangeUpdatedSignal rangeUpdatedsignal = new TmfTraceRangeUpdatedSignal(this, this, timeRange);
725
726 // Broadcast in separate thread to prevent deadlock
727 broadcastAsync(rangeUpdatedsignal);
728 }
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
746 /**
747 * Signal handler for the TmfTraceUpdatedSignal signal
748 *
749 * @param signal The incoming signal
750 * @since 3.0
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
761 // ------------------------------------------------------------------------
762 // Timestamp transformation functions
763 // ------------------------------------------------------------------------
764
765 /**
766 * @since 3.0
767 */
768 @Override
769 public ITmfTimestampTransform getTimestampTransform() {
770 if (fTsTransform == null) {
771 fTsTransform = TimestampTransformFactory.getTimestampTransform(getResource());
772 }
773 return fTsTransform;
774 }
775
776 /**
777 * @since 3.0
778 */
779 @Override
780 public void setTimestampTransform(final ITmfTimestampTransform tt) {
781 fTsTransform = tt;
782 TimestampTransformFactory.setTimestampTransform(getResource(), tt);
783 }
784
785 /**
786 * @since 3.0
787 */
788 @Override
789 public ITmfTimestamp createTimestamp(long ts) {
790 return new TmfNanoTimestamp(getTimestampTransform().transform(ts));
791 }
792
793 // ------------------------------------------------------------------------
794 // toString
795 // ------------------------------------------------------------------------
796
797 @Override
798 @SuppressWarnings("nls")
799 public synchronized String toString() {
800 return "TmfTrace [fPath=" + fPath + ", fCacheSize=" + fCacheSize
801 + ", fNbEvents=" + fNbEvents + ", fStartTime=" + fStartTime
802 + ", fEndTime=" + fEndTime + ", fStreamingInterval=" + fStreamingInterval + "]";
803 }
804
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 }
827 }
This page took 0.070578 seconds and 5 git commands to generate.