/*******************************************************************************
- * Copyright (c) 2009, 2010, 2012 Ericsson
+ * Copyright (c) 2009, 2013 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* Contributors:
* Francois Chouinard - Initial API and implementation
* Francois Chouinard - Updated as per TMF Trace Model 1.0
+ * Patrick Tasse - Updated for removal of context clone
+ * Patrick Tasse - Updated for ranks in experiment location
*******************************************************************************/
package org.eclipse.linuxtools.tmf.core.trace;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentContext;
import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentLocation;
import org.eclipse.linuxtools.internal.tmf.core.trace.TmfLocationArray;
import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
-import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
-import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
-import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
-import org.eclipse.linuxtools.tmf.core.signal.TmfEndSynchSignal;
-import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentDisposedSignal;
-import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal;
-import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;
-import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentUpdatedSignal;
+import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
+import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
+import org.eclipse.linuxtools.tmf.core.signal.TmfClearExperimentSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
-import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
/**
* TmfExperiment presents a time-ordered, unified view of a set of ITmfTrace:s
* that are part of a tracing experiment.
+ *
+ * @version 1.0
+ * @author Francois Chouinard
*/
-public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements ITmfEventParser<T> {
+public class TmfExperiment extends TmfTrace implements ITmfEventParser {
// ------------------------------------------------------------------------
// Constants
// Attributes
// ------------------------------------------------------------------------
- /**
- * The currently selected experiment (null if none)
- */
- protected static TmfExperiment<?> fCurrentExperiment = null;
-
/**
* The set of traces that constitute the experiment
*/
- protected ITmfTrace<T>[] fTraces;
+ protected ITmfTrace[] fTraces;
/**
* The set of traces that constitute the experiment
// ------------------------------------------------------------------------
/**
+ * @param type the event type
+ * @param id the experiment id
+ * @param traces the experiment set of traces
+ */
+ public TmfExperiment(final Class<? extends ITmfEvent> type, final String id, final ITmfTrace[] traces) {
+ this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, null);
+ }
+
+ /**
+ * Constructor of experiment taking type, path, traces and resource
+ *
* @param type
+ * the event type
* @param id
+ * the experiment id
* @param traces
- * @throws TmfTraceException
+ * the experiment set of traces
+ * @param resource
+ * the resource associated to the experiment
*/
- public TmfExperiment(final Class<T> type, final String id, final ITmfTrace<T>[] traces) {
- this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE);
+ public TmfExperiment(final Class<? extends ITmfEvent> type, final String id, final ITmfTrace[] traces, IResource resource) {
+ this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, resource);
}
+
/**
+ * @param type the event type
+ * @param path the experiment path
+ * @param traces the experiment set of traces
+ * @param indexPageSize the experiment index page size
+ */
+ public TmfExperiment(final Class<? extends ITmfEvent> type, final String path, final ITmfTrace[] traces, final int indexPageSize) {
+ this(type, path, traces, indexPageSize, null);
+ }
+
+ /**
+ * Full constructor of an experiment, taking the type, path, traces,
+ * indexPageSize and resource
+ *
* @param type
- * @param id
+ * the event type
+ * @param path
+ * the experiment path
* @param traces
+ * the experiment set of traces
* @param indexPageSize
- * @throws TmfTraceException
+ * the experiment index page size
+ * @param resource
+ * the resource associated to the experiment
*/
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public TmfExperiment(final Class<T> type, final String path, final ITmfTrace<T>[] traces, final int indexPageSize) {
+ public TmfExperiment(final Class<? extends ITmfEvent> type, final String path, final ITmfTrace[] traces, final int indexPageSize, IResource resource) {
setCacheSize(indexPageSize);
setStreamingInterval(0);
setIndexer(new TmfCheckpointIndexer(this, indexPageSize));
setParser(this);
try {
- super.initialize(null, path, type);
+ super.initialize(resource, path, type);
} catch (TmfTraceException e) {
e.printStackTrace();
}
fTraces = traces;
- setTimeRange(TmfTimeRange.NULL_RANGE);
}
/**
* Clears the experiment
*/
@Override
- @SuppressWarnings("rawtypes")
public synchronized void dispose() {
- final TmfExperimentDisposedSignal<T> signal = new TmfExperimentDisposedSignal<T>(this, this);
- broadcast(signal);
-
- if (fCurrentExperiment == this) {
- fCurrentExperiment = null;
+ // Clean up the index if applicable
+ if (getIndexer() != null) {
+ getIndexer().dispose();
}
if (fTraces != null) {
- for (final ITmfTrace trace : fTraces)
+ for (final ITmfTrace trace : fTraces) {
trace.dispose();
+ }
fTraces = null;
}
super.dispose();
}
+ /**
+ * @param signal the clear view signal
+ * @since 2.0
+ */
+ @TmfSignalHandler
+ public void handleClearExperimentSignal(TmfClearExperimentSignal signal) {
+ dispose();
+ }
+
// ------------------------------------------------------------------------
// ITmfTrace - Initializers
// ------------------------------------------------------------------------
- /* (non-Javadoc)
- * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(org.eclipse.core.resources.IProject, java.lang.String)
- */
@Override
- public boolean validate(final IProject project, final String path) {
- return true;
+ public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) {
}
- /* (non-Javadoc)
- * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#initTrace(org.eclipse.core.resources.IResource, java.lang.String, java.lang.Class)
+ /**
+ * @since 2.0
*/
@Override
- public void initTrace(final IResource resource, final String path, final Class<T> type) {
+ public IStatus validate(final IProject project, final String path) {
+ return Status.OK_STATUS;
}
// ------------------------------------------------------------------------
// Accessors
// ------------------------------------------------------------------------
- /**
- * Selects the current, framework-wide, experiment
- *
- * @param experiment das experiment
- */
- public static void setCurrentExperiment(final TmfExperiment<?> experiment) {
- if (fCurrentExperiment != null && fCurrentExperiment != experiment) {
- fCurrentExperiment.dispose();
- }
- fCurrentExperiment = experiment;
- }
-
- /**
- * @return das experiment
- */
- public static TmfExperiment<?> getCurrentExperiment() {
- return fCurrentExperiment;
- }
-
- /**
- * Get the list of traces. Handle with care...
- *
- * @return the experiment traces
- */
- public ITmfTrace<T>[] getTraces() {
+ @Override
+ public ITmfTrace[] getTraces() {
return fTraces;
}
/**
* Returns the timestamp of the event at the requested index. If none,
* returns null.
- *
+ *
* @param index the event index (rank)
* @return the corresponding event timestamp
+ * @since 2.0
*/
public ITmfTimestamp getTimestamp(final int index) {
final ITmfContext context = seekEvent(index);
final ITmfEvent event = getNext(context);
+ context.dispose();
return (event != null) ? event.getTimestamp() : null;
}
/**
* Set the file to be used for bookmarks on this experiment
- *
+ *
* @param file the bookmarks file
*/
public void setBookmarksFile(final IFile file) {
/**
* Get the file used for bookmarks on this experiment
- *
+ *
* @return the bookmarks file or null if none is set
*/
public IFile getBookmarksFile() {
}
// ------------------------------------------------------------------------
- // ITmfTrace trace positioning
+ // Request management
// ------------------------------------------------------------------------
- /* (non-Javadoc)
- *
- * Returns a brand new context based on the location provided and
- * initializes the event queues
- *
- * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools.tmf.core.trace.ITmfLocation)
+ /**
+ * @since 2.0
*/
@Override
- public synchronized ITmfContext seekEvent(final ITmfLocation<?> location) {
+ public synchronized ITmfContext armRequest(final ITmfDataRequest request) {
+
+ // Make sure we have something to read from
+ if (fTraces == null) {
+ return null;
+ }
+
+ if (request instanceof ITmfEventRequest
+ && !TmfTimestamp.BIG_BANG.equals(((ITmfEventRequest) request).getRange().getStartTime())
+ && request.getIndex() == 0)
+ {
+ final ITmfContext context = seekEvent(((ITmfEventRequest) request).getRange().getStartTime());
+ ((ITmfEventRequest) request).setStartIndex((int) context.getRank());
+ return context;
+
+ }
+
+ return seekEvent(request.getIndex());
+ }
+
+ // ------------------------------------------------------------------------
+ // ITmfTrace trace positioning
+ // ------------------------------------------------------------------------
+
+ @Override
+ public synchronized ITmfContext seekEvent(final ITmfLocation location) {
// Validate the location
if (location != null && !(location instanceof TmfExperimentLocation)) {
return null; // Throw an exception?
return null;
}
- // Instantiate the location
- final TmfExperimentLocation expLocation = (location == null)
- ? new TmfExperimentLocation(new TmfLocationArray(new ITmfLocation<?>[fTraces.length]))
- : (TmfExperimentLocation) location.clone();
+ // Initialize the location array if necessary
+ TmfLocationArray locationArray = ((location == null) ?
+ new TmfLocationArray(fTraces.length) :
+ ((TmfExperimentLocation) location).getLocationInfo());
+
+ ITmfLocation[] locations = locationArray.getLocations();
+ long[] ranks = locationArray.getRanks();
// Create and populate the context's traces contexts
- final TmfExperimentContext context = new TmfExperimentContext(new ITmfContext[fTraces.length]);
+ final TmfExperimentContext context = new TmfExperimentContext(fTraces.length);
+ // Position the traces
+ long rank = 0;
for (int i = 0; i < fTraces.length; i++) {
// Get the relevant trace attributes
- final ITmfLocation<?> traceLocation = expLocation.getLocation().getLocations()[i];
- context.getContexts()[i] = fTraces[i].seekEvent(traceLocation);
- expLocation.getLocation().getLocations()[i] = context.getContexts()[i].getLocation().clone();
- context.getEvents()[i] = fTraces[i].getNext(context.getContexts()[i]);
+ final ITmfContext traceContext = fTraces[i].seekEvent(locations[i]);
+ context.getContexts()[i] = traceContext;
+ traceContext.setRank(ranks[i]);
+ locations[i] = traceContext.getLocation(); // update location after seek
+ context.getEvents()[i] = fTraces[i].getNext(traceContext);
+ rank += ranks[i];
}
// Finalize context
- context.setLocation(expLocation);
+ context.setLocation(new TmfExperimentLocation(new TmfLocationArray(locations, ranks)));
context.setLastTrace(TmfExperimentContext.NO_TRACE);
- context.setRank(ITmfContext.UNKNOWN_RANK);
- return (ITmfContext) context;
+ context.setRank(rank);
+
+ return context;
}
- /* (non-Javadoc)
- * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(double)
- */
+ // ------------------------------------------------------------------------
+ // ITmfTrace - SeekEvent operations (returning a trace context)
+ // ------------------------------------------------------------------------
+
@Override
public ITmfContext seekEvent(final double ratio) {
- final ITmfContext context = seekEvent((long) (ratio * getNbEvents()));
+ final ITmfContext context = seekEvent(Math.round(ratio * getNbEvents()));
return context;
}
- /* (non-Javadoc)
- * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getLocationRatio(org.eclipse.linuxtools.tmf.core.trace.ITmfLocation)
- */
@Override
- public double getLocationRatio(final ITmfLocation<?> location) {
+ public double getLocationRatio(final ITmfLocation location) {
if (location instanceof TmfExperimentLocation) {
- return (double) seekEvent(location).getRank() / getNbEvents();
+ long rank = 0;
+ TmfLocationArray locationArray = ((TmfExperimentLocation) location).getLocationInfo();
+ for (int i = 0; i < locationArray.size(); i++) {
+ rank += locationArray.getRank(i);
+ }
+ return (double) rank / getNbEvents();
}
return 0.0;
}
- /* (non-Javadoc)
- * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
- */
@Override
- public ITmfLocation<?> getCurrentLocation() {
- ITmfLocation<?>[] locations = new ITmfLocation<?>[fTraces.length];
- for (int i = 0; i < fTraces.length; i++) {
- locations[i] = fTraces[i].getCurrentLocation();
- }
- return new TmfExperimentLocation(new TmfLocationArray(locations));
+ public ITmfLocation getCurrentLocation() {
+ // never used
+ return null;
}
// ------------------------------------------------------------------------
// ITmfTrace trace positioning
// ------------------------------------------------------------------------
- /* (non-Javadoc)
- * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#getNext(org.eclipse.linuxtools.tmf.core.trace.ITmfContext)
- */
@Override
- public synchronized T getNext(final ITmfContext context) {
- final ITmfContext previousContext = (TmfExperimentContext) context.clone();
- final T event = parseEvent(context);
- if (event != null) {
- updateAttributes(previousContext, event.getTimestamp());
-
- TmfExperimentContext expContext = (TmfExperimentContext) context;
- int trace = expContext.getLastTrace();
- if (trace != TmfExperimentContext.NO_TRACE) {
- TmfExperimentLocation location = (TmfExperimentLocation) expContext.getLocation();
- location.getLocation().getLocations()[trace] = expContext.getContexts()[trace].getLocation();
- }
-
- context.increaseRank();
- processEvent(event);
- }
+ public synchronized ITmfEvent parseEvent(final ITmfContext context) {
+ final ITmfContext tmpContext = seekEvent(context.getLocation());
+ final ITmfEvent event = getNext(tmpContext);
return event;
}
- /* (non-Javadoc)
- * @see org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser#parseEvent(org.eclipse.linuxtools.tmf.core.trace.ITmfContext)
- */
- @SuppressWarnings("unchecked")
@Override
- public T parseEvent(ITmfContext context) {
+ public synchronized ITmfEvent getNext(ITmfContext context) {
// Validate the context
if (!(context instanceof TmfExperimentContext)) {
return null; // Throw an exception?
}
+ // Make sure that we have something to read from
+ if (fTraces == null) {
+ return null;
+ }
+
TmfExperimentContext expContext = (TmfExperimentContext) context;
// If an event was consumed previously, first get the next one from that trace
}
}
- T event = null;
+ ITmfEvent event = null;
if (trace != TmfExperimentContext.NO_TRACE) {
- event = (T) expContext.getEvents()[trace];
+ event = expContext.getEvents()[trace];
+ if (event != null) {
+ updateAttributes(expContext, event.getTimestamp());
+ expContext.increaseRank();
+ expContext.setLastTrace(trace);
+ final ITmfContext traceContext = expContext.getContexts()[trace];
+
+ // Update the experiment location
+ TmfLocationArray locationArray = new TmfLocationArray(
+ ((TmfExperimentLocation) expContext.getLocation()).getLocationInfo(),
+ trace, traceContext.getLocation(), traceContext.getRank());
+ expContext.setLocation(new TmfExperimentLocation(locationArray));
+
+ processEvent(event);
+ }
}
- expContext.setLastTrace(trace);
return event;
}
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
+ /**
+ * @since 2.0
*/
+ @Override
+ public ITmfTimestamp getInitialRangeOffset() {
+ if ((fTraces == null) || (fTraces.length == 0)) {
+ return super.getInitialRangeOffset();
+ }
+
+ ITmfTimestamp initTs = TmfTimestamp.BIG_CRUNCH;
+ for (int i = 0; i < fTraces.length; i++) {
+ ITmfTimestamp ts = fTraces[i].getInitialRangeOffset();
+ if (ts.compareTo(initTs) < 0) {
+ initTs = ts;
+ }
+ }
+ return initTs;
+ }
+
@Override
@SuppressWarnings("nls")
- public String toString() {
+ public synchronized String toString() {
return "[TmfExperiment (" + getName() + ")]";
}
if (getStreamingInterval() == 0) {
final ITmfContext context = seekEvent(0);
final ITmfEvent event = getNext(context);
- if (event == null)
+ context.dispose();
+ if (event == null) {
return;
- final TmfTimeRange timeRange = new TmfTimeRange(event.getTimestamp().clone(), TmfTimestamp.BIG_CRUNCH);
- final TmfExperimentRangeUpdatedSignal signal = new TmfExperimentRangeUpdatedSignal(this, this, timeRange);
+ }
+ final TmfTimeRange timeRange = new TmfTimeRange(event.getTimestamp(), TmfTimestamp.BIG_CRUNCH);
+ final TmfTraceRangeUpdatedSignal signal = new TmfTraceRangeUpdatedSignal(this, this, timeRange);
// Broadcast in separate thread to prevent deadlock
new Thread() {
final Thread thread = new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$
private ITmfTimestamp safeTimestamp = null;
+ private ITmfTimestamp lastSafeTimestamp = null;
private TmfTimeRange timeRange = null;
@Override
public void run() {
- while (!fExecutor.isShutdown()) {
+ while (!executorIsShutdown()) {
if (!getIndexer().isIndexing()) {
ITmfTimestamp startTimestamp = TmfTimestamp.BIG_CRUNCH;
ITmfTimestamp endTimestamp = TmfTimestamp.BIG_BANG;
- for (final ITmfTrace<T> trace : fTraces) {
- if (trace.getStartTime().compareTo(startTimestamp) < 0)
+ for (final ITmfTrace trace : fTraces) {
+ if (trace.getStartTime().compareTo(startTimestamp) < 0) {
startTimestamp = trace.getStartTime();
- if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0)
+ }
+ if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0) {
endTimestamp = trace.getEndTime();
+ }
}
- if (safeTimestamp != null && safeTimestamp.compareTo(getTimeRange().getEndTime(), false) > 0)
+ if (safeTimestamp != null && (lastSafeTimestamp == null || safeTimestamp.compareTo(lastSafeTimestamp, false) > 0)) {
timeRange = new TmfTimeRange(startTimestamp, safeTimestamp);
- else
+ lastSafeTimestamp = safeTimestamp;
+ } else {
timeRange = null;
+ }
safeTimestamp = endTimestamp;
if (timeRange != null) {
- final TmfExperimentRangeUpdatedSignal signal =
- new TmfExperimentRangeUpdatedSignal(TmfExperiment.this, TmfExperiment.this, timeRange);
+ final TmfTraceRangeUpdatedSignal signal =
+ new TmfTraceRangeUpdatedSignal(TmfExperiment.this, TmfExperiment.this, timeRange);
broadcast(signal);
}
}
thread.start();
}
- /* (non-Javadoc)
- * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getStreamingInterval()
- */
@Override
public long getStreamingInterval() {
long interval = 0;
- for (final ITmfTrace<T> trace : fTraces)
+ for (final ITmfTrace trace : fTraces) {
interval = Math.max(interval, trace.getStreamingInterval());
+ }
return interval;
}
// Signal handlers
// ------------------------------------------------------------------------
- private Integer fEndSynchReference;
-
- /**
- * Signal handler for the TmfExperimentSelectedSignal signal
- *
- * @param signal
- */
- @TmfSignalHandler
- public void experimentSelected(final TmfExperimentSelectedSignal<T> signal) {
- final TmfExperiment<?> experiment = signal.getExperiment();
- if (experiment == this) {
- setCurrentExperiment(experiment);
- fEndSynchReference = Integer.valueOf(signal.getReference());
- }
- }
-
- /**
- * Signal handler for the TmfEndSynchSignal signal
- *
- * @param signal
- */
- @TmfSignalHandler
- public void endSync(final TmfEndSynchSignal signal) {
- if (fEndSynchReference != null && fEndSynchReference.intValue() == signal.getReference()) {
- fEndSynchReference = null;
- initializeStreamingMonitor();
- }
- }
-
- /**
- * Signal handler for the TmfTraceUpdatedSignal signal
- *
- * @param signal
- */
+ @Override
@TmfSignalHandler
- public void traceUpdated(final TmfTraceUpdatedSignal signal) {
+ public void traceOpened(TmfTraceOpenedSignal signal) {
if (signal.getTrace() == this) {
- broadcast(new TmfExperimentUpdatedSignal(this, this));
- }
- }
-
- /**
- * Signal handler for the TmfExperimentRangeUpdatedSignal signal
- *
- * @param signal
- */
- @TmfSignalHandler
- public void experimentRangeUpdated(final TmfExperimentRangeUpdatedSignal signal) {
- if (signal.getExperiment() == this) {
- getIndexer().buildIndex(getNbEvents(), signal.getRange(), false);
+ initializeStreamingMonitor();
}
}