Fix context location after first event seek.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / viewers / statistics / TmfStatisticsViewer.java
CommitLineData
cfd22ad0
MD
1/*******************************************************************************
2 * Copyright (c) 2012 Ericsson
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
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.tmf.ui.viewers.statistics;
14
15import java.util.List;
16
17import org.eclipse.jface.viewers.TreeViewer;
18import org.eclipse.jface.viewers.TreeViewerColumn;
19import org.eclipse.jface.viewers.Viewer;
20import org.eclipse.jface.viewers.ViewerComparator;
21import org.eclipse.linuxtools.tmf.core.component.TmfComponent;
05627bda
MD
22import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
23import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
24import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
25import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal;
26import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentUpdatedSignal;
27import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
28import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
29import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
30import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
31import org.eclipse.linuxtools.tmf.ui.viewers.TmfViewer;
cfd22ad0
MD
32import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.AbsTmfStatisticsTree;
33import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.ITmfColumnDataProvider;
34import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnData;
35import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider;
36import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseStatisticsTree;
37import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode;
38import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeRootFactory;
39import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfTreeContentProvider;
40import org.eclipse.swt.SWT;
41import org.eclipse.swt.events.SelectionAdapter;
42import org.eclipse.swt.events.SelectionEvent;
43import org.eclipse.swt.graphics.Color;
44import org.eclipse.swt.graphics.Cursor;
cfd22ad0
MD
45import org.eclipse.swt.widgets.Composite;
46import org.eclipse.swt.widgets.Control;
47import org.eclipse.swt.widgets.Display;
48import org.eclipse.swt.widgets.Event;
49import org.eclipse.swt.widgets.Listener;
50
51/**
52 * A basic viewer to display statistics in the statistics view.
53 *
54 * @author Mathieu Denis
55 * @version 2.0
56 * @since 2.0
57 */
05627bda 58public class TmfStatisticsViewer extends TmfViewer {
cfd22ad0
MD
59
60 /**
05627bda 61 * The initial window span (in nanoseconds)
cfd22ad0 62 */
05627bda
MD
63 public static final long INITIAL_WINDOW_SPAN = (1L * 100 * 1000 * 1000); // .1sec
64
65 /**
66 * Timestamp scale (nanosecond)
67 */
68 public static final byte TIME_SCALE = -9;
69
70 /**
71 * Default PAGE_SIZE for background requests.
72 */
73 protected static final int PAGE_SIZE = 50000;
74
75 /**
76 * Refresh frequency.
77 */
78 protected final Long STATS_INPUT_CHANGED_REFRESH = 5000L;
79
80 /**
81 * Stores the request to the experiment
82 */
83 protected TmfStatisticsRequest fRequest = null;
84
85 /**
86 * Stores the ranged request to the experiment
87 */
88 protected TmfStatisticsRequest fRequestRange = null;
cfd22ad0
MD
89
90 /**
91 * The actual tree viewer to display
92 */
93 protected TreeViewer fTreeViewer;
94
95 /**
05627bda
MD
96 * The statistics tree linked to this viewer
97 */
98 protected AbsTmfStatisticsTree fStatisticsData;
99
100 /**
101 * Update synchronization parameter (used for streaming): Update busy
102 * indicator.
103 */
104 protected boolean fStatisticsUpdateBusy = false;
105
106 /**
107 * Update synchronization parameter (used for streaming): Update pending
108 * indicator.
109 */
110 protected boolean fStatisticsUpdatePending = false;
111
112 /**
113 * Update synchronization parameter (used for streaming): Pending Update
114 * time range.
115 */
116 protected TmfTimeRange fStatisticsUpdateRange = null;
117
118 /**
119 * Update synchronization object.
120 */
121 protected final Object fStatisticsUpdateSyncObj = new Object();
122
123 /**
124 * Indicates to process all events
125 */
126 private boolean fProcessAll;
127
128 /**
129 * View instance counter (for multiple statistics views)
cfd22ad0
MD
130 */
131 private static int fCountInstance = 0;
132
133 /**
134 * Number of this instance. Used as an instance ID.
135 */
136 private int fInstanceNb;
137
05627bda
MD
138 /**
139 * The trace that is displayed by this viewer
140 */
141 private ITmfTrace fTrace;
142
cfd22ad0
MD
143 /**
144 * Object to store the cursor while waiting for the experiment to load
145 */
146 private Cursor fWaitCursor = null;
147
148 /**
05627bda
MD
149 * Counts the number of times waitCursor() has been called. It avoids
150 * removing the waiting cursor, since there may be multiple requests running
151 * at the same time.
152 */
153 private int fWaitCursorCount = 0;
154
155 /**
156 * Tells to send a time range request when the experiment gets updated.
157 */
158 private boolean fSendRangeRequest = true;
159
160 /**
161 * Empty constructor. To be used in conjunction with
162 * {@link TmfStatisticsViewer#init(Composite, String, ITmfTrace)}
163 */
164 public TmfStatisticsViewer() {
165 super();
166 }
167
168 /**
169 * Create a basic statistics viewer. To be used in conjunction with
170 * {@link TmfStatisticsViewer#init(Composite, String, ITmfTrace)}
171 *
172 * @param parent
173 * The parent composite that will hold the viewer
174 * @param viewerName
175 * The name that will be assigned to this viewer
176 * @param trace
177 * The trace that is displayed by this viewer
178 * @see TmfComponent
179 */
180 public TmfStatisticsViewer(Composite parent, String viewerName, ITmfTrace trace) {
181 init(parent, viewerName, trace);
182 }
183
184 /**
185 * Initialize the statistics viewer.
cfd22ad0
MD
186 *
187 * @param parent
05627bda
MD
188 * The parent component of the viewer.
189 * @param viewerName
190 * The name to give to the viewer.
191 * @param trace
192 * The trace that will be displayed by the viewer.
cfd22ad0 193 */
05627bda
MD
194 public void init(Composite parent, String viewerName, ITmfTrace trace) {
195 super.init(parent, viewerName);
cfd22ad0
MD
196 // Increment a counter to make sure the tree ID is unique.
197 fCountInstance++;
198 fInstanceNb = fCountInstance;
05627bda
MD
199 fTrace = trace;
200
201 // The viewer will process all events if he is assigned to the experiment
202 fProcessAll = (trace instanceof TmfExperiment);
203
204 initContent(parent);
205 }
206
207 /*
208 * (non-Javadoc)
209 *
210 * @see org.eclipse.linuxtools.tmf.core.component.TmfComponent#dispose()
211 */
212 @Override
213 public void dispose() {
214 super.dispose();
215 if (fWaitCursor != null) {
216 fWaitCursor.dispose();
217 }
218 /*
219 * Make sure there is no request running before removing the statistics
220 * tree
221 */
222 cancelOngoingRequest(fRequestRange);
223 cancelOngoingRequest(fRequest);
224 }
225
226 /**
227 * Handles the signal about new experiment range.
228 *
229 * @param signal
230 * The experiment range updated signal
231 */
232 @TmfSignalHandler
233 public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal) {
234 TmfExperiment experiment = signal.getExperiment();
235 // validate
236 if (!experiment.equals(TmfExperiment.getCurrentExperiment())) {
237 return;
238 }
239
240 // Sends the time range request only once in this method.
241 if (fSendRangeRequest) {
242 fSendRangeRequest = false;
243 // Calculate the selected time range to request
244 long startTime = signal.getRange().getStartTime().normalize(0, TIME_SCALE).getValue();
245 TmfTimestamp startTS = new TmfTimestamp(startTime, TIME_SCALE);
246 TmfTimestamp endTS = new TmfTimestamp(startTime + INITIAL_WINDOW_SPAN, TIME_SCALE);
247 TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS);
248
249 requestTimeRangeData(experiment, timeRange);
250 }
251 requestData(experiment, signal.getRange());
252 }
253
254 /**
255 * Handles the experiment updated signal. This will detect new events in
256 * case the indexing is not coalesced with a statistics request.
257 *
258 * @param signal
259 * The experiment updated signal
260 */
261 @TmfSignalHandler
262 public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
263 TmfExperiment experiment = signal.getExperiment();
264 if (!experiment.equals(TmfExperiment.getCurrentExperiment())) {
265 return;
266 }
267
268 long nbEvents = 0;
269 if (fRequest != null) {
270 nbEvents = fRequest.getLastEventIndex();
271 }
272 /*
273 * In the normal case, the statistics request is coalesced with indexing
274 * and the number of events are the same, there is nothing to do. But if
275 * it's not the case, trigger a new request to count the new events.
276 */
277 if (nbEvents < experiment.getNbEvents()) {
278 requestData(experiment, experiment.getTimeRange());
279 }
280 }
281
282 /**
283 * * Handles the time range updated signal. It updates the time range
284 * statistics.
285 *
286 * @param signal
287 * Contains the information about the new selected time range.
288 */
289 @TmfSignalHandler
290 public void timeRangeUpdated(TmfRangeSynchSignal signal) {
291 /*
292 * It is possible that the time range changes while a request is
293 * processing.
294 */
295 cancelOngoingRequest(fRequestRange);
296
297 requestTimeRangeData(TmfExperiment.getCurrentExperiment(), signal.getCurrentRange());
298 }
299
300 /*
301 * Returns the primary control associated with this viewer.
302 *
303 * @return the SWT control which displays this viewer's content
304 */
305 @Override
306 public Control getControl() {
307 return fTreeViewer.getControl();
308 }
309
310 /**
311 * Get the input of the viewer.
312 *
313 * @return an object representing the input of the statistics viewer.
314 */
315 public Object getInput() {
316 return fTreeViewer.getInput();
317 }
318
319 /**
320 * Return the size of the request when performing background request.
321 *
322 * @return the block size for background request.
323 */
324 public int getPageSize() {
325 return PAGE_SIZE;
326 }
327
328 /**
329 * Return the number of events to receive before a refresh of the viewer is
330 * performed.
331 *
332 * @return the input refresh rate
333 */
334 public long getRefreshRate() {
335 return STATS_INPUT_CHANGED_REFRESH;
336 }
337
338 /**
339 * This method can be overridden to implement another way of representing
340 * the statistics data and to retrieve the information for display.
341 *
342 * @return a TmfStatisticsData object.
343 */
344 public AbsTmfStatisticsTree getStatisticData() {
345 if (fStatisticsData == null) {
346 fStatisticsData = new TmfBaseStatisticsTree();
347 }
348 return fStatisticsData;
349 }
350
351 /**
352 * Returns a unique ID based on name to be associated with the statistics
353 * tree for this viewer. For a same name, it will always return the same ID.
354 *
355 * @return a unique statistics tree ID.
356 */
357 public String getTreeID() {
358 return getName() + fInstanceNb;
359 }
360
361 @Override
362 public void refresh() {
363 final Control viewerControl = getControl();
364 // Ignore update if disposed
365 if (viewerControl.isDisposed()) {
366 return;
367 }
368
369 viewerControl.getDisplay().asyncExec(new Runnable() {
370 @Override
371 public void run() {
372 if (!viewerControl.isDisposed()) {
373 fTreeViewer.refresh();
374 }
375 }
376 });
377 }
378
379 /**
380 * Focus on the statistics tree of the viewer
381 */
382 public void setFocus() {
383 fTreeViewer.getTree().setFocus();
384 }
385
386 /**
387 * Sets or clears the input for this viewer.
388 *
389 * @param input
390 * The input of this viewer, or <code>null</code> if none
391 */
392 public void setInput(TmfStatisticsTreeNode input) {
393 resetUpdateSynchronization();
394 fTreeViewer.setInput(input);
395 }
396
397 /**
398 * Cancels the request if it is not already completed
399 *
400 * @param request
401 * The request to be canceled
402 */
403 protected void cancelOngoingRequest(ITmfDataRequest request) {
404 if (request != null && !request.isCompleted()) {
405 request.cancel();
406 }
407 }
408
409 /**
410 * This method can be overridden to change the representation of the data in
411 * the columns.
412 *
413 * @return an object implementing ITmfBaseColumnDataProvider.
414 */
415 protected ITmfColumnDataProvider getColumnDataProvider() {
416 return new TmfBaseColumnDataProvider();
417 }
cfd22ad0 418
05627bda
MD
419 /**
420 * Initialize the content that will be drawn in this viewer
421 *
422 * @param parent
423 * The parent of the control to create
424 */
425 protected void initContent(Composite parent) {
cfd22ad0 426 final List<TmfBaseColumnData> columnDataList = getColumnDataProvider().getColumnData();
cfd22ad0
MD
427
428 fTreeViewer = new TreeViewer(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
429 fTreeViewer.setContentProvider(new TmfTreeContentProvider());
430 fTreeViewer.getTree().setHeaderVisible(true);
431 fTreeViewer.setUseHashlookup(true);
432
433 // Creates the columns defined by the column data provider
434 for (final TmfBaseColumnData columnData : columnDataList) {
435 final TreeViewerColumn treeColumn = new TreeViewerColumn(fTreeViewer, columnData.getAlignment());
436 treeColumn.getColumn().setText(columnData.getHeader());
437 treeColumn.getColumn().setWidth(columnData.getWidth());
438 treeColumn.getColumn().setToolTipText(columnData.getTooltip());
439
440 if (columnData.getComparator() != null) { // A comparator is defined.
441 // Adds a listener on the columns header for sorting purpose.
442 treeColumn.getColumn().addSelectionListener(new SelectionAdapter() {
443
444 private ViewerComparator reverseComparator;
445
446 @Override
447 public void widgetSelected(SelectionEvent e) {
448 // Initializes the reverse comparator once.
449 if (reverseComparator == null) {
450 reverseComparator = new ViewerComparator() {
451 @Override
452 public int compare(Viewer viewer, Object e1, Object e2) {
453 return -1 * columnData.getComparator().compare(viewer, e1, e2);
454 }
455 };
456 }
457
458 if (fTreeViewer.getTree().getSortDirection() == SWT.UP
459 || fTreeViewer.getTree().getSortColumn() != treeColumn.getColumn()) {
460 /*
461 * Puts the descendant order if the old order was
462 * up or if the selected column has changed.
463 */
464 fTreeViewer.setComparator(columnData.getComparator());
465 fTreeViewer.getTree().setSortDirection(SWT.DOWN);
466 } else {
467 /*
468 * Puts the ascendant ordering if the selected
469 * column hasn't changed.
470 */
471 fTreeViewer.setComparator(reverseComparator);
472 fTreeViewer.getTree().setSortDirection(SWT.UP);
473 }
474 fTreeViewer.getTree().setSortColumn(treeColumn.getColumn());
475 }
476 });
477 }
478 treeColumn.setLabelProvider(columnData.getLabelProvider());
479 }
480
481 // Handler that will draw the bar charts.
482 fTreeViewer.getTree().addListener(SWT.EraseItem, new Listener() {
483 @Override
484 public void handleEvent(Event event) {
485 if (columnDataList.get(event.index).getPercentageProvider() != null) {
486 TmfStatisticsTreeNode node = (TmfStatisticsTreeNode) event.item.getData();
487
488 double percentage = columnDataList.get(event.index).getPercentageProvider().getPercentage(node);
489 if (percentage == 0) { // No bar to draw
490 return;
491 }
492
493 if ((event.detail & SWT.SELECTED) > 0) { // The item is selected.
494 // Draws our own background to avoid overwritten the bar.
495 event.gc.fillRectangle(event.x, event.y, event.width, event.height);
496 event.detail &= ~SWT.SELECTED;
497 }
498
499 int barWidth = (int) ((fTreeViewer.getTree().getColumn(event.index).getWidth() - 8) * percentage);
500 int oldAlpha = event.gc.getAlpha();
501 Color oldForeground = event.gc.getForeground();
502 Color oldBackground = event.gc.getBackground();
503 /*
504 * Draws a transparent gradient rectangle from the color of
505 * foreground and background.
506 */
507 event.gc.setAlpha(64);
508 event.gc.setForeground(event.item.getDisplay().getSystemColor(SWT.COLOR_BLUE));
509 event.gc.setBackground(event.item.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
510 event.gc.fillGradientRectangle(event.x, event.y, barWidth, event.height, true);
511 event.gc.drawRectangle(event.x, event.y, barWidth, event.height);
512 // Restores old values
513 event.gc.setForeground(oldForeground);
514 event.gc.setBackground(oldBackground);
515 event.gc.setAlpha(oldAlpha);
516 event.detail &= ~SWT.BACKGROUND;
517 }
518 }
519 });
520
521 // Initializes the comparator parameters
522 fTreeViewer.setComparator(columnDataList.get(0).getComparator());
523 fTreeViewer.getTree().setSortColumn(fTreeViewer.getTree().getColumn(0));
524 fTreeViewer.getTree().setSortDirection(SWT.DOWN);
525 }
526
527 /**
05627bda 528 * Tells if the viewer is listening to a trace from the selected experiment.
cfd22ad0 529 *
05627bda
MD
530 * @param traceName
531 * The trace that the viewer may be listening
532 * @return true if the viewer is listening to the trace, false otherwise
cfd22ad0 533 */
05627bda
MD
534 protected boolean isListeningTo(String traceName) {
535 if (fProcessAll || traceName.equals(fTrace.getName())) {
536 return true;
cfd22ad0 537 }
05627bda 538 return false;
cfd22ad0
MD
539 }
540
541 /**
05627bda 542 * Called when an experiment request has been completed successfully.
cfd22ad0 543 *
05627bda
MD
544 * @param global
545 * Tells if the request is a global or time range (partial)
546 * request.
cfd22ad0 547 */
05627bda
MD
548 protected void modelComplete(boolean global) {
549 refresh();
550 waitCursor(false);
551 if (global) {
552 sendPendingUpdate();
553 }
cfd22ad0
MD
554 }
555
556 /**
05627bda 557 * Called when an experiment request has failed or has been cancelled.
cfd22ad0 558 *
05627bda
MD
559 * @param isGlobalRequest
560 * Tells if the request is a global or time range (partial)
561 * request.
cfd22ad0 562 */
05627bda
MD
563 protected void modelIncomplete(boolean isGlobalRequest) {
564 if (isGlobalRequest) { // Clean the global statistics
565 /*
566 * The data is invalid and shall be removed to refresh upon next
567 * selection
568 */
569 Object input = getInput();
570 if (input instanceof TmfStatisticsTreeNode) {
571 TmfStatisticsTreeRootFactory.removeStatTreeRoot(getTreeID());
572 }
573 resetUpdateSynchronization();
574 sendPendingUpdate();
575 } else { // Clean the partial statistics
576 resetTimeRangeValue();
577 }
578 refresh();
579 waitCursor(false);
cfd22ad0
MD
580 }
581
582 /**
05627bda 583 * Sends the request to the experiment for the whole trace
cfd22ad0 584 *
05627bda
MD
585 * @param experiment
586 * The experiment used to send the request
587 * @param range
588 * The range to request to the experiment
cfd22ad0 589 */
05627bda
MD
590 protected void requestData(TmfExperiment experiment, TmfTimeRange range) {
591 // Check if an update is already ongoing
592 if (checkUpdateBusy(range)) {
593 return;
594 }
595
596 long index = 0;
597 /*
598 * Sets the index to the last event retrieved from the experiment during
599 * the last request.
600 */
601 if (fRequest != null) {
602 index = fRequest.getLastEventIndex();
603 }
604
605 fRequest = new TmfStatisticsRequest(this, range, index, true);
606 waitCursor(true);
607 experiment.sendRequest(fRequest);
cfd22ad0
MD
608 }
609
610 /**
05627bda 611 * Sends the time range request from the experiment
cfd22ad0 612 *
05627bda
MD
613 * @param experiment
614 * The experiment used to send the request
615 * @param range
616 * The range to request to the experiment
cfd22ad0 617 */
05627bda
MD
618 protected void requestTimeRangeData(TmfExperiment experiment, TmfTimeRange range) {
619 resetTimeRangeValue();
620 fRequestRange = new TmfStatisticsRequest(this, range, 0, false);
621 waitCursor(true);
622 experiment.sendRequest(fRequestRange);
cfd22ad0
MD
623 }
624
625 /**
05627bda 626 * Resets the number of events within the time range
cfd22ad0 627 */
05627bda
MD
628 protected void resetTimeRangeValue() {
629 TmfStatisticsTreeNode treeModelRoot = TmfStatisticsTreeRootFactory.getStatTreeRoot(getTreeID());
630 if (treeModelRoot != null && treeModelRoot.hasChildren()) {
631 treeModelRoot.resetTimeRangeValue();
632 }
cfd22ad0
MD
633 }
634
635 /**
636 * When the experiment is loading the cursor will be different so the user
05627bda
MD
637 * knows that the processing is not finished yet.
638 *
639 * Calls to this method are stacked.
cfd22ad0 640 *
05627bda 641 * @param waitRequested
cfd22ad0 642 * Indicates if we need to show the waiting cursor, or the
05627bda 643 * default one.
cfd22ad0 644 */
05627bda 645 protected void waitCursor(final boolean waitRequested) {
cfd22ad0
MD
646 if ((fTreeViewer == null) || (fTreeViewer.getTree().isDisposed())) {
647 return;
648 }
649
05627bda 650 boolean needsUpdate = false;
cfd22ad0 651 Display display = fTreeViewer.getControl().getDisplay();
05627bda
MD
652 if (waitRequested) {
653 fWaitCursorCount++;
654 if (fWaitCursor == null) { // The cursor hasn't been initialized yet
655 fWaitCursor = new Cursor(display, SWT.CURSOR_WAIT);
656 }
657 if (fWaitCursorCount == 1) { // The cursor is not in waiting mode
658 needsUpdate = true;
659 }
660 } else {
661 if (fWaitCursorCount > 0) { // The cursor is in waiting mode
662 fWaitCursorCount--;
663 if (fWaitCursorCount == 0) { // No more reason to wait
664 // Put back the default cursor
665 needsUpdate = true;
666 }
667 }
cfd22ad0
MD
668 }
669
05627bda
MD
670 if (needsUpdate) {
671 // Performs the updates on the UI thread
672 display.asyncExec(new Runnable() {
673 @Override
674 public void run() {
675 if ((fTreeViewer != null)
676 && (!fTreeViewer.getTree().isDisposed())) {
677 Cursor cursor = null; // indicates default
678 if (waitRequested) {
679 cursor = fWaitCursor;
680 }
681 fTreeViewer.getControl().setCursor(cursor);
cfd22ad0 682 }
cfd22ad0 683 }
05627bda
MD
684 });
685 }
cfd22ad0
MD
686 }
687
05627bda
MD
688 // ------------------------------------------------------------------------
689 // Methods reserved for the streaming functionality
690 // ------------------------------------------------------------------------
691
cfd22ad0 692 /**
05627bda 693 * Resets update synchronization information
cfd22ad0 694 */
05627bda
MD
695 protected void resetUpdateSynchronization() {
696 synchronized (fStatisticsUpdateSyncObj) {
697 fStatisticsUpdateBusy = false;
698 fStatisticsUpdatePending = false;
699 fStatisticsUpdateRange = null;
700 }
cfd22ad0
MD
701 }
702
703 /**
05627bda
MD
704 * Checks if statistics update is ongoing. If it is ongoing, the new time
705 * range is stored as pending
cfd22ad0 706 *
05627bda
MD
707 * @param timeRange
708 * - new time range
709 * @return true if statistic update is ongoing else false
cfd22ad0 710 */
05627bda
MD
711 protected boolean checkUpdateBusy(TmfTimeRange timeRange) {
712 synchronized (fStatisticsUpdateSyncObj) {
713 if (fStatisticsUpdateBusy) {
714 fStatisticsUpdatePending = true;
715 if (fStatisticsUpdateRange == null
716 || timeRange.getEndTime().compareTo(fStatisticsUpdateRange.getEndTime()) > 0) {
717 fStatisticsUpdateRange = timeRange;
718 }
719 return true;
720 }
721 fStatisticsUpdateBusy = true;
722 return false;
723 }
724 }
725
726 /**
727 * Sends pending request (if any)
728 */
729 protected void sendPendingUpdate() {
730 synchronized (fStatisticsUpdateSyncObj) {
731 fStatisticsUpdateBusy = false;
732 if (fStatisticsUpdatePending) {
733 fStatisticsUpdatePending = false;
734 requestData(TmfExperiment.getCurrentExperiment(), fStatisticsUpdateRange);
735 fStatisticsUpdateRange = null;
736 }
737 }
cfd22ad0
MD
738 }
739}
This page took 0.054813 seconds and 5 git commands to generate.