Commit | Line | Data |
---|---|---|
03c96217 | 1 | /****************************************************************************** |
edded5c1 | 2 | * Copyright (c) 2015, 2016 Ericsson |
03c96217 BH |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * France Lapointe Nguyen - Initial API and implementation | |
11 | * Bernd Hufmann - Extracted abstract class from LatencyScatterGraphViewer | |
12 | *******************************************************************************/ | |
13 | ||
edded5c1 | 14 | package org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.scatter; |
03c96217 | 15 | |
21c917fe | 16 | import java.text.Format; |
03c96217 BH |
17 | import java.util.ArrayList; |
18 | import java.util.Collection; | |
19 | import java.util.Collections; | |
20 | import java.util.Iterator; | |
21 | import java.util.List; | |
22 | ||
23 | import org.eclipse.core.runtime.IProgressMonitor; | |
24 | import org.eclipse.core.runtime.IStatus; | |
25 | import org.eclipse.core.runtime.Status; | |
26 | import org.eclipse.core.runtime.jobs.Job; | |
27 | import org.eclipse.jdt.annotation.Nullable; | |
28 | import org.eclipse.swt.graphics.Point; | |
29 | import org.eclipse.swt.widgets.Composite; | |
30 | import org.eclipse.swt.widgets.Display; | |
03c96217 | 31 | import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener; |
0f769d2b | 32 | import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider; |
21c917fe | 33 | import org.eclipse.tracecompass.analysis.timing.ui.views.segmentstore.SubSecondTimeWithUnitFormat; |
03c96217 BH |
34 | import org.eclipse.tracecompass.common.core.NonNullUtils; |
35 | import org.eclipse.tracecompass.internal.analysis.timing.ui.Activator; | |
edded5c1 | 36 | import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.scatter.Messages; |
21c917fe | 37 | import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.scatter.SegmentStoreScatterGraphTooltipProvider; |
03c96217 BH |
38 | import org.eclipse.tracecompass.segmentstore.core.ISegment; |
39 | import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; | |
40 | import org.eclipse.tracecompass.segmentstore.core.SegmentComparators; | |
0f769d2b | 41 | import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule; |
03c96217 BH |
42 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; |
43 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; | |
44 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal; | |
45 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; | |
46 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; | |
47 | import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal; | |
03c96217 BH |
48 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; |
49 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
50 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; | |
51 | import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo; | |
52 | import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentSignal; | |
53 | import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfChartTimeStampFormat; | |
54 | import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer; | |
55 | import org.swtchart.Chart; | |
56 | import org.swtchart.IAxis; | |
57 | import org.swtchart.IAxisTick; | |
58 | import org.swtchart.ILineSeries; | |
59 | import org.swtchart.ILineSeries.PlotSymbolType; | |
60 | import org.swtchart.ISeries.SeriesType; | |
61 | import org.swtchart.ISeriesSet; | |
62 | import org.swtchart.LineStyle; | |
63 | import org.swtchart.Range; | |
64 | ||
65 | /** | |
0f769d2b | 66 | * Displays the segment store provider data in a scatter graph |
03c96217 BH |
67 | * |
68 | * @author France Lapointe Nguyen | |
69 | * @author Matthew Khouzam - reduced memory usage | |
70 | * @since 2.0 | |
71 | */ | |
72 | public abstract class AbstractSegmentStoreScatterGraphViewer extends TmfCommonXLineChartViewer { | |
03c96217 | 73 | |
21c917fe MK |
74 | private static final Format FORMAT = new SubSecondTimeWithUnitFormat(); |
75 | ||
03c96217 BH |
76 | private final class CompactingSegmentStoreQuery extends Job { |
77 | private static final long MAX_POINTS = 1000; | |
78 | private final TmfTimeRange fCurrentRange; | |
79 | ||
80 | private CompactingSegmentStoreQuery(TmfTimeRange currentRange) { | |
81 | super(Messages.SegmentStoreScatterGraphViewer_compactTitle); | |
82 | fCurrentRange = currentRange; | |
83 | } | |
84 | ||
85 | @Override | |
86 | protected IStatus run(@Nullable IProgressMonitor monitor) { | |
87 | final IProgressMonitor statusMonitor = monitor; | |
88 | if (statusMonitor == null) { | |
89 | return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Monitor is null"); //$NON-NLS-1$ | |
90 | } | |
91 | ||
0f769d2b | 92 | ISegmentStoreProvider segmentProvider = getSegmentProvider(); |
16801c72 MK |
93 | final long startTimeInNanos = fCurrentRange.getStartTime().toNanos(); |
94 | final long endTimeInNanos = fCurrentRange.getEndTime().toNanos(); | |
0f769d2b | 95 | if (segmentProvider == null) { |
03c96217 | 96 | setWindowRange(startTimeInNanos, endTimeInNanos); |
df2597e0 | 97 | redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST); |
0f769d2b | 98 | return new Status(IStatus.WARNING, Activator.PLUGIN_ID, "segment provider not available"); //$NON-NLS-1$ |
03c96217 BH |
99 | } |
100 | ||
0f769d2b | 101 | final ISegmentStore<ISegment> segStore = segmentProvider.getSegmentStore(); |
73c74de7 | 102 | if (segStore == null) { |
03c96217 | 103 | setWindowRange(startTimeInNanos, endTimeInNanos); |
df2597e0 | 104 | redraw(statusMonitor, startTimeInNanos, startTimeInNanos, Collections.EMPTY_LIST); |
0f769d2b | 105 | return new Status(IStatus.INFO, Activator.PLUGIN_ID, "Segment provider does not have segments"); //$NON-NLS-1$ |
03c96217 BH |
106 | } |
107 | ||
108 | final long startTime = fCurrentRange.getStartTime().getValue(); | |
109 | final long endTime = fCurrentRange.getEndTime().getValue(); | |
110 | fPixelStart = startTime; | |
111 | fPixelSize = (endTime - startTime) / MAX_POINTS; | |
73c74de7 | 112 | final Iterable<ISegment> intersectingElements = segStore.getIntersectingElements(startTime, endTime); |
03c96217 BH |
113 | |
114 | final List<ISegment> list = convertIterableToList(intersectingElements, statusMonitor); | |
115 | final List<ISegment> displayData = (!list.isEmpty()) ? compactList(startTime, list, statusMonitor) : list; | |
116 | ||
117 | setWindowRange(startTimeInNanos, endTimeInNanos); | |
118 | redraw(statusMonitor, startTime, endTime, displayData); | |
119 | ||
120 | if (statusMonitor.isCanceled()) { | |
121 | return NonNullUtils.checkNotNull(Status.CANCEL_STATUS); | |
122 | } | |
123 | return NonNullUtils.checkNotNull(Status.OK_STATUS); | |
124 | ||
125 | } | |
126 | ||
127 | private void redraw(final IProgressMonitor statusMonitor, final long startTime, final long endTime, final List<ISegment> displayData) { | |
128 | fDisplayData = displayData; | |
129 | Display.getDefault().asyncExec(new Runnable() { | |
130 | ||
131 | @Override | |
132 | public void run() { | |
133 | updateData(startTime, endTime, displayData.size(), statusMonitor); | |
134 | } | |
135 | }); | |
136 | } | |
137 | ||
138 | private List<ISegment> compactList(final long startTime, final List<ISegment> listToCompact, final IProgressMonitor statusMonitor) { | |
139 | List<ISegment> displayData = new ArrayList<>(); | |
140 | ISegment last = listToCompact.get(0); | |
141 | if (last.getStart() >= startTime) { | |
142 | displayData.add(last); | |
143 | } | |
144 | for (ISegment next : listToCompact) { | |
145 | if (next.getStart() < startTime) { | |
146 | continue; | |
147 | } | |
148 | if (statusMonitor.isCanceled()) { | |
df2597e0 | 149 | return Collections.EMPTY_LIST; |
03c96217 BH |
150 | } |
151 | if (!overlaps(last, next)) { | |
152 | displayData.add(next); | |
153 | last = next; | |
154 | } | |
155 | } | |
156 | return displayData; | |
157 | } | |
158 | ||
159 | private List<ISegment> convertIterableToList(final Iterable<ISegment> iterable, final IProgressMonitor statusMonitor) { | |
160 | final List<ISegment> list = new ArrayList<>(); | |
161 | for (ISegment seg : iterable) { | |
162 | if (statusMonitor.isCanceled()) { | |
df2597e0 | 163 | return Collections.EMPTY_LIST; |
03c96217 BH |
164 | } |
165 | list.add(seg); | |
166 | } | |
167 | Collections.sort(list, SegmentComparators.INTERVAL_START_COMPARATOR); | |
168 | return list; | |
169 | } | |
170 | ||
171 | private boolean overlaps(ISegment last, ISegment next) { | |
172 | long timePerPix = fPixelSize; | |
173 | final long start = last.getStart(); | |
174 | final long pixelStart = fPixelStart; | |
175 | final long pixelDuration = start - pixelStart; | |
176 | long startPixBoundL = pixelDuration / timePerPix * timePerPix + pixelStart; | |
177 | long startPixBoundR = startPixBoundL + timePerPix; | |
178 | final long currentStart = next.getStart(); | |
179 | if (currentStart >= startPixBoundL && currentStart <= startPixBoundR) { | |
180 | long length = last.getLength(); | |
181 | long lengthNext = next.getLength(); | |
182 | long lengthLow = length / timePerPix * timePerPix; | |
183 | long lengthHigh = lengthLow + timePerPix; | |
184 | return (lengthNext >= lengthLow && lengthNext <= lengthHigh); | |
185 | } | |
186 | return false; | |
187 | } | |
188 | } | |
189 | ||
190 | // ------------------------------------------------------------------------ | |
191 | // Attributes | |
192 | // ------------------------------------------------------------------------ | |
193 | ||
194 | /** | |
0f769d2b MK |
195 | * Listener to update the model with the segment store provider results once |
196 | * its segment store is fully completed | |
03c96217 | 197 | */ |
0f769d2b | 198 | private final class SegmentStoreProviderProgressListener implements IAnalysisProgressListener { |
03c96217 BH |
199 | |
200 | @Override | |
0f769d2b | 201 | public void onComplete(ISegmentStoreProvider segmentProvider, ISegmentStore<ISegment> segmentStore) { |
03c96217 | 202 | // Only update the model if trace that was analyzed is active trace |
0f769d2b MK |
203 | if (segmentProvider.equals(getSegmentProvider())) { |
204 | updateModel(segmentStore); | |
03c96217 BH |
205 | updateRange(TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange()); |
206 | } | |
207 | } | |
208 | } | |
209 | ||
210 | private long fPixelSize = -1; | |
211 | ||
212 | private long fPixelStart = 0; | |
213 | /** | |
214 | * Data to display | |
215 | */ | |
df2597e0 | 216 | private Collection<ISegment> fDisplayData = Collections.EMPTY_LIST; |
03c96217 BH |
217 | |
218 | /** | |
0f769d2b | 219 | * Provider completion listener |
03c96217 | 220 | */ |
0f769d2b | 221 | private SegmentStoreProviderProgressListener fListener; |
03c96217 BH |
222 | |
223 | /** | |
0f769d2b | 224 | * Current segment provider |
03c96217 | 225 | */ |
0f769d2b | 226 | private @Nullable ISegmentStoreProvider fSegmentProvider; |
03c96217 BH |
227 | |
228 | private @Nullable Job fCompactingJob; | |
229 | ||
230 | // ------------------------------------------------------------------------ | |
231 | // Constructor | |
232 | // ------------------------------------------------------------------------ | |
233 | ||
234 | /** | |
235 | * Constructor | |
236 | * | |
237 | * @param parent | |
238 | * parent composite | |
239 | * @param title | |
240 | * name of the graph | |
241 | * @param xLabel | |
242 | * name of the x axis | |
243 | * @param yLabel | |
244 | * name of the y axis | |
245 | */ | |
246 | public AbstractSegmentStoreScatterGraphViewer(Composite parent, String title, String xLabel, String yLabel) { | |
247 | super(parent, title, xLabel, yLabel); | |
a2de198a | 248 | setTooltipProvider(new SegmentStoreScatterGraphTooltipProvider(this)); |
0f769d2b | 249 | fListener = new SegmentStoreProviderProgressListener(); |
03c96217 | 250 | ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace(); |
0f769d2b | 251 | initializeProvider(trace); |
03c96217 | 252 | getSwtChart().getLegend().setVisible(false); |
21c917fe | 253 | getSwtChart().getAxisSet().getYAxis(0).getTick().setFormat(FORMAT); |
03c96217 BH |
254 | } |
255 | ||
0f769d2b | 256 | private final void initializeProvider(@Nullable ITmfTrace trace) { |
03c96217 | 257 | if (trace != null) { |
0f769d2b MK |
258 | final ISegmentStoreProvider segmentStoreProvider = getSegmentStoreProvider(trace); |
259 | if (segmentStoreProvider != null) { | |
260 | segmentStoreProvider.addListener(fListener); | |
261 | setData(segmentStoreProvider); | |
03c96217 BH |
262 | updateRange(TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange()); |
263 | } | |
264 | } | |
265 | } | |
266 | ||
267 | // ------------------------------------------------------------------------ | |
268 | // Operations | |
269 | // ------------------------------------------------------------------------ | |
270 | ||
271 | /** | |
272 | * Update the data in the graph | |
273 | * | |
274 | * @param dataInput | |
275 | * new model | |
276 | */ | |
277 | public void updateModel(@Nullable ISegmentStore<ISegment> dataInput) { | |
278 | // Update new window range | |
279 | TmfTimeRange currentRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange(); | |
16801c72 MK |
280 | long currentStart = currentRange.getStartTime().toNanos(); |
281 | long currentEnd = currentRange.getEndTime().toNanos(); | |
03c96217 BH |
282 | if (dataInput == null) { |
283 | if (!getDisplay().isDisposed()) { | |
284 | Display.getDefault().syncExec(new Runnable() { | |
285 | @Override | |
286 | public void run() { | |
287 | clearContent(); | |
288 | } | |
289 | }); | |
290 | } | |
df2597e0 | 291 | fDisplayData = Collections.EMPTY_LIST; |
03c96217 BH |
292 | } else { |
293 | Collection<ISegment> elements = (Collection<ISegment>) dataInput.getIntersectingElements(currentStart, currentEnd); | |
294 | // getIntersectingElements can return an unsorted iterable, make | |
295 | // sure our collection is sorted | |
296 | ArrayList<ISegment> list = new ArrayList<>(elements); | |
297 | Collections.sort(list, SegmentComparators.INTERVAL_START_COMPARATOR); | |
298 | fDisplayData = list; | |
299 | } | |
300 | setWindowRange(currentStart, currentEnd); | |
301 | updateRange(currentRange); | |
302 | } | |
303 | ||
304 | @Override | |
305 | protected void initializeDataSource() { | |
306 | ITmfTrace trace = getTrace(); | |
0f769d2b | 307 | initializeProvider(trace); |
03c96217 | 308 | if (trace != null) { |
0f769d2b | 309 | setData(getSegmentStoreProvider(trace)); |
03c96217 BH |
310 | } |
311 | } | |
312 | ||
313 | @Override | |
314 | protected void updateData(final long start, final long end, int nb, @Nullable IProgressMonitor monitor) { | |
315 | // Third parameter is not used by implementation | |
316 | // Determine data that needs to be visible | |
317 | Collection<ISegment> data = fDisplayData; | |
318 | ||
319 | final int dataSize = (nb == 0) ? data.size() : nb; | |
320 | if (dataSize == 0 || end == start) { | |
321 | return; | |
322 | } | |
323 | ||
324 | final double[] xSeries = new double[dataSize]; | |
325 | final double[] ySeries = new double[dataSize]; | |
326 | // For each visible segments, add start time to x value and duration | |
327 | // for y value | |
328 | Iterator<ISegment> modelIter = data.iterator(); | |
329 | long maxTempY = 1; | |
330 | for (int i = 0; i < dataSize; i++) { | |
331 | if (modelIter.hasNext()) { | |
332 | ISegment segment = modelIter.next(); | |
333 | xSeries[i] = segment.getStart() - start; | |
334 | ySeries[i] = segment.getLength(); | |
335 | maxTempY = Math.max(maxTempY, segment.getLength()); | |
336 | } | |
337 | } | |
338 | final long maxY = maxTempY; | |
339 | setXAxis(xSeries); | |
340 | final Chart swtChart = getSwtChart(); | |
341 | if (swtChart.isDisposed() || xSeries.length < 1) { | |
342 | return; | |
343 | } | |
344 | swtChart.updateLayout(); | |
345 | setSeries(Messages.SegmentStoreScatterGraphViewer_legend, ySeries); // $NON-NLS-1$ | |
346 | final TmfChartTimeStampFormat tmfChartTimeStampFormat = new TmfChartTimeStampFormat(getTimeOffset()); | |
347 | ILineSeries series = (ILineSeries) swtChart.getSeriesSet().getSeries(Messages.SegmentStoreScatterGraphViewer_legend); | |
348 | if (series == null) { | |
349 | series = addSeries(Messages.SegmentStoreScatterGraphViewer_legend); | |
350 | } | |
351 | series.setXSeries(xSeries); | |
352 | /* Find the minimal and maximum values in this series */ | |
353 | series.setYSeries(ySeries); | |
354 | ||
355 | final IAxis xAxis = swtChart.getAxisSet().getXAxis(0); | |
356 | IAxisTick xTick = xAxis.getTick(); | |
357 | xTick.setFormat(tmfChartTimeStampFormat); | |
358 | xAxis.setRange(new Range(0.0, end - start)); | |
359 | if (maxY > 0.0) { | |
360 | swtChart.getAxisSet().getYAxis(0).setRange(new Range(0.0, maxY)); | |
361 | } | |
362 | swtChart.redraw(); | |
363 | ||
364 | if (isSendTimeAlignSignals()) { | |
365 | // The width of the chart might have changed and its | |
366 | // time axis might be misaligned with the other views | |
367 | Point viewPos = AbstractSegmentStoreScatterGraphViewer.this.getParent().getParent().toDisplay(0, 0); | |
368 | int axisPos = swtChart.toDisplay(0, 0).x + getPointAreaOffset(); | |
369 | int timeAxisOffset = axisPos - viewPos.x; | |
370 | TmfTimeViewAlignmentInfo timeAlignmentInfo = new TmfTimeViewAlignmentInfo(getControl().getShell(), viewPos, timeAxisOffset); | |
371 | TmfSignalManager.dispatchSignal(new TmfTimeViewAlignmentSignal(AbstractSegmentStoreScatterGraphViewer.this, timeAlignmentInfo, true)); | |
372 | } | |
373 | } | |
374 | ||
375 | @Override | |
376 | protected void setWindowRange(final long windowStartTime, final long windowEndTime) { | |
377 | super.setWindowRange(windowStartTime, windowEndTime); | |
378 | } | |
379 | ||
380 | @Override | |
381 | protected ILineSeries addSeries(@Nullable String seriesName) { | |
382 | ISeriesSet seriesSet = getSwtChart().getSeriesSet(); | |
383 | ILineSeries series = (ILineSeries) seriesSet.createSeries(SeriesType.LINE, seriesName); | |
384 | series.setVisible(true); | |
385 | series.enableArea(false); | |
386 | series.setLineStyle(LineStyle.NONE); | |
387 | series.setSymbolType(PlotSymbolType.DIAMOND); | |
388 | return series; | |
389 | } | |
390 | ||
391 | /** | |
0f769d2b MK |
392 | * Set the data into the viewer. If the provider is an analysis, it will |
393 | * update the model if the analysis is completed or run the analysis if not | |
394 | * completed | |
03c96217 | 395 | * |
0f769d2b MK |
396 | * @param provider |
397 | * Segment store provider | |
03c96217 | 398 | */ |
0f769d2b MK |
399 | public void setData(@Nullable ISegmentStoreProvider provider) { |
400 | if (provider == null) { | |
03c96217 BH |
401 | updateModel(null); |
402 | return; | |
403 | } | |
0f769d2b MK |
404 | ISegmentStore<ISegment> segStore = provider.getSegmentStore(); |
405 | // If results are not null, then segment store is completed and model | |
406 | // can be updated | |
73c74de7 JCK |
407 | if (segStore != null) { |
408 | updateModel(segStore); | |
0f769d2b | 409 | setSegmentProvider(provider); |
03c96217 BH |
410 | return; |
411 | } | |
412 | updateModel(null); | |
0f769d2b MK |
413 | provider.addListener(fListener); |
414 | if (provider instanceof IAnalysisModule) { | |
415 | ((IAnalysisModule) provider).schedule(); | |
416 | } | |
417 | setSegmentProvider(provider); | |
03c96217 BH |
418 | } |
419 | ||
420 | /** | |
0f769d2b | 421 | * Returns the segment store provider |
df2597e0 | 422 | * |
03c96217 BH |
423 | * @param trace |
424 | * The trace to consider | |
0f769d2b | 425 | * @return the segment store provider |
03c96217 | 426 | */ |
0f769d2b | 427 | protected @Nullable abstract ISegmentStoreProvider getSegmentStoreProvider(ITmfTrace trace); |
03c96217 | 428 | |
03c96217 BH |
429 | // ------------------------------------------------------------------------ |
430 | // Signal handlers | |
431 | // ------------------------------------------------------------------------ | |
432 | ||
433 | /** | |
434 | * @param signal | |
435 | * Signal received when a different trace is selected | |
436 | */ | |
437 | @Override | |
438 | @TmfSignalHandler | |
439 | public void traceSelected(@Nullable TmfTraceSelectedSignal signal) { | |
440 | super.traceSelected(signal); | |
441 | if (signal == null) { | |
442 | return; | |
443 | } | |
444 | ITmfTrace trace = signal.getTrace(); | |
445 | setTrace(trace); | |
446 | if (trace != null) { | |
447 | final TmfTimeRange timeRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange(); | |
448 | setWindowRange( | |
16801c72 MK |
449 | timeRange.getStartTime().toNanos(), |
450 | timeRange.getEndTime().toNanos()); | |
0f769d2b | 451 | setData(getSegmentStoreProvider(trace)); |
03c96217 BH |
452 | updateRange(timeRange); |
453 | } | |
454 | } | |
455 | ||
456 | /** | |
457 | * @param signal | |
458 | * Signal received when trace is opened | |
459 | */ | |
460 | @Override | |
461 | @TmfSignalHandler | |
462 | public void traceOpened(@Nullable TmfTraceOpenedSignal signal) { | |
463 | super.traceOpened(signal); | |
464 | if (signal == null) { | |
465 | return; | |
466 | } | |
467 | ITmfTrace trace = signal.getTrace(); | |
468 | setTrace(trace); | |
469 | if (trace != null) { | |
470 | ||
0f769d2b | 471 | final ISegmentStoreProvider segmentStoreProvider = getSegmentStoreProvider(trace); |
03c96217 BH |
472 | final TmfTimeRange timeRange = TmfTraceManager.getInstance().getCurrentTraceContext().getWindowRange(); |
473 | setWindowRange( | |
16801c72 MK |
474 | timeRange.getStartTime().toNanos(), |
475 | timeRange.getEndTime().toNanos()); | |
0f769d2b | 476 | setData(segmentStoreProvider); |
03c96217 BH |
477 | } |
478 | ||
479 | } | |
480 | ||
481 | private void updateRange(final @Nullable TmfTimeRange timeRange) { | |
482 | Job compactingJob = fCompactingJob; | |
483 | if (compactingJob != null && compactingJob.getState() == Job.RUNNING) { | |
484 | compactingJob.cancel(); | |
485 | } | |
486 | compactingJob = new CompactingSegmentStoreQuery(NonNullUtils.checkNotNull(timeRange)); | |
487 | fCompactingJob = compactingJob; | |
488 | compactingJob.schedule(); | |
489 | } | |
490 | ||
491 | /** | |
492 | * @param signal | |
493 | * Signal received when last opened trace is closed | |
494 | */ | |
495 | @Override | |
496 | @TmfSignalHandler | |
497 | public void traceClosed(@Nullable TmfTraceClosedSignal signal) { | |
498 | super.traceClosed(signal); | |
499 | if (signal != null) { | |
500 | // Check if there is no more opened trace | |
501 | if (TmfTraceManager.getInstance().getActiveTrace() == null) { | |
0f769d2b MK |
502 | ISegmentStoreProvider provider = getSegmentProvider(); |
503 | if (provider != null) { | |
504 | provider.removeListener(fListener); | |
03c96217 BH |
505 | } |
506 | clearContent(); | |
507 | } | |
508 | } | |
509 | refresh(); | |
510 | } | |
511 | ||
512 | /** | |
513 | * @param signal | |
514 | * Signal received when window range is updated | |
515 | */ | |
516 | @Override | |
517 | @TmfSignalHandler | |
518 | public void windowRangeUpdated(@Nullable TmfWindowRangeUpdatedSignal signal) { | |
519 | super.windowRangeUpdated(signal); | |
520 | if (signal == null) { | |
521 | return; | |
522 | } | |
523 | if (getTrace() != null) { | |
524 | final TmfTimeRange currentRange = signal.getCurrentRange(); | |
525 | updateRange(currentRange); | |
526 | } else { | |
527 | Activator.getDefault().logInfo("No Trace to update"); //$NON-NLS-1$ | |
528 | } | |
529 | } | |
530 | ||
0f769d2b MK |
531 | private @Nullable ISegmentStoreProvider getSegmentProvider() { |
532 | return fSegmentProvider; | |
03c96217 BH |
533 | } |
534 | ||
0f769d2b MK |
535 | private void setSegmentProvider(ISegmentStoreProvider provider) { |
536 | fSegmentProvider = provider; | |
03c96217 | 537 | } |
03c96217 | 538 | } |