package org.eclipse.linuxtools.tmf.core.trace;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.Set;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.linuxtools.internal.tmf.core.Activator;
-import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule;
import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper;
import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal;
-import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform;
-import org.eclipse.linuxtools.tmf.core.synchronization.TmfTimestampTransform;
+import org.eclipse.linuxtools.tmf.core.synchronization.TimestampTransformFactory;
import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer;
* accomplish this is by making the concrete class extend TmfTrace and
* implement ITmfEventParser.
* <p>
+ * When constructing an event, the concrete trace should use the trace's
+ * timestamp transform to create the timestamp, by either transforming the
+ * parsed time value directly or by using the method createTimestamp().
+ * <p>
* The concrete class can either specify its own indexer or use the provided
* TmfCheckpointIndexer (default). In this case, the trace cache size will be
* used as checkpoint interval.
* @see ITmfTraceIndexer
* @see ITmfEventParser
*/
-public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace {
+public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace, ITmfTraceCompleteness {
// ------------------------------------------------------------------------
// Attributes
private int fCacheSize = ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
// The number of events collected (so far)
- private long fNbEvents = 0;
+ private volatile long fNbEvents = 0;
// The time span of the event stream
private ITmfTimestamp fStartTime = TmfTimestamp.BIG_BANG;
// The trace parser
private ITmfEventParser fParser;
-
- /**
- * The collection of state systems that are registered with this trace. Each
- * sub-class can decide to add its (one or many) state system to this map
- * during their {@link #buildStateSystem()}.
- *
- * @since 2.0
- */
- @Deprecated
- protected final Map<String, ITmfStateSystem> fStateSystems = new LinkedHashMap<>();
-
private ITmfTimestampTransform fTsTransform;
private final Map<String, IAnalysisModule> fAnalysisModules =
Collections.synchronizedMap(new LinkedHashMap<String, IAnalysisModule>());
- private static final String SYNCHRONIZATION_FORMULA_FILE = "sync_formula"; //$NON-NLS-1$
-
// ------------------------------------------------------------------------
// Construction
// ------------------------------------------------------------------------
// ITmfTrace - Initializers
// ------------------------------------------------------------------------
+ @Override
+ public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type, String name) throws TmfTraceException {
+ setName(name);
+ initTrace(resource, path, type);
+ }
+
@Override
public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException {
initialize(resource, path, type);
}
fPath = path;
fResource = resource;
- String traceName = (resource != null) ? resource.getName() : null;
- // If no resource was provided, extract the display name the trace path
- if (traceName == null) {
- traceName = new Path(path).lastSegment();
+ String traceName = getName();
+ if (traceName == null || traceName.isEmpty()) {
+ traceName = (resource != null) ? resource.getName() : new Path(path).lastSegment();
}
if (fParser == null) {
if (this instanceof ITmfEventParser) {
super.init(traceName, type);
// register as VIP after super.init() because TmfComponent registers to signal manager there
TmfSignalManager.registerVIP(this);
+ if (fIndexer != null) {
+ fIndexer.dispose();
+ }
fIndexer = createIndexer(fCacheSize);
}
getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, waitForCompletion);
}
- /**
- * Build the state system(s) associated with this trace type.
- *
- * @return An IStatus indicating if the state system could be build
- * successfully or not.
- * @since 3.0
- */
- @Deprecated
- protected IStatus buildStateSystem() {
- /*
- * Nothing is done in the base implementation, please specify
- * how/if to register a new state system in derived classes.
- */
- return Status.OK_STATUS;
- }
-
/**
* Instantiate the applicable analysis modules and executes the analysis
* modules that are meant to be automatically executed
status.add(module.schedule());
}
} catch (TmfAnalysisException e) {
- status.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
+ status.add(new Status(IStatus.WARNING, Activator.PLUGIN_ID, e.getMessage()));
}
}
return status;
getIndexer().dispose();
}
- /* Clean up the state systems */
- for (ITmfStateSystem ss : fStateSystems.values()) {
- ss.dispose();
- }
-
/* Clean up the analysis modules */
synchronized (fAnalysisModules) {
for (IAnalysisModule module : fAnalysisModules.values()) {
module.dispose();
}
+ fAnalysisModules.clear();
}
super.dispose();
return fParser;
}
- /**
- * @since 2.0
- * @deprecated See {@link ITmfTrace}
- */
- @Deprecated
- @Override
- public final Map<String, ITmfStateSystem> getStateSystems() {
- return Collections.unmodifiableMap(fStateSystems);
- }
-
- /**
- * @since 2.0
- * @deprecated See {@link ITmfTrace}
- */
- @Deprecated
- @Override
- public final void registerStateSystem(String id, ITmfStateSystem ss) {
- fStateSystems.put(id, ss);
- }
-
// ------------------------------------------------------------------------
// ITmfTrace - Trace characteristics getters
// ------------------------------------------------------------------------
@Override
- public synchronized long getNbEvents() {
+ public long getNbEvents() {
return fNbEvents;
}
* The signal is either for this trace, or for an experiment containing
* this trace.
*/
- MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
- status.add(buildStateSystem());
- status.add(executeAnalysis());
+ IStatus status = executeAnalysis();
if (!status.isOK()) {
Activator.log(status);
}
- refreshSupplementaryFiles();
+ TmfTraceManager.refreshSupplementaryFiles(this);
if (signal.getTrace() == this) {
/* Additionally, the signal is directly for this trace. */
return;
}
- final TmfTimeRange timeRange = new TmfTimeRange(getStartTime(), TmfTimestamp.BIG_CRUNCH);
- final TmfTraceRangeUpdatedSignal rangeUpdatedsignal = new TmfTraceRangeUpdatedSignal(this, this, timeRange);
-
- // Broadcast in separate thread to prevent deadlock
- broadcastAsync(rangeUpdatedsignal);
- return;
- }
- }
+ if (isComplete()) {
+ final TmfTimeRange timeRange = new TmfTimeRange(getStartTime(), TmfTimestamp.BIG_CRUNCH);
+ final TmfTraceRangeUpdatedSignal rangeUpdatedsignal = new TmfTraceRangeUpdatedSignal(this, this, timeRange);
- /**
- * Refresh the supplementary files resources, so it can pick up new files
- * that got created.
- * @since 3.0
- */
- public void refreshSupplementaryFiles() {
- if (fResource != null) {
- IProject project = fResource.getProject();
- IFolder supplFolder = project.getFolder(TmfCommonConstants.TRACE_SUPPLEMENATARY_FOLDER_NAME);
- if (supplFolder.exists()) {
- try {
- supplFolder.refreshLocal(IResource.DEPTH_INFINITE, null);
- } catch (CoreException e) {
- Activator.logError("Error refreshing resources", e); //$NON-NLS-1$
- }
+ // Broadcast in separate thread to prevent deadlock
+ broadcastAsync(rangeUpdatedsignal);
}
+ return;
}
}
}
}
- /**
- * Returns the file resource used to store synchronization formula. The file
- * may not exist.
- *
- * @return the synchronization file
- */
- private File getSyncFormulaFile() {
- File file = null;
- if (fResource instanceof IFolder) {
- try {
- String supplDirectory;
-
- supplDirectory = fResource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER);
-
- file = new File(supplDirectory + File.separator + SYNCHRONIZATION_FORMULA_FILE);
-
- } catch (CoreException e) {
-
- }
- }
- return file;
- }
-
// ------------------------------------------------------------------------
// Timestamp transformation functions
// ------------------------------------------------------------------------
@Override
public ITmfTimestampTransform getTimestampTransform() {
if (fTsTransform == null) {
- /* Check if a formula is stored somewhere in the resources */
- File sync_file = getSyncFormulaFile();
- if (sync_file != null && sync_file.exists()) {
-
- try (FileInputStream fis = new FileInputStream(sync_file);
- ObjectInputStream ois = new ObjectInputStream(fis);) {
-
- fTsTransform = (ITmfTimestampTransform) ois.readObject();
-
- } catch (ClassNotFoundException | IOException e) {
- fTsTransform = TmfTimestampTransform.IDENTITY;
- }
- } else {
- fTsTransform = TmfTimestampTransform.IDENTITY;
- }
+ fTsTransform = TimestampTransformFactory.getTimestampTransform(getResource());
}
return fTsTransform;
}
@Override
public void setTimestampTransform(final ITmfTimestampTransform tt) {
fTsTransform = tt;
-
- /* Save the timestamp transform to a file */
- File sync_file = getSyncFormulaFile();
- if (sync_file != null) {
- if (sync_file.exists()) {
- sync_file.delete();
- }
- FileOutputStream fos;
- ObjectOutputStream oos;
-
- /* Save the header of the file */
- try {
- fos = new FileOutputStream(sync_file, false);
- oos = new ObjectOutputStream(fos);
-
- oos.writeObject(fTsTransform);
- oos.close();
- fos.close();
- } catch (IOException e1) {
- Activator.logError("Error writing timestamp transform for trace", e1); //$NON-NLS-1$
- }
- }
+ TimestampTransformFactory.setTimestampTransform(getResource(), tt);
}
/**
*/
@Override
public ITmfTimestamp createTimestamp(long ts) {
- return new TmfTimestamp(getTimestampTransform().transform(ts));
+ return new TmfNanoTimestamp(getTimestampTransform().transform(ts));
}
// ------------------------------------------------------------------------
+ ", fEndTime=" + fEndTime + ", fStreamingInterval=" + fStreamingInterval + "]";
}
+ /**
+ * @since 3.1
+ */
+ @Override
+ public boolean isComplete() {
+ /*
+ * Be default, all traces are "complete" which means no more data will
+ * be added later
+ */
+ return true;
+ }
+
+ /**
+ * @since 3.1
+ */
+ @Override
+ public void setComplete(boolean isComplete) {
+ /*
+ * This should be overridden by trace classes that can support live
+ * reading (traces in an incomplete state)
+ */
+ }
}