tmf: Split the statistics in two separate providers
authorAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Wed, 3 Apr 2013 17:26:39 +0000 (13:26 -0400)
committerAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Fri, 18 Oct 2013 12:34:58 +0000 (08:34 -0400)
Use separate state providers and backends (and so, two separate .ht files)
to store the statistics information. This will make it easier to eventually
swtich the event-types provider to a partial history backend - two one-liners
basically (or do we say one two-liner?)

Change-Id: If11956af12795a406f42c05b2cd67f82867850da
Signed-off-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
Reviewed-on: https://git.eclipse.org/r/11458
Tested-by: Hudson CI
Reviewed-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statistics/TmfLostEventStatisticsTest.java
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/statistics/TmfStateStatisticsTest.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/StatsProviderEventTypes.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/StatsProviderTotals.java [new file with mode: 0644]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/StatsStateProvider.java [deleted file]
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/TmfStateStatistics.java

index c42668b8d61363f5c48d5e661ef6b163667e15b2..fdcd3939238b78a4e35067034849b40b67fbacb6 100644 (file)
@@ -59,8 +59,10 @@ public class TmfLostEventStatisticsTest {
     public static void setUpClass() {
         try {
             assumeTrue(lostEventsTrace.exists());
-            File htFile = File.createTempFile("stats-test-lostevents", ".ht");
-            backend = new TmfStateStatistics(lostEventsTrace.getTrace(), htFile);
+            File htFileTotals = File.createTempFile("stats-test-lostevents-totals", ".ht");
+            File htFileTypes = File.createTempFile("stats-test-lostevents-types", ".ht");
+
+            backend = new TmfStateStatistics(lostEventsTrace.getTrace(), htFileTotals, htFileTypes);
 
         } catch (IOException e) {
             fail();
index bbac2ee1ced0145d25bfe80ecf03c94c4e7a1baa..06d1ed9b7d74782a809aab47a43b9465af366352 100644 (file)
@@ -30,7 +30,8 @@ import org.junit.BeforeClass;
  */
 public class TmfStateStatisticsTest extends TmfStatisticsTest {
 
-    private static File htFile;
+    private static File htFileTotals;
+    private static File htFileTypes;
 
     /**
      * Set up the fixture (build the state history, etc.) once for all tests.
@@ -39,8 +40,10 @@ public class TmfStateStatisticsTest extends TmfStatisticsTest {
     public static void setUpClass() {
         assumeTrue(testTrace.exists());
         try {
-            htFile = File.createTempFile("stats-test", ".ht");
-            backend = new TmfStateStatistics(testTrace.getTrace(), htFile);
+            htFileTotals = File.createTempFile("stats-test-totals", ".ht");
+            htFileTypes = File.createTempFile("stats-test-types", ".ht");
+
+            backend = new TmfStateStatistics(testTrace.getTrace(), htFileTotals, htFileTypes);
 
         } catch (TmfTraceException e) {
             fail();
@@ -54,6 +57,7 @@ public class TmfStateStatisticsTest extends TmfStatisticsTest {
      */
     @AfterClass
     public static void tearDownClass() {
-        htFile.delete();
+        htFileTotals.delete();
+        htFileTypes.delete();
     }
 }
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/StatsProviderEventTypes.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/StatsProviderEventTypes.java
new file mode 100644 (file)
index 0000000..9c5afc1
--- /dev/null
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Alexandre Montplaisir - Initial API and implementation
+ *   Patrick Tasse - Fix javadoc
+ ******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.statistics;
+
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.ITmfLostEvent;
+import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
+import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
+import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
+import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider;
+import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
+import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics.Attributes;
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * The state provider for traces statistics that use TmfStateStatistics. It
+ * should work with any trace type for which we can use the state system.
+ *
+ * It will store number of events seen, per event types. The resulting attribute
+ * tree will look like this:
+ *
+ * <pre>
+ * (root)
+ *   \-- event_types
+ *        |-- (event name 1)
+ *        |-- (event name 2)
+ *        |-- (event name 3)
+ *       ...
+ * </pre>
+ *
+ * And each (event name)'s value will be an integer, representing how many times
+ * this particular event type has been seen in the trace so far.
+ *
+ * @author Alexandre Montplaisir
+ * @version 1.0
+ */
+class StatsProviderEventTypes extends AbstractTmfStateProvider {
+
+    /**
+     * Version number of this input handler. Please bump this if you modify the
+     * contents of the generated state history in some way.
+     */
+    private static final int VERSION = 2;
+
+    /**
+     * Constructor
+     *
+     * @param trace
+     *            The trace for which we build this state system
+     */
+    public StatsProviderEventTypes(ITmfTrace trace) {
+        super(trace, ITmfEvent.class ,"TMF Statistics, events per type"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getVersion() {
+        return VERSION;
+    }
+
+    @Override
+    public StatsProviderEventTypes getNewInstance() {
+        return new StatsProviderEventTypes(this.getTrace());
+    }
+
+    @Override
+    protected void eventHandle(ITmfEvent event) {
+        int quark;
+
+        /* Since this can be used for any trace types, normalize all the
+         * timestamp values to nanoseconds. */
+        final long ts = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+
+        final String eventName = event.getType().getName();
+
+        try {
+            /* Special handling for lost events */
+            if (event instanceof ITmfLostEvent) {
+                ITmfLostEvent le = (ITmfLostEvent) event;
+                quark = ss.getQuarkAbsoluteAndAdd(Attributes.EVENT_TYPES, eventName);
+
+                int curVal = ss.queryOngoingState(quark).unboxInt();
+                if (curVal == -1) {
+                    curVal = 0;
+                }
+
+                TmfStateValue value = TmfStateValue.newValueInt((int) (curVal + le.getNbLostEvents()));
+                ss.modifyAttribute(ts, value, quark);
+                return;
+            }
+
+            /* Number of events of each type, globally */
+            quark = ss.getQuarkAbsoluteAndAdd(Attributes.EVENT_TYPES, eventName);
+            ss.incrementAttribute(ts, quark);
+
+//            /* Number of events per CPU */
+//            quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
+//            ss.incrementAttribute(ts, quark);
+//
+//            /* Number of events per process */
+//            quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
+//            ss.incrementAttribute(ts, quark);
+
+        } catch (StateValueTypeException e) {
+            e.printStackTrace();
+        } catch (TimeRangeException e) {
+            e.printStackTrace();
+        } catch (AttributeNotFoundException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/StatsProviderTotals.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/StatsProviderTotals.java
new file mode 100644 (file)
index 0000000..894e9f5
--- /dev/null
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * 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
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Alexandre Montplaisir - Initial API and implementation
+ *   Patrick Tasse - Fix javadoc
+ ******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.statistics;
+
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.ITmfLostEvent;
+import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
+import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
+import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
+import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider;
+import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics.Attributes;
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * The state provider for traces statistics that use TmfStateStatistics. It
+ * should work with any trace type for which we can use the state system.
+ *
+ * Only one attribute will be stored, containing the total of events seen so
+ * far. The resulting attribute tree will look like this:
+ *
+ * <pre>
+ * (root)
+ *   \-- total
+ * </pre>
+ *
+ * @author Alexandre Montplaisir
+ * @version 1.0
+ */
+class StatsProviderTotals extends AbstractTmfStateProvider {
+
+    /**
+     * Version number of this input handler. Please bump this if you modify the
+     * contents of the generated state history in some way.
+     */
+    private static final int VERSION = 2;
+
+    /**
+     * Constructor
+    *
+     * @param trace
+     *            The trace for which we build this state system
+     */
+    public StatsProviderTotals(ITmfTrace trace) {
+        super(trace, ITmfEvent.class ,"TMF Statistics, event totals"); //$NON-NLS-1$
+    }
+
+    @Override
+    public int getVersion() {
+        return VERSION;
+    }
+
+    @Override
+    public StatsProviderTotals getNewInstance() {
+        return new StatsProviderTotals(this.getTrace());
+    }
+
+    @Override
+    protected void eventHandle(ITmfEvent event) {
+        /* Do not count lost events in the total */
+        if (event instanceof ITmfLostEvent) {
+            return;
+        }
+
+        /* Since this can be used for any trace types, normalize all the
+         * timestamp values to nanoseconds. */
+        final long ts = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
+
+        try {
+            /* Total number of events */
+            int quark = ss.getQuarkAbsoluteAndAdd(Attributes.TOTAL);
+            ss.incrementAttribute(ts, quark);
+
+        } catch (StateValueTypeException e) {
+            e.printStackTrace();
+        } catch (TimeRangeException e) {
+            e.printStackTrace();
+        } catch (AttributeNotFoundException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/StatsStateProvider.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statistics/StatsStateProvider.java
deleted file mode 100644 (file)
index 5f54347..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*******************************************************************************
- * 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
- * accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *   Alexandre Montplaisir - Initial API and implementation
- *   Patrick Tasse - Fix javadoc
- ******************************************************************************/
-
-package org.eclipse.linuxtools.tmf.core.statistics;
-
-import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
-import org.eclipse.linuxtools.tmf.core.event.ITmfLostEvent;
-import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
-import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
-import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
-import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider;
-import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
-import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics.Attributes;
-import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
-import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
-
-/**
- * The state provider for traces statistics that use TmfStateStatistics. It
- * should work with any trace type for which we can use the state system.
- *
- * The resulting attribute tree will look like this:
- *<pre>
- * (root)
- *   |-- total
- *   \-- event_types
- *        |-- (event name 1)
- *        |-- (event name 2)
- *        |-- (event name 3)
- *       ...
- *</pre>
- * And each (event name)'s value will be an integer, representing how many times
- * this particular event type has been seen in the trace so far.
- *
- * @author Alexandre Montplaisir
- * @version 1.0
- */
-class StatsStateProvider extends AbstractTmfStateProvider {
-
-    /**
-     * Version number of this input handler. Please bump this if you modify the
-     * contents of the generated state history in some way.
-     */
-    private static final int VERSION = 1;
-
-    /**
-     * Constructor
-     *
-     * @param trace
-     *            The trace for which we build this state system
-     */
-    public StatsStateProvider(ITmfTrace trace) {
-        super(trace, ITmfEvent.class ,"TMF Statistics"); //$NON-NLS-1$
-    }
-
-    @Override
-    public int getVersion() {
-        return VERSION;
-    }
-
-    @Override
-    public StatsStateProvider getNewInstance() {
-        return new StatsStateProvider(this.getTrace());
-    }
-
-    @Override
-    protected void eventHandle(ITmfEvent event) {
-        int quark;
-
-        /* Since this can be used for any trace types, normalize all the
-         * timestamp values to nanoseconds. */
-        final long ts = event.getTimestamp().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
-
-        final String eventName = event.getType().getName();
-
-        try {
-            /* Special handling for lost events */
-            if (event instanceof ITmfLostEvent) {
-                ITmfLostEvent le = (ITmfLostEvent) event;
-                quark = ss.getQuarkAbsoluteAndAdd(Attributes.EVENT_TYPES, eventName);
-
-                int curVal = ss.queryOngoingState(quark).unboxInt();
-                if (curVal == -1) { curVal = 0; }
-
-                TmfStateValue value = TmfStateValue.newValueInt((int) (curVal + le.getNbLostEvents()));
-                ss.modifyAttribute(ts, value, quark);
-                return;
-            }
-
-            /* Total number of events */
-            quark = ss.getQuarkAbsoluteAndAdd(Attributes.TOTAL);
-            ss.incrementAttribute(ts, quark);
-
-            /* Number of events of each type, globally */
-            quark = ss.getQuarkAbsoluteAndAdd(Attributes.EVENT_TYPES, eventName);
-            ss.incrementAttribute(ts, quark);
-
-//            /* Number of events per CPU */
-//            quark = ss.getQuarkRelativeAndAdd(currentCPUNode, Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
-//            ss.incrementAttribute(ts, quark);
-//
-//            /* Number of events per process */
-//            quark = ss.getQuarkRelativeAndAdd(currentThreadNode, Attributes.STATISTICS, Attributes.EVENT_TYPES, eventName);
-//            ss.incrementAttribute(ts, quark);
-
-        } catch (StateValueTypeException e) {
-            e.printStackTrace();
-        } catch (TimeRangeException e) {
-            e.printStackTrace();
-        } catch (AttributeNotFoundException e) {
-            e.printStackTrace();
-        }
-    }
-}
index 45789a5fc006713f9ceedce75a2e449a6cb03f52..e8d48b39b4a7619f91b62722482b339756136ff3 100644 (file)
@@ -35,38 +35,68 @@ import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
 
 /**
  * Implementation of ITmfStatistics which uses a state history for storing its
- * information.
+ * information. In reality, it uses two state histories, one for "event totals"
+ * information (which should ideally use a fast backend), and another one for
+ * the rest (per event type, per CPU, etc.).
  *
- * It requires building the history first, but gives very fast response times
- * when built : Queries are O(log n) wrt the size of the trace, and O(1) wrt to
- * the size of the time interval selected.
+ * Compared to the event-request-based statistics calculations, it adds the
+ * building the history first, but gives much faster response times once built :
+ * Queries are O(log n) wrt the size of the trace, and O(1) wrt to the size of
+ * the time interval selected.
  *
  * @author Alexandre Montplaisir
  * @since 2.0
  */
 public class TmfStateStatistics implements ITmfStatistics {
 
-    /** ID for the statistics state system */
+    // ------------------------------------------------------------------------
+    // Constants
+    // ------------------------------------------------------------------------
+
+    /**
+     * @deprecated Do not use, it's been replaced by {@link #TOTALS_STATE_ID}
+     *              and {@link #TYPES_STATE_ID}
+     */
+    @Deprecated
     public static final String STATE_ID = "org.eclipse.linuxtools.tmf.statistics"; //$NON-NLS-1$
 
-    /** Filename the "statistics state history" file will have */
-    private static final String STATS_STATE_FILENAME = "statistics.ht"; //$NON-NLS-1$
+    /** ID for the "event totals" statistics state system
+     * @since 2.2 */
+    public static final String TOTALS_STATE_ID = "org.eclipse.linuxtools.tmf.statistics.totals"; //$NON-NLS-1$
+
+    /** ID for the "event types" statistics state system
+     * @since 2.2 */
+    public static final String TYPES_STATE_ID = "org.eclipse.linuxtools.tmf.statistics.types"; //$NON-NLS-1$
+
+    /** Filename for the "event totals" state history file */
+    private static final String TOTALS_STATE_FILENAME = "statistics-totals.ht"; //$NON-NLS-1$
+
+    /** Filename for the "event types" state history file */
+    private static final String TYPES_STATE_FILENAME = "statistics-types.ht"; //$NON-NLS-1$
+
+    // ------------------------------------------------------------------------
+    // Fields
+    // ------------------------------------------------------------------------
 
     private final ITmfTrace trace;
 
-    /**
-     * The state system that's used to stored the statistics. It's hidden from
-     * the trace, so that it doesn't conflict with ITmfTrace.getStateSystem()
-     * (which is something else!)
-     */
-    private final ITmfStateSystem stats;
+    /** The event totals state system */
+    private final ITmfStateSystem totalsStats;
+
+    /** The state system for event types */
+    private final ITmfStateSystem typesStats;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
 
     /**
      * Empty constructor. The resulting TmfStatistics object will not be usable,
      * but it might be needed for sub-classes.
      */
     public TmfStateStatistics() {
-        stats = null;
+        totalsStats = null;
+        typesStats = null;
         trace = null;
     }
 
@@ -80,39 +110,63 @@ public class TmfStateStatistics implements ITmfStatistics {
      */
     public TmfStateStatistics(ITmfTrace trace) throws TmfTraceException {
         this.trace = trace;
-
         String directory = TmfTraceManager.getSupplementaryFileDir(trace);
-        final File htFile = new File(directory + STATS_STATE_FILENAME);
-        final ITmfStateProvider htInput = new StatsStateProvider(trace);
 
-        this.stats = TmfStateSystemFactory.newFullHistory(htFile, htInput, false);
+        final File totalsFile = new File(directory + TOTALS_STATE_FILENAME);
+        final ITmfStateProvider totalsInput = new StatsProviderTotals(trace);
+        this.totalsStats = TmfStateSystemFactory.newFullHistory(totalsFile, totalsInput, false);
+
+        final File typesFile = new File(directory + TYPES_STATE_FILENAME);
+        final ITmfStateProvider typesInput = new StatsProviderEventTypes(trace);
+        this.typesStats = TmfStateSystemFactory.newFullHistory(typesFile, typesInput, false);
+
         registerStateSystems();
     }
 
+    /**
+     * Old manual constructor.
+     *
+     * @param trace Trace
+     * @param historyFile Full history file
+     * @deprecated Need to use {@link #TmfStateStatistics(ITmfTrace trace,
+     * File fullHistoryFile, File partialHistoryFile)} now.
+     */
+    @Deprecated
+    public TmfStateStatistics(ITmfTrace trace, File historyFile) {
+        this();
+    }
+
     /**
      * Manual constructor. This should be used if the trace's Resource is null
      * (ie, for unit tests). It requires specifying the location of the history
-     * file manually.
+     * files manually.
      *
      * @param trace
      *            The trace for which we build these statistics
-     * @param historyFile
-     *            The location of the state history file to build for the stats
+     * @param totalsHistoryFile
+     *            The location of the totals state history file
+     * @param typesHistoryFile
+     *            The location of the types state history file
      * @throws TmfTraceException
      *             If the file could not be written to
+     * @since 2.2
      */
-    public TmfStateStatistics(ITmfTrace trace, File historyFile) throws TmfTraceException {
+    public TmfStateStatistics(ITmfTrace trace, File totalsHistoryFile,
+            File typesHistoryFile) throws TmfTraceException {
         this.trace = trace;
-        final ITmfStateProvider htInput = new StatsStateProvider(trace);
-        this.stats = TmfStateSystemFactory.newFullHistory(historyFile, htInput, true);
+        final ITmfStateProvider totalsInput = new StatsProviderTotals(trace);
+        final ITmfStateProvider typesInput = new StatsProviderEventTypes(trace);
+        this.totalsStats = TmfStateSystemFactory.newFullHistory(totalsHistoryFile, totalsInput, true);
+        this.typesStats = TmfStateSystemFactory.newFullHistory(typesHistoryFile, typesInput, true);
         registerStateSystems();
     }
 
     /**
-     * Register the state systems used here into the trace's state system array.
+     * Register the state systems used here into the trace's state system map.
      */
     private void registerStateSystems() {
-        trace.registerStateSystem(STATE_ID, stats);
+        trace.registerStateSystem(TOTALS_STATE_ID, totalsStats);
+        trace.registerStateSystem(TYPES_STATE_ID, typesStats);
     }
 
     // ------------------------------------------------------------------------
@@ -121,7 +175,8 @@ public class TmfStateStatistics implements ITmfStatistics {
 
     @Override
     public void dispose() {
-        stats.dispose();
+        totalsStats.dispose();
+        typesStats.dispose();
     }
 
     @Override
@@ -136,17 +191,14 @@ public class TmfStateStatistics implements ITmfStatistics {
         Thread statsThread = new Thread("Statistics update") { //$NON-NLS-1$
             @Override
             public void run() {
-                long total;
-                Map<String, Long> map;
-
-                /* Wait until the history building completed */
-                if (!stats.waitUntilBuilt()) {
+                /* Wait until the history building is completed */
+                if (!waitUntilBuilt()) {
                     return;
                 }
 
                 /* Range should be valid for both global and time range queries */
-                total = getEventsInRange(start, end);
-                map = getEventTypesInRange(start, end);
+                long total = getEventsInRange(start, end);
+                Map<String, Long> map = getEventTypesInRange(start, end);
 
                 /* Send the signal to notify the stats viewer to update its display */
                 TmfSignal sig = new TmfStatsUpdatedSignal(this, trace, isGlobal, total, map);
@@ -162,16 +214,15 @@ public class TmfStateStatistics implements ITmfStatistics {
         final List<Long> list = new LinkedList<Long>();
         final long increment = (end - start) / nb;
 
-        /* Wait until the history building completed */
-        if (!stats.waitUntilBuilt()) {
-            return null;
+        if (!totalsStats.waitUntilBuilt()) {
+            return list;
         }
 
         /*
          * We will do one state system query per "border", and save the
          * differences between each border.
          */
-        long prevTotal = (start == stats.getStartTime()) ? 0 : getEventCountAt(start);
+        long prevTotal = (start == totalsStats.getStartTime()) ? 0 : getEventCountAt(start);
         long curTime = start + increment;
 
         long curTotal, count;
@@ -198,14 +249,14 @@ public class TmfStateStatistics implements ITmfStatistics {
     @Override
     public long getEventsTotal() {
         /* We need the complete state history to be built to answer this. */
-        stats.waitUntilBuilt();
+        totalsStats.waitUntilBuilt();
 
-        long endTime = stats.getCurrentEndTime();
+        long endTime = totalsStats.getCurrentEndTime();
         int count = 0;
 
         try {
-            final int quark = stats.getQuarkAbsolute(Attributes.TOTAL);
-            count= stats.querySingleState(endTime, quark).getStateValue().unboxInt();
+            final int quark = totalsStats.getQuarkAbsolute(Attributes.TOTAL);
+            count= totalsStats.querySingleState(endTime, quark).getStateValue().unboxInt();
 
         } catch (TimeRangeException e) {
             /* Assume there is no events for that range */
@@ -224,23 +275,23 @@ public class TmfStateStatistics implements ITmfStatistics {
     @Override
     public Map<String, Long> getEventTypesTotal() {
         /* We need the complete state history to be built to answer this. */
-        stats.waitUntilBuilt();
+        typesStats.waitUntilBuilt();
 
         Map<String, Long> map = new HashMap<String, Long>();
-        long endTime = stats.getCurrentEndTime();
+        long endTime = typesStats.getCurrentEndTime();
 
         try {
             /* Get the list of quarks, one for each even type in the database */
-            int quark = stats.getQuarkAbsolute(Attributes.EVENT_TYPES);
-            List<Integer> quarks = stats.getSubAttributes(quark, false);
+            int quark = typesStats.getQuarkAbsolute(Attributes.EVENT_TYPES);
+            List<Integer> quarks = typesStats.getSubAttributes(quark, false);
 
             /* Since we want the total we can look only at the end */
-            List<ITmfStateInterval> endState = stats.queryFullState(endTime);
+            List<ITmfStateInterval> endState = typesStats.queryFullState(endTime);
 
             String curEventName;
             long eventCount;
             for (int typeQuark : quarks) {
-                curEventName = stats.getAttributeName(typeQuark);
+                curEventName = typesStats.getAttributeName(typeQuark);
                 eventCount = endState.get(typeQuark).getStateValue().unboxInt();
                 map.put(curEventName, eventCount);
             }
@@ -261,10 +312,10 @@ public class TmfStateStatistics implements ITmfStatistics {
     public long getEventsInRange(long start, long end) {
         // FIXME Instead of waiting until the end, we could check the current
         // end time, and answer as soon as possible...
-        stats.waitUntilBuilt();
+        totalsStats.waitUntilBuilt();
 
         long startCount;
-        if (start == stats.getStartTime()) {
+        if (start == totalsStats.getStartTime()) {
             startCount = 0;
         } else {
             /*
@@ -282,7 +333,7 @@ public class TmfStateStatistics implements ITmfStatistics {
     public Map<String, Long> getEventTypesInRange(long start, long end) {
         // FIXME Instead of waiting until the end, we could check the current
         // end time, and answer as soon as possible...
-        stats.waitUntilBuilt();
+        typesStats.waitUntilBuilt();
 
         Map<String, Long> map = new HashMap<String, Long>();
 
@@ -294,18 +345,18 @@ public class TmfStateStatistics implements ITmfStatistics {
 
         try {
             /* Get the list of quarks, one for each even type in the database */
-            int quark = stats.getQuarkAbsolute(Attributes.EVENT_TYPES);
-            List<Integer> quarks = stats.getSubAttributes(quark, false);
+            int quark = typesStats.getQuarkAbsolute(Attributes.EVENT_TYPES);
+            List<Integer> quarks = typesStats.getSubAttributes(quark, false);
 
-            List<ITmfStateInterval> endState = stats.queryFullState(endTime);
+            List<ITmfStateInterval> endState = typesStats.queryFullState(endTime);
 
             String curEventName;
             long countAtStart, countAtEnd, eventCount;
 
-            if (startTime == stats.getStartTime()) {
+            if (startTime == typesStats.getStartTime()) {
                 /* Only use the values picked up at the end time */
                 for (int typeQuark : quarks) {
-                    curEventName = stats.getAttributeName(typeQuark);
+                    curEventName = typesStats.getAttributeName(typeQuark);
                     eventCount = endState.get(typeQuark).getStateValue().unboxInt();
                     if (eventCount == -1) {
                         eventCount = 0;
@@ -317,9 +368,9 @@ public class TmfStateStatistics implements ITmfStatistics {
                  * Query the start time at -1, so the beginning of the interval
                  * is inclusive.
                  */
-                List<ITmfStateInterval> startState = stats.queryFullState(startTime - 1);
+                List<ITmfStateInterval> startState = typesStats.queryFullState(startTime - 1);
                 for (int typeQuark : quarks) {
-                    curEventName = stats.getAttributeName(typeQuark);
+                    curEventName = typesStats.getAttributeName(typeQuark);
                     countAtStart = startState.get(typeQuark).getStateValue().unboxInt();
                     countAtEnd = endState.get(typeQuark).getStateValue().unboxInt();
 
@@ -350,14 +401,18 @@ public class TmfStateStatistics implements ITmfStatistics {
         return map;
     }
 
+    // ------------------------------------------------------------------------
+    // Helper methods
+    // ------------------------------------------------------------------------
+
     private long getEventCountAt(long timestamp) {
         /* Make sure the target time is within the range of the history */
         long ts = checkStartTime(timestamp);
         ts = checkEndTime(ts);
 
         try {
-            final int quark = stats.getQuarkAbsolute(Attributes.TOTAL);
-            long count = stats.querySingleState(ts, quark).getStateValue().unboxInt();
+            final int quark = totalsStats.getQuarkAbsolute(Attributes.TOTAL);
+            long count = totalsStats.querySingleState(ts, quark).getStateValue().unboxInt();
             return count;
 
         } catch (TimeRangeException e) {
@@ -375,20 +430,31 @@ public class TmfStateStatistics implements ITmfStatistics {
 
     private long checkStartTime(long initialStart) {
         long start = initialStart;
-        if (start < stats.getStartTime()) {
-            return stats.getStartTime();
+        if (start < totalsStats.getStartTime()) {
+            return totalsStats.getStartTime();
         }
         return start;
     }
 
     private long checkEndTime(long initialEnd) {
         long end = initialEnd;
-        if (end > stats.getCurrentEndTime()) {
-            return stats.getCurrentEndTime();
+        if (end > totalsStats.getCurrentEndTime()) {
+            return totalsStats.getCurrentEndTime();
         }
         return end;
     }
 
+    /**
+     * Wait until both backing state systems are finished building.
+     *
+     * @return If both state systems were built successfully
+     */
+    private boolean waitUntilBuilt() {
+        boolean check1 = totalsStats.waitUntilBuilt();
+        boolean check2 = typesStats.waitUntilBuilt();
+        return (check1 && check2);
+    }
+
 
     /**
      * The attribute names that are used in the state provider
This page took 0.05238 seconds and 5 git commands to generate.