tmf: Remove TmfStatsUpdatedSignal
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / viewers / statistics / TmfStatisticsViewer.java
index d15f0f281b9e4781a89b3a1bb57e4a77070ef7c8..52d782a0fbbf3cc2189cc5f76dae4cfda1932bc6 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2012, 2013 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -8,35 +8,41 @@
  *
  * Contributors:
  *   Mathieu Denis <mathieu.denis@polymtl.ca> - Initial API and implementation
+ *   Alexandre Montplaisir - Port to ITmfStatistics provider
+ *   Patrick Tasse - Support selection range
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.ui.viewers.statistics;
 
 import java.util.List;
+import java.util.Map;
 
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.jface.viewers.TreeViewerColumn;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerComparator;
 import org.eclipse.linuxtools.tmf.core.component.TmfComponent;
-import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
-import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
-import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
-import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal;
-import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentUpdatedSignal;
+import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
 import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
+import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics;
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
 import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
 import org.eclipse.linuxtools.tmf.ui.viewers.TmfViewer;
-import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.AbsTmfStatisticsTree;
 import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.ITmfColumnDataProvider;
 import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnData;
 import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseColumnDataProvider;
-import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfBaseStatisticsTree;
+import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTree;
+import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeManager;
 import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeNode;
-import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfStatisticsTreeRootFactory;
 import org.eclipse.linuxtools.tmf.ui.viewers.statistics.model.TmfTreeContentProvider;
+import org.eclipse.linuxtools.tmf.ui.views.statistics.TmfStatisticsModule;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
@@ -59,15 +65,10 @@ import org.eclipse.swt.widgets.Listener;
  */
 public class TmfStatisticsViewer extends TmfViewer {
 
-    /**
-     * The initial window span (in nanoseconds)
-     */
-    public static final long INITIAL_WINDOW_SPAN = (1L * 100 * 1000 * 1000); // .1sec
-
     /**
      * Timestamp scale (nanosecond)
      */
-    public static final byte TIME_SCALE = -9;
+    public static final byte TIME_SCALE = ITmfTimestamp.NANOSECOND_SCALE;
 
     /**
      * Default PAGE_SIZE for background requests.
@@ -79,16 +80,6 @@ public class TmfStatisticsViewer extends TmfViewer {
      */
     protected final Long STATS_INPUT_CHANGED_REFRESH = 5000L;
 
-    /**
-     * Stores the request to the experiment
-     */
-    protected TmfStatisticsRequest fRequest = null;
-
-    /**
-     * Stores the ranged request to the experiment
-     */
-    protected TmfStatisticsRequest fRequestRange = null;
-
     /**
      * The actual tree viewer to display
      */
@@ -97,7 +88,7 @@ public class TmfStatisticsViewer extends TmfViewer {
     /**
      * The statistics tree linked to this viewer
      */
-    protected AbsTmfStatisticsTree fStatisticsData;
+    protected TmfStatisticsTree fStatisticsData;
 
     /**
      * Update synchronization parameter (used for streaming): Update busy
@@ -127,6 +118,16 @@ public class TmfStatisticsViewer extends TmfViewer {
      */
     protected final Object fStatisticsRangeUpdateSyncObj = new Object();
 
+    /**
+     * The trace that is displayed by this viewer
+     */
+    protected ITmfTrace fTrace;
+
+    /**
+     * Stores the requested time range.
+     */
+    protected TmfTimeRange fRequestedTimerange;
+
     /**
      * Indicates to process all events
      */
@@ -143,12 +144,7 @@ public class TmfStatisticsViewer extends TmfViewer {
     private int fInstanceNb;
 
     /**
-     * The trace that is displayed by this viewer
-     */
-    private ITmfTrace fTrace;
-
-    /**
-     * Object to store the cursor while waiting for the experiment to load
+     * Object to store the cursor while waiting for the trace to load
      */
     private Cursor fWaitCursor = null;
 
@@ -160,16 +156,20 @@ public class TmfStatisticsViewer extends TmfViewer {
     private int fWaitCursorCount = 0;
 
     /**
-     * Tells to send a time range request when the experiment gets updated.
+     * Tells to send a time range request when the trace gets updated.
      */
     private boolean fSendRangeRequest = true;
 
+    /** Reference to the trace manager */
+    private final TmfTraceManager fTraceManager;
+
     /**
      * Empty constructor. To be used in conjunction with
      * {@link TmfStatisticsViewer#init(Composite, String, ITmfTrace)}
      */
     public TmfStatisticsViewer() {
         super();
+        fTraceManager = TmfTraceManager.getInstance();
     }
 
     /**
@@ -186,6 +186,7 @@ public class TmfStatisticsViewer extends TmfViewer {
      */
     public TmfStatisticsViewer(Composite parent, String viewerName, ITmfTrace trace) {
         init(parent, viewerName, trace);
+        fTraceManager = TmfTraceManager.getInstance();
     }
 
     /**
@@ -205,46 +206,39 @@ public class TmfStatisticsViewer extends TmfViewer {
         fInstanceNb = fCountInstance;
         fTrace = trace;
 
-        // The viewer will process all events if he is assigned to the experiment
+        // The viewer will process all events if he is assigned to an experiment
         fProcessAll = (trace instanceof TmfExperiment);
 
         initContent(parent);
         initInput();
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.eclipse.linuxtools.tmf.core.component.TmfComponent#dispose()
-     */
     @Override
     public void dispose() {
         super.dispose();
         if (fWaitCursor != null) {
             fWaitCursor.dispose();
         }
-        /*
-         * Make sure there is no request running before removing the statistics
-         * tree
-         */
-        cancelOngoingRequest(fRequestRange);
-        cancelOngoingRequest(fRequest);
 
-        // Clean the model
-        TmfStatisticsTreeRootFactory.removeStatTreeRoot(getTreeID());
+        // Clean the model for this viewer
+        TmfStatisticsTreeManager.removeStatTreeRoot(getTreeID());
     }
 
+    // ------------------------------------------------------------------------
+    // Signal handlers
+    // ------------------------------------------------------------------------
+
     /**
-     * Handles the signal about new experiment range.
+     * Handles the signal about new trace range.
      *
      * @param signal
-     *            The experiment range updated signal
+     *            The trace range updated signal
      */
     @TmfSignalHandler
-    public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal) {
-        TmfExperiment experiment = signal.getExperiment();
+    public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) {
+        ITmfTrace trace = signal.getTrace();
         // validate
-        if (!experiment.equals(TmfExperiment.getCurrentExperiment())) {
+        if (!isListeningTo(trace)) {
             return;
         }
 
@@ -252,64 +246,52 @@ public class TmfStatisticsViewer extends TmfViewer {
             // Sends the time range request only once from this method.
             if (fSendRangeRequest) {
                 fSendRangeRequest = false;
-                // Calculate the selected time range to request
-                long startTime = signal.getRange().getStartTime().normalize(0, TIME_SCALE).getValue();
-                TmfTimestamp startTS = new TmfTimestamp(startTime, TIME_SCALE);
-                TmfTimestamp endTS = new TmfTimestamp(startTime + INITIAL_WINDOW_SPAN, TIME_SCALE);
-                TmfTimeRange timeRange = new TmfTimeRange(startTS, endTS);
-
-                requestTimeRangeData(experiment, timeRange);
+                ITmfTimestamp begin = fTraceManager.getSelectionBeginTime();
+                ITmfTimestamp end = fTraceManager.getSelectionEndTime();
+                TmfTimeRange timeRange = new TmfTimeRange(begin, end);
+                requestTimeRangeData(trace, timeRange);
             }
         }
-        requestData(experiment, signal.getRange());
+        requestData(trace, signal.getRange());
     }
 
     /**
-     * Handles the experiment updated signal. This will detect new events in
-     * case the indexing is not coalesced with a statistics request.
+     * Handles the time range updated signal. It updates the time range
+     * statistics.
      *
      * @param signal
-     *            The experiment updated signal
+     *            Contains the information about the new selected time range.
+     * @deprecated
+     *            As of 2.1, use {@link #timeSynchUpdated(TmfTimeSynchSignal)}
      */
+    @Deprecated
     @TmfSignalHandler
-    public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
-        TmfExperiment experiment = signal.getExperiment();
-        if (!experiment.equals(TmfExperiment.getCurrentExperiment())) {
-            return;
-        }
-
-        long nbEvents = 0;
-        if (fRequest != null) {
-            nbEvents = fRequest.getLastEventIndex();
-        }
-        /*
-         * In the normal case, the statistics request is coalesced with indexing
-         * and the number of events are the same, there is nothing to do. But if
-         * it's not the case, trigger a new request to count the new events.
-         */
-        if (nbEvents < experiment.getNbEvents()) {
-            requestData(experiment, experiment.getTimeRange());
-        }
+    public void timeRangeUpdated(TmfRangeSynchSignal signal) {
     }
 
     /**
-     * * Handles the time range updated signal. It updates the time range
+     * Handles the time synch updated signal. It updates the time range
      * statistics.
      *
      * @param signal
      *            Contains the information about the new selected time range.
+     * @since 2.1
      */
     @TmfSignalHandler
-    public void timeRangeUpdated(TmfRangeSynchSignal signal) {
-        /*
-         * It is possible that the time range changes while a request is
-         * processing.
-         */
-        cancelOngoingRequest(fRequestRange);
-
-        requestTimeRangeData(TmfExperiment.getCurrentExperiment(), signal.getCurrentRange());
+    public void timeSynchUpdated(TmfTimeSynchSignal signal) {
+        if (fTrace == null) {
+            return;
+        }
+        ITmfTimestamp begin = signal.getBeginTime();
+        ITmfTimestamp end = signal.getEndTime();
+        TmfTimeRange timeRange = new TmfTimeRange(begin, end);
+        requestTimeRangeData(fTrace, timeRange);
     }
 
+    // ------------------------------------------------------------------------
+    // Class methods
+    // ------------------------------------------------------------------------
+
     /*
      * Returns the primary control associated with this viewer.
      *
@@ -354,9 +336,9 @@ public class TmfStatisticsViewer extends TmfViewer {
      *
      * @return a TmfStatisticsData object.
      */
-    public AbsTmfStatisticsTree getStatisticData() {
+    public TmfStatisticsTree getStatisticData() {
         if (fStatisticsData == null) {
-            fStatisticsData = new TmfBaseStatisticsTree();
+            fStatisticsData = new TmfStatisticsTree();
         }
         return fStatisticsData;
     }
@@ -410,8 +392,9 @@ public class TmfStatisticsViewer extends TmfViewer {
      *
      * @param request
      *            The request to be canceled
+     * @since 3.0
      */
-    protected void cancelOngoingRequest(ITmfDataRequest request) {
+    protected void cancelOngoingRequest(ITmfEventRequest request) {
         if (request != null && !request.isCompleted()) {
             request.cancel();
         }
@@ -537,28 +520,19 @@ public class TmfStatisticsViewer extends TmfViewer {
 
     /**
      * Initializes the input for the tree viewer.
-     *
-     * @param input
-     *            The input of this viewer, or <code>null</code> if none
      */
     protected void initInput() {
         String treeID = getTreeID();
-        TmfStatisticsTreeNode experimentTreeNode;
-        if (TmfStatisticsTreeRootFactory.containsTreeRoot(treeID)) {
-            // The experiment root is already present
-            experimentTreeNode = TmfStatisticsTreeRootFactory.getStatTreeRoot(treeID);
+        TmfStatisticsTreeNode statisticsTreeNode;
+        if (TmfStatisticsTreeManager.containsTreeRoot(treeID)) {
+            // The statistics root is already present
+            statisticsTreeNode = TmfStatisticsTreeManager.getStatTreeRoot(treeID);
 
             // Checks if the trace is already in the statistics tree.
-            int numNodeTraces = experimentTreeNode.getNbChildren();
-
-            int numTraces = 1;
-            ITmfTrace[] trace = { fTrace };
-            // For experiment, gets all the traces within it
-            if (fTrace instanceof TmfExperiment) {
-                TmfExperiment experiment = (TmfExperiment) fTrace;
-                numTraces = experiment.getTraces().length;
-                trace = experiment.getTraces();
-            }
+            int numNodeTraces = statisticsTreeNode.getNbChildren();
+
+            ITmfTrace[] traces = TmfTraceManager.getTraceSet(fTrace);
+            int numTraces = traces.length;
 
             if (numTraces == numNodeTraces) {
                 boolean same = true;
@@ -567,8 +541,8 @@ public class TmfStatisticsViewer extends TmfViewer {
                  * previously selected.
                  */
                 for (int i = 0; i < numTraces; i++) {
-                    String traceName = trace[i].getName();
-                    if (!experimentTreeNode.containsChild(traceName)) {
+                    String traceName = traces[i].getName();
+                    if (!statisticsTreeNode.containsChild(traceName)) {
                         same = false;
                         break;
                     }
@@ -576,38 +550,38 @@ public class TmfStatisticsViewer extends TmfViewer {
 
                 if (same) {
                     // No need to reload data, all traces are already loaded
-                    fTreeViewer.setInput(experimentTreeNode);
+                    fTreeViewer.setInput(statisticsTreeNode);
                     return;
                 }
                 // Clears the old content to start over
-                experimentTreeNode.reset();
+                statisticsTreeNode.reset();
             }
         } else {
             // Creates a new tree
-            experimentTreeNode = TmfStatisticsTreeRootFactory.addStatsTreeRoot(treeID, getStatisticData());
+            statisticsTreeNode = TmfStatisticsTreeManager.addStatsTreeRoot(treeID, getStatisticData());
         }
 
         // Sets the input to a clean data model
-        fTreeViewer.setInput(experimentTreeNode);
+        fTreeViewer.setInput(statisticsTreeNode);
         resetUpdateSynchronization();
     }
 
     /**
-     * Tells if the viewer is listening to a trace from the selected experiment.
+     * Tells if the viewer is listening to a trace.
      *
-     * @param traceName
+     * @param trace
      *            The trace that the viewer may be listening
      * @return true if the viewer is listening to the trace, false otherwise
      */
-    protected boolean isListeningTo(String traceName) {
-        if (fProcessAll || traceName.equals(fTrace.getName())) {
+    protected boolean isListeningTo(ITmfTrace trace) {
+        if (fProcessAll || trace == fTrace) {
             return true;
         }
         return false;
     }
 
     /**
-     * Called when an experiment request has been completed successfully.
+     * Called when an trace request has been completed successfully.
      *
      * @param global
      *            Tells if the request is a global or time range (partial)
@@ -622,7 +596,7 @@ public class TmfStatisticsViewer extends TmfViewer {
     }
 
     /**
-     * Called when an experiment request has failed or has been cancelled.
+     * Called when an trace request has failed or has been cancelled.
      *
      * @param isGlobalRequest
      *            Tells if the request is a global or time range (partial)
@@ -644,60 +618,169 @@ public class TmfStatisticsViewer extends TmfViewer {
     }
 
     /**
-     * Sends the request to the experiment for the whole trace
+     * Sends the request to the trace for the whole trace
      *
-     * @param experiment
-     *            The experiment used to send the request
-     * @param range
-     *            The range to request to the experiment
-     */
-    protected void requestData(TmfExperiment experiment, TmfTimeRange range) {
-        // Check if an update is already ongoing
-        if (checkUpdateBusy(range)) {
+     * @param trace
+     *            The trace used to send the request
+     * @param timeRange
+     *            The range to request to the trace
+     */
+    protected void requestData(final ITmfTrace trace, final TmfTimeRange timeRange) {
+        buildStatisticsTree(trace, timeRange, true);
+    }
+
+    /**
+     * Sends the time range request from the trace
+     *
+     * @param trace
+     *            The trace used to send the request
+     * @param timeRange
+     *            The range to request to the trace
+     */
+    protected void requestTimeRangeData(final ITmfTrace trace, final TmfTimeRange timeRange) {
+        fRequestedTimerange = timeRange;
+        buildStatisticsTree(trace, timeRange, false);
+    }
+
+    /**
+     * Requests all the data of the trace to the state system which
+     * contains information about the statistics.
+     *
+     * Since the viewer may be listening to multiple traces, it may receive
+     * an experiment rather than a single trace. The filtering is done with the
+     * method {@link #isListeningTo(String trace)}.
+     *
+     * @param trace
+     *            The trace for which a request must be done
+     * @param timeRange
+     *            The time range that will be requested to the state system
+     * @param isGlobal
+     *            Tells if the request is for the global event count or the
+     *            partial one.
+     */
+    private void buildStatisticsTree(final ITmfTrace trace, final TmfTimeRange timeRange, final boolean isGlobal) {
+        final TmfStatisticsTreeNode statTree = TmfStatisticsTreeManager.getStatTreeRoot(getTreeID());
+        final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(getTreeID());
+        if (statsData == null) {
             return;
         }
 
-        long index = 0;
-        /*
-         * Sets the index to the last event retrieved from the experiment during
-         * the last request.
-         */
-        if (fRequest != null) {
-            index = fRequest.getLastEventIndex();
-        }
+        synchronized (statsData) {
+            if (isGlobal) {
+                statTree.resetGlobalValue();
+            } else {
+                statTree.resetTimeRangeValue();
+            }
 
-        fRequest = new TmfStatisticsRequest(this, range, index, true);
-        waitCursor(true);
-        experiment.sendRequest(fRequest);
+            for (final ITmfTrace aTrace : TmfTraceManager.getTraceSet(trace)) {
+                if (!isListeningTo(aTrace)) {
+                    continue;
+                }
+
+                /* Retrieve the statistics object */
+                final TmfStatisticsModule statsMod = aTrace.getAnalysisModuleOfClass(TmfStatisticsModule.class, TmfStatisticsModule.ID);
+                if (statsMod == null) {
+                    /* No statistics module available for this trace */
+                    continue;
+                }
+
+                /* Run the potentially long queries in a separate thread */
+                Thread statsThread = new Thread("Statistics update") { //$NON-NLS-1$
+                    @Override
+                    public void run() {
+                        /* Wait until the analysis is ready */
+                        if (!statsMod.waitForCompletion(new NullProgressMonitor())) {
+                            return;
+                        }
+
+                        ITmfStatistics stats = statsMod.getStatistics();
+                        if (stats == null) {
+                            /* It should have worked, but didn't */
+                            return;
+                        }
+
+                        /*
+                         * The generic statistics are stored in nanoseconds, so
+                         * we must make sure the time range is scaled correctly.
+                         */
+                        long start = timeRange.getStartTime().normalize(0, TIME_SCALE).getValue();
+                        long end = timeRange.getEndTime().normalize(0, TIME_SCALE).getValue();
+
+                        Map<String, Long> map = stats.getEventTypesInRange(start, end);
+                        updateStats(isGlobal, map);
+                    }
+                };
+                statsThread.start();
+                return;
+            }
+        }
     }
 
     /**
-     * Sends the time range request from the experiment
+     * Whenever a trace's statistics back-end finishes computing the statistics
+     * for a given interval, it will send the StatsUpdated signal. This method
+     * will receive this signal and update the statistics view accordingly.
      *
-     * @param experiment
-     *            The experiment used to send the request
-     * @param range
-     *            The range to request to the experiment
+     * @param sig
+     *            The signal that is received
      */
-    protected void requestTimeRangeData(TmfExperiment experiment, TmfTimeRange range) {
-        resetTimeRangeValue();
-        fRequestRange = new TmfStatisticsRequest(this, range, 0, false);
-        waitCursor(true);
-        experiment.sendRequest(fRequestRange);
+    private void updateStats(boolean isGlobal, Map<String, Long> eventsPerType) {
+
+        final TmfStatisticsTree statsData = TmfStatisticsTreeManager.getStatTree(getTreeID());
+        Map<String, Long> map = eventsPerType;
+        String name = fTrace.getName();
+
+        /*
+         * "Global", "partial", "total", etc., it's all very confusing...
+         *
+         * The base view shows the total count for the trace and for
+         * each even types, organized in columns like this:
+         *
+         *                   |  Global  |  Time range |
+         * trace name        |    A     |      B      |
+         *    Event Type     |          |             |
+         *       <event 1>   |    C     |      D      |
+         *       <event 2>   |   ...    |     ...     |
+         *         ...       |          |             |
+         *
+         * Here, we called the cells like this:
+         *  A : GlobalTotal
+         *  B : TimeRangeTotal
+         *  C : GlobalTypeCount(s)
+         *  D : TimeRangeTypeCount(s)
+         */
+
+        /* Fill in an the event counts (either cells C or D) */
+        for (Map.Entry<String, Long> entry : map.entrySet()) {
+            statsData.setTypeCount(name, entry.getKey(), isGlobal, entry.getValue());
+        }
+
+        /*
+         * Calculate the totals (cell A or B, depending if isGlobal). We will
+         * use the results of the previous request instead of sending another
+         * one.
+         */
+        long globalTotal = 0;
+        for (long val : map.values()) {
+            globalTotal += val;
+        }
+        statsData.setTotal(name, isGlobal, globalTotal);
+
+        modelComplete(isGlobal);
     }
 
     /**
      * Resets the number of events within the time range
      */
     protected void resetTimeRangeValue() {
-        TmfStatisticsTreeNode treeModelRoot = TmfStatisticsTreeRootFactory.getStatTreeRoot(getTreeID());
+        TmfStatisticsTreeNode treeModelRoot = TmfStatisticsTreeManager.getStatTreeRoot(getTreeID());
         if (treeModelRoot != null && treeModelRoot.hasChildren()) {
             treeModelRoot.resetTimeRangeValue();
         }
     }
 
     /**
-     * When the experiment is loading the cursor will be different so the user
+     * When the trace is loading the cursor will be different so the user
      * knows that the processing is not finished yet.
      *
      * Calls to this method are stacked.
@@ -795,7 +878,7 @@ public class TmfStatisticsViewer extends TmfViewer {
             fStatisticsUpdateBusy = false;
             if (fStatisticsUpdatePending) {
                 fStatisticsUpdatePending = false;
-                requestData(TmfExperiment.getCurrentExperiment(), fStatisticsUpdateRange);
+                requestData(fTrace, fStatisticsUpdateRange);
                 fStatisticsUpdateRange = null;
             }
         }
This page took 0.036814 seconds and 5 git commands to generate.