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