1 /*******************************************************************************
2 * Copyright (c) 2009, 2013 Ericsson, École Polytechnique de Montréal
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
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 *******************************************************************************/
17 package org
.eclipse
.linuxtools
.tmf
.core
.trace
;
20 import java
.io
.FileInputStream
;
21 import java
.io
.FileNotFoundException
;
22 import java
.io
.FileOutputStream
;
23 import java
.io
.IOException
;
24 import java
.io
.ObjectInputStream
;
25 import java
.io
.ObjectOutputStream
;
26 import java
.util
.Collections
;
27 import java
.util
.HashMap
;
28 import java
.util
.LinkedHashMap
;
30 import java
.util
.Map
.Entry
;
32 import org
.eclipse
.core
.resources
.IFolder
;
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
.ITmfDataRequest
;
49 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfEventRequest
;
50 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
51 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalManager
;
52 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceOpenedSignal
;
53 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceRangeUpdatedSignal
;
54 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceUpdatedSignal
;
55 import org
.eclipse
.linuxtools
.tmf
.core
.statesystem
.ITmfStateSystem
;
56 import org
.eclipse
.linuxtools
.tmf
.core
.statistics
.ITmfStatistics
;
57 import org
.eclipse
.linuxtools
.tmf
.core
.statistics
.TmfStateStatistics
;
58 import org
.eclipse
.linuxtools
.tmf
.core
.synchronization
.ITmfTimestampTransform
;
59 import org
.eclipse
.linuxtools
.tmf
.core
.synchronization
.TmfTimestampTransform
;
60 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.ITmfTimestamp
;
61 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimeRange
;
62 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimestamp
;
63 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.indexer
.ITmfTraceIndexer
;
64 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.indexer
.checkpoint
.TmfCheckpointIndexer
;
65 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.location
.ITmfLocation
;
68 * Abstract implementation of ITmfTrace.
70 * Since the concept of 'location' is trace specific, the concrete classes have
71 * to provide the related methods, namely:
73 * <li> public ITmfLocation<?> getCurrentLocation()
74 * <li> public double getLocationRatio(ITmfLocation<?> location)
75 * <li> public ITmfContext seekEvent(ITmfLocation<?> location)
76 * <li> public ITmfContext seekEvent(double ratio)
77 * <li> public IStatus validate(IProject project, String path)
79 * A concrete trace must provide its corresponding parser. A common way to
80 * accomplish this is by making the concrete class extend TmfTrace and
81 * implement ITmfEventParser.
83 * The concrete class can either specify its own indexer or use the provided
84 * TmfCheckpointIndexer (default). In this case, the trace cache size will be
85 * used as checkpoint interval.
88 * @author Francois Chouinard
91 * @see ITmfTraceIndexer
92 * @see ITmfEventParser
94 public abstract class TmfTrace
extends TmfEventProvider
implements ITmfTrace
{
96 // ------------------------------------------------------------------------
98 // ------------------------------------------------------------------------
100 // The resource used for persistent properties for this trace
101 private IResource fResource
;
104 private String fPath
;
106 // The trace cache page size
107 private int fCacheSize
= ITmfTrace
.DEFAULT_TRACE_CACHE_SIZE
;
109 // The number of events collected (so far)
110 private long fNbEvents
= 0;
112 // The time span of the event stream
113 private ITmfTimestamp fStartTime
= TmfTimestamp
.BIG_BANG
;
114 private ITmfTimestamp fEndTime
= TmfTimestamp
.BIG_BANG
;
116 // The trace streaming interval (0 = no streaming)
117 private long fStreamingInterval
= 0;
120 private ITmfTraceIndexer fIndexer
;
123 private ITmfEventParser fParser
;
125 // The trace's statistics
126 private ITmfStatistics fStatistics
;
129 * The collection of state systems that are registered with this trace. Each
130 * sub-class can decide to add its (one or many) state system to this map
131 * during their {@link #buildStateSystem()}.
135 protected final Map
<String
, ITmfStateSystem
> fStateSystems
=
136 new LinkedHashMap
<String
, ITmfStateSystem
>();
138 private ITmfTimestampTransform fTsTransform
;
140 private final Map
<String
, IAnalysisModule
> fAnalysisModules
=
141 new LinkedHashMap
<String
, IAnalysisModule
>();
143 private static final String SYNCHRONIZATION_FORMULA_FILE
= "sync_formula"; //$NON-NLS-1$
145 // ------------------------------------------------------------------------
147 // ------------------------------------------------------------------------
150 * The default, parameterless, constructor
154 fIndexer
= createIndexer(DEFAULT_BLOCK_SIZE
);
161 * The resource associated to the trace
163 * The type of events that will be read from this trace
165 * The path to the trace on the filesystem
167 * The trace cache size. Pass '-1' to use the default specified
168 * in {@link ITmfTrace#DEFAULT_TRACE_CACHE_SIZE}
170 * The trace streaming interval. You can use '0' for post-mortem
173 * The trace event parser. Use 'null' if (and only if) the trace
174 * object itself is also the ITmfEventParser to be used.
175 * @throws TmfTraceException
176 * If something failed during the opening
178 protected TmfTrace(final IResource resource
,
179 final Class
<?
extends ITmfEvent
> type
,
183 final ITmfEventParser parser
)
184 throws TmfTraceException
{
186 fCacheSize
= (cacheSize
> 0) ? cacheSize
: ITmfTrace
.DEFAULT_TRACE_CACHE_SIZE
;
187 fStreamingInterval
= interval
;
189 initialize(resource
, path
, type
);
195 * @param trace the original trace
196 * @throws TmfTraceException Should not happen usually
198 public TmfTrace(final TmfTrace trace
) throws TmfTraceException
{
201 throw new IllegalArgumentException();
203 fCacheSize
= trace
.getCacheSize();
204 fStreamingInterval
= trace
.getStreamingInterval();
205 fParser
= trace
.fParser
;
206 initialize(trace
.getResource(), trace
.getPath(), trace
.getEventType());
210 * Creates the indexer instance. Classes extending this class can override
211 * this to provide a different indexer implementation.
213 * @param interval the checkpoints interval
215 * @return the indexer
218 protected ITmfTraceIndexer
createIndexer(int interval
) {
219 return new TmfCheckpointIndexer(this, interval
);
222 // ------------------------------------------------------------------------
223 // ITmfTrace - Initializers
224 // ------------------------------------------------------------------------
227 public void initTrace(final IResource resource
, final String path
, final Class
<?
extends ITmfEvent
> type
) throws TmfTraceException
{
228 initialize(resource
, path
, type
);
232 * Initialize the trace common attributes and the base component.
234 * @param resource the Eclipse resource (trace)
235 * @param path the trace path
236 * @param type the trace event type
238 * @throws TmfTraceException If something failed during the initialization
240 protected void initialize(final IResource resource
,
242 final Class
<?
extends ITmfEvent
> type
)
243 throws TmfTraceException
{
245 throw new TmfTraceException("Invalid trace path"); //$NON-NLS-1$
248 fResource
= resource
;
249 String traceName
= (resource
!= null) ? resource
.getName() : null;
250 // If no resource was provided, extract the display name the trace path
251 if (traceName
== null) {
252 traceName
= new Path(path
).lastSegment();
254 if (fParser
== null) {
255 if (this instanceof ITmfEventParser
) {
256 fParser
= (ITmfEventParser
) this;
258 throw new TmfTraceException("Invalid trace parser"); //$NON-NLS-1$
261 super.init(traceName
, type
);
262 // register as VIP after super.init() because TmfComponent registers to signal manager there
263 TmfSignalManager
.registerVIP(this);
264 fIndexer
= createIndexer(fCacheSize
);
268 * Indicates if the path points to an existing file/directory
270 * @param path the path to test
271 * @return true if the file/directory exists
273 protected boolean fileExists(final String path
) {
274 final File file
= new File(path
);
275 return file
.exists();
282 public void indexTrace(boolean waitForCompletion
) {
283 getIndexer().buildIndex(0, TmfTimeRange
.ETERNITY
, waitForCompletion
);
287 * The default implementation of TmfTrace uses a TmfStatistics back-end.
288 * Override this if you want to specify another type (or none at all).
290 * @return An IStatus indicating if the statistics could be built
291 * successfully or not.
294 protected IStatus
buildStatistics() {
296 * Initialize the statistics provider, but only if a Resource has been
297 * set (so we don't build it for experiments, for unit tests, etc.)
300 fStatistics
= (fResource
== null ?
null : new TmfStateStatistics(this) );
301 } catch (TmfTraceException e
) {
302 return new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, e
.getMessage(), e
);
304 return Status
.OK_STATUS
;
308 * Build the state system(s) associated with this trace type.
310 * @return An IStatus indicating if the state system could be build
311 * successfully or not.
315 protected IStatus
buildStateSystem() {
317 * Nothing is done in the base implementation, please specify
318 * how/if to register a new state system in derived classes.
320 return Status
.OK_STATUS
;
324 * Instantiate the applicable analysis modules and executes the analysis
325 * modules that are meant to be automatically executed
327 * @return An IStatus indicating whether the analysis could be run
328 * successfully or not
331 protected IStatus
executeAnalysis() {
332 MultiStatus status
= new MultiStatus(Activator
.PLUGIN_ID
, IStatus
.OK
, null, null);
333 Map
<String
, IAnalysisModuleHelper
> modules
= TmfAnalysisManager
.getAnalysisModules(this.getClass());
334 for (IAnalysisModuleHelper helper
: modules
.values()) {
336 IAnalysisModule module
= helper
.newModule(this);
337 fAnalysisModules
.put(module
.getId(), module
);
338 if (module
.isAutomatic()) {
339 status
.add(module
.schedule());
341 } catch (TmfAnalysisException e
) {
342 status
.add(new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, e
.getMessage(), e
));
349 public final IAnalysisModule
getAnalysisModule(String analysisId
) {
350 return fAnalysisModules
.get(analysisId
);
354 public <T
> Map
<String
, T
> getAnalysisModules(Class
<T
> moduleclass
) {
355 Map
<String
, T
> modules
= new HashMap
<String
, T
>();
356 for (Entry
<String
, IAnalysisModule
> entry
: fAnalysisModules
.entrySet()) {
357 if (moduleclass
.isAssignableFrom(entry
.getValue().getClass())) {
358 modules
.put(entry
.getKey(), moduleclass
.cast(entry
.getValue()));
365 public Map
<String
, IAnalysisModule
> getAnalysisModules() {
366 return Collections
.unmodifiableMap(fAnalysisModules
);
373 public synchronized void dispose() {
374 /* Clean up the index if applicable */
375 if (getIndexer() != null) {
376 getIndexer().dispose();
379 /* Clean up the statistics */
380 if (fStatistics
!= null) {
381 fStatistics
.dispose();
384 /* Clean up the state systems */
385 for (ITmfStateSystem ss
: fStateSystems
.values()) {
392 // ------------------------------------------------------------------------
393 // ITmfTrace - Basic getters
394 // ------------------------------------------------------------------------
397 public Class
<ITmfEvent
> getEventType() {
398 return (Class
<ITmfEvent
>) super.getType();
402 public IResource
getResource() {
407 public String
getPath() {
412 public int getCacheSize() {
417 public long getStreamingInterval() {
418 return fStreamingInterval
;
422 * @return the trace indexer
425 protected ITmfTraceIndexer
getIndexer() {
430 * @return the trace parser
432 protected ITmfEventParser
getParser() {
440 public ITmfStatistics
getStatistics() {
446 * @deprecated See {@link ITmfTrace}
448 @SuppressWarnings("deprecation")
451 public final Map
<String
, ITmfStateSystem
> getStateSystems() {
452 return Collections
.unmodifiableMap(fStateSystems
);
457 * @deprecated See {@link ITmfTrace}
459 @SuppressWarnings("deprecation")
462 public final void registerStateSystem(String id
, ITmfStateSystem ss
) {
463 fStateSystems
.put(id
, ss
);
466 // ------------------------------------------------------------------------
467 // ITmfTrace - Trace characteristics getters
468 // ------------------------------------------------------------------------
471 public synchronized long getNbEvents() {
479 public TmfTimeRange
getTimeRange() {
480 return new TmfTimeRange(fStartTime
, fEndTime
);
487 public ITmfTimestamp
getStartTime() {
495 public ITmfTimestamp
getEndTime() {
503 public ITmfTimestamp
getInitialRangeOffset() {
504 final long DEFAULT_INITIAL_OFFSET_VALUE
= (1L * 100 * 1000 * 1000); // .1sec
505 return new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE
, ITmfTimestamp
.NANOSECOND_SCALE
);
512 public String
getHostId() {
513 return this.getName();
516 // ------------------------------------------------------------------------
517 // Convenience setters
518 // ------------------------------------------------------------------------
521 * Set the trace cache size. Must be done at initialization time.
523 * @param cacheSize The trace cache size
525 protected void setCacheSize(final int cacheSize
) {
526 fCacheSize
= cacheSize
;
530 * Set the trace known number of events. This can be quite dynamic
531 * during indexing or for live traces.
533 * @param nbEvents The number of events
535 protected synchronized void setNbEvents(final long nbEvents
) {
536 fNbEvents
= (nbEvents
> 0) ? nbEvents
: 0;
540 * Update the trace events time range
542 * @param range the new time range
545 protected void setTimeRange(final TmfTimeRange range
) {
546 fStartTime
= range
.getStartTime();
547 fEndTime
= range
.getEndTime();
551 * Update the trace chronologically first event timestamp
553 * @param startTime the new first event timestamp
556 protected void setStartTime(final ITmfTimestamp startTime
) {
557 fStartTime
= startTime
;
561 * Update the trace chronologically last event timestamp
563 * @param endTime the new last event timestamp
566 protected void setEndTime(final ITmfTimestamp endTime
) {
571 * Set the polling interval for live traces (default = 0 = no streaming).
573 * @param interval the new trace streaming interval
575 protected void setStreamingInterval(final long interval
) {
576 fStreamingInterval
= (interval
> 0) ? interval
: 0;
580 * Set the trace parser. Must be done at initialization time.
582 * @param parser the new trace parser
584 protected void setParser(final ITmfEventParser parser
) {
588 // ------------------------------------------------------------------------
589 // ITmfTrace - SeekEvent operations (returning a trace context)
590 // ------------------------------------------------------------------------
593 public synchronized ITmfContext
seekEvent(final long rank
) {
595 // A rank <= 0 indicates to seek the first event
597 ITmfContext context
= seekEvent((ITmfLocation
) null);
602 // Position the trace at the checkpoint
603 final ITmfContext context
= fIndexer
.seekIndex(rank
);
605 // And locate the requested event context
606 long pos
= context
.getRank();
608 ITmfEvent event
= getNext(context
);
609 while ((event
!= null) && (++pos
< rank
)) {
610 event
= getNext(context
);
620 public synchronized ITmfContext
seekEvent(final ITmfTimestamp timestamp
) {
622 // A null timestamp indicates to seek the first event
623 if (timestamp
== null) {
624 ITmfContext context
= seekEvent((ITmfLocation
) null);
629 // Position the trace at the checkpoint
630 ITmfContext context
= fIndexer
.seekIndex(timestamp
);
632 // And locate the requested event context
633 ITmfLocation previousLocation
= context
.getLocation();
634 long previousRank
= context
.getRank();
635 ITmfEvent event
= getNext(context
);
636 while (event
!= null && event
.getTimestamp().compareTo(timestamp
, false) < 0) {
637 previousLocation
= context
.getLocation();
638 previousRank
= context
.getRank();
639 event
= getNext(context
);
642 context
.setLocation(null);
643 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
646 context
= seekEvent(previousLocation
);
647 context
.setRank(previousRank
);
652 // ------------------------------------------------------------------------
653 // ITmfTrace - Read operations (returning an actual event)
654 // ------------------------------------------------------------------------
657 public synchronized ITmfEvent
getNext(final ITmfContext context
) {
658 // parseEvent() does not update the context
659 final ITmfEvent event
= fParser
.parseEvent(context
);
661 updateAttributes(context
, event
.getTimestamp());
662 context
.setLocation(getCurrentLocation());
663 context
.increaseRank();
670 * Hook for special event processing by the concrete class
671 * (called by TmfTrace.getEvent())
673 * @param event the event
675 protected void processEvent(final ITmfEvent event
) {
680 * Update the trace attributes
682 * @param context the current trace context
683 * @param timestamp the corresponding timestamp
686 protected synchronized void updateAttributes(final ITmfContext context
, final ITmfTimestamp timestamp
) {
687 if (fStartTime
.equals(TmfTimestamp
.BIG_BANG
) || (fStartTime
.compareTo(timestamp
, false) > 0)) {
688 fStartTime
= timestamp
;
690 if (fEndTime
.equals(TmfTimestamp
.BIG_CRUNCH
) || (fEndTime
.compareTo(timestamp
, false) < 0)) {
691 fEndTime
= timestamp
;
693 if (context
.hasValidRank()) {
694 long rank
= context
.getRank();
695 if (fNbEvents
<= rank
) {
696 fNbEvents
= rank
+ 1;
698 if (fIndexer
!= null) {
699 fIndexer
.updateIndex(context
, timestamp
);
704 // ------------------------------------------------------------------------
706 // ------------------------------------------------------------------------
712 public synchronized ITmfContext
armRequest(final ITmfDataRequest request
) {
713 if (executorIsShutdown()) {
716 if ((request
instanceof ITmfEventRequest
)
717 && !TmfTimestamp
.BIG_BANG
.equals(((ITmfEventRequest
) request
).getRange().getStartTime())
718 && (request
.getIndex() == 0))
720 final ITmfContext context
= seekEvent(((ITmfEventRequest
) request
).getRange().getStartTime());
721 ((ITmfEventRequest
) request
).setStartIndex((int) context
.getRank());
725 return seekEvent(request
.getIndex());
728 // ------------------------------------------------------------------------
730 // ------------------------------------------------------------------------
733 * Handler for the Trace Opened signal
736 * The incoming signal
740 public void traceOpened(TmfTraceOpenedSignal signal
) {
741 boolean signalIsForUs
= false;
742 for (ITmfTrace trace
: TmfTraceManager
.getTraceSet(signal
.getTrace())) {
744 signalIsForUs
= true;
749 if (!signalIsForUs
) {
754 * The signal is either for this trace, or for an experiment containing
757 MultiStatus status
= new MultiStatus(Activator
.PLUGIN_ID
, IStatus
.OK
, null, null);
758 status
.add(buildStatistics());
759 status
.add(buildStateSystem());
760 status
.add(executeAnalysis());
761 if (!status
.isOK()) {
762 Activator
.log(status
);
765 /* Refresh the project, so it can pick up new files that got created. */
767 if (fResource
!= null) {
768 fResource
.getProject().refreshLocal(IResource
.DEPTH_INFINITE
, null);
770 } catch (CoreException e
) {
774 if (signal
.getTrace() == this) {
775 /* Additionally, the signal is directly for this trace. */
776 if (getNbEvents() == 0) {
780 /* For a streaming trace, the range updated signal should be sent
781 * by the subclass when a new safe time is determined.
783 if (getStreamingInterval() > 0) {
787 final TmfTimeRange timeRange
= new TmfTimeRange(getStartTime(), TmfTimestamp
.BIG_CRUNCH
);
788 final TmfTraceRangeUpdatedSignal rangeUpdatedsignal
= new TmfTraceRangeUpdatedSignal(this, this, timeRange
);
790 // Broadcast in separate thread to prevent deadlock
794 broadcast(rangeUpdatedsignal
);
802 * Signal handler for the TmfTraceRangeUpdatedSignal signal
804 * @param signal The incoming signal
808 public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal
) {
809 if (signal
.getTrace() == this) {
810 getIndexer().buildIndex(getNbEvents(), signal
.getRange(), false);
815 * Signal handler for the TmfTraceUpdatedSignal signal
817 * @param signal The incoming signal
821 public void traceUpdated(final TmfTraceUpdatedSignal signal
) {
822 if (signal
.getSource() == getIndexer()) {
823 fNbEvents
= signal
.getNbEvents();
824 fStartTime
= signal
.getRange().getStartTime();
825 fEndTime
= signal
.getRange().getEndTime();
830 * Returns the file resource used to store synchronization formula. The file
833 * @return the synchronization file
835 private File
getSyncFormulaFile() {
837 if (fResource
instanceof IFolder
) {
839 String supplDirectory
;
841 supplDirectory
= fResource
.getPersistentProperty(TmfCommonConstants
.TRACE_SUPPLEMENTARY_FOLDER
);
843 file
= new File(supplDirectory
+ File
.separator
+ SYNCHRONIZATION_FORMULA_FILE
);
845 } catch (CoreException e
) {
852 // ------------------------------------------------------------------------
853 // Timestamp transformation functions
854 // ------------------------------------------------------------------------
860 public ITmfTimestampTransform
getTimestampTransform() {
861 if (fTsTransform
== null) {
862 /* Check if a formula is stored somewhere in the resources */
863 File sync_file
= getSyncFormulaFile();
864 if (sync_file
!= null && sync_file
.exists()) {
867 FileInputStream fis
= new FileInputStream(sync_file
);
868 ObjectInputStream ois
= new ObjectInputStream(fis
);
869 fTsTransform
= (ITmfTimestampTransform
) ois
.readObject();
873 } catch (ClassNotFoundException e1
) {
874 fTsTransform
= TmfTimestampTransform
.IDENTITY
;
875 } catch (FileNotFoundException e1
) {
876 fTsTransform
= TmfTimestampTransform
.IDENTITY
;
877 } catch (IOException e1
) {
878 fTsTransform
= TmfTimestampTransform
.IDENTITY
;
881 fTsTransform
= TmfTimestampTransform
.IDENTITY
;
891 public void setTimestampTransform(final ITmfTimestampTransform tt
) {
894 /* Save the timestamp transform to a file */
895 File sync_file
= getSyncFormulaFile();
896 if (sync_file
!= null) {
897 if (sync_file
.exists()) {
900 FileOutputStream fos
;
901 ObjectOutputStream oos
;
903 /* Save the header of the file */
905 fos
= new FileOutputStream(sync_file
, false);
906 oos
= new ObjectOutputStream(fos
);
908 oos
.writeObject(fTsTransform
);
911 } catch (IOException e1
) {
912 Activator
.logError("Error writing timestamp transform for trace", e1
); //$NON-NLS-1$
921 public ITmfTimestamp
createTimestamp(long ts
) {
922 return new TmfTimestamp(getTimestampTransform().transform(ts
));
925 // ------------------------------------------------------------------------
927 // ------------------------------------------------------------------------
930 @SuppressWarnings("nls")
931 public synchronized String
toString() {
932 return "TmfTrace [fPath=" + fPath
+ ", fCacheSize=" + fCacheSize
933 + ", fNbEvents=" + fNbEvents
+ ", fStartTime=" + fStartTime
934 + ", fEndTime=" + fEndTime
+ ", fStreamingInterval=" + fStreamingInterval
+ "]";