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