tmf: Deprecate TmfStateSystemFactory and HistoryBuilder
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / trace / TmfTrace.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2013 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.linuxtools.tmf.core.trace;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.io.ObjectInputStream;
24 import java.io.ObjectOutputStream;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.LinkedHashMap;
28 import java.util.Map;
29 import java.util.Map.Entry;
30
31 import org.eclipse.core.resources.IFolder;
32 import org.eclipse.core.resources.IProject;
33 import org.eclipse.core.resources.IResource;
34 import org.eclipse.core.runtime.CoreException;
35 import org.eclipse.core.runtime.IStatus;
36 import org.eclipse.core.runtime.MultiStatus;
37 import org.eclipse.core.runtime.Path;
38 import org.eclipse.core.runtime.Status;
39 import org.eclipse.linuxtools.internal.tmf.core.Activator;
40 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
41 import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule;
42 import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper;
43 import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager;
44 import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
45 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
46 import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
47 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
48 import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
49 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
50 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
51 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
52 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
53 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal;
54 import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
55 import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics;
56 import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics;
57 import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform;
58 import org.eclipse.linuxtools.tmf.core.synchronization.TmfTimestampTransform;
59 import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
60 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
61 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
62 import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer;
63 import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer;
64 import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
65
66 /**
67 * Abstract implementation of ITmfTrace.
68 * <p>
69 * Since the concept of 'location' is trace specific, the concrete classes have
70 * to provide the related methods, namely:
71 * <ul>
72 * <li> public ITmfLocation<?> getCurrentLocation()
73 * <li> public double getLocationRatio(ITmfLocation<?> location)
74 * <li> public ITmfContext seekEvent(ITmfLocation<?> location)
75 * <li> public ITmfContext seekEvent(double ratio)
76 * <li> public IStatus validate(IProject project, String path)
77 * </ul>
78 * A concrete trace must provide its corresponding parser. A common way to
79 * accomplish this is by making the concrete class extend TmfTrace and
80 * implement ITmfEventParser.
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 {
94
95 // ------------------------------------------------------------------------
96 // Attributes
97 // ------------------------------------------------------------------------
98
99 // The resource used for persistent properties for this trace
100 private IResource fResource;
101
102 // The trace path
103 private String fPath;
104
105 // The trace cache page size
106 private int fCacheSize = ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
107
108 // The number of events collected (so far)
109 private long fNbEvents = 0;
110
111 // The time span of the event stream
112 private ITmfTimestamp fStartTime = TmfTimestamp.BIG_BANG;
113 private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG;
114
115 // The trace streaming interval (0 = no streaming)
116 private long fStreamingInterval = 0;
117
118 // The trace indexer
119 private ITmfTraceIndexer fIndexer;
120
121 // The trace parser
122 private ITmfEventParser fParser;
123
124 // The trace's statistics
125 private ITmfStatistics fStatistics;
126
127 /**
128 * The collection of state systems that are registered with this trace. Each
129 * sub-class can decide to add its (one or many) state system to this map
130 * during their {@link #buildStateSystem()}.
131 *
132 * @since 2.0
133 */
134 protected final Map<String, ITmfStateSystem> fStateSystems =
135 new LinkedHashMap<>();
136
137 private ITmfTimestampTransform fTsTransform;
138
139 private final Map<String, IAnalysisModule> fAnalysisModules =
140 new LinkedHashMap<>();
141
142 private static final String SYNCHRONIZATION_FORMULA_FILE = "sync_formula"; //$NON-NLS-1$
143
144 // ------------------------------------------------------------------------
145 // Construction
146 // ------------------------------------------------------------------------
147
148 /**
149 * The default, parameterless, constructor
150 */
151 public TmfTrace() {
152 super();
153 fIndexer = createIndexer(DEFAULT_BLOCK_SIZE);
154 }
155
156 /**
157 * Full constructor.
158 *
159 * @param resource
160 * The resource associated to the trace
161 * @param type
162 * The type of events that will be read from this trace
163 * @param path
164 * The path to the trace on the filesystem
165 * @param cacheSize
166 * The trace cache size. Pass '-1' to use the default specified
167 * in {@link ITmfTrace#DEFAULT_TRACE_CACHE_SIZE}
168 * @param interval
169 * The trace streaming interval. You can use '0' for post-mortem
170 * traces.
171 * @param parser
172 * The trace event parser. Use 'null' if (and only if) the trace
173 * object itself is also the ITmfEventParser to be used.
174 * @throws TmfTraceException
175 * If something failed during the opening
176 */
177 protected TmfTrace(final IResource resource,
178 final Class<? extends ITmfEvent> type,
179 final String path,
180 final int cacheSize,
181 final long interval,
182 final ITmfEventParser parser)
183 throws TmfTraceException {
184 super();
185 fCacheSize = (cacheSize > 0) ? cacheSize : ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
186 fStreamingInterval = interval;
187 fParser = parser;
188 initialize(resource, path, type);
189 }
190
191 /**
192 * Copy constructor
193 *
194 * @param trace the original trace
195 * @throws TmfTraceException Should not happen usually
196 */
197 public TmfTrace(final TmfTrace trace) throws TmfTraceException {
198 super();
199 if (trace == null) {
200 throw new IllegalArgumentException();
201 }
202 fCacheSize = trace.getCacheSize();
203 fStreamingInterval = trace.getStreamingInterval();
204 fParser = trace.fParser;
205 initialize(trace.getResource(), trace.getPath(), trace.getEventType());
206 }
207
208 /**
209 * Creates the indexer instance. Classes extending this class can override
210 * this to provide a different indexer implementation.
211 *
212 * @param interval the checkpoints interval
213 *
214 * @return the indexer
215 * @since 3.0
216 */
217 protected ITmfTraceIndexer createIndexer(int interval) {
218 return new TmfCheckpointIndexer(this, interval);
219 }
220
221 // ------------------------------------------------------------------------
222 // ITmfTrace - Initializers
223 // ------------------------------------------------------------------------
224
225 @Override
226 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException {
227 initialize(resource, path, type);
228 }
229
230 /**
231 * Initialize the trace common attributes and the base component.
232 *
233 * @param resource the Eclipse resource (trace)
234 * @param path the trace path
235 * @param type the trace event type
236 *
237 * @throws TmfTraceException If something failed during the initialization
238 */
239 protected void initialize(final IResource resource,
240 final String path,
241 final Class<? extends ITmfEvent> type)
242 throws TmfTraceException {
243 if (path == null) {
244 throw new TmfTraceException("Invalid trace path"); //$NON-NLS-1$
245 }
246 fPath = path;
247 fResource = resource;
248 String traceName = (resource != null) ? resource.getName() : null;
249 // If no resource was provided, extract the display name the trace path
250 if (traceName == null) {
251 traceName = new Path(path).lastSegment();
252 }
253 if (fParser == null) {
254 if (this instanceof ITmfEventParser) {
255 fParser = (ITmfEventParser) this;
256 } else {
257 throw new TmfTraceException("Invalid trace parser"); //$NON-NLS-1$
258 }
259 }
260 super.init(traceName, type);
261 // register as VIP after super.init() because TmfComponent registers to signal manager there
262 TmfSignalManager.registerVIP(this);
263 fIndexer = createIndexer(fCacheSize);
264 }
265
266 /**
267 * Indicates if the path points to an existing file/directory
268 *
269 * @param path the path to test
270 * @return true if the file/directory exists
271 */
272 protected boolean fileExists(final String path) {
273 final File file = new File(path);
274 return file.exists();
275 }
276
277 /**
278 * @since 2.0
279 */
280 @Override
281 public void indexTrace(boolean waitForCompletion) {
282 getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, waitForCompletion);
283 }
284
285 /**
286 * The default implementation of TmfTrace uses a TmfStatistics back-end.
287 * Override this if you want to specify another type (or none at all).
288 *
289 * @return An IStatus indicating if the statistics could be built
290 * successfully or not.
291 * @since 3.0
292 */
293 protected IStatus buildStatistics() {
294 /*
295 * Initialize the statistics provider, but only if a Resource has been
296 * set (so we don't build it for experiments, for unit tests, etc.)
297 */
298 try {
299 fStatistics = (fResource == null ? null : new TmfStateStatistics(this) );
300 } catch (TmfTraceException e) {
301 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e);
302 }
303 return Status.OK_STATUS;
304 }
305
306 /**
307 * Build the state system(s) associated with this trace type.
308 *
309 * @return An IStatus indicating if the state system could be build
310 * successfully or not.
311 * @since 3.0
312 */
313 @Deprecated
314 protected IStatus buildStateSystem() {
315 /*
316 * Nothing is done in the base implementation, please specify
317 * how/if to register a new state system in derived classes.
318 */
319 return Status.OK_STATUS;
320 }
321
322 /**
323 * Instantiate the applicable analysis modules and executes the analysis
324 * modules that are meant to be automatically executed
325 *
326 * @return An IStatus indicating whether the analysis could be run
327 * successfully or not
328 * @since 3.0
329 */
330 protected IStatus executeAnalysis() {
331 MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
332 Map<String, IAnalysisModuleHelper> modules = TmfAnalysisManager.getAnalysisModules(this.getClass());
333 for (IAnalysisModuleHelper helper : modules.values()) {
334 try {
335 IAnalysisModule module = helper.newModule(this);
336 fAnalysisModules.put(module.getId(), module);
337 if (module.isAutomatic()) {
338 status.add(module.schedule());
339 }
340 } catch (TmfAnalysisException e) {
341 status.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
342 }
343 }
344 return status;
345 }
346
347 /**
348 * @since 3.0
349 */
350 @Override
351 public final IAnalysisModule getAnalysisModule(String analysisId) {
352 return fAnalysisModules.get(analysisId);
353 }
354
355 /**
356 * @since 3.0
357 */
358 @Override
359 public <T> Map<String, T> getAnalysisModules(Class<T> moduleclass) {
360 Map<String, T> modules = new HashMap<>();
361 for (Entry<String, IAnalysisModule> entry : fAnalysisModules.entrySet()) {
362 if (moduleclass.isAssignableFrom(entry.getValue().getClass())) {
363 modules.put(entry.getKey(), moduleclass.cast(entry.getValue()));
364 }
365 }
366 return modules;
367 }
368
369 /**
370 * @since 3.0
371 */
372 @Override
373 public Map<String, IAnalysisModule> getAnalysisModules() {
374 return Collections.unmodifiableMap(fAnalysisModules);
375 }
376
377 /**
378 * Clears the trace
379 */
380 @Override
381 public synchronized void dispose() {
382 /* Clean up the index if applicable */
383 if (getIndexer() != null) {
384 getIndexer().dispose();
385 }
386
387 /* Clean up the statistics */
388 if (fStatistics != null) {
389 fStatistics.dispose();
390 }
391
392 /* Clean up the state systems */
393 for (ITmfStateSystem ss : fStateSystems.values()) {
394 ss.dispose();
395 }
396
397 super.dispose();
398 }
399
400 // ------------------------------------------------------------------------
401 // ITmfTrace - Basic getters
402 // ------------------------------------------------------------------------
403
404 @Override
405 public Class<? extends ITmfEvent> getEventType() {
406 return super.getType();
407 }
408
409 @Override
410 public IResource getResource() {
411 return fResource;
412 }
413
414 @Override
415 public String getPath() {
416 return fPath;
417 }
418
419 @Override
420 public int getCacheSize() {
421 return fCacheSize;
422 }
423
424 @Override
425 public long getStreamingInterval() {
426 return fStreamingInterval;
427 }
428
429 /**
430 * @return the trace indexer
431 * @since 3.0
432 */
433 protected ITmfTraceIndexer getIndexer() {
434 return fIndexer;
435 }
436
437 /**
438 * @return the trace parser
439 */
440 protected ITmfEventParser getParser() {
441 return fParser;
442 }
443
444 /**
445 * @since 2.0
446 */
447 @Override
448 public ITmfStatistics getStatistics() {
449 return fStatistics;
450 }
451
452 /**
453 * @since 2.0
454 * @deprecated See {@link ITmfTrace}
455 */
456 @Deprecated
457 @Override
458 public final Map<String, ITmfStateSystem> getStateSystems() {
459 return Collections.unmodifiableMap(fStateSystems);
460 }
461
462 /**
463 * @since 2.0
464 * @deprecated See {@link ITmfTrace}
465 */
466 @Deprecated
467 @Override
468 public final void registerStateSystem(String id, ITmfStateSystem ss) {
469 fStateSystems.put(id, ss);
470 }
471
472 // ------------------------------------------------------------------------
473 // ITmfTrace - Trace characteristics getters
474 // ------------------------------------------------------------------------
475
476 @Override
477 public synchronized long getNbEvents() {
478 return fNbEvents;
479 }
480
481 /**
482 * @since 2.0
483 */
484 @Override
485 public TmfTimeRange getTimeRange() {
486 return new TmfTimeRange(fStartTime, fEndTime);
487 }
488
489 /**
490 * @since 2.0
491 */
492 @Override
493 public ITmfTimestamp getStartTime() {
494 return fStartTime;
495 }
496
497 /**
498 * @since 2.0
499 */
500 @Override
501 public ITmfTimestamp getEndTime() {
502 return fEndTime;
503 }
504
505 /**
506 * @since 2.0
507 */
508 @Override
509 public ITmfTimestamp getInitialRangeOffset() {
510 final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec
511 return new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE);
512 }
513
514 /**
515 * @since 3.0
516 */
517 @Override
518 public String getHostId() {
519 return this.getName();
520 }
521
522 // ------------------------------------------------------------------------
523 // Convenience setters
524 // ------------------------------------------------------------------------
525
526 /**
527 * Set the trace cache size. Must be done at initialization time.
528 *
529 * @param cacheSize The trace cache size
530 */
531 protected void setCacheSize(final int cacheSize) {
532 fCacheSize = cacheSize;
533 }
534
535 /**
536 * Set the trace known number of events. This can be quite dynamic
537 * during indexing or for live traces.
538 *
539 * @param nbEvents The number of events
540 */
541 protected synchronized void setNbEvents(final long nbEvents) {
542 fNbEvents = (nbEvents > 0) ? nbEvents : 0;
543 }
544
545 /**
546 * Update the trace events time range
547 *
548 * @param range the new time range
549 * @since 2.0
550 */
551 protected void setTimeRange(final TmfTimeRange range) {
552 fStartTime = range.getStartTime();
553 fEndTime = range.getEndTime();
554 }
555
556 /**
557 * Update the trace chronologically first event timestamp
558 *
559 * @param startTime the new first event timestamp
560 * @since 2.0
561 */
562 protected void setStartTime(final ITmfTimestamp startTime) {
563 fStartTime = startTime;
564 }
565
566 /**
567 * Update the trace chronologically last event timestamp
568 *
569 * @param endTime the new last event timestamp
570 * @since 2.0
571 */
572 protected void setEndTime(final ITmfTimestamp endTime) {
573 fEndTime = endTime;
574 }
575
576 /**
577 * Set the polling interval for live traces (default = 0 = no streaming).
578 *
579 * @param interval the new trace streaming interval
580 */
581 protected void setStreamingInterval(final long interval) {
582 fStreamingInterval = (interval > 0) ? interval : 0;
583 }
584
585 /**
586 * Set the trace parser. Must be done at initialization time.
587 *
588 * @param parser the new trace parser
589 */
590 protected void setParser(final ITmfEventParser parser) {
591 fParser = parser;
592 }
593
594 // ------------------------------------------------------------------------
595 // ITmfTrace - SeekEvent operations (returning a trace context)
596 // ------------------------------------------------------------------------
597
598 @Override
599 public synchronized ITmfContext seekEvent(final long rank) {
600
601 // A rank <= 0 indicates to seek the first event
602 if (rank <= 0) {
603 ITmfContext context = seekEvent((ITmfLocation) null);
604 context.setRank(0);
605 return context;
606 }
607
608 // Position the trace at the checkpoint
609 final ITmfContext context = fIndexer.seekIndex(rank);
610
611 // And locate the requested event context
612 long pos = context.getRank();
613 if (pos < rank) {
614 ITmfEvent event = getNext(context);
615 while ((event != null) && (++pos < rank)) {
616 event = getNext(context);
617 }
618 }
619 return context;
620 }
621
622 /**
623 * @since 2.0
624 */
625 @Override
626 public synchronized ITmfContext seekEvent(final ITmfTimestamp timestamp) {
627
628 // A null timestamp indicates to seek the first event
629 if (timestamp == null) {
630 ITmfContext context = seekEvent((ITmfLocation) null);
631 context.setRank(0);
632 return context;
633 }
634
635 // Position the trace at the checkpoint
636 ITmfContext context = fIndexer.seekIndex(timestamp);
637
638 // And locate the requested event context
639 ITmfLocation previousLocation = context.getLocation();
640 long previousRank = context.getRank();
641 ITmfEvent event = getNext(context);
642 while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) {
643 previousLocation = context.getLocation();
644 previousRank = context.getRank();
645 event = getNext(context);
646 }
647 if (event == null) {
648 context.setLocation(null);
649 context.setRank(ITmfContext.UNKNOWN_RANK);
650 } else {
651 context.dispose();
652 context = seekEvent(previousLocation);
653 context.setRank(previousRank);
654 }
655 return context;
656 }
657
658 // ------------------------------------------------------------------------
659 // ITmfTrace - Read operations (returning an actual event)
660 // ------------------------------------------------------------------------
661
662 @Override
663 public synchronized ITmfEvent getNext(final ITmfContext context) {
664 // parseEvent() does not update the context
665 final ITmfEvent event = fParser.parseEvent(context);
666 if (event != null) {
667 updateAttributes(context, event.getTimestamp());
668 context.setLocation(getCurrentLocation());
669 context.increaseRank();
670 processEvent(event);
671 }
672 return event;
673 }
674
675 /**
676 * Hook for special event processing by the concrete class
677 * (called by TmfTrace.getEvent())
678 *
679 * @param event the event
680 */
681 protected void processEvent(final ITmfEvent event) {
682 // Do nothing
683 }
684
685 /**
686 * Update the trace attributes
687 *
688 * @param context the current trace context
689 * @param timestamp the corresponding timestamp
690 * @since 2.0
691 */
692 protected synchronized void updateAttributes(final ITmfContext context, final ITmfTimestamp timestamp) {
693 if (fStartTime.equals(TmfTimestamp.BIG_BANG) || (fStartTime.compareTo(timestamp, false) > 0)) {
694 fStartTime = timestamp;
695 }
696 if (fEndTime.equals(TmfTimestamp.BIG_CRUNCH) || (fEndTime.compareTo(timestamp, false) < 0)) {
697 fEndTime = timestamp;
698 }
699 if (context.hasValidRank()) {
700 long rank = context.getRank();
701 if (fNbEvents <= rank) {
702 fNbEvents = rank + 1;
703 }
704 if (fIndexer != null) {
705 fIndexer.updateIndex(context, timestamp);
706 }
707 }
708 }
709
710 // ------------------------------------------------------------------------
711 // TmfDataProvider
712 // ------------------------------------------------------------------------
713
714 /**
715 * @since 2.0
716 */
717 @Override
718 public synchronized ITmfContext armRequest(final ITmfEventRequest request) {
719 if (executorIsShutdown()) {
720 return null;
721 }
722 if (!TmfTimestamp.BIG_BANG.equals(request.getRange().getStartTime())
723 && (request.getIndex() == 0)) {
724 final ITmfContext context = seekEvent(request.getRange().getStartTime());
725 request.setStartIndex((int) context.getRank());
726 return context;
727
728 }
729 return seekEvent(request.getIndex());
730 }
731
732 // ------------------------------------------------------------------------
733 // Signal handlers
734 // ------------------------------------------------------------------------
735
736 /**
737 * Handler for the Trace Opened signal
738 *
739 * @param signal
740 * The incoming signal
741 * @since 2.0
742 */
743 @TmfSignalHandler
744 public void traceOpened(TmfTraceOpenedSignal signal) {
745 boolean signalIsForUs = false;
746 for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) {
747 if (trace == this) {
748 signalIsForUs = true;
749 break;
750 }
751 }
752
753 if (!signalIsForUs) {
754 return;
755 }
756
757 /*
758 * The signal is either for this trace, or for an experiment containing
759 * this trace.
760 */
761 MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
762 status.add(buildStatistics());
763 status.add(buildStateSystem());
764 status.add(executeAnalysis());
765 if (!status.isOK()) {
766 Activator.log(status);
767 }
768
769 refreshSupplementaryFiles();
770
771 if (signal.getTrace() == this) {
772 /* Additionally, the signal is directly for this trace. */
773 if (getNbEvents() == 0) {
774 return;
775 }
776
777 /* For a streaming trace, the range updated signal should be sent
778 * by the subclass when a new safe time is determined.
779 */
780 if (getStreamingInterval() > 0) {
781 return;
782 }
783
784 final TmfTimeRange timeRange = new TmfTimeRange(getStartTime(), TmfTimestamp.BIG_CRUNCH);
785 final TmfTraceRangeUpdatedSignal rangeUpdatedsignal = new TmfTraceRangeUpdatedSignal(this, this, timeRange);
786
787 // Broadcast in separate thread to prevent deadlock
788 new Thread() {
789 @Override
790 public void run() {
791 broadcast(rangeUpdatedsignal);
792 }
793 }.start();
794 return;
795 }
796 }
797
798 /**
799 * Refresh the supplementary files resources, so it can pick up new files
800 * that got created.
801 * @since 3.0
802 */
803 public void refreshSupplementaryFiles() {
804 if (fResource != null) {
805 IProject project = fResource.getProject();
806 IFolder supplFolder = project.getFolder(TmfCommonConstants.TRACE_SUPPLEMENATARY_FOLDER_NAME);
807 if (supplFolder.exists()) {
808 try {
809 supplFolder.refreshLocal(IResource.DEPTH_INFINITE, null);
810 } catch (CoreException e) {
811 Activator.logError("Error refreshing resources", e); //$NON-NLS-1$
812 }
813 }
814 }
815 }
816
817 /**
818 * Signal handler for the TmfTraceRangeUpdatedSignal signal
819 *
820 * @param signal The incoming signal
821 * @since 2.0
822 */
823 @TmfSignalHandler
824 public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal) {
825 if (signal.getTrace() == this) {
826 getIndexer().buildIndex(getNbEvents(), signal.getRange(), false);
827 }
828 }
829
830 /**
831 * Signal handler for the TmfTraceUpdatedSignal signal
832 *
833 * @param signal The incoming signal
834 * @since 3.0
835 */
836 @TmfSignalHandler
837 public void traceUpdated(final TmfTraceUpdatedSignal signal) {
838 if (signal.getSource() == getIndexer()) {
839 fNbEvents = signal.getNbEvents();
840 fStartTime = signal.getRange().getStartTime();
841 fEndTime = signal.getRange().getEndTime();
842 }
843 }
844
845 /**
846 * Returns the file resource used to store synchronization formula. The file
847 * may not exist.
848 *
849 * @return the synchronization file
850 */
851 private File getSyncFormulaFile() {
852 File file = null;
853 if (fResource instanceof IFolder) {
854 try {
855 String supplDirectory;
856
857 supplDirectory = fResource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER);
858
859 file = new File(supplDirectory + File.separator + SYNCHRONIZATION_FORMULA_FILE);
860
861 } catch (CoreException e) {
862
863 }
864 }
865 return file;
866 }
867
868 // ------------------------------------------------------------------------
869 // Timestamp transformation functions
870 // ------------------------------------------------------------------------
871
872 /**
873 * @since 3.0
874 */
875 @Override
876 public ITmfTimestampTransform getTimestampTransform() {
877 if (fTsTransform == null) {
878 /* Check if a formula is stored somewhere in the resources */
879 File sync_file = getSyncFormulaFile();
880 if (sync_file != null && sync_file.exists()) {
881
882 try (FileInputStream fis = new FileInputStream(sync_file);
883 ObjectInputStream ois = new ObjectInputStream(fis);) {
884
885 fTsTransform = (ITmfTimestampTransform) ois.readObject();
886
887 } catch (ClassNotFoundException | IOException e) {
888 fTsTransform = TmfTimestampTransform.IDENTITY;
889 }
890 } else {
891 fTsTransform = TmfTimestampTransform.IDENTITY;
892 }
893 }
894 return fTsTransform;
895 }
896
897 /**
898 * @since 3.0
899 */
900 @Override
901 public void setTimestampTransform(final ITmfTimestampTransform tt) {
902 fTsTransform = tt;
903
904 /* Save the timestamp transform to a file */
905 File sync_file = getSyncFormulaFile();
906 if (sync_file != null) {
907 if (sync_file.exists()) {
908 sync_file.delete();
909 }
910 FileOutputStream fos;
911 ObjectOutputStream oos;
912
913 /* Save the header of the file */
914 try {
915 fos = new FileOutputStream(sync_file, false);
916 oos = new ObjectOutputStream(fos);
917
918 oos.writeObject(fTsTransform);
919 oos.close();
920 fos.close();
921 } catch (IOException e1) {
922 Activator.logError("Error writing timestamp transform for trace", e1); //$NON-NLS-1$
923 }
924 }
925 }
926
927 /**
928 * @since 3.0
929 */
930 @Override
931 public ITmfTimestamp createTimestamp(long ts) {
932 return new TmfTimestamp(getTimestampTransform().transform(ts));
933 }
934
935 // ------------------------------------------------------------------------
936 // toString
937 // ------------------------------------------------------------------------
938
939 @Override
940 @SuppressWarnings("nls")
941 public synchronized String toString() {
942 return "TmfTrace [fPath=" + fPath + ", fCacheSize=" + fCacheSize
943 + ", fNbEvents=" + fNbEvents + ", fStartTime=" + fStartTime
944 + ", fEndTime=" + fEndTime + ", fStreamingInterval=" + fStreamingInterval + "]";
945 }
946
947 }
This page took 0.051869 seconds and 6 git commands to generate.