import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
-import org.eclipse.tracecompass.analysis.timing.core.segmentstore.AbstractSegmentStoreAnalysisModule;
import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.SubSecondTimeWithUnitFormat;
import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.internal.analysis.timing.ui.Activator;
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
import org.eclipse.tracecompass.segmentstore.core.SegmentComparators;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
-import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
-import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
-import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal;
-import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfChartTimeStampFormat;
import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer;
-import org.swtchart.Chart;
-import org.swtchart.IAxis;
-import org.swtchart.IAxisTick;
import org.swtchart.ILineSeries;
import org.swtchart.ILineSeries.PlotSymbolType;
import org.swtchart.ISeries.SeriesType;
import org.swtchart.ISeriesSet;
import org.swtchart.LineStyle;
-import org.swtchart.Range;
+
+import com.google.common.primitives.Doubles;
/**
- * Displays the segment store analysis data in a scatter graph
+ * Displays the segment store provider data in a scatter graph
*
* @author France Lapointe Nguyen
* @author Matthew Khouzam - reduced memory usage
private static final Format FORMAT = new SubSecondTimeWithUnitFormat();
+ private final AtomicInteger fDirty = new AtomicInteger();
+
private final class CompactingSegmentStoreQuery extends Job {
private static final long MAX_POINTS = 1000;
private final TmfTimeRange fCurrentRange;
@Override
protected IStatus run(@Nullable IProgressMonitor monitor) {
final IProgressMonitor statusMonitor = monitor;
- if (statusMonitor == null) {
- return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Monitor is null"); //$NON-NLS-1$
- }
+ try {
+ if (statusMonitor == null) {
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Monitor is null"); //$NON-NLS-1$
+ }
- AbstractSegmentStoreAnalysisModule module = getAnalysisModule();
- final long startTimeInNanos = fCurrentRange.getStartTime().toNanos();
- final long endTimeInNanos = fCurrentRange.getEndTime().toNanos();
- if (module == null) {
- setWindowRange(startTimeInNanos, endTimeInNanos);
- redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST);
- return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Analysis module not available"); //$NON-NLS-1$
- }
+ ISegmentStoreProvider segmentProvider = getSegmentProvider();
+ final long startTimeInNanos = fCurrentRange.getStartTime().toNanos();
+ final long endTimeInNanos = fCurrentRange.getEndTime().toNanos();
+ if (segmentProvider == null) {
+ setWindowRange(startTimeInNanos, endTimeInNanos);
+ redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST);
+ return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "segment provider not available"); //$NON-NLS-1$
+ }
- final ISegmentStore<ISegment> segStore = module.getSegmentStore();
- if (segStore == null) {
- setWindowRange(startTimeInNanos, endTimeInNanos);
- redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST);
- return new Status(IStatus.INFO, Activator.PLUGIN_ID, "Analysis module does not have results"); //$NON-NLS-1$
- }
+ final ISegmentStore<ISegment> segStore = segmentProvider.getSegmentStore();
+ if (segStore == null) {
+ setWindowRange(startTimeInNanos, endTimeInNanos);
+ redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST);
+ return new Status(IStatus.INFO, Activator.PLUGIN_ID, "Segment provider does not have segments"); //$NON-NLS-1$
+ }
- final long startTime = fCurrentRange.getStartTime().getValue();
- final long endTime = fCurrentRange.getEndTime().getValue();
- fPixelStart = startTime;
- fPixelSize = (endTime - startTime) / MAX_POINTS;
- final Iterable<ISegment> intersectingElements = segStore.getIntersectingElements(startTime, endTime);
+ final long startTime = fCurrentRange.getStartTime().getValue();
+ final long endTime = fCurrentRange.getEndTime().getValue();
+ fPixelStart = startTime;
+ fPixelSize = Math.max(1, (endTime - startTime) / MAX_POINTS);
+ final Iterable<ISegment> intersectingElements = segStore.getIntersectingElements(startTime, endTime);
- final List<ISegment> list = convertIterableToList(intersectingElements, statusMonitor);
- final List<ISegment> displayData = (!list.isEmpty()) ? compactList(startTime, list, statusMonitor) : list;
+ final List<ISegment> list = convertIterableToList(intersectingElements, statusMonitor);
+ final List<ISegment> displayData = (!list.isEmpty()) ? compactList(startTime, list, statusMonitor) : list;
- setWindowRange(startTimeInNanos, endTimeInNanos);
- redraw(statusMonitor, startTime, endTime, displayData);
+ setWindowRange(startTimeInNanos, endTimeInNanos);
+ redraw(statusMonitor, startTime, endTime, displayData);
- if (statusMonitor.isCanceled()) {
- return NonNullUtils.checkNotNull(Status.CANCEL_STATUS);
+ if (statusMonitor.isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
+ return Status.OK_STATUS;
+ } finally {
+ /*
+ * fDirty should have been incremented before creating a job, so
+ * we decrement it once the job is done
+ */
+ fDirty.decrementAndGet();
}
- return NonNullUtils.checkNotNull(Status.OK_STATUS);
}
private void redraw(final IProgressMonitor statusMonitor, final long startTime, final long endTime, final List<ISegment> displayData) {
fDisplayData = displayData;
+ /*
+ * Increment at every redraw, since the content of the view is not
+ * current
+ */
+ fDirty.incrementAndGet();
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
- updateData(startTime, endTime, displayData.size(), statusMonitor);
+ try {
+ updateData(startTime, endTime, displayData.size(), statusMonitor);
+ } finally {
+ /* Decrement once the redraw is done */
+ fDirty.decrementAndGet();
+ }
}
});
}
// ------------------------------------------------------------------------
/**
- * Listener to update the model with the semgent store analysis results
- * once the analysis is fully completed
+ * Listener to update the model with the segment store provider results once
+ * its segment store is fully completed
*/
- private final class AnalysisProgressListener implements IAnalysisProgressListener {
+ private final class SegmentStoreProviderProgressListener implements IAnalysisProgressListener {
@Override
- public void onComplete(AbstractSegmentStoreAnalysisModule activeAnalysis, ISegmentStore<ISegment> results) {
+ public void onComplete(ISegmentStoreProvider segmentProvider, ISegmentStore<ISegment> segmentStore) {
// Only update the model if trace that was analyzed is active trace
- if (activeAnalysis.equals(getAnalysisModule())) {
- updateModel(results);
- updateRange(TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange());
+ if (segmentProvider.equals(getSegmentProvider())) {
+ updateModel(segmentStore);
}
}
}
private Collection<ISegment> fDisplayData = Collections.EMPTY_LIST;
/**
- * Analysis completion listener
+ * Provider completion listener
*/
- private AnalysisProgressListener fListener;
+ private SegmentStoreProviderProgressListener fListener;
/**
- * Current analysis module
+ * Current segment provider
*/
- private @Nullable AbstractSegmentStoreAnalysisModule fAnalysisModule;
+ private @Nullable ISegmentStoreProvider fSegmentProvider;
private @Nullable Job fCompactingJob;
public AbstractSegmentStoreScatterGraphViewer(Composite parent, String title, String xLabel, String yLabel) {
super(parent, title, xLabel, yLabel);
setTooltipProvider(new SegmentStoreScatterGraphTooltipProvider(this));
- fListener = new AnalysisProgressListener();
+ fListener = new SegmentStoreProviderProgressListener();
ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
- initializeModule(trace);
+ initializeProvider(trace);
getSwtChart().getLegend().setVisible(false);
getSwtChart().getAxisSet().getYAxis(0).getTick().setFormat(FORMAT);
}
- private final void initializeModule(@Nullable ITmfTrace trace) {
+ private final void initializeProvider(@Nullable ITmfTrace trace) {
if (trace != null) {
- final AbstractSegmentStoreAnalysisModule analysisModuleOfClass = getSegmentStoreAnalysisModule(trace);
- if (analysisModuleOfClass != null) {
- analysisModuleOfClass.addListener(fListener);
- setData(analysisModuleOfClass);
- updateRange(TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange());
+ final ISegmentStoreProvider segmentStoreProvider = getSegmentStoreProvider(trace);
+ if (segmentStoreProvider != null) {
+ segmentStoreProvider.addListener(fListener);
+ setData(segmentStoreProvider);
}
}
}
@Override
protected void initializeDataSource() {
ITmfTrace trace = getTrace();
- initializeModule(trace);
+ initializeProvider(trace);
if (trace != null) {
- setData(getSegmentStoreAnalysisModule(trace));
+ setData(getSegmentStoreProvider(trace));
}
}
Collection<ISegment> data = fDisplayData;
final int dataSize = (nb == 0) ? data.size() : nb;
- if (dataSize == 0 || end == start) {
+ if (end == start) {
return;
}
- final double[] xSeries = new double[dataSize];
- final double[] ySeries = new double[dataSize];
+ List<Double> xSeries = new ArrayList<>(dataSize);
+ List<Double> ySeries = new ArrayList<>(dataSize);
// For each visible segments, add start time to x value and duration
// for y value
Iterator<ISegment> modelIter = data.iterator();
- long maxTempY = 1;
- for (int i = 0; i < dataSize; i++) {
- if (modelIter.hasNext()) {
- ISegment segment = modelIter.next();
- xSeries[i] = segment.getStart() - start;
- ySeries[i] = segment.getLength();
- maxTempY = Math.max(maxTempY, segment.getLength());
- }
- }
- final long maxY = maxTempY;
- setXAxis(xSeries);
- final Chart swtChart = getSwtChart();
- if (swtChart.isDisposed() || xSeries.length < 1) {
- return;
- }
- swtChart.updateLayout();
- setSeries(Messages.SegmentStoreScatterGraphViewer_legend, ySeries); // $NON-NLS-1$
- final TmfChartTimeStampFormat tmfChartTimeStampFormat = new TmfChartTimeStampFormat(getTimeOffset());
- ILineSeries series = (ILineSeries) swtChart.getSeriesSet().getSeries(Messages.SegmentStoreScatterGraphViewer_legend);
- if (series == null) {
- series = addSeries(Messages.SegmentStoreScatterGraphViewer_legend);
- }
- series.setXSeries(xSeries);
- /* Find the minimal and maximum values in this series */
- series.setYSeries(ySeries);
-
- final IAxis xAxis = swtChart.getAxisSet().getXAxis(0);
- IAxisTick xTick = xAxis.getTick();
- xTick.setFormat(tmfChartTimeStampFormat);
- xAxis.setRange(new Range(0.0, end - start));
- if (maxY > 0.0) {
- swtChart.getAxisSet().getYAxis(0).setRange(new Range(0.0, maxY));
- }
- swtChart.redraw();
-
- if (isSendTimeAlignSignals()) {
- // The width of the chart might have changed and its
- // time axis might be misaligned with the other views
- Point viewPos = AbstractSegmentStoreScatterGraphViewer.this.getParent().getParent().toDisplay(0, 0);
- int axisPos = swtChart.toDisplay(0, 0).x + getPointAreaOffset();
- int timeAxisOffset = axisPos - viewPos.x;
- TmfTimeViewAlignmentInfo timeAlignmentInfo = new TmfTimeViewAlignmentInfo(getControl().getShell(), viewPos, timeAxisOffset);
- TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(AbstractSegmentStoreScatterGraphViewer.this, timeAlignmentInfo, true));
+ while (modelIter.hasNext()) {
+ ISegment segment = modelIter.next();
+ xSeries.add((double) (segment.getStart() - start));
+ ySeries.add((double) segment.getLength());
}
+ setXAxis(Doubles.toArray(xSeries));
+ setSeries(Messages.SegmentStoreScatterGraphViewer_legend, Doubles.toArray(ySeries));
+ updateDisplay();
}
@Override
}
/**
- * Set the data into the viewer. Will update model is analysis is completed
- * or run analysis if not completed
+ * Set the data into the viewer. If the provider is an analysis, it will
+ * update the model if the analysis is completed or run the analysis if not
+ * completed
*
- * @param analysis
- * Segment store analysis module
+ * @param provider
+ * Segment store provider
*/
- public void setData(@Nullable AbstractSegmentStoreAnalysisModule analysis) {
- if (analysis == null) {
+ public void setData(@Nullable ISegmentStoreProvider provider) {
+ if (provider == null) {
updateModel(null);
return;
}
- ISegmentStore<ISegment> segStore = analysis.getSegmentStore();
- // If results are not null, then analysis is completed and model can be
- // updated
+ ISegmentStore<ISegment> segStore = provider.getSegmentStore();
+ // If results are not null, then segment store is completed and model
+ // can be updated
if (segStore != null) {
updateModel(segStore);
- setAnalysisModule(analysis);
+ setSegmentProvider(provider);
return;
}
updateModel(null);
- analysis.addListener(fListener);
- analysis.schedule();
- setAnalysisModule(analysis);
+ provider.addListener(fListener);
+ if (provider instanceof IAnalysisModule) {
+ ((IAnalysisModule) provider).schedule();
+ }
+ setSegmentProvider(provider);
}
/**
- * Returns the segment store analysis module
+ * Returns the segment store provider
*
* @param trace
* The trace to consider
- * @return the analysis module
+ * @return the segment store provider
*/
- protected @Nullable abstract AbstractSegmentStoreAnalysisModule getSegmentStoreAnalysisModule(ITmfTrace trace);
+ protected @Nullable abstract ISegmentStoreProvider getSegmentStoreProvider(ITmfTrace trace);
// ------------------------------------------------------------------------
// Signal handlers
setWindowRange(
timeRange.getStartTime().toNanos(),
timeRange.getEndTime().toNanos());
- setData(getSegmentStoreAnalysisModule(trace));
+ setData(getSegmentStoreProvider(trace));
updateRange(timeRange);
}
}
setTrace(trace);
if (trace != null) {
- final AbstractSegmentStoreAnalysisModule analysisModuleOfClass = getSegmentStoreAnalysisModule(trace);
+ final ISegmentStoreProvider segmentStoreProvider = getSegmentStoreProvider(trace);
final TmfTimeRange timeRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange();
setWindowRange(
timeRange.getStartTime().toNanos(),
timeRange.getEndTime().toNanos());
- setData(analysisModuleOfClass);
+ setData(segmentStoreProvider);
}
}
private void updateRange(final @Nullable TmfTimeRange timeRange) {
+ /*
+ * Update is request, content is not up to date, fDirty will be
+ * decremented in the compacting job
+ */
+ fDirty.incrementAndGet();
Job compactingJob = fCompactingJob;
if (compactingJob != null && compactingJob.getState() == Job.RUNNING) {
compactingJob.cancel();
if (signal != null) {
// Check if there is no more opened trace
if (TmfTraceManager.getInstance().getActiveTrace() == null) {
- AbstractSegmentStoreAnalysisModule analysis = getAnalysisModule();
- if (analysis != null) {
- analysis.removeListener(fListener);
+ ISegmentStoreProvider provider = getSegmentProvider();
+ if (provider != null) {
+ provider.removeListener(fListener);
}
clearContent();
}
}
}
- private @Nullable AbstractSegmentStoreAnalysisModule getAnalysisModule() {
- return fAnalysisModule;
+ private @Nullable ISegmentStoreProvider getSegmentProvider() {
+ return fSegmentProvider;
}
- private void setAnalysisModule(AbstractSegmentStoreAnalysisModule analysisModule) {
- fAnalysisModule = analysisModule;
+ private void setSegmentProvider(ISegmentStoreProvider provider) {
+ fSegmentProvider = provider;
+ }
+
+ @Override
+ public boolean isDirty() {
+ /* Check the parent's or this view's own dirtiness */
+ return super.isDirty() || (fDirty.get() != 0);
}
}
\ No newline at end of file