-package org.eclipse.linuxtools.tmf.core.ctfadaptor;
+/*******************************************************************************
+ * Copyright (c) 2012 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors: Matthew Khouzam - Initial API and implementation
+ *******************************************************************************/
-import java.io.FileNotFoundException;
+package org.eclipse.linuxtools.tmf.core.ctfadaptor;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
import org.eclipse.linuxtools.ctf.core.trace.CTFTrace;
-import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTimestamp.TimestampType;
import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
-import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
-import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
-import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
-import org.eclipse.linuxtools.tmf.core.signal.TmfSignal;
-import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemQuerier;
import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;
import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
-import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
-
-public class CtfTmfTrace extends TmfEventProvider<CtfTmfEvent> implements
- ITmfTrace<CtfTmfEvent> {
+import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
- // ------------------------------------------------------------------------
- // Constants
- // ------------------------------------------------------------------------
+/**
+ * The CTf trace handler
+ *
+ * @version 1.0
+ * @author Matthew khouzam
+ */
+public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
- // ------------------------------------------------------------------------
- // Attributes
- // ------------------------------------------------------------------------
- // the Ctf Trace
- private CTFTrace fTrace;
-
- // The number of events collected
- protected long fNbEvents = 0;
+ //-------------------------------------------
+ // Constants
+ //-------------------------------------------
+ /**
+ * Default cache size for CTF traces
+ */
+ protected static final int DEFAULT_CACHE_SIZE = 50000;
- // The time span of the event stream
- private ITmfTimestamp fStartTime = TmfTimestamp.BIG_CRUNCH;
- private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG;
+ //-------------------------------------------
+ // Fields
+ //-------------------------------------------
- // The trace resource
- private IResource fResource;
+ /** Reference to the state system assigned to this trace */
+ protected IStateSystemQuerier ss = null;
- /*
- * Since in TMF, "traces" can read events, this trace here will have its own
- * iterator. The user can instantiate extra iterator if they want to seek at
- * many places at the same time.
- */
- protected CtfIterator iterator;
+ /* Reference to the CTF Trace */
+ private CTFTrace fTrace;
- // ------------------------------------------------------------------------
- // Constructors
- // ------------------------------------------------------------------------
- public CtfTmfTrace() {
- super();
- }
+ //-------------------------------------------
+ // TmfTrace Overrides
+ //-------------------------------------------
+ /**
+ * Method initTrace.
+ *
+ * @param resource
+ * The resource associated with this trace
+ * @param path
+ * The path to the trace file
+ * @param eventType
+ * The type of events that will be read from this trace
+ * @throws TmfTraceException
+ * If something when wrong while reading the trace
+ */
@Override
- public void initTrace(String name, String path, Class<CtfTmfEvent> eventType)
- throws FileNotFoundException {
+ public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> eventType)
+ throws TmfTraceException {
+ /*
+ * Set the cache size. This has to be done before the call to super()
+ * because the super needs to know the cache size.
+ */
+ setCacheSize();
+ super.initTrace(resource, path, eventType);
+
+ @SuppressWarnings("unused")
+ CtfTmfEventType type;
+
try {
this.fTrace = new CTFTrace(path);
- } catch (CTFReaderException e) {
+ CtfIteratorManager.addTrace(this);
+ CtfTmfLightweightContext ctx;
+ /* Set the start and (current) end times for this trace */
+ ctx = (CtfTmfLightweightContext) seekEvent(0L);
+ CtfTmfEvent event = getNext(ctx);
+ if((ctx.getLocation().equals(CtfIterator.NULL_LOCATION)) || (ctx.getCurrentEvent() == null)) {
+ /* Handle the case where the trace is empty */
+ this.setStartTime(TmfTimestamp.BIG_BANG);
+ } else {
+ final ITmfTimestamp curTime = event.getTimestamp();
+ this.setStartTime(curTime);
+ this.setEndTime(curTime);
+ }
+
+ } catch (final CTFReaderException 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
* the new type of exception expected by the rest of TMF.
*/
- System.err.println("Cannot find file " + path); //$NON-NLS-1$
- throw new FileNotFoundException(e.getMessage());
+ throw new TmfTraceException(e.getMessage(), e);
}
- this.iterator = new CtfIterator(this, 0, 0);
- setStartTime(iterator.getCurrentEvent().getTimestamp());
- TmfSignalManager.register(this);
- // this.currLocation.setTimestamp(this.fEvent.getTimestamp().getValue());
- // this.fStartTime = new TmfSimpleTimestamp(this.currLocation
- // .getLocation().getStartTime());
- // this.fEndTime = new TmfSimpleTimestamp(this.currLocation
- // .getLocation().getEndTime());
- // setTimeRange(new TmfTimeRange(this.fStartTime.clone(),
- // this.fEndTime.clone()));
- }
+ //FIXME This should be called via the ExperimentUpdated signal
+ buildStateSystem();
-
- @Override
- public void indexTrace(boolean waitForCompletion) {
- }
-
- @Override
- public void dispose() {
- TmfSignalManager.deregister(this);
+ /* Refresh the project, so it can pick up new files that got created. */
+ if ( resource != null) {
+ try {
+ resource.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
+ } catch (CoreException e) {
+ throw new TmfTraceException(e.getMessage(), e);
+ }
+ }
}
+ /* (non-Javadoc)
+ * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#dispose()
+ */
@Override
- public void broadcast(TmfSignal signal) {
- TmfSignalManager.dispatchSignal(signal);
+ public synchronized void dispose() {
+ CtfIteratorManager.removeTrace(this);
+ super.dispose();
}
+ /**
+ * Method validate.
+ * @param project IProject
+ * @param path String
+ * @return boolean
+ * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String)
+ */
@Override
- public boolean validate(IProject project, String path) {
+ public boolean validate(final IProject project, final String path) {
try {
final CTFTrace temp = new CTFTrace(path);
return temp.majortIsSet(); // random test
- } catch (CTFReaderException e) {
+ } catch (final CTFReaderException e) {
/* Nope, not a CTF trace we can read */
return false;
}
}
- @Override
- public CtfTmfTrace clone() throws CloneNotSupportedException {
- CtfTmfTrace clone = null;
- clone = (CtfTmfTrace) super.clone();
- clone.fStartTime = this.fStartTime.clone();
- clone.fEndTime = this.fEndTime.clone();
- clone.fTrace = this.fTrace;
- return clone;
- }
-
- // ------------------------------------------------------------------------
- // Accessors
- // ------------------------------------------------------------------------
-
/**
- * @return the trace path
+ * Method getCurrentLocation. This is not applicable in CTF
+ * @return null, since the trace has no knowledge of the current location
+ * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
*/
@Override
- public String getPath() {
- return this.fTrace.getPath();
+ public ITmfLocation getCurrentLocation() {
+ return null;
}
- @Override
- public String getName() {
- String temp[] = this.fTrace.getPath().split(
- System.getProperty("file.separator")); //$NON-NLS-1$
- if (temp.length > 2) {
- return temp[temp.length - 1];
- }
- return temp[0];
- }
- @Override
- public int getIndexPageSize() {
- return this.fIndexPageSize;
- }
@Override
- public long getNbEvents() {
- return this.fNbEvents;
+ public double getLocationRatio(ITmfLocation location) {
+ final CtfLocation curLocation = (CtfLocation) location;
+ final CtfTmfLightweightContext context = new CtfTmfLightweightContext(this);
+ context.setLocation(curLocation);
+ context.seek(curLocation.getLocationData());
+ final CtfLocationData currentTime = ((CtfLocationData)context.getLocation().getLocationData());
+ final long startTime = getIterator(this, context).getStartTime();
+ final long endTime = getIterator(this, context).getEndTime();
+ return ((double) currentTime.getTimestamp() - startTime)
+ / (endTime - startTime);
}
- @Override
- public TmfTimeRange getTimeRange() {
- return new TmfTimeRange(this.fStartTime, this.fEndTime);
- }
- @Override
- public ITmfTimestamp getStartTime() {
- return this.fStartTime;
- }
- @Override
- public ITmfTimestamp getEndTime() {
- return this.fEndTime;
- }
- @Override
- public ITmfLocation<?> getCurrentLocation() {
- return iterator.getLocation();
- }
+ /* (non-Javadoc)
+ * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#seekEvent(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
+ */
@Override
- public long getRank(ITmfTimestamp timestamp) {
- ITmfContext context = seekEvent(timestamp);
- return context.getRank();
+ public synchronized ITmfContext seekEvent(ITmfTimestamp timestamp) {
+ if( timestamp instanceof CtfTmfTimestamp){
+ CtfTmfLightweightContext iter = new CtfTmfLightweightContext(this);
+ iter.seek(timestamp.getValue());
+ return iter;
+ }
+ return super.seekEvent(timestamp);
}
- // ------------------------------------------------------------------------
- // Operators
- // ------------------------------------------------------------------------
-
- protected void setTimeRange(TmfTimeRange range) {
- this.fStartTime = range.getStartTime();
- this.fEndTime = range.getEndTime();
+ /**
+ * Method seekEvent.
+ * @param location ITmfLocation<?>
+ * @return ITmfContext
+ */
+ @Override
+ public ITmfContext seekEvent(final ITmfLocation location) {
+ CtfLocation currentLocation = (CtfLocation) location;
+ CtfTmfLightweightContext context = new CtfTmfLightweightContext(this);
+ /*
+ * The rank is set to 0 if the iterator seeks the beginning. If not, it
+ * will be set to UNKNOWN_RANK, since CTF traces don't support seeking
+ * by rank for now.
+ */
+ if (currentLocation == null) {
+ currentLocation = new CtfLocation(new CtfLocationData(0L, 0L));
+ context.setRank(0);
+ }
+ if (currentLocation.getLocationData() == CtfLocation.INVALID_LOCATION) {
+ ((CtfTmfTimestamp) getEndTime()).setType(TimestampType.NANOS);
+ currentLocation.setLocation(getEndTime().getValue() + 1, 0L);
+ }
+ context.setLocation(currentLocation);
+ if (location == null) {
+ CtfTmfEvent event = getIterator(this, context).getCurrentEvent();
+ if (event != null) {
+ currentLocation.setLocation(event.getTimestamp().getValue(), 0);
+ }
+ }
+ if(context.getRank() != 0) {
+ context.setRank(ITmfContext.UNKNOWN_RANK);
+ }
+ return context;
}
- protected void setStartTime(ITmfTimestamp startTime) {
- this.fStartTime = startTime;
- }
- protected void setEndTime(ITmfTimestamp endTime) {
- this.fEndTime = endTime;
+ @Override
+ public ITmfContext seekEvent(double ratio) {
+ CtfTmfLightweightContext context = new CtfTmfLightweightContext(this);
+ final long end = this.getEndTime().getValue();
+ final long start = this.getStartTime().getValue();
+ final long diff = end - start;
+ final long ratioTs = (long) (diff * ratio) + start;
+ context.seek(ratioTs);
+ context.setRank(ITmfContext.UNKNOWN_RANK);
+ return context;
}
- // ------------------------------------------------------------------------
- // TmfProvider
- // ------------------------------------------------------------------------
-
+ /**
+ * Method readNextEvent.
+ * @param context ITmfContext
+ * @return CtfTmfEvent
+ * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNext(ITmfContext)
+ */
@Override
- public ITmfContext armRequest(ITmfDataRequest<CtfTmfEvent> request) {
- if ((request instanceof ITmfEventRequest<?>)
- && !TmfTimestamp.BIG_BANG
- .equals(((ITmfEventRequest<CtfTmfEvent>) request)
- .getRange().getStartTime())
- && (request.getIndex() == 0)) {
- ITmfContext context = seekEvent(((ITmfEventRequest<CtfTmfEvent>) request)
- .getRange().getStartTime());
- ((ITmfEventRequest<CtfTmfEvent>) request)
- .setStartIndex((int) context.getRank());
- return context;
+ public synchronized CtfTmfEvent getNext(final ITmfContext context) {
+ CtfTmfEvent event = null;
+ if (context instanceof CtfTmfLightweightContext) {
+ if (CtfLocation.INVALID_LOCATION.equals(context.getLocation().getLocationData())) {
+ return null;
+ }
+ CtfTmfLightweightContext ctfContext = (CtfTmfLightweightContext) context;
+ event = ctfContext.getCurrentEvent();
+
+ if (event != null) {
+ updateAttributes(context, event.getTimestamp());
+ ctfContext.advance();
+ ctfContext.increaseRank();
+ }
}
- return seekEvent(request.getIndex());
+
+ return event;
}
/**
- * The trace reader keeps its own iterator: the "context" parameter here
- * will be ignored.
- *
- * If you wish to specify a new context, instantiate a new CtfIterator and
- * seek() it to where you want, and use that to read events.
+ * Suppressing the warning, because the 'throws' will usually happen in
+ * sub-classes.
*
- * FIXME merge with getNextEvent below once they both use the same parameter
- * type.
+ * @throws TmfTraceException
*/
- @Override
- public CtfTmfEvent getNext(ITmfContext context) {
- iterator.advance();
- return iterator.getCurrentEvent();
+ @SuppressWarnings("unused")
+ protected void buildStateSystem() throws TmfTraceException {
+ /*
+ * Nothing is done in the basic implementation, please specify
+ * how/if to build a state system in derived classes.
+ */
+ return;
}
- // ------------------------------------------------------------------------
- // ITmfTrace
- // ------------------------------------------------------------------------
-
- @Override
- public ITmfContext seekLocation(ITmfLocation<?> location) {
- iterator.setLocation(location);
- return iterator;
+ /**
+ * Method getStateSystem.
+ *
+ * @return IStateSystemQuerier
+ */
+ public IStateSystemQuerier getStateSystem() {
+ return this.ss;
}
- @Override
- public double getLocationRatio(ITmfLocation<?> location) {
- CtfIterator curLocation = (CtfIterator) location;
- return ((double) curLocation.getCurrentEvent().getTimestampValue() - curLocation
- .getStartTime())
- / (curLocation.getEndTime() - curLocation.getStartTime());
+ /**
+ * gets the CTFtrace that this is wrapping
+ * @return the CTF trace
+ */
+ public CTFTrace getCTFTrace() {
+ return fTrace;
}
- @Override
- public long getStreamingInterval() {
- return 0;
- }
- @Override
- public ITmfContext seekEvent(ITmfTimestamp timestamp) {
- iterator.seek(timestamp.getValue());
- return iterator;
+ //-------------------------------------------
+ // Environment Parameters
+ //-------------------------------------------
+ /**
+ * Method getNbEnvVars.
+ *
+ * @return int
+ */
+ public int getNbEnvVars() {
+ return this.fTrace.getEnvironment().size();
}
/**
- * Seek by rank
+ * Method getEnvNames.
+ *
+ * @return String[]
*/
- @Override
- public ITmfContext seekEvent(long rank) {
- iterator.setRank(rank);
- return iterator;
+ public String[] getEnvNames() {
+ final String[] s = new String[getNbEnvVars()];
+ return this.fTrace.getEnvironment().keySet().toArray(s);
}
/**
- * Seek rank ratio
+ * Method getEnvValue.
+ *
+ * @param key
+ * String
+ * @return String
*/
- @Override
- public ITmfContext seekLocation(double ratio) {
- iterator.seek((long) (this.fNbEvents * ratio));
- return iterator;
+ public String getEnvValue(final String key) {
+ return this.fTrace.getEnvironment().get(key);
}
- @Override
- public CtfTmfEvent getNextEvent(ITmfContext context) {
- iterator.advance();
- return iterator.getCurrentEvent();
+ //-------------------------------------------
+ // Clocks
+ //-------------------------------------------
+
+ /**
+ * gets the clock offset
+ * @return the clock offset in ns
+ */
+ public long getOffset(){
+ if( fTrace != null ) {
+ return fTrace.getOffset();
+ }
+ return 0;
}
+ //-------------------------------------------
+ // Parser
+ //-------------------------------------------
+
@Override
public CtfTmfEvent parseEvent(ITmfContext context) {
- return iterator.getCurrentEvent();
+ CtfTmfEvent event = null;
+ if( context instanceof CtfTmfLightweightContext ){
+ CtfTmfLightweightContext itt = (CtfTmfLightweightContext) context.clone();
+ event = itt.getCurrentEvent();
+ }
+ return event;
}
- @Override
- public IResource getResource() {
- return this.fResource;
+ /**
+ * Sets the cache size for a CtfTmfTrace.
+ */
+ protected void setCacheSize() {
+ setCacheSize(DEFAULT_CACHE_SIZE);
}
- @Override
- public void setResource(IResource fResource) {
- this.fResource = fResource;
- }
+ //-------------------------------------------
+ // Helpers
+ //-------------------------------------------
- CTFTrace getCTFTrace() {
- return fTrace;
+ private static CtfIterator getIterator(CtfTmfTrace trace, CtfTmfLightweightContext context) {
+ return CtfIteratorManager.getIterator(trace, context);
}
-
}