X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=analysis%2Forg.eclipse.tracecompass.analysis.timing.ui%2Fsrc%2Forg%2Feclipse%2Ftracecompass%2Fanalysis%2Ftiming%2Fui%2Fviews%2Fsegmentstore%2Fscatter%2FAbstractSegmentStoreScatterGraphViewer.java;h=e55fbe0780e7a09fec3144c9c7e3b988c6a592db;hb=e18d40d0604c06dbf62f0af4eeed910c28526c41;hp=23bc35c128b402b2c8d90b83b6a3254e474d14ad;hpb=edded5c11bb7d5defa41042e78e1b16f1789567a;p=deliverable%2Ftracecompass.git diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/scatter/AbstractSegmentStoreScatterGraphViewer.java b/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/scatter/AbstractSegmentStoreScatterGraphViewer.java index 23bc35c128..e55fbe0780 100644 --- a/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/scatter/AbstractSegmentStoreScatterGraphViewer.java +++ b/analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/scatter/AbstractSegmentStoreScatterGraphViewer.java @@ -13,55 +13,51 @@ package org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.scatter; +import java.text.Format; import java.util.ArrayList; import java.util.Collection; 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.internal.analysis.timing.ui.views.segmentstore.scatter.SegmentStoreScatterGraphTooltipProvider; import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.scatter.Messages; +import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.scatter.SegmentStoreScatterGraphTooltipProvider; 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.signal.TmfWindowRangeUpdatedSignal; -import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; 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 @@ -69,6 +65,10 @@ import org.swtchart.Range; */ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXLineChartViewer { + 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; @@ -81,52 +81,70 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL @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 = getTimeInNanos(fCurrentRange.getStartTime()); - final long endTimeInNanos = getTimeInNanos(fCurrentRange.getEndTime()); - 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 results = module.getResults(); - if (results == 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 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 intersectingElements = results.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 intersectingElements = segStore.getIntersectingElements(startTime, endTime); - final List list = convertIterableToList(intersectingElements, statusMonitor); - final List displayData = (!list.isEmpty()) ? compactList(startTime, list, statusMonitor) : list; + final List list = convertIterableToList(intersectingElements, statusMonitor); + final List 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 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(); + } } }); } @@ -188,17 +206,16 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL // ------------------------------------------------------------------------ /** - * 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 results) { + public void onComplete(ISegmentStoreProvider segmentProvider, ISegmentStore 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); } } } @@ -212,14 +229,14 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL private Collection 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; @@ -242,19 +259,19 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL 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); } } } @@ -272,8 +289,8 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL public void updateModel(@Nullable ISegmentStore dataInput) { // Update new window range TmfTimeRange currentRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange(); - long currentStart = getTimeInNanos(currentRange.getStartTime()); - long currentEnd = getTimeInNanos(currentRange.getEndTime()); + long currentStart = currentRange.getStartTime().toNanos(); + long currentEnd = currentRange.getEndTime().toNanos(); if (dataInput == null) { if (!getDisplay().isDisposed()) { Display.getDefault().syncExec(new Runnable() { @@ -299,9 +316,9 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL @Override protected void initializeDataSource() { ITmfTrace trace = getTrace(); - initializeModule(trace); + initializeProvider(trace); if (trace != null) { - setData(getSegmentStoreAnalysisModule(trace)); + setData(getSegmentStoreProvider(trace)); } } @@ -312,59 +329,23 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL Collection 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 xSeries = new ArrayList<>(dataSize); + List ySeries = new ArrayList<>(dataSize); // For each visible segments, add start time to x value and duration // for y value Iterator 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 @@ -384,39 +365,42 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL } /** - * 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 results = analysis.getResults(); - // If results are not null, then analysis is completed and model can be - // updated - if (results != null) { - updateModel(results); - setAnalysisModule(analysis); + ISegmentStore segStore = provider.getSegmentStore(); + // If results are not null, then segment store is completed and model + // can be updated + if (segStore != null) { + updateModel(segStore); + 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 @@ -438,9 +422,9 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL if (trace != null) { final TmfTimeRange timeRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange(); setWindowRange( - timeRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(), - timeRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue()); - setData(getSegmentStoreAnalysisModule(trace)); + timeRange.getStartTime().toNanos(), + timeRange.getEndTime().toNanos()); + setData(getSegmentStoreProvider(trace)); updateRange(timeRange); } } @@ -460,17 +444,22 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL setTrace(trace); if (trace != null) { - final AbstractSegmentStoreAnalysisModule analysisModuleOfClass = getSegmentStoreAnalysisModule(trace); + final ISegmentStoreProvider segmentStoreProvider = getSegmentStoreProvider(trace); final TmfTimeRange timeRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange(); setWindowRange( - getTimeInNanos(timeRange.getStartTime()), - getTimeInNanos(timeRange.getEndTime())); - setData(analysisModuleOfClass); + timeRange.getStartTime().toNanos(), + timeRange.getEndTime().toNanos()); + 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(); @@ -491,9 +480,9 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL 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(); } @@ -520,15 +509,17 @@ public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXL } } - 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; } - private static long getTimeInNanos(final ITmfTimestamp currentTime) { - return currentTime.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + @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