/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal
+ * Copyright (c) 2012, 2015 Ericsson, École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0 which
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.ctf.core.CTFException;
import org.eclipse.tracecompass.ctf.core.event.CTFCallsite;
import org.eclipse.tracecompass.ctf.core.event.CTFClock;
import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration;
-import org.eclipse.tracecompass.ctf.core.trace.CTFReaderException;
import org.eclipse.tracecompass.ctf.core.trace.CTFTrace;
import org.eclipse.tracecompass.ctf.core.trace.CTFTraceReader;
+import org.eclipse.tracecompass.ctf.core.trace.Metadata;
import org.eclipse.tracecompass.internal.tmf.ctf.core.Activator;
import org.eclipse.tracecompass.internal.tmf.ctf.core.trace.iterator.CtfIterator;
import org.eclipse.tracecompass.internal.tmf.ctf.core.trace.iterator.CtfIteratorManager;
import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceProperties;
import org.eclipse.tracecompass.tmf.ctf.core.event.aspect.CtfChannelAspect;
import org.eclipse.tracecompass.tmf.ctf.core.event.aspect.CtfCpuAspect;
import org.eclipse.tracecompass.tmf.ctf.core.event.lookup.CtfTmfCallsite;
-import org.eclipse.tracecompass.tmf.ctf.core.timestamp.CtfTmfTimestamp;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
/**
* Event aspects available for all CTF traces
+ * @since 1.0
*/
protected static final @NonNull Collection<ITmfEventAspect> CTF_ASPECTS =
checkNotNull(ImmutableList.of(
*/
private static final String CLOCK_HOST_PROPERTY = "uuid"; //$NON-NLS-1$
private static final int CONFIDENCE = 10;
+ private static final int MIN_CONFIDENCE = 1;
// -------------------------------------------
// Fields
}
}
}
- } catch (final CTFReaderException e) {
+ } catch (final CTFException e) {
/*
* If it failed at the init(), we can assume it's because the file
* was not found or was not recognized as a CTF trace. Throw into
}
}
- /**
- * Return the iterator manager of this trace
- *
- * @return The iterator manager
- */
- public CtfIteratorManager getIteratorManager() {
- return fIteratorManager;
- }
-
@Override
public void close() {
dispose();
/**
* {@inheritDoc}
* <p>
- * The default implementation sets the confidence to 10 if the trace is a
- * valid CTF trace.
+ * The default implementation of a CTF trace.
+ *
+ * Firstly a weak validation of the metadata is done to determine if the
+ * path is actually for a CTF trace. After that a full validation is done.
+ *
+ * If the weak and full validation are successful the confidence is set
+ * to 10.
+ *
+ * If the weak validation was successful, but the full validation fails
+ * a TraceValidationStatus with severity warning and confidence of 1 is
+ * returned.
+ *
+ * If both weak and full validation fails an error status is returned.
*/
@Override
public IStatus validate(final IProject project, final String path) {
- IStatus status = new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID);
+ boolean isMetadataFile = false;
try {
- final CTFTrace temp = new CTFTrace(path);
- if (!temp.majorIsSet()) {
- status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_MajorNotSet);
- } else {
- try (CTFTraceReader ctfTraceReader = new CTFTraceReader(temp);) {
- if (!ctfTraceReader.hasMoreEvents()) {
- // TODO: This will need an additional check when we
- // support live traces
- // because having no event is valid for a live trace
- status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_NoEvent);
+ isMetadataFile = Metadata.preValidate(path);
+ } catch (final CTFException e) {
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError + ": " + e.toString(), e); //$NON-NLS-1$
+ }
+
+ if (isMetadataFile) {
+ // Trace is pre-validated, continue will full validation
+ try {
+ final CTFTrace trace = new CTFTrace(path);
+ if (!trace.majorIsSet()) {
+ if (isMetadataFile) {
+ return new TraceValidationStatus(MIN_CONFIDENCE, IStatus.WARNING, Activator.PLUGIN_ID, Messages.CtfTmfTrace_MajorNotSet, null);
}
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_MajorNotSet);
}
+
+ // Validate using reader initialization
+ try (CTFTraceReader ctfTraceReader = new CTFTraceReader(trace)) {}
+
+ // Trace is validated, return with confidence
+ return new CtfTraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID, trace.getEnvironment());
+
+ } catch (final CTFException | BufferOverflowException e ) {
+ // return warning since it's a CTF trace but with errors in it
+ return new TraceValidationStatus(MIN_CONFIDENCE, IStatus.WARNING, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError + ": " + e.toString(), e); //$NON-NLS-1$
}
- } catch (final CTFReaderException e) {
- status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError + ": " + e.toString()); //$NON-NLS-1$
- } catch (final BufferOverflowException e) {
- status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError + ": " + Messages.CtfTmfTrace_BufferOverflowErrorMessage); //$NON-NLS-1$
}
-
- return status;
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError);
}
@Override
*
* @return null, since the trace has no knowledge of the current location
* @see org.eclipse.tracecompass.tmf.core.trace.ITmfTrace#getCurrentLocation()
- * @since 3.0
*/
@Override
public ITmfLocation getCurrentLocation() {
return null;
}
- /**
- * @since 3.0
- */
@Override
public double getLocationRatio(ITmfLocation location) {
final CtfLocation curLocation = (CtfLocation) location;
- final CtfTmfContext context = new CtfTmfContext(this);
- context.setLocation(curLocation);
- context.seek(curLocation.getLocationInfo());
- final CtfLocationInfo currentTime = ((CtfLocationInfo) context.getLocation().getLocationInfo());
- final long startTime = fIteratorManager.getIterator(context).getStartTime();
- final long endTime = fIteratorManager.getIterator(context).getEndTime();
- return ((double) currentTime.getTimestamp() - startTime)
- / (endTime - startTime);
+ final long startTime = getStartTime().getValue();
+ final double diff = curLocation.getLocationInfo().getTimestamp() - startTime;
+ final double total = getEndTime().getValue() - startTime;
+ return Math.max(0.0, Math.min(1.0, diff / total));
}
/**
* @param location
* ITmfLocation<?>
* @return ITmfContext
- * @since 3.0
*/
@Override
public synchronized ITmfContext seekEvent(final ITmfLocation location) {
if (currentLocation == null) {
currentLocation = new CtfLocation(new CtfLocationInfo(0L, 0L));
context.setRank(0);
- }
- if (currentLocation.getLocationInfo() == CtfLocation.INVALID_LOCATION) {
- currentLocation = new CtfLocation(fTrace.getCurrentEndTime() + 1, 0L);
- }
- context.setLocation(currentLocation);
- if (location == null) {
- long timestamp = fIteratorManager.getIterator(context).getCurrentTimestamp();
- currentLocation = new CtfLocation(timestamp, 0);
- }
- if (context.getRank() != 0) {
+ } else {
context.setRank(ITmfContext.UNKNOWN_RANK);
+ if (currentLocation.getLocationInfo() == CtfLocation.INVALID_LOCATION) {
+ currentLocation = new CtfLocation(fTrace.getCurrentEndTime() + 1, 0L);
+ }
}
+ /* This will seek and update the location after the seek */
+ context.setLocation(currentLocation);
return context;
}
context.setRank(ITmfContext.UNKNOWN_RANK);
return context;
}
- final long end = fTrace.getCurrentEndTime();
- final long start = fTrace.getCurrentStartTime();
+ final long end = getEndTime().getValue();
+ final long start = getStartTime().getValue();
final long diff = end - start;
final long ratioTs = Math.round(diff * ratio) + start;
context.seek(ratioTs);
// ITmfTraceProperties
// -------------------------------------------
- /**
- * @since 2.0
- */
@Override
public Map<String, String> getTraceProperties() {
Map<String, String> properties = new HashMap<>();
/**
* Gets the list of declared events
- *
- * @since 3.0
*/
@Override
public Set<CtfTmfEventType> getContainedEventTypes() {
* Get an iterator to the trace
*
* @return an iterator to the trace
- * @since 2.0
*/
public ITmfContext createIterator() {
try {
return new CtfIterator(fTrace, this);
- } catch (CTFReaderException e) {
+ } catch (CTFException e) {
Activator.getDefault().logError(e.getMessage(), e);
}
return null;
public ITmfContext createIterator(CtfLocationInfo ctfLocationData, long rank) {
try {
return new CtfIterator(fTrace, this, ctfLocationData, rank);
- } catch (CTFReaderException e) {
+ } catch (CTFException e) {
Activator.getDefault().logError(e.getMessage(), e);
}
return null;
}
+ /**
+ * Create the 'CtfIterator' object from a CtfTmfContext.
+ *
+ * @param context
+ * The iterator will initially be pointing to this context
+ * @return A new CtfIterator object
+ * @since 1.0
+ */
+ public ITmfContext createIteratorFromContext(CtfTmfContext context) {
+ return fIteratorManager.getIterator(context);
+ }
+
+ /**
+ * Dispose an iterator that was create with
+ * {@link #createIteratorFromContext}
+ *
+ * @param context
+ * The last context that was pointed to by the iterator (this is
+ * the 'key' to find the correct iterator to dispose).
+ * @since 1.0
+ */
+ public void disposeContext(CtfTmfContext context) {
+ fIteratorManager.removeIterator(context);
+ }
+
// ------------------------------------------------------------------------
// Timestamp transformation functions
// ------------------------------------------------------------------------
/**
- * @since 3.0
+ * @since 1.0
*/
@Override
- public CtfTmfTimestamp createTimestamp(long ts) {
- return new CtfTmfTimestamp(getTimestampTransform().transform(ts));
+ public @NonNull TmfNanoTimestamp createTimestamp(long ts) {
+ return new TmfNanoTimestamp(getTimestampTransform().transform(ts));
}
private static int fCheckpointSize = -1;
- /**
- * @since 3.0
- */
@Override
public synchronized int getCheckpointSize() {
if (fCheckpointSize == -1) {
- TmfCheckpoint c = new TmfCheckpoint(new CtfTmfTimestamp(0), new CtfLocation(0, 0), 0);
+ TmfCheckpoint c = new TmfCheckpoint(new TmfNanoTimestamp(0), new CtfLocation(0, 0), 0);
ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE);
b.clear();
c.serialize(b);
return new TmfBTreeTraceIndexer(this, interval);
}
- /**
- * @since 3.0
- */
@Override
public ITmfLocation restoreLocation(ByteBuffer bufferIn) {
return new CtfLocation(bufferIn);