tmf: Introduce a central trace manager
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / viewers / statistics / TmfStatisticsViewer.java
CommitLineData
cfd22ad0 1/*******************************************************************************
c8422608 2 * Copyright (c) 2012, 2013 Ericsson
cfd22ad0
MD
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 * Mathieu Denis <mathieu.denis@polymtl.ca> - Initial API and implementation
89c06060 11 * Alexandre Montplaisir - Port to ITmfStatistics provider
cfd22ad0
MD
12 *******************************************************************************/
13
14package org.eclipse.linuxtools.tmf.ui.viewers.statistics;
15
16import java.util.List;
89c06060 17import java.util.Map;
cfd22ad0
MD
18
19import org.eclipse.jface.viewers.TreeViewer;
20import org.eclipse.jface.viewers.TreeViewerColumn;
21import org.eclipse.jface.viewers.Viewer;
22import org.eclipse.jface.viewers.ViewerComparator;
23import org.eclipse.linuxtools.tmf.core.component.TmfComponent;
05627bda 24import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
05627bda
MD
25import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
26import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
1c0de632 27import org.eclipse.linuxtools.tmf.core.signal.TmfStatsUpdatedSignal;
faa38350 28import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
89c06060 29import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics;
3bd46eef
AM
30import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
31import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
05627bda
MD
32import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
33import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
34import org.eclipse.linuxtools.tmf.ui.viewers.TmfViewer;
cfd22ad0
MD
35import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.ITmfColumnDataProvider;
36import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnData;
37import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider;
36033ff0
AM
38import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTree;
39import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeManager;
cfd22ad0 40import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode;
cfd22ad0
MD
41import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfTreeContentProvider;
42import org.eclipse.swt.SWT;
43import org.eclipse.swt.events.SelectionAdapter;
44import org.eclipse.swt.events.SelectionEvent;
45import org.eclipse.swt.graphics.Color;
46import org.eclipse.swt.graphics.Cursor;
cfd22ad0
MD
47import org.eclipse.swt.widgets.Composite;
48import org.eclipse.swt.widgets.Control;
49import org.eclipse.swt.widgets.Display;
50import org.eclipse.swt.widgets.Event;
51import org.eclipse.swt.widgets.Listener;
52
53/**
54 * A basic viewer to display statistics in the statistics view.
55 *
8b60cb37
MD
56 * It is linked to a single ITmfTrace until its disposal.
57 *
cfd22ad0
MD
58 * @author Mathieu Denis
59 * @version 2.0
60 * @since 2.0
61 */
05627bda 62public class TmfStatisticsViewer extends TmfViewer {
cfd22ad0 63
05627bda
MD
64 /**
65 * Timestamp scale (nanosecond)
66 */
faa38350 67 public static final byte TIME_SCALE = ITmfTimestamp.NANOSECOND_SCALE;
05627bda
MD
68
69 /**
70 * Default PAGE_SIZE for background requests.
71 */
72 protected static final int PAGE_SIZE = 50000;
73
74 /**
75 * Refresh frequency.
76 */
77 protected final Long STATS_INPUT_CHANGED_REFRESH = 5000L;
78
cfd22ad0
MD
79 /**
80 * The actual tree viewer to display
81 */
82 protected TreeViewer fTreeViewer;
83
84 /**
05627bda
MD
85 * The statistics tree linked to this viewer
86 */
36033ff0 87 protected TmfStatisticsTree fStatisticsData;
05627bda
MD
88
89 /**
90 * Update synchronization parameter (used for streaming): Update busy
91 * indicator.
92 */
93 protected boolean fStatisticsUpdateBusy = false;
94
95 /**
96 * Update synchronization parameter (used for streaming): Update pending
97 * indicator.
98 */
99 protected boolean fStatisticsUpdatePending = false;
100
101 /**
102 * Update synchronization parameter (used for streaming): Pending Update
103 * time range.
104 */
105 protected TmfTimeRange fStatisticsUpdateRange = null;
106
107 /**
108 * Update synchronization object.
109 */
110 protected final Object fStatisticsUpdateSyncObj = new Object();
111
3c934968
MD
112 /**
113 * Update range synchronization object.
114 */
115 protected final Object fStatisticsRangeUpdateSyncObj = new Object();
116
89c06060 117 /**
73fbf6be
MD
118 * The trace that is displayed by this viewer
119 */
120 protected ITmfTrace fTrace;
121
89c06060
AM
122 /**
123 * Stores the requested time range.
124 */
125 protected TmfTimeRange fRequestedTimerange;
126
05627bda
MD
127 /**
128 * Indicates to process all events
129 */
130 private boolean fProcessAll;
131
132 /**
133 * View instance counter (for multiple statistics views)
cfd22ad0
MD
134 */
135 private static int fCountInstance = 0;
136
137 /**
138 * Number of this instance. Used as an instance ID.
139 */
140 private int fInstanceNb;
141
142 /**
faa38350 143 * Object to store the cursor while waiting for the trace to load
cfd22ad0
MD
144 */
145 private Cursor fWaitCursor = null;
146
147 /**
05627bda
MD
148 * Counts the number of times waitCursor() has been called. It avoids
149 * removing the waiting cursor, since there may be multiple requests running
150 * at the same time.
151 */
152 private int fWaitCursorCount = 0;
153
154 /**
faa38350 155 * Tells to send a time range request when the trace gets updated.
05627bda
MD
156 */
157 private boolean fSendRangeRequest = true;
158
159 /**
160 * Empty constructor. To be used in conjunction with
161 * {@link TmfStatisticsViewer#init(Composite, String, ITmfTrace)}
162 */
163 public TmfStatisticsViewer() {
164 super();
165 }
166
167 /**
168 * Create a basic statistics viewer. To be used in conjunction with
169 * {@link TmfStatisticsViewer#init(Composite, String, ITmfTrace)}
170 *
171 * @param parent
172 * The parent composite that will hold the viewer
173 * @param viewerName
174 * The name that will be assigned to this viewer
175 * @param trace
176 * The trace that is displayed by this viewer
177 * @see TmfComponent
178 */
179 public TmfStatisticsViewer(Composite parent, String viewerName, ITmfTrace trace) {
180 init(parent, viewerName, trace);
181 }
182
183 /**
184 * Initialize the statistics viewer.
cfd22ad0
MD
185 *
186 * @param parent
05627bda
MD
187 * The parent component of the viewer.
188 * @param viewerName
189 * The name to give to the viewer.
190 * @param trace
191 * The trace that will be displayed by the viewer.
cfd22ad0 192 */
05627bda
MD
193 public void init(Composite parent, String viewerName, ITmfTrace trace) {
194 super.init(parent, viewerName);
cfd22ad0
MD
195 // Increment a counter to make sure the tree ID is unique.
196 fCountInstance++;
197 fInstanceNb = fCountInstance;
05627bda
MD
198 fTrace = trace;
199
faa38350 200 // The viewer will process all events if he is assigned to an experiment
05627bda
MD
201 fProcessAll = (trace instanceof TmfExperiment);
202
203 initContent(parent);
8b60cb37 204 initInput();
05627bda
MD
205 }
206
05627bda
MD
207 @Override
208 public void dispose() {
209 super.dispose();
210 if (fWaitCursor != null) {
211 fWaitCursor.dispose();
212 }
8b60cb37 213
66792052 214 // Clean the model for this viewer
36033ff0 215 TmfStatisticsTreeManager.removeStatTreeRoot(getTreeID());
05627bda
MD
216 }
217
1c0de632
AM
218 // ------------------------------------------------------------------------
219 // Signal handlers
220 // ------------------------------------------------------------------------
89c06060 221
05627bda 222 /**
faa38350 223 * Handles the signal about new trace range.
05627bda
MD
224 *
225 * @param signal
faa38350 226 * The trace range updated signal
05627bda
MD
227 */
228 @TmfSignalHandler
faa38350
PT
229 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) {
230 ITmfTrace trace = signal.getTrace();
05627bda 231 // validate
faa38350 232 if (!isListeningTo(trace)) {
05627bda
MD
233 return;
234 }
235
3c934968
MD
236 synchronized (fStatisticsRangeUpdateSyncObj) {
237 // Sends the time range request only once from this method.
238 if (fSendRangeRequest) {
239 fSendRangeRequest = false;
d7ee91bb 240 requestTimeRangeData(trace, fTrace.getCurrentRange());
3c934968 241 }
05627bda 242 }
faa38350 243 requestData(trace, signal.getRange());
05627bda
MD
244 }
245
246 /**
89c06060 247 * Handles the time range updated signal. It updates the time range
05627bda
MD
248 * statistics.
249 *
250 * @param signal
251 * Contains the information about the new selected time range.
252 */
253 @TmfSignalHandler
254 public void timeRangeUpdated(TmfRangeSynchSignal signal) {
faa38350
PT
255 if (fTrace == null) {
256 return;
257 }
258 requestTimeRangeData(fTrace, signal.getCurrentRange());
05627bda
MD
259 }
260
1c0de632
AM
261 /**
262 * Whenever a trace's statistics back-end finishes computing the statistics
263 * for a given interval, it will send the StatsUpdated signal. This method
264 * will receive this signal and update the statistics view accordingly.
265 *
266 * @param sig
267 * The signal that is received
268 */
269 @TmfSignalHandler
270 public void statsUpdated(TmfStatsUpdatedSignal sig) {
271 /* Only handle this signal if it's about the trace we represent. */
272 if (!isListeningTo(sig.getTrace())) {
273 return;
274 }
275
276 final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(getTreeID());
277 Map<String, Long> map = sig.getEventsPerType();
278 String name = sig.getTrace().getName();
279 boolean isGlobal = sig.isGlobal();
280
281 /*
282 * "Global", "partial", "total", etc., it's all very confusing...
283 *
284 * The base view shows the total count for the trace and for
285 * each even types, organized in columns like this:
286 *
287 * | Global | Time range |
288 * trace name | A | B |
289 * Event Type | | |
290 * <event 1> | C | D |
291 * <event 2> | ... | ... |
292 * ... | | |
293 *
294 * Here, we called the cells like this:
295 * A : GlobalTotal
296 * B : TimeRangeTotal
297 * C : GlobalTypeCount(s)
298 * D : TimeRangeTypeCount(s)
299 */
300
301 /* Fill in an the event counts (either cells C or D) */
302 for (Map.Entry<String, Long> entry : map.entrySet()) {
303 statsData.setTypeCount(name, entry.getKey(), isGlobal, entry.getValue());
304 }
305
306 /*
307 * Calculate the totals (cell A or B, depending if isGlobal). We will
308 * use the results of the previous request instead of sending another
309 * one.
310 */
311 long globalTotal = 0;
312 for (long val : map.values()) {
313 globalTotal += val;
314 }
315 statsData.setTotal(name, isGlobal, globalTotal);
316
317 modelComplete(isGlobal);
318 }
319
320 // ------------------------------------------------------------------------
321 // Class methods
322 // ------------------------------------------------------------------------
323
05627bda
MD
324 /*
325 * Returns the primary control associated with this viewer.
326 *
327 * @return the SWT control which displays this viewer's content
328 */
329 @Override
330 public Control getControl() {
331 return fTreeViewer.getControl();
332 }
333
334 /**
335 * Get the input of the viewer.
336 *
337 * @return an object representing the input of the statistics viewer.
338 */
339 public Object getInput() {
340 return fTreeViewer.getInput();
341 }
342
343 /**
344 * Return the size of the request when performing background request.
345 *
346 * @return the block size for background request.
347 */
348 public int getPageSize() {
349 return PAGE_SIZE;
350 }
351
352 /**
353 * Return the number of events to receive before a refresh of the viewer is
354 * performed.
355 *
356 * @return the input refresh rate
357 */
358 public long getRefreshRate() {
359 return STATS_INPUT_CHANGED_REFRESH;
360 }
361
362 /**
363 * This method can be overridden to implement another way of representing
364 * the statistics data and to retrieve the information for display.
365 *
366 * @return a TmfStatisticsData object.
367 */
36033ff0 368 public TmfStatisticsTree getStatisticData() {
05627bda 369 if (fStatisticsData == null) {
36033ff0 370 fStatisticsData = new TmfStatisticsTree();
05627bda
MD
371 }
372 return fStatisticsData;
373 }
374
375 /**
376 * Returns a unique ID based on name to be associated with the statistics
377 * tree for this viewer. For a same name, it will always return the same ID.
378 *
379 * @return a unique statistics tree ID.
380 */
381 public String getTreeID() {
382 return getName() + fInstanceNb;
383 }
384
385 @Override
386 public void refresh() {
387 final Control viewerControl = getControl();
388 // Ignore update if disposed
389 if (viewerControl.isDisposed()) {
390 return;
391 }
392
393 viewerControl.getDisplay().asyncExec(new Runnable() {
394 @Override
395 public void run() {
396 if (!viewerControl.isDisposed()) {
397 fTreeViewer.refresh();
398 }
399 }
400 });
401 }
402
3c934968
MD
403 /**
404 * Will force a request on the partial event count if one is needed.
405 */
406 public void sendPartialRequestOnNextUpdate() {
407 synchronized (fStatisticsRangeUpdateSyncObj) {
408 fSendRangeRequest = true;
409 }
410 }
411
05627bda
MD
412 /**
413 * Focus on the statistics tree of the viewer
414 */
415 public void setFocus() {
416 fTreeViewer.getTree().setFocus();
417 }
418
05627bda
MD
419 /**
420 * Cancels the request if it is not already completed
421 *
422 * @param request
423 * The request to be canceled
424 */
425 protected void cancelOngoingRequest(ITmfDataRequest request) {
426 if (request != null && !request.isCompleted()) {
427 request.cancel();
428 }
429 }
430
431 /**
432 * This method can be overridden to change the representation of the data in
433 * the columns.
434 *
435 * @return an object implementing ITmfBaseColumnDataProvider.
436 */
437 protected ITmfColumnDataProvider getColumnDataProvider() {
438 return new TmfBaseColumnDataProvider();
439 }
cfd22ad0 440
05627bda
MD
441 /**
442 * Initialize the content that will be drawn in this viewer
443 *
444 * @param parent
445 * The parent of the control to create
446 */
447 protected void initContent(Composite parent) {
cfd22ad0 448 final List<TmfBaseColumnData> columnDataList = getColumnDataProvider().getColumnData();
cfd22ad0
MD
449
450 fTreeViewer = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
451 fTreeViewer.setContentProvider(new TmfTreeContentProvider());
452 fTreeViewer.getTree().setHeaderVisible(true);
453 fTreeViewer.setUseHashlookup(true);
454
455 // Creates the columns defined by the column data provider
456 for (final TmfBaseColumnData columnData : columnDataList) {
457 final TreeViewerColumn treeColumn = new TreeViewerColumn(fTreeViewer, columnData.getAlignment());
458 treeColumn.getColumn().setText(columnData.getHeader());
459 treeColumn.getColumn().setWidth(columnData.getWidth());
460 treeColumn.getColumn().setToolTipText(columnData.getTooltip());
461
462 if (columnData.getComparator() != null) { // A comparator is defined.
463 // Adds a listener on the columns header for sorting purpose.
464 treeColumn.getColumn().addSelectionListener(new SelectionAdapter() {
465
466 private ViewerComparator reverseComparator;
467
468 @Override
469 public void widgetSelected(SelectionEvent e) {
470 // Initializes the reverse comparator once.
471 if (reverseComparator == null) {
472 reverseComparator = new ViewerComparator() {
473 @Override
474 public int compare(Viewer viewer, Object e1, Object e2) {
475 return -1 * columnData.getComparator().compare(viewer, e1, e2);
476 }
477 };
478 }
479
480 if (fTreeViewer.getTree().getSortDirection() == SWT.UP
481 || fTreeViewer.getTree().getSortColumn() != treeColumn.getColumn()) {
482 /*
483 * Puts the descendant order if the old order was
484 * up or if the selected column has changed.
485 */
486 fTreeViewer.setComparator(columnData.getComparator());
487 fTreeViewer.getTree().setSortDirection(SWT.DOWN);
488 } else {
489 /*
490 * Puts the ascendant ordering if the selected
491 * column hasn't changed.
492 */
493 fTreeViewer.setComparator(reverseComparator);
494 fTreeViewer.getTree().setSortDirection(SWT.UP);
495 }
496 fTreeViewer.getTree().setSortColumn(treeColumn.getColumn());
497 }
498 });
499 }
500 treeColumn.setLabelProvider(columnData.getLabelProvider());
501 }
502
503 // Handler that will draw the bar charts.
504 fTreeViewer.getTree().addListener(SWT.EraseItem, new Listener() {
505 @Override
506 public void handleEvent(Event event) {
507 if (columnDataList.get(event.index).getPercentageProvider() != null) {
508 TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) event.item.getData();
509
510 double percentage = columnDataList.get(event.index).getPercentageProvider().getPercentage(node);
511 if (percentage == 0) { // No bar to draw
512 return;
513 }
514
515 if ((event.detail & SWT.SELECTED) > 0) { // The item is selected.
516 // Draws our own background to avoid overwritten the bar.
517 event.gc.fillRectangle(event.x, event.y, event.width, event.height);
518 event.detail &= ~SWT.SELECTED;
519 }
520
521 int barWidth = (int) ((fTreeViewer.getTree().getColumn(event.index).getWidth() - 8) * percentage);
522 int oldAlpha = event.gc.getAlpha();
523 Color oldForeground = event.gc.getForeground();
524 Color oldBackground = event.gc.getBackground();
525 /*
526 * Draws a transparent gradient rectangle from the color of
527 * foreground and background.
528 */
529 event.gc.setAlpha(64);
530 event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_BLUE));
531 event.gc.setBackground(event.item.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
532 event.gc.fillGradientRectangle(event.x, event.y, barWidth, event.height, true);
533 event.gc.drawRectangle(event.x, event.y, barWidth, event.height);
534 // Restores old values
535 event.gc.setForeground(oldForeground);
536 event.gc.setBackground(oldBackground);
537 event.gc.setAlpha(oldAlpha);
538 event.detail &= ~SWT.BACKGROUND;
539 }
540 }
541 });
542
543 // Initializes the comparator parameters
544 fTreeViewer.setComparator(columnDataList.get(0).getComparator());
545 fTreeViewer.getTree().setSortColumn(fTreeViewer.getTree().getColumn(0));
546 fTreeViewer.getTree().setSortDirection(SWT.DOWN);
547 }
548
8b60cb37
MD
549 /**
550 * Initializes the input for the tree viewer.
8b60cb37
MD
551 */
552 protected void initInput() {
553 String treeID = getTreeID();
faa38350 554 TmfStatisticsTreeNode statisticsTreeNode;
36033ff0 555 if (TmfStatisticsTreeManager.containsTreeRoot(treeID)) {
faa38350
PT
556 // The statistics root is already present
557 statisticsTreeNode = TmfStatisticsTreeManager.getStatTreeRoot(treeID);
8b60cb37
MD
558
559 // Checks if the trace is already in the statistics tree.
faa38350 560 int numNodeTraces = statisticsTreeNode.getNbChildren();
8b60cb37 561
fe0c44c4
AM
562 ITmfTrace[] traces = fTrace.getTraces();
563 int numTraces = traces.length;
8b60cb37
MD
564
565 if (numTraces == numNodeTraces) {
566 boolean same = true;
567 /*
568 * Checks if the experiment contains the same traces as when
569 * previously selected.
570 */
571 for (int i = 0; i < numTraces; i++) {
fe0c44c4 572 String traceName = traces[i].getName();
faa38350 573 if (!statisticsTreeNode.containsChild(traceName)) {
8b60cb37
MD
574 same = false;
575 break;
576 }
577 }
578
579 if (same) {
580 // No need to reload data, all traces are already loaded
faa38350 581 fTreeViewer.setInput(statisticsTreeNode);
8b60cb37
MD
582 return;
583 }
584 // Clears the old content to start over
faa38350 585 statisticsTreeNode.reset();
8b60cb37
MD
586 }
587 } else {
588 // Creates a new tree
faa38350 589 statisticsTreeNode = TmfStatisticsTreeManager.addStatsTreeRoot(treeID, getStatisticData());
8b60cb37
MD
590 }
591
592 // Sets the input to a clean data model
faa38350 593 fTreeViewer.setInput(statisticsTreeNode);
8b60cb37
MD
594 resetUpdateSynchronization();
595 }
596
cfd22ad0 597 /**
faa38350 598 * Tells if the viewer is listening to a trace.
cfd22ad0 599 *
1c0de632 600 * @param trace
05627bda
MD
601 * The trace that the viewer may be listening
602 * @return true if the viewer is listening to the trace, false otherwise
cfd22ad0 603 */
1c0de632
AM
604 protected boolean isListeningTo(ITmfTrace trace) {
605 if (fProcessAll || trace == fTrace) {
05627bda 606 return true;
cfd22ad0 607 }
05627bda 608 return false;
cfd22ad0
MD
609 }
610
611 /**
faa38350 612 * Called when an trace request has been completed successfully.
cfd22ad0 613 *
05627bda
MD
614 * @param global
615 * Tells if the request is a global or time range (partial)
616 * request.
cfd22ad0 617 */
05627bda
MD
618 protected void modelComplete(boolean global) {
619 refresh();
620 waitCursor(false);
621 if (global) {
622 sendPendingUpdate();
623 }
cfd22ad0
MD
624 }
625
626 /**
faa38350 627 * Called when an trace request has failed or has been cancelled.
cfd22ad0 628 *
05627bda
MD
629 * @param isGlobalRequest
630 * Tells if the request is a global or time range (partial)
631 * request.
cfd22ad0 632 */
05627bda
MD
633 protected void modelIncomplete(boolean isGlobalRequest) {
634 if (isGlobalRequest) { // Clean the global statistics
635 /*
763f4972
MD
636 * No need to reset the global number of events, since the index of
637 * the last requested event is known.
05627bda 638 */
05627bda
MD
639 resetUpdateSynchronization();
640 sendPendingUpdate();
641 } else { // Clean the partial statistics
642 resetTimeRangeValue();
643 }
644 refresh();
645 waitCursor(false);
cfd22ad0
MD
646 }
647
648 /**
faa38350 649 * Sends the request to the trace for the whole trace
cfd22ad0 650 *
faa38350
PT
651 * @param trace
652 * The trace used to send the request
8b260d9f 653 * @param timeRange
faa38350 654 * The range to request to the trace
cfd22ad0 655 */
faa38350
PT
656 protected void requestData(final ITmfTrace trace, final TmfTimeRange timeRange) {
657 buildStatisticsTree(trace, timeRange, true);
cfd22ad0
MD
658 }
659
660 /**
faa38350 661 * Sends the time range request from the trace
cfd22ad0 662 *
faa38350
PT
663 * @param trace
664 * The trace used to send the request
8b260d9f 665 * @param timeRange
faa38350 666 * The range to request to the trace
cfd22ad0 667 */
faa38350 668 protected void requestTimeRangeData(final ITmfTrace trace, final TmfTimeRange timeRange) {
89c06060 669 fRequestedTimerange = timeRange;
faa38350 670 buildStatisticsTree(trace, timeRange, false);
89c06060
AM
671 }
672
673 /**
faa38350 674 * Requests all the data of the trace to the state system which
89c06060
AM
675 * contains information about the statistics.
676 *
faa38350
PT
677 * Since the viewer may be listening to multiple traces, it may receive
678 * an experiment rather than a single trace. The filtering is done with the
89c06060
AM
679 * method {@link #isListeningTo(String trace)}.
680 *
faa38350
PT
681 * @param trace
682 * The trace for which a request must be done
89c06060
AM
683 * @param timeRange
684 * The time range that will be requested to the state system
685 * @param isGlobal
686 * Tells if the request is for the global event count or the
687 * partial one.
688 */
faa38350 689 private void buildStatisticsTree(final ITmfTrace trace, TmfTimeRange timeRange, boolean isGlobal) {
36033ff0
AM
690 final TmfStatisticsTreeNode statTree = TmfStatisticsTreeManager.getStatTreeRoot(getTreeID());
691 final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(getTreeID());
89c06060
AM
692 if (statsData == null) {
693 return;
694 }
695
696 synchronized (statsData) {
697 if (isGlobal) {
698 statTree.resetGlobalValue();
699 } else {
700 statTree.resetTimeRangeValue();
701 }
702
fe0c44c4 703 ITmfTrace[] traces = trace.getTraces();
faa38350
PT
704 for (final ITmfTrace aTrace : traces) {
705 if (!isListeningTo(aTrace)) {
89c06060
AM
706 continue;
707 }
708
709 /* Retrieves the statistics object */
faa38350 710 final ITmfStatistics stats = aTrace.getStatistics();
89c06060
AM
711 if (stats == null) {
712 /*
1c0de632
AM
713 * The statistics provider for this trace is not accessible
714 * (yet?). Try the next one.
89c06060
AM
715 */
716 continue;
717 }
718
1c0de632
AM
719 /* The generic statistics are stored in nanoseconds, so we must make
720 * sure the time range is scaled correctly. */
8b260d9f
AM
721 long start = timeRange.getStartTime().normalize(0, TIME_SCALE).getValue();
722 long end = timeRange.getEndTime().normalize(0, TIME_SCALE).getValue();
89c06060 723
1c0de632
AM
724 /*
725 * Send a request to update the statistics view. The result will
726 * be sent through a {@link TmfStatsUpdatedSignal}, and will be
727 * processed by the signal handler.
728 */
faa38350 729 aTrace.getStatistics().updateStats(isGlobal, start, end);
89c06060 730 }
89c06060 731 }
cfd22ad0
MD
732 }
733
734 /**
05627bda 735 * Resets the number of events within the time range
cfd22ad0 736 */
05627bda 737 protected void resetTimeRangeValue() {
36033ff0 738 TmfStatisticsTreeNode treeModelRoot = TmfStatisticsTreeManager.getStatTreeRoot(getTreeID());
05627bda
MD
739 if (treeModelRoot != null && treeModelRoot.hasChildren()) {
740 treeModelRoot.resetTimeRangeValue();
741 }
cfd22ad0
MD
742 }
743
744 /**
faa38350 745 * When the trace is loading the cursor will be different so the user
05627bda
MD
746 * knows that the processing is not finished yet.
747 *
748 * Calls to this method are stacked.
cfd22ad0 749 *
05627bda 750 * @param waitRequested
cfd22ad0 751 * Indicates if we need to show the waiting cursor, or the
05627bda 752 * default one.
cfd22ad0 753 */
05627bda 754 protected void waitCursor(final boolean waitRequested) {
cfd22ad0
MD
755 if ((fTreeViewer == null) || (fTreeViewer.getTree().isDisposed())) {
756 return;
757 }
758
05627bda 759 boolean needsUpdate = false;
cfd22ad0 760 Display display = fTreeViewer.getControl().getDisplay();
05627bda
MD
761 if (waitRequested) {
762 fWaitCursorCount++;
763 if (fWaitCursor == null) { // The cursor hasn't been initialized yet
764 fWaitCursor = new Cursor(display, SWT.CURSOR_WAIT);
765 }
766 if (fWaitCursorCount == 1) { // The cursor is not in waiting mode
767 needsUpdate = true;
768 }
769 } else {
770 if (fWaitCursorCount > 0) { // The cursor is in waiting mode
771 fWaitCursorCount--;
772 if (fWaitCursorCount == 0) { // No more reason to wait
773 // Put back the default cursor
774 needsUpdate = true;
775 }
776 }
cfd22ad0
MD
777 }
778
05627bda
MD
779 if (needsUpdate) {
780 // Performs the updates on the UI thread
781 display.asyncExec(new Runnable() {
782 @Override
783 public void run() {
784 if ((fTreeViewer != null)
785 && (!fTreeViewer.getTree().isDisposed())) {
786 Cursor cursor = null; // indicates default
787 if (waitRequested) {
788 cursor = fWaitCursor;
789 }
790 fTreeViewer.getControl().setCursor(cursor);
cfd22ad0 791 }
cfd22ad0 792 }
05627bda
MD
793 });
794 }
cfd22ad0
MD
795 }
796
05627bda
MD
797 // ------------------------------------------------------------------------
798 // Methods reserved for the streaming functionality
799 // ------------------------------------------------------------------------
800
cfd22ad0 801 /**
05627bda 802 * Resets update synchronization information
cfd22ad0 803 */
05627bda
MD
804 protected void resetUpdateSynchronization() {
805 synchronized (fStatisticsUpdateSyncObj) {
806 fStatisticsUpdateBusy = false;
807 fStatisticsUpdatePending = false;
808 fStatisticsUpdateRange = null;
809 }
cfd22ad0
MD
810 }
811
812 /**
05627bda
MD
813 * Checks if statistics update is ongoing. If it is ongoing, the new time
814 * range is stored as pending
cfd22ad0 815 *
05627bda
MD
816 * @param timeRange
817 * - new time range
818 * @return true if statistic update is ongoing else false
cfd22ad0 819 */
05627bda
MD
820 protected boolean checkUpdateBusy(TmfTimeRange timeRange) {
821 synchronized (fStatisticsUpdateSyncObj) {
822 if (fStatisticsUpdateBusy) {
823 fStatisticsUpdatePending = true;
824 if (fStatisticsUpdateRange == null
825 || timeRange.getEndTime().compareTo(fStatisticsUpdateRange.getEndTime()) > 0) {
826 fStatisticsUpdateRange = timeRange;
827 }
828 return true;
829 }
830 fStatisticsUpdateBusy = true;
831 return false;
832 }
833 }
834
835 /**
836 * Sends pending request (if any)
837 */
838 protected void sendPendingUpdate() {
839 synchronized (fStatisticsUpdateSyncObj) {
840 fStatisticsUpdateBusy = false;
841 if (fStatisticsUpdatePending) {
842 fStatisticsUpdatePending = false;
faa38350 843 requestData(fTrace, fStatisticsUpdateRange);
05627bda
MD
844 fStatisticsUpdateRange = null;
845 }
846 }
cfd22ad0
MD
847 }
848}
This page took 0.074363 seconds and 5 git commands to generate.