/*******************************************************************************
* 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:
* Francois Chouinard - Initial API and implementation
*******************************************************************************/
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentContext;
+import org.eclipse.linuxtools.tmf.core.component.TmfDataProvider;
import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
/**
* A simple indexer that manages the trace index as an array of trace
- * checkpoints. Checkpoints are stored at fixed intervals (event rank) in
+ * checkpoints. Checkpoints are stored at fixed intervals (event rank) in
* ascending timestamp order.
* <p>
* The goal being to access a random trace event reasonably fast from the user's
* <p>
* Locating a specific checkpoint is trivial for both rank (rank % interval) and
* timestamp (bsearch in the array).
- *
+ *
* @version 1.0
* @author Francois Chouinard
*
* @see ITmfTrace
* @see ITmfEvent
*/
-public class TmfCheckpointIndexer<T extends ITmfTrace<ITmfEvent>> implements ITmfTraceIndexer<T> {
+public class TmfCheckpointIndexer implements ITmfTraceIndexer {
// ------------------------------------------------------------------------
// Attributes
// ------------------------------------------------------------------------
// The event trace to index
- private final ITmfTrace<ITmfEvent> fTrace;
+ protected final ITmfTrace fTrace;
// The interval between checkpoints
private final int fCheckpointInterval;
* The trace index. It is composed of checkpoints taken at intervals of
* fCheckpointInterval events.
*/
- private final List<TmfCheckpoint> fTraceIndex;
+ protected final List<ITmfCheckpoint> fTraceIndex;
/**
- * The indexing request
+ * The indexing request
*/
- private ITmfEventRequest<ITmfEvent> fIndexingRequest = null;
-
+ private ITmfEventRequest fIndexingRequest = null;
+
// ------------------------------------------------------------------------
// Construction
// ------------------------------------------------------------------------
/**
* Basic constructor that uses the default trace block size as checkpoints
* intervals
- *
+ *
* @param trace the trace to index
*/
- public TmfCheckpointIndexer(final ITmfTrace<ITmfEvent> trace) {
- this(trace, TmfTrace.DEFAULT_BLOCK_SIZE);
+ public TmfCheckpointIndexer(final ITmfTrace trace) {
+ this(trace, TmfDataProvider.DEFAULT_BLOCK_SIZE);
}
/**
* Full trace indexer
- *
+ *
* @param trace the trace to index
* @param interval the checkpoints interval
*/
- public TmfCheckpointIndexer(final ITmfTrace<ITmfEvent> trace, final int interval) {
+ public TmfCheckpointIndexer(final ITmfTrace trace, final int interval) {
fTrace = trace;
fCheckpointInterval = interval;
- fTraceIndex = new ArrayList<TmfCheckpoint>();
+ fTraceIndex = new ArrayList<ITmfCheckpoint>();
fIsIndexing = false;
}
// ------------------------------------------------------------------------
/* (non-Javadoc)
- *
+ *
* The index is a list of contexts that point to events at regular interval
* (rank-wise) in the trace. After it is built, the index can be used to
* quickly access any event by rank or timestamp (using seekIndex()).
- *
+ *
* The index is built simply by reading the trace
*
* @see org.eclipse.linuxtools.tmf.core.trace.ITmfTraceIndexer#buildIndex(long, org.eclipse.linuxtools.tmf.core.event.TmfTimeRange, boolean)
@Override
public void buildIndex(final long offset, final TmfTimeRange range, final boolean waitForCompletion) {
- // Don't do anything if we are already indexing
+ // Don't do anything if we are already indexing
synchronized (fTraceIndex) {
if (fIsIndexing) {
return;
};
job.schedule();
- // Clear the checkpoints
- fTraceIndex.clear();
-
// Build a background request for all the trace data. The index is
// updated as we go by readNextEvent().
- fIndexingRequest = new TmfEventRequest<ITmfEvent>(ITmfEvent.class,
+ fIndexingRequest = new TmfEventRequest(ITmfEvent.class,
range, offset, TmfDataRequest.ALL_DATA, fCheckpointInterval, ITmfDataRequest.ExecutionType.BACKGROUND)
{
- private ITmfTimestamp startTime = null;
- private ITmfTimestamp lastTime = null;
-
@Override
public void handleData(final ITmfEvent event) {
super.handleData(event);
if (event != null) {
- final ITmfTimestamp timestamp = event.getTimestamp();
- if (startTime == null) {
- startTime = timestamp.clone();
- }
- lastTime = timestamp.clone();
-
// Update the trace status at regular intervals
if ((getNbRead() % fCheckpointInterval) == 0) {
updateTraceStatus();
}
private void updateTraceStatus() {
- if (getNbRead() != 0) {
- signalNewTimeRange(startTime, lastTime);
+ if (fTrace.getNbEvents() > 0) {
+ signalNewTimeRange(fTrace.getStartTime(), fTrace.getEndTime());
}
}
};
/**
* Notify the interested parties that the trace time range has changed
- *
+ *
* @param startTime the new start time
* @param endTime the new end time
*/
final long position = rank / fCheckpointInterval;
// Add new entry at proper location (if empty)
if (fTraceIndex.size() == position) {
- final ITmfLocation<?> location = context.getLocation().clone();
- fTraceIndex.add(new TmfCheckpoint(timestamp.clone(), location));
+ fTraceIndex.add(new TmfCheckpoint(timestamp.clone(), saveContext(context)));
}
}
}
}
// Position the trace at the checkpoint
- return seekCheckpoint(index);
+ return restoreCheckpoint(index);
}
/* (non-Javadoc)
final int index = (int) rank / fCheckpointInterval;
// Position the trace at the checkpoint
- return seekCheckpoint(index);
+ return restoreCheckpoint(index);
}
/**
* Position the trace at the given checkpoint
- *
+ *
* @param checkpoint the checkpoint index
* @return the corresponding context
*/
- private ITmfContext seekCheckpoint(final int checkpoint) {
- ITmfLocation<?> location = null;
- int index = checkpoint;
+ private ITmfContext restoreCheckpoint(final int checkpoint) {
+ ITmfLocation location = null;
+ int index = 0;
synchronized (fTraceIndex) {
if (!fTraceIndex.isEmpty()) {
+ index = checkpoint;
if (index >= fTraceIndex.size()) {
index = fTraceIndex.size() - 1;
}
- location = fTraceIndex.get(index).getLocation();
+ return restoreContext(fTraceIndex.get(index).getContext());
}
}
final ITmfContext context = fTrace.seekEvent(location);
/**
* @return the trace index
*/
- protected List<TmfCheckpoint> getTraceIndex() {
+ protected List<ITmfCheckpoint> getTraceIndex() {
return fTraceIndex;
}
+
+ // ------------------------------------------------------------------------
+ // Context conversion functions
+ // ------------------------------------------------------------------------
+
+ private static ITmfContext saveContext(ITmfContext context) {
+ if (context instanceof TmfExperimentContext) {
+ return saveExpContext(context);
+ }
+ TmfContext ctx = new TmfContext(context.getLocation().clone(), context.getRank());
+ return ctx;
+ }
+
+ private static ITmfContext saveExpContext(ITmfContext context) {
+ TmfExperimentContext expContext = (TmfExperimentContext) context;
+ int size = expContext.getContexts().length;
+ ITmfContext[] trcCtxts = new TmfContext[size];
+ for (int i = 0; i < size; i++) {
+ ITmfContext ctx = expContext.getContexts()[i];
+ trcCtxts[i] = (ctx != null) ? new TmfContext(ctx.getLocation().clone(), ctx.getRank()) : null;
+ }
+ TmfExperimentContext expCtx = new TmfExperimentContext(trcCtxts);
+ expCtx.setLocation(context.getLocation().clone());
+ expCtx.setRank(context.getRank());
+ ITmfEvent[] trcEvts = expCtx.getEvents();
+ for (int i = 0; i < size; i++) {
+ ITmfEvent event = expContext.getEvents()[i];
+ trcEvts[i] = (event != null) ? event.clone() : null;
+ }
+ return expCtx;
+ }
+
+ private ITmfContext restoreContext(ITmfContext context) {
+ if (context instanceof TmfExperimentContext) {
+ return restoreExpContext(context);
+ }
+ ITmfContext ctx = fTrace.seekEvent(context.getLocation());
+ ctx.setRank(context.getRank());
+ return ctx;
+ }
+
+ private ITmfContext restoreExpContext(ITmfContext context) {
+ TmfExperimentContext expContext = (TmfExperimentContext) context;
+ int size = expContext.getContexts().length;
+ ITmfContext[] trcCtxts = new ITmfContext[size];
+ for (int i = 0; i < size; i++) {
+ ITmfTrace trace = ((TmfExperiment) fTrace).getTraces()[i];
+ ITmfContext ctx = expContext.getContexts()[i];
+ trcCtxts[i] = trace.seekEvent(ctx.getLocation().clone());
+ trcCtxts[i].setRank(ctx.getRank());
+ }
+ TmfExperimentContext ctx = new TmfExperimentContext(trcCtxts);
+ ctx.setLocation(context.getLocation().clone());
+ ctx.setRank(context.getRank());
+ ITmfEvent[] trcEvts = expContext.getEvents();
+ for (int i = 0; i < size; i++) {
+ ITmfEvent event = trcEvts[i];
+ ctx.getEvents()[i] = (event != null) ? event.clone() : null;
+ }
+ return ctx;
+ }
+
}