Work on request coalescing
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / histogram / HistogramView.java
CommitLineData
6e512b93 1/*******************************************************************************
e0752744 2 * Copyright (c) 2009, 2010, 2011, 2012 Ericsson
6e512b93
ASL
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:
b59134e1 10 * William Bourque - Initial API and implementation
c392540b
FC
11 * Yuriy Vashchuk - GUI reorganisation, simplification and some related code improvements.
12 * Yuriy Vashchuk - Histograms optimisation.
13 * Yuriy Vashchuk - Histogram Canvas Heritage correction
14 * Francois Chouinard - Cleanup and refactoring
e0752744 15 * Francois Chouinard - Moved from LTTng to TMF
6e512b93 16 *******************************************************************************/
3e9fdb8b 17
e0752744 18package org.eclipse.linuxtools.tmf.ui.views.histogram;
6e512b93 19
e0752744 20import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
4df4581d 21import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
6c13869b
FC
22import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
23import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
24import org.eclipse.linuxtools.tmf.core.experiment.TmfExperiment;
25import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType;
f6ad2e3d 26import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
6c13869b
FC
27import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal;
28import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;
a28d503d 29import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentUpdatedSignal;
6c13869b
FC
30import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
31import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
32import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
33import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
b59134e1
WB
34import org.eclipse.linuxtools.tmf.ui.views.TmfView;
35import org.eclipse.swt.SWT;
36import org.eclipse.swt.layout.GridData;
252ae4bd 37import org.eclipse.swt.layout.GridLayout;
6e512b93 38import org.eclipse.swt.widgets.Composite;
6e512b93 39
544fe9b7
WB
40/**
41 * <b><u>HistogramView</u></b>
42 * <p>
12c155f5 43 * The purpose of this view is to provide graphical time distribution statistics about the experiment/trace events.
544fe9b7 44 * <p>
c392540b
FC
45 * The view is composed of two histograms and two controls:
46 * <ul>
47 * <li>an event distribution histogram for the whole experiment;
48 * <li>an event distribution histogram for current time window (window span);
49 * <li>the timestamp of the currently selected event;
50 * <li>the window span (size of the time window of the smaller histogram).
51 * </ul>
52 * The histograms x-axis show their respective time range.
544fe9b7 53 */
c392540b
FC
54public class HistogramView extends TmfView {
55
56 // ------------------------------------------------------------------------
57 // Constants
58 // ------------------------------------------------------------------------
59
60 // The view ID as defined in plugin.xml
e0752744 61 public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.histogram"; //$NON-NLS-1$
c392540b
FC
62
63 // The initial window span (in nanoseconds)
1cceddbe 64 public static final long INITIAL_WINDOW_SPAN = (1L * 100 * 1000 * 1000); // .1sec
c392540b
FC
65
66 // Time scale
67 private final byte TIME_SCALE = Histogram.TIME_SCALE;
68
69 // ------------------------------------------------------------------------
70 // Attributes
71 // ------------------------------------------------------------------------
72
73 // Parent widget
74 private Composite fParent;
75
76 // The current experiment
e0752744 77 private TmfExperiment<ITmfEvent> fCurrentExperiment;
c392540b
FC
78
79 // Current timestamp/time window
80 private long fExperimentStartTime;
81 private long fExperimentEndTime;
82 private long fWindowStartTime;
83 private long fWindowEndTime;
84 private long fWindowSpan = INITIAL_WINDOW_SPAN;
85 private long fCurrentTimestamp;
86
87 // Time controls
88 private HistogramTextControl fCurrentEventTimeControl;
89 private HistogramTextControl fTimeSpanControl;
90
91 // Histogram/request for the full trace range
92 private static FullTraceHistogram fFullTraceHistogram;
93 private HistogramRequest fFullTraceRequest;
94
95 // Histogram/request for the selected time range
96 private static TimeRangeHistogram fTimeRangeHistogram;
97 private HistogramRequest fTimeRangeRequest;
98
99 // ------------------------------------------------------------------------
100 // Constructor
101 // ------------------------------------------------------------------------
102
103 public HistogramView() {
104 super(ID);
105 }
106
6a13fa07 107 @Override
c392540b 108 public void dispose() {
4dc47e28
FC
109 if (fTimeRangeRequest != null && !fTimeRangeRequest.isCompleted()) {
110 fTimeRangeRequest.cancel();
111 }
112 if (fFullTraceRequest != null && !fFullTraceRequest.isCompleted()) {
113 fFullTraceRequest.cancel();
114 }
6a13fa07
FC
115 fFullTraceHistogram.dispose();
116 fTimeRangeHistogram.dispose();
4dc47e28 117 super.dispose();
c392540b
FC
118 }
119
120 // ------------------------------------------------------------------------
121 // TmfView
122 // ------------------------------------------------------------------------
123
124 @Override
b59134e1 125 @SuppressWarnings("unchecked")
c392540b
FC
126 public void createPartControl(Composite parent) {
127
128 fParent = parent;
129
130 // Control labels
131 final String currentEventLabel = Messages.HistogramView_currentEventLabel;
132 final String windowSpanLabel = Messages.HistogramView_windowSpanLabel;
133
134 // --------------------------------------------------------------------
135 // Set the HistogramView layout
136 // --------------------------------------------------------------------
137
138 Composite viewComposite = new Composite(fParent, SWT.FILL);
139 GridLayout gridLayout = new GridLayout();
140 gridLayout.numColumns = 2;
141 gridLayout.horizontalSpacing = 5;
142 gridLayout.verticalSpacing = 0;
143 gridLayout.marginHeight = 0;
144 gridLayout.marginWidth = 0;
145 viewComposite.setLayout(gridLayout);
146
147 // Use all available space
148 GridData gridData = new GridData();
149 gridData.horizontalAlignment = SWT.FILL;
150 gridData.verticalAlignment = SWT.FILL;
151 gridData.grabExcessHorizontalSpace = true;
152 viewComposite.setLayoutData(gridData);
153
154 // --------------------------------------------------------------------
155 // Time controls
156 // --------------------------------------------------------------------
157
158 Composite controlsComposite = new Composite(viewComposite, SWT.FILL);
159 gridLayout = new GridLayout();
160 gridLayout.numColumns = 2;
161 gridLayout.marginHeight = 0;
162 gridLayout.marginWidth = 0;
163 gridLayout.horizontalSpacing = 5;
164 gridLayout.verticalSpacing = 0;
165 gridLayout.makeColumnsEqualWidth = true;
166 gridLayout.marginLeft = 5;
167 gridLayout.marginRight = 5;
168 controlsComposite.setLayout(gridLayout);
169
170 // Current event time control
171 gridData = new GridData();
172 gridData.horizontalAlignment = SWT.CENTER;
173 gridData.verticalAlignment = SWT.CENTER;
0301dc43 174 fCurrentEventTimeControl = new HistogramCurrentTimeControl(this, controlsComposite, SWT.BORDER, SWT.NONE,
12c155f5 175 currentEventLabel, HistogramUtils.nanosecondsToString(0L));
c392540b
FC
176 fCurrentEventTimeControl.setLayoutData(gridData);
177
178 // Window span time control
179 gridData = new GridData();
180 gridData.horizontalAlignment = SWT.CENTER;
181 gridData.verticalAlignment = SWT.CENTER;
0301dc43 182 fTimeSpanControl = new HistogramTimeRangeControl(this, controlsComposite, SWT.BORDER, SWT.NONE,
12c155f5 183 windowSpanLabel, HistogramUtils.nanosecondsToString(0L));
c392540b
FC
184 fTimeSpanControl.setLayoutData(gridData);
185
186 // --------------------------------------------------------------------
187 // Time range histogram
188 // --------------------------------------------------------------------
189
190 Composite timeRangeComposite = new Composite(viewComposite, SWT.FILL);
191 gridLayout = new GridLayout();
192 gridLayout.numColumns = 1;
193 gridLayout.marginHeight = 0;
194 gridLayout.marginWidth = 0;
195 gridLayout.marginTop = 5;
196 gridLayout.horizontalSpacing = 0;
197 gridLayout.verticalSpacing = 0;
198 gridLayout.marginLeft = 5;
199 gridLayout.marginRight = 5;
200 timeRangeComposite.setLayout(gridLayout);
201
202 // Use remaining horizontal space
203 gridData = new GridData();
204 gridData.horizontalAlignment = SWT.FILL;
205 gridData.verticalAlignment = SWT.FILL;
206 gridData.grabExcessHorizontalSpace = true;
207 timeRangeComposite.setLayoutData(gridData);
208
209 // Histogram
210 fTimeRangeHistogram = new TimeRangeHistogram(this, timeRangeComposite);
211
212 // --------------------------------------------------------------------
213 // Full range histogram
214 // --------------------------------------------------------------------
215
216 Composite fullRangeComposite = new Composite(viewComposite, SWT.FILL);
217 gridLayout = new GridLayout();
218 gridLayout.numColumns = 1;
219 gridLayout.marginHeight = 0;
220 gridLayout.marginWidth = 0;
221 gridLayout.marginTop = 5;
222 gridLayout.horizontalSpacing = 0;
223 gridLayout.verticalSpacing = 0;
224 gridLayout.marginLeft = 5;
225 gridLayout.marginRight = 5;
226 fullRangeComposite.setLayout(gridLayout);
227
228 // Use remaining horizontal space
229 gridData = new GridData();
230 gridData.horizontalAlignment = SWT.FILL;
231 gridData.verticalAlignment = SWT.FILL;
232 gridData.horizontalSpan = 2;
233 gridData.grabExcessHorizontalSpace = true;
234 fullRangeComposite.setLayoutData(gridData);
235
236 // Histogram
237 fFullTraceHistogram = new FullTraceHistogram(this, fullRangeComposite);
238
239 // Load the experiment if present
e0752744 240 fCurrentExperiment = (TmfExperiment<ITmfEvent>) TmfExperiment.getCurrentExperiment();
c392540b
FC
241 if (fCurrentExperiment != null)
242 loadExperiment();
ecfd1d41 243 }
c392540b
FC
244
245 @Override
3e9fdb8b 246 @SuppressWarnings("unchecked")
c392540b 247 public void setFocus() {
e0752744 248 TmfExperiment<ITmfEvent> experiment = (TmfExperiment<ITmfEvent>) TmfExperiment.getCurrentExperiment();
c392540b
FC
249 if ((experiment != null) && (experiment != fCurrentExperiment)) {
250 fCurrentExperiment = experiment;
251 initializeHistograms();
252 }
253 fParent.redraw();
833a21aa 254 }
c392540b
FC
255
256 // ------------------------------------------------------------------------
257 // Accessors
258 // ------------------------------------------------------------------------
259
260 public TmfTimeRange getTimeRange() {
12c155f5
FC
261 return new TmfTimeRange(new TmfTimestamp(fWindowStartTime, TIME_SCALE), new TmfTimestamp(fWindowEndTime,
262 TIME_SCALE));
c392540b
FC
263 }
264
265 // ------------------------------------------------------------------------
266 // Operations
267 // ------------------------------------------------------------------------
268
269 public void updateCurrentEventTime(long newTime) {
270 if (fCurrentExperiment != null) {
a4115405 271 TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(newTime, TIME_SCALE), TmfTimestamp.BIG_CRUNCH);
f6ad2e3d 272 HistogramRequest request = new HistogramRequest(fTimeRangeHistogram.getDataModel(), timeRange, 0, 1, 0, ExecutionType.FOREGROUND) {
c392540b 273 @Override
e0752744 274 public void handleData(ITmfEvent event) {
c392540b
FC
275 if (event != null) {
276 TmfTimeSynchSignal signal = new TmfTimeSynchSignal(this, event.getTimestamp());
277 TmfSignalManager.dispatchSignal(signal);
278 }
279 }
280 };
281 fCurrentExperiment.sendRequest(request);
282 }
283 }
284
285 public void updateTimeRange(long startTime, long endTime) {
286 if (fCurrentExperiment != null) {
287 // Build the new time range; keep the current time
12c155f5
FC
288 TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(startTime, TIME_SCALE), new TmfTimestamp(
289 endTime, TIME_SCALE));
c392540b 290 TmfTimestamp currentTime = new TmfTimestamp(fCurrentTimestamp, TIME_SCALE);
6a13fa07 291
c392540b
FC
292 fTimeSpanControl.setValue(endTime - startTime);
293
294 // Send the FW signal
295 TmfRangeSynchSignal signal = new TmfRangeSynchSignal(this, timeRange, currentTime);
296 TmfSignalManager.dispatchSignal(signal);
297 }
298 }
299
300 public synchronized void updateTimeRange(long newDuration) {
301 if (fCurrentExperiment != null) {
6a13fa07
FC
302 long delta = newDuration - fWindowSpan;
303 long newStartTime = fWindowStartTime + delta / 2;
304 setNewRange(newStartTime, newDuration);
c392540b
FC
305 }
306 }
307
308 private void setNewRange(long startTime, long duration) {
309 if (startTime < fExperimentStartTime)
6a13fa07 310 startTime = fExperimentStartTime;
c392540b
FC
311
312 long endTime = startTime + duration;
313 if (endTime > fExperimentEndTime) {
6a13fa07
FC
314 endTime = fExperimentEndTime;
315 if (endTime - duration > fExperimentStartTime)
316 startTime = endTime - duration;
317 else {
318 startTime = fExperimentStartTime;
319 }
c392540b
FC
320 }
321 updateTimeRange(startTime, endTime);
833a21aa 322 }
c392540b
FC
323
324 // ------------------------------------------------------------------------
325 // Signal handlers
326 // ------------------------------------------------------------------------
327
1406f802 328 @TmfSignalHandler
c392540b 329 @SuppressWarnings("unchecked")
e0752744 330 public void experimentSelected(TmfExperimentSelectedSignal<ITmfEvent> signal) {
c392540b 331 assert (signal != null);
e0752744 332 fCurrentExperiment = (TmfExperiment<ITmfEvent>) signal.getExperiment();
c392540b 333 loadExperiment();
ecfd1d41 334 }
550d787e 335
c392540b 336 private void loadExperiment() {
c392540b
FC
337 initializeHistograms();
338 fParent.redraw();
550d787e
FC
339 }
340
74237cc3 341 @TmfSignalHandler
74237cc3
FC
342 public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal) {
343
09d11238
PT
344 if (signal.getExperiment() != fCurrentExperiment) {
345 return;
346 }
347
74237cc3
FC
348 boolean drawTimeRangeHistogram = fExperimentStartTime == 0;
349 TmfTimeRange fullRange = signal.getRange();
350
351 fExperimentStartTime = fullRange.getStartTime().getValue();
352 fExperimentEndTime = fullRange.getEndTime().getValue();
353
354 fFullTraceHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
355 fTimeRangeHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
356
357 if (drawTimeRangeHistogram) {
358 fCurrentTimestamp = fExperimentStartTime;
359 fCurrentEventTimeControl.setValue(fCurrentTimestamp);
360 fFullTraceHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
361 fTimeRangeHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
362 sendTimeRangeRequest(fExperimentStartTime, fExperimentStartTime + INITIAL_WINDOW_SPAN);
363 }
364
365 sendFullRangeRequest(fullRange);
366 }
c392540b 367
a28d503d
PT
368 @TmfSignalHandler
369 public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
370 if (signal.getExperiment() != fCurrentExperiment) {
371 return;
372 }
373 TmfTimeRange fullRange = signal.getExperiment().getTimeRange();
374 fExperimentStartTime = fullRange.getStartTime().getValue();
375 fExperimentEndTime = fullRange.getEndTime().getValue();
376
377 fFullTraceHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
378 fTimeRangeHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
379 }
380
c392540b
FC
381 @TmfSignalHandler
382 public void currentTimeUpdated(TmfTimeSynchSignal signal) {
383 // Because this can't happen :-)
384 assert (signal != null);
385
386 // Update the selected event time
4df4581d 387 ITmfTimestamp currentTime = signal.getCurrentTime();
c392540b
FC
388 fCurrentTimestamp = currentTime.getValue();
389
390 // Notify the relevant widgets
391 fFullTraceHistogram.setCurrentEvent(fCurrentTimestamp);
392 fTimeRangeHistogram.setCurrentEvent(fCurrentTimestamp);
393 fCurrentEventTimeControl.setValue(fCurrentTimestamp);
ecfd1d41 394 }
f05aabed 395
c392540b
FC
396 @TmfSignalHandler
397 public void timeRangeUpdated(TmfRangeSynchSignal signal) {
398 // Because this can't happen :-)
399 assert (signal != null);
400
401 if (fCurrentExperiment != null) {
402 // Update the time range
403 fWindowStartTime = signal.getCurrentRange().getStartTime().getValue();
404 fWindowEndTime = signal.getCurrentRange().getEndTime().getValue();
405 fWindowSpan = fWindowEndTime - fWindowStartTime;
406
407 // Notify the relevant widgets
408 sendTimeRangeRequest(fWindowStartTime, fWindowEndTime);
409 fFullTraceHistogram.setTimeRange(fWindowStartTime, fWindowSpan);
410 fTimeSpanControl.setValue(fWindowSpan);
411 }
b59134e1 412 }
c392540b
FC
413
414 // ------------------------------------------------------------------------
415 // Helper functions
416 // ------------------------------------------------------------------------
417
418 private void initializeHistograms() {
74237cc3
FC
419 TmfTimeRange fullRange = updateExperimentTimeRange(fCurrentExperiment);
420
421 fTimeRangeHistogram.clear();
c392540b
FC
422 fTimeRangeHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
423 fTimeRangeHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
424 fTimeRangeHistogram.setCurrentEvent(fExperimentStartTime);
425
74237cc3 426 fFullTraceHistogram.clear();
6a13fa07 427 fFullTraceHistogram.setFullRange(fExperimentStartTime, fExperimentEndTime);
c392540b
FC
428 fFullTraceHistogram.setTimeRange(fExperimentStartTime, INITIAL_WINDOW_SPAN);
429 fFullTraceHistogram.setCurrentEvent(fExperimentStartTime);
430
431 fWindowStartTime = fExperimentStartTime;
432 fWindowSpan = INITIAL_WINDOW_SPAN;
433 fWindowEndTime = fWindowStartTime + fWindowSpan;
6a13fa07 434
c392540b
FC
435 fCurrentEventTimeControl.setValue(fExperimentStartTime);
436 fTimeSpanControl.setValue(fWindowSpan);
6a13fa07 437
c392540b 438 sendTimeRangeRequest(fExperimentStartTime, fExperimentStartTime + fWindowSpan);
74237cc3
FC
439 sendFullRangeRequest(fullRange);
440 }
441
e0752744 442 private TmfTimeRange updateExperimentTimeRange(TmfExperiment<ITmfEvent> experiment) {
74237cc3
FC
443 fExperimentStartTime = 0;
444 fExperimentEndTime = 0;
445 fCurrentTimestamp = 0;
446
447 TmfTimeRange timeRange = fCurrentExperiment.getTimeRange();
a4115405 448 if (timeRange != TmfTimeRange.NULL_RANGE) {
74237cc3
FC
449 fExperimentStartTime = timeRange.getStartTime().getValue();
450 fExperimentEndTime = timeRange.getEndTime().getValue();
451 fCurrentTimestamp = fExperimentStartTime;
452 }
453 return timeRange;
b59134e1 454 }
c392540b
FC
455
456 private void sendTimeRangeRequest(long startTime, long endTime) {
457 if (fTimeRangeRequest != null && !fTimeRangeRequest.isCompleted()) {
458 fTimeRangeRequest.cancel();
088c1d4e 459 }
c392540b
FC
460 TmfTimestamp startTS = new TmfTimestamp(startTime, TIME_SCALE);
461 TmfTimestamp endTS = new TmfTimestamp(endTime, TIME_SCALE);
462 TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS);
463
464 fTimeRangeHistogram.clear();
465 fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime);
f6ad2e3d
FC
466 int cacheSize = fCurrentExperiment.getCacheSize();
467 fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram.getDataModel(), timeRange, 0, TmfDataRequest.ALL_DATA, cacheSize, ExecutionType.FOREGROUND);
c392540b 468 fCurrentExperiment.sendRequest(fTimeRangeRequest);
088c1d4e 469 }
c392540b 470
74237cc3 471 private void sendFullRangeRequest(TmfTimeRange fullRange) {
c392540b
FC
472 if (fFullTraceRequest != null && !fFullTraceRequest.isCompleted()) {
473 fFullTraceRequest.cancel();
474 }
f6ad2e3d 475 int cacheSize = fCurrentExperiment.getCacheSize();
fbd124dd 476 fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(), fullRange, (int) fFullTraceHistogram.fDataModel.getNbEvents(),
f6ad2e3d 477 TmfDataRequest.ALL_DATA, cacheSize, ExecutionType.BACKGROUND);
c392540b 478 fCurrentExperiment.sendRequest(fFullTraceRequest);
ed4b3b9f 479 }
c392540b 480
6e512b93 481}
This page took 0.066783 seconds and 5 git commands to generate.