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