timing.core: Add local statistics to the latency statistics
authorJean-Christian Kouame <jean-christian.kouame@ericsson.com>
Tue, 6 Sep 2016 17:21:04 +0000 (13:21 -0400)
committerJean-Christian Kouame <jean-christian.kouame@ericsson.com>
Thu, 20 Oct 2016 15:05:22 +0000 (11:05 -0400)
Add the local statistics in the statistics view and update the general
item tree of the view. The SystemCallLatencyStatisticsTableAnalysisTest
is updated in consequence.

Change-Id: I5209f9c6430ee4658e3cf55ef50f4769b8e28772
Signed-off-by: Jean-Christian Kouame <jean-christian.kouame@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/80952
Reviewed-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Tested-by: Genevieve Bastien <gbastien+lttng@versatic.net>
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
analysis/org.eclipse.tracecompass.analysis.os.linux.ui.swtbot.tests/src/org/eclipse/tracecompass/analysis/os/linux/ui/swtbot/tests/latency/SystemCallLatencyStatisticsTableAnalysisTest.java
analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/statistics/AbstractStatsAnalysisTest.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/statistics/StubSegmentStatisticsAnalysis.java [new file with mode: 0644]
analysis/org.eclipse.tracecompass.analysis.timing.core/src/org/eclipse/tracecompass/analysis/timing/core/segmentstore/statistics/AbstractSegmentStatisticsAnalysis.java
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/analysis/timing/ui/views/segmentstore/statistics/AbstractSegmentStoreStatisticsViewer.java
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/statistics/Messages.java
analysis/org.eclipse.tracecompass.analysis.timing.ui/src/org/eclipse/tracecompass/internal/analysis/timing/ui/views/segmentstore/statistics/messages.properties
tmf/org.eclipse.tracecompass.tmf.core.tests/stubs/org/eclipse/tracecompass/tmf/tests/stubs/trace/xml/TmfXmlTraceStub.java

index 187b733f302535a3d6101765e145d74045d6de0f..7143045c73c78fffc25eafeea1c11e8b31bb62c3 100644 (file)
@@ -194,7 +194,6 @@ public class SystemCallLatencyStatisticsTableAnalysisTest {
         assertEquals("175.875 ms", fTreeBot.cell(0, STDEV_COL));
         assertEquals("1801", fTreeBot.cell(0, COUNT_COL));
         SWTBotTreeItem treeItem = fTreeBot.getTreeItem("Total");
-        treeItem = treeItem.getNode(0);
         assertEquals(55, treeItem.getNodes().size());
         validate(treeItem.getNode(2), "select", "13.600 µs", "1.509 s", "192.251 ms", "386.369 ms", "58");
         validate(treeItem.getNode(3), "poll", "6.300 µs", "6.800 µs", "6.550 µs", "---", "2");
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/statistics/AbstractStatsAnalysisTest.java b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/statistics/AbstractStatsAnalysisTest.java
new file mode 100644 (file)
index 0000000..2358902
--- /dev/null
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.timing.core.tests.segmentstore.statistics;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.statistics.AbstractSegmentStatisticsAnalysis;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.statistics.SegmentStoreStatistics;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStub;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Test class to test the {@link AbstractSegmentStatisticsAnalysis} class
+ *
+ * @author Matthew Khouzam
+ */
+public class AbstractStatsAnalysisTest {
+
+    /**
+     * Test execution with no trace
+     *
+     * @throws TmfAnalysisException
+     *             should not happen
+     */
+    @Test
+    public void testExecuteNoTrace() throws TmfAnalysisException {
+        StubSegmentStatisticsAnalysis fixture = new StubSegmentStatisticsAnalysis();
+        assertFalse(fixture.executeAnalysis(new NullProgressMonitor()));
+    }
+
+    /**
+     * Test execution with no dependent analyses
+     *
+     * @throws TmfAnalysisException
+     *             should not happen
+     */
+    @Test
+    public void testExecuteNoDepend() throws TmfAnalysisException {
+        StubSegmentStatisticsAnalysis fixture = new StubSegmentStatisticsAnalysis();
+        fixture.setTrace(new TmfXmlTraceStub());
+        assertFalse(fixture.executeAnalysis(new NullProgressMonitor()));
+    }
+
+    /**
+     * Test good execution
+     *
+     * @throws TmfAnalysisException
+     *             should not happen
+     */
+    @Test
+    public void testExecute() throws TmfAnalysisException {
+        StubSegmentStatisticsAnalysis fixture = new StubSegmentStatisticsAnalysis();
+        TmfXmlTraceStub trace = new TmfXmlTraceStub();
+        fixture.setTrace(trace);
+        fixture.getDependentAnalyses();
+        assertTrue(fixture.executeAnalysis(new NullProgressMonitor()));
+    }
+
+    /**
+     * Test total statistics
+     *
+     * @throws TmfAnalysisException
+     *             should not happen
+     *
+     */
+    @Test
+    public void testTotalStats() throws TmfAnalysisException {
+        StubSegmentStatisticsAnalysis fixture = getValidSegmentStats();
+        SegmentStoreStatistics totalStats = fixture.getTotalStats();
+        assertNotNull(totalStats);
+        // no need to test the content much as it is tested in the other test.
+        assertEquals(StubSegmentStatisticsAnalysis.SIZE, totalStats.getNbSegments());
+    }
+
+    /**
+     * Test per-type statistics
+     *
+     * @throws TmfAnalysisException
+     *             should not happen
+     *
+     */
+    @Test
+    public void testPerTypeStats() throws TmfAnalysisException {
+        StubSegmentStatisticsAnalysis fixture = getValidSegmentStats();
+        Map<@NonNull String, @NonNull SegmentStoreStatistics> perTypeStats = fixture.getPerSegmentTypeStats();
+        assertNotNull(perTypeStats);
+        // no need to test the content much as it is tested in the other test.
+        assertEquals(2, perTypeStats.size());
+        assertEquals(ImmutableSet.<String> of("odd", "even"), perTypeStats.keySet());
+        SegmentStoreStatistics segmentStoreStatistics = perTypeStats.get("even");
+        assertNotNull(segmentStoreStatistics);
+        // starts with 0  so size + 1
+        assertEquals(StubSegmentStatisticsAnalysis.SIZE / 2 + 1, segmentStoreStatistics.getNbSegments());
+    }
+
+    /**
+     * Test the partial statistics
+     *
+     * @throws TmfAnalysisException
+     *             should not happen
+     *
+     */
+    @Test
+    public void testPartialStats() throws TmfAnalysisException {
+        StubSegmentStatisticsAnalysis fixture = getValidSegmentStats();
+        SegmentStoreStatistics totalStats = fixture.getTotalStatsForRange(100, 1100, new NullProgressMonitor());
+        assertNotNull(totalStats);
+        // no need to test the content much as it is tested in the other test.
+
+        // 1051 = 1001 where start is between start and end + 50 overlapping
+        // start
+        assertEquals(1051, totalStats.getNbSegments());
+    }
+
+    /**
+     * Test the partial per type statistic
+     *
+     * @throws TmfAnalysisException
+     *             should not happen
+     *
+     */
+    @Test
+    public void testPartialPerTypeStats() throws TmfAnalysisException {
+        StubSegmentStatisticsAnalysis fixture = getValidSegmentStats();
+        Map<@NonNull String, @NonNull SegmentStoreStatistics> perTypeStats = fixture.getPerSegmentTypeStatsForRange(100, 1100, new NullProgressMonitor());
+        assertNotNull(perTypeStats);
+        // no need to test the content much as it is tested in the other test.
+        assertEquals(2, perTypeStats.size());
+        assertEquals(ImmutableSet.<String> of("odd", "even"), perTypeStats.keySet());
+        SegmentStoreStatistics segmentStoreStatistics = perTypeStats.get("even");
+        assertNotNull(segmentStoreStatistics);
+        // 526 = 1051/2+1 = see explanation of 1051 in #testPartialStats
+        assertEquals(526, segmentStoreStatistics.getNbSegments());
+    }
+
+    /**
+     * Test the cancel operation
+     *
+     * @throws TmfAnalysisException
+     *             should not happen
+     */
+    @Test
+    public void testPartialPerTypeStatsCancel() throws TmfAnalysisException {
+        StubSegmentStatisticsAnalysis fixture = getValidSegmentStats();
+        NullProgressMonitor monitor = new NullProgressMonitor();
+        monitor.setCanceled(true);
+        Map<@NonNull String, @NonNull SegmentStoreStatistics> perTypeStats = fixture.getPerSegmentTypeStatsForRange(100, 1100, monitor);
+        assertEquals(Collections.emptyMap(), perTypeStats);
+    }
+
+    private static StubSegmentStatisticsAnalysis getValidSegmentStats() throws TmfAnalysisException {
+        StubSegmentStatisticsAnalysis fixture = new StubSegmentStatisticsAnalysis();
+        TmfXmlTraceStub trace = new TmfXmlTraceStub();
+        fixture.setTrace(trace);
+        fixture.getDependentAnalyses();
+        fixture.executeAnalysis(new NullProgressMonitor());
+        return fixture;
+    }
+
+}
diff --git a/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/statistics/StubSegmentStatisticsAnalysis.java b/analysis/org.eclipse.tracecompass.analysis.timing.core.tests/src/org/eclipse/tracecompass/analysis/timing/core/tests/segmentstore/statistics/StubSegmentStatisticsAnalysis.java
new file mode 100644 (file)
index 0000000..c65e7e2
--- /dev/null
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2016 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
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.analysis.timing.core.tests.segmentstore.statistics;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.IAnalysisProgressListener;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
+import org.eclipse.tracecompass.analysis.timing.core.segmentstore.statistics.AbstractSegmentStatisticsAnalysis;
+import org.eclipse.tracecompass.segmentstore.core.BasicSegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegment;
+import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
+import org.eclipse.tracecompass.segmentstore.core.SegmentStoreFactory;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.tests.stubs.analysis.TestAnalysis;
+import org.eclipse.tracecompass.tmf.tests.stubs.trace.xml.TmfXmlTraceStub;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+/**
+ * Test stuf for statistics analysis
+ *
+ * @author Matthew Khouzam
+ *
+ */
+class StubSegmentStatisticsAnalysis extends AbstractSegmentStatisticsAnalysis {
+
+    private final class StubProvider extends TestAnalysis implements ISegmentStoreProvider {
+        private final ISegmentStore<@NonNull ISegment> ifFixture;
+
+        public StubProvider(ISegmentStore<@NonNull ISegment> fixture) {
+            ifFixture = fixture;
+        }
+
+        @Override
+        public void removeListener(@NonNull IAnalysisProgressListener listener) {
+            // nothing
+        }
+
+        @Override
+        public @Nullable ISegmentStore<@NonNull ISegment> getSegmentStore() {
+            return ifFixture;
+        }
+
+        @Override
+        public @NonNull Iterable<@NonNull ISegmentAspect> getSegmentAspects() {
+            return Collections.emptyList();
+        }
+
+        @Override
+        public void addListener(@NonNull IAnalysisProgressListener listener) {
+            // nothing
+        }
+    }
+
+    public static final int SIZE = 65535;
+
+    private final List<@NonNull ISegment> fPreFixture;
+    private final ISegmentStore<@NonNull ISegment> fFixture = SegmentStoreFactory.createSegmentStore();
+    private StubProvider fSegmentStoreProvider;
+
+    public StubSegmentStatisticsAnalysis() {
+        ImmutableList.Builder<@NonNull ISegment> builder = new Builder<>();
+        for (int i = 0; i < SIZE; i++) {
+            ISegment seg = new BasicSegment(i, i + i);
+            builder.add(seg);
+        }
+        fPreFixture = builder.build();
+        fFixture.addAll(fPreFixture);
+        fSegmentStoreProvider = new StubProvider(fFixture);
+    }
+
+    @Override
+    public boolean setTrace(@NonNull ITmfTrace trace) throws TmfAnalysisException {
+        if (trace instanceof TmfXmlTraceStub) {
+            TmfXmlTraceStub tmfXmlTraceStub = (TmfXmlTraceStub) trace;
+            tmfXmlTraceStub.addAnalysisModule(this);
+            tmfXmlTraceStub.addAnalysisModule(fSegmentStoreProvider);
+
+        }
+        return super.setTrace(trace);
+    }
+    @Override
+    protected @Nullable String getSegmentType(@NonNull ISegment segment) {
+        return segment.getLength() % 2 == 0 ? "even" : "odd";
+    }
+
+    @Override
+    protected @Nullable ISegmentStoreProvider getSegmentProviderAnalysis(@NonNull ITmfTrace trace) {
+        return fSegmentStoreProvider;
+    }
+
+    // visibility change
+    @Override
+    public boolean executeAnalysis(@NonNull IProgressMonitor monitor) throws TmfAnalysisException {
+        return super.executeAnalysis(monitor);
+    }
+
+    // visibility change
+    @Override
+    public @NonNull Iterable<@NonNull IAnalysisModule> getDependentAnalyses() {
+        return super.getDependentAnalyses();
+    }
+}
index efbd8b43ae64cd10c9f0df58ed5488ee425661c8..fcba4aeeebb757e55c7469a40b9c6e7650a05f95 100644 (file)
@@ -8,13 +8,14 @@
  *******************************************************************************/
 package org.eclipse.tracecompass.analysis.timing.core.segmentstore.statistics;
 
-import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
-
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.analysis.timing.core.segmentstore.ISegmentStoreProvider;
 import org.eclipse.tracecompass.segmentstore.core.ISegment;
@@ -22,6 +23,7 @@ import org.eclipse.tracecompass.segmentstore.core.ISegmentStore;
 import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 
 import com.google.common.collect.ImmutableList;
@@ -37,7 +39,7 @@ public abstract class AbstractSegmentStatisticsAnalysis extends TmfAbstractAnaly
 
     private @Nullable SegmentStoreStatistics fTotalStats;
 
-    private @Nullable Map<String, SegmentStoreStatistics> fPerSegmentTypeStats;
+    private Map<String, SegmentStoreStatistics> fPerSegmentTypeStats = new HashMap<>();
 
     @Override
     protected Iterable<IAnalysisModule> getDependentAnalyses() {
@@ -54,52 +56,130 @@ public abstract class AbstractSegmentStatisticsAnalysis extends TmfAbstractAnaly
 
     @Override
     protected boolean executeAnalysis(IProgressMonitor monitor) throws TmfAnalysisException {
-        IAnalysisModule segmentStoreProviderModule = fSegmentStoreProviderModule;
-        ITmfTrace trace = getTrace();
-        if (!(segmentStoreProviderModule instanceof ISegmentStoreProvider) || (trace == null)) {
+        if (monitor.isCanceled()) {
+            return false;
+        }
+        @Nullable SegmentStoreStatistics totalStats = getTotalStats(TmfTimeRange.ETERNITY.getStartTime().toNanos(), TmfTimeRange.ETERNITY.getEndTime().toNanos(), monitor);
+        if (totalStats == null) {
             return false;
         }
-        segmentStoreProviderModule.waitForCompletion();
 
-        ISegmentStore<ISegment> segStore = ((ISegmentStoreProvider) segmentStoreProviderModule).getSegmentStore();
+        @Nullable Map<@NonNull String, @NonNull SegmentStoreStatistics> perTypeStats = getPerTypeStats(TmfTimeRange.ETERNITY.getStartTime().toNanos(), TmfTimeRange.ETERNITY.getEndTime().toNanos(), monitor);
+        if (perTypeStats == null) {
+            return false;
+        }
+        fTotalStats = totalStats;
+        fPerSegmentTypeStats = perTypeStats;
+        return true;
+    }
 
-        if (segStore != null) {
+    private @Nullable SegmentStoreStatistics getTotalStats(long start, long end , IProgressMonitor monitor) {
+        Collection<@NonNull ISegment> store = getSegmentStore(start, end);
+        if (store == null) {
+            return null;
+        }
+        if (monitor.isCanceled()) {
+            return null;
+        }
+        return calculateTotalManual(store, monitor);
+    }
 
-            boolean result = calculateTotalManual(segStore, monitor);
+    /**
+     * Get the total statistics for a specific range. If the range start is
+     * TmfTimeRange.ETERNITY.getStartTime().toNanos() and the range end is
+     * TmfTimeRange.ETERNITY.getEndTime().toNanos(), it will return the
+     * statistics for the whole trace.
+     *
+     * @param start
+     *            The start time of the range
+     * @param end
+     *            The end time of the range
+     * @param monitor
+     *            The progress monitor
+     * @return The total statistics, or null if segment store is not valid or if
+     *         the request is canceled
+     * @since 1.2
+     */
+    public @Nullable SegmentStoreStatistics getTotalStatsForRange(long start, long end, IProgressMonitor monitor) {
+        @Nullable ITmfTrace trace = getTrace();
+        if (trace != null && (start == TmfTimeRange.ETERNITY.getStartTime().toNanos() && end == TmfTimeRange.ETERNITY.getEndTime().toNanos())) {
+            waitForCompletion();
+            return getTotalStats();
+        }
+        return getTotalStats(start, end, monitor);
+    }
 
-            if (!result) {
-                return false;
-            }
+    private @Nullable Map<@NonNull String, @NonNull SegmentStoreStatistics> getPerTypeStats(long start, long end , IProgressMonitor monitor) {
+        Collection<@NonNull ISegment> store = getSegmentStore(start, end);
+        if (monitor.isCanceled()) {
+            return Collections.EMPTY_MAP;
+        }
+        return calculateTotalPerType(store, monitor);
+    }
 
-            result = calculateTotalPerType(segStore, monitor);
-            if (!result) {
-                return false;
-            }
+    /**
+     * Get the per segment type statistics for a specific range. If the range
+     * start is TmfTimeRange.ETERNITY.getStartTime().toNanos() and the range end
+     * is TmfTimeRange.ETERNITY.getEndTime().toNanos(), it will return the
+     * statistics for the whole trace.
+     *
+     * @param start
+     *            The start time of the range
+     * @param end
+     *            The end time of the range
+     * @param monitor
+     *            The progress monitor
+     * @return The per segment type statistics, or null if segment store is not
+     *         valid or if the request is canceled
+     * @since 1.2
+     */
+    public @Nullable Map<@NonNull String, @NonNull SegmentStoreStatistics> getPerSegmentTypeStatsForRange(long start, long end, IProgressMonitor monitor) {
+        @Nullable ITmfTrace trace = getTrace();
+        if (trace != null && (start == TmfTimeRange.ETERNITY.getStartTime().toNanos() && end == TmfTimeRange.ETERNITY.getEndTime().toNanos())) {
+            waitForCompletion();
+            return getPerSegmentTypeStats();
         }
-        return true;
+        return getPerTypeStats(start, end, monitor);
     }
 
-    private boolean calculateTotalManual(ISegmentStore<ISegment> store, IProgressMonitor monitor) {
+    /**
+     * Get the segment store from which we want the statistics
+     *
+     * @return The segment store
+     */
+    private @Nullable Collection<@NonNull ISegment> getSegmentStore(long start, long end) {
+        IAnalysisModule segmentStoreProviderModule = fSegmentStoreProviderModule;
+        if (!(segmentStoreProviderModule instanceof ISegmentStoreProvider)) {
+            return null;
+        }
+        segmentStoreProviderModule.waitForCompletion();
+
+        @Nullable ISegmentStore<@NonNull ISegment> segmentStore = ((ISegmentStoreProvider) segmentStoreProviderModule).getSegmentStore();
+        return segmentStore != null ?
+                    start != TmfTimeRange.ETERNITY.getStartTime().toNanos() || end != TmfTimeRange.ETERNITY.getEndTime().toNanos() ? (Collection<@NonNull ISegment>) segmentStore.getIntersectingElements(start, end) : segmentStore
+                    : Collections.EMPTY_LIST;
+    }
+
+    private static @Nullable SegmentStoreStatistics calculateTotalManual(Collection<@NonNull ISegment> segments, IProgressMonitor monitor) {
         SegmentStoreStatistics total = new SegmentStoreStatistics();
-        Iterator<ISegment> iter = store.iterator();
+        Iterator<@NonNull ISegment> iter = segments.iterator();
         while (iter.hasNext()) {
             if (monitor.isCanceled()) {
-                return false;
+                return null;
             }
-            ISegment segment = iter.next();
-            total.update(checkNotNull(segment));
+            @NonNull ISegment segment = iter.next();
+            total.update(segment);
         }
-        fTotalStats = total;
-        return true;
+        return total;
     }
 
-    private boolean calculateTotalPerType(ISegmentStore<ISegment> store, IProgressMonitor monitor) {
+    private Map<@NonNull String, @NonNull SegmentStoreStatistics> calculateTotalPerType(Collection<ISegment> segments, IProgressMonitor monitor) {
         Map<String, SegmentStoreStatistics> perSegmentTypeStats = new HashMap<>();
 
-        Iterator<ISegment> iter = store.iterator();
+        Iterator<ISegment> iter = segments.iterator();
         while (iter.hasNext()) {
             if (monitor.isCanceled()) {
-                return false;
+                return Collections.EMPTY_MAP;
             }
             ISegment segment = iter.next();
             String segmentType = getSegmentType(segment);
@@ -112,8 +192,7 @@ public abstract class AbstractSegmentStatisticsAnalysis extends TmfAbstractAnaly
                 perSegmentTypeStats.put(segmentType, values);
             }
         }
-        fPerSegmentTypeStats = perSegmentTypeStats;
-        return true;
+        return perSegmentTypeStats;
     }
 
     /**
index 5bb0544cf0529cb2a1d124d4250f50803f4b891d..4bf0f3a4608c89fb429a2e16678418112d99aa1c 100644 (file)
@@ -19,6 +19,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IAction;
@@ -40,6 +43,8 @@ import org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.s
 import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractTmfTreeViewer;
@@ -59,8 +64,7 @@ public abstract class AbstractSegmentStoreStatisticsViewer extends AbstractTmfTr
 
     private static final Format FORMATTER = new SubSecondTimeWithUnitFormat();
 
-    @Nullable
-    private TmfAbstractAnalysisModule fModule;
+    private @Nullable TmfAbstractAnalysisModule fModule;
     private MenuManager fTablePopupMenuManager;
 
     private static final String[] COLUMN_NAMES = new String[] {
@@ -322,6 +326,7 @@ public abstract class AbstractSegmentStoreStatisticsViewer extends AbstractTmfTr
                     long start = segment.getEntry().getMinSegment().getStart();
                     long end = segment.getEntry().getMinSegment().getEnd();
                     broadcast(new TmfSelectionRangeUpdatedSignal(AbstractSegmentStoreStatisticsViewer.this, TmfTimestamp.fromNanos(start), TmfTimestamp.fromNanos(end)));
+                    updateContent(start, end, true);
                 }
             };
 
@@ -331,6 +336,7 @@ public abstract class AbstractSegmentStoreStatisticsViewer extends AbstractTmfTr
                     long start = segment.getEntry().getMaxSegment().getStart();
                     long end = segment.getEntry().getMaxSegment().getEnd();
                     broadcast(new TmfSelectionRangeUpdatedSignal(AbstractSegmentStoreStatisticsViewer.this, TmfTimestamp.fromNanos(start), TmfTimestamp.fromNanos(end)));
+                    updateContent(start, end, true);
                 }
             };
 
@@ -387,9 +393,6 @@ public abstract class AbstractSegmentStoreStatisticsViewer extends AbstractTmfTr
 
     @Override
     protected @Nullable ITmfTreeViewerEntry updateElements(long start, long end, boolean isSelection) {
-        if (isSelection || (start == end)) {
-            return null;
-        }
 
         TmfAbstractAnalysisModule analysisModule = getStatisticsAnalysisModule();
 
@@ -402,24 +405,41 @@ public abstract class AbstractSegmentStoreStatisticsViewer extends AbstractTmfTr
         module.waitForCompletion();
 
         TmfTreeViewerEntry root = new TmfTreeViewerEntry(""); //$NON-NLS-1$
-        final SegmentStoreStatistics entry = module.getTotalStats();
-        if (entry != null) {
+        List<ITmfTreeViewerEntry> entryList = root.getChildren();
 
-            List<ITmfTreeViewerEntry> entryList = root.getChildren();
+        if (isSelection) {
+            setStats(start, end, entryList, module, true, new NullProgressMonitor());
+        }
+        setStats(start, end, entryList, module, false, new NullProgressMonitor());
+        return root;
+    }
+
+    private void setStats(long start, long end, List<ITmfTreeViewerEntry> entryList, AbstractSegmentStatisticsAnalysis module, boolean isSelection, IProgressMonitor monitor) {
+        String label = isSelection ? getSelectionLabel() : getTotalLabel();
+        final SegmentStoreStatistics entry = isSelection ? module.getTotalStatsForRange(start, end, monitor) : module.getTotalStats();
+        if (entry != null) {
 
-            TmfTreeViewerEntry aggregateEntry = new SegmentStoreStatisticsEntry(getTotalLabel(), entry);
-            entryList.add(aggregateEntry);
-            HiddenTreeViewerEntry category = new HiddenTreeViewerEntry(getTypeLabel());
-            aggregateEntry.addChild(category);
+            if (entry.getNbSegments() == 0) {
+                return;
+            }
+            TmfTreeViewerEntry child = new SegmentStoreStatisticsEntry(checkNotNull(label), entry);
+            entryList.add(child);
 
-            Map<String, SegmentStoreStatistics> perSegmentStats = module.getPerSegmentTypeStats();
-            if (perSegmentStats != null) {
-                for (Entry<String, SegmentStoreStatistics> statsEntry : perSegmentStats.entrySet()) {
-                    category.addChild(new SegmentStoreStatisticsEntry(statsEntry.getKey(), statsEntry.getValue()));
+            final Map<@NonNull String, @NonNull SegmentStoreStatistics> perTypeStats = isSelection? module.getPerSegmentTypeStatsForRange(start, end, monitor) : module.getPerSegmentTypeStats();
+            if (perTypeStats != null) {
+                for (Entry<@NonNull String, @NonNull SegmentStoreStatistics> statsEntry : perTypeStats.entrySet()) {
+                    child.addChild(new SegmentStoreStatisticsEntry(statsEntry.getKey(), statsEntry.getValue()));
                 }
             }
         }
-        return root;
+    }
+
+    @Override
+    @TmfSignalHandler
+    public void windowRangeUpdated(@Nullable TmfWindowRangeUpdatedSignal signal) {
+        // Do nothing. We do not want to update the view and lose the selection
+        // if the window range is updated with current selection outside of this
+        // new range.
     }
 
     /**
@@ -442,6 +462,16 @@ public abstract class AbstractSegmentStoreStatisticsViewer extends AbstractTmfTr
         return checkNotNull(Messages.AbstractSegmentStoreStatisticsViewer_total);
     }
 
+    /**
+     * Get the selection column label
+     *
+     * @return The selection column label
+     * @since 1.2
+     */
+    protected String getSelectionLabel() {
+        return checkNotNull(Messages.AbstractSegmentStoreStatisticsViewer_selection);
+    }
+
     /**
      * Class to define a level in the tree that doesn't have any values.
      */
index 2e4579e7cf04d2cf639b24bc99cd50f07b17dcc4..0458bee907367466532c1c8699d4af4a78e83385 100644 (file)
@@ -22,6 +22,8 @@ public class Messages extends NLS {
 
     private static final String BUNDLE_NAME = "org.eclipse.tracecompass.internal.analysis.timing.ui.views.segmentstore.statistics.messages"; //$NON-NLS-1$
 
+    /** Default "selection" label in statistics viewer */
+    public static String AbstractSegmentStoreStatisticsViewer_selection;
     /** Default "total" label in statistics viewer */
     public static String AbstractSegmentStoreStatisticsViewer_total;
     /** Default "category" label in statistics viewer */
index 73a47d34ca2ba19d8f82d2ca4c6998f79f63cff5..e6924cbfbc9e9e06b0281ab7284c7c0ae4e931f4 100644 (file)
@@ -9,6 +9,7 @@
 # Contributors:
 #     Bernd Hufmann - Initial API and implementation
 ###############################################################################
+AbstractSegmentStoreStatisticsViewer_selection=Selection
 AbstractSegmentStoreStatisticsViewer_total=Total
 AbstractSegmentStoreStatisticsViewer_types=Types
 SegmentStoreStatistics_LevelLabel=Level
index e7f28ff4f4ba343fa9914b149a5927c59df52203..af595419c838e1d081581a434b89a8b072cea2d3 100644 (file)
@@ -22,6 +22,8 @@ import java.io.InputStream;
 import java.net.URL;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Optional;
+import java.util.stream.StreamSupport;
 
 import javax.xml.XMLConstants;
 import javax.xml.transform.Source;
@@ -36,18 +38,20 @@ import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.jdt.annotation.DefaultLocation;
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.tracecompass.internal.tmf.core.Activator;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEventType;
 import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
 import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
 import org.eclipse.tracecompass.tmf.core.event.TmfEventType;
-import org.eclipse.tracecompass.tmf.core.event.aspect.TmfBaseAspects;
 import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
+import org.eclipse.tracecompass.tmf.core.event.aspect.TmfBaseAspects;
 import org.eclipse.tracecompass.tmf.core.event.aspect.TmfContentFieldAspect;
 import org.eclipse.tracecompass.tmf.core.event.aspect.TmfCpuAspect;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
@@ -67,6 +71,7 @@ import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation;
 import org.xml.sax.SAXException;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
 
 /**
  * An XML development trace using a custom XML trace definition and schema.
@@ -106,6 +111,7 @@ public class TmfXmlTraceStub extends TmfTrace {
 
     private Collection<ITmfEventAspect<?>> fAspects = TmfTrace.BASE_ASPECTS;
     private final Collection<ITmfEventAspect<?>> fAdditionalAspects = new HashSet<>();
+    private final Collection<IAnalysisModule> fAdditionalModules = new HashSet<>();
 
     /**
      * Validate and initialize a {@link TmfXmlTraceStub} object
@@ -402,4 +408,26 @@ public class TmfXmlTraceStub extends TmfTrace {
         fAdditionalAspects.add(aspect);
     }
 
+    /**
+     * Add an additional new module
+     *
+     * @param module
+     *            The new module
+     */
+    public void addAnalysisModule(IAnalysisModule module) {
+        fAdditionalModules.add(module);
+    }
+
+    @Override
+    public Iterable<@NonNull IAnalysisModule> getAnalysisModules() {
+        @NonNull Iterable<IAnalysisModule> modules = super.getAnalysisModules();
+        return checkNotNull(Iterables.concat(modules, fAdditionalModules));
+    }
+
+    @Override
+    public @Nullable IAnalysisModule getAnalysisModule(@Nullable String analysisId) {
+        Iterable<@NonNull IAnalysisModule> modules = getAnalysisModules();
+        Optional<IAnalysisModule> opt = StreamSupport.stream(modules.spliterator(), false).filter(analysis -> analysis.getId().equals(analysisId)).findFirst();
+        return opt.isPresent() ? opt.get() : null;
+    }
 }
This page took 0.036595 seconds and 5 git commands to generate.