analysis: Keep thread selection and follow CPU when switching traces
authorJean-Christian Kouame <jean-christian.kouame@ericsson.com>
Mon, 13 Jun 2016 17:24:43 +0000 (13:24 -0400)
committerJean-Christian Kouame <jean-christian.kouame@ericsson.com>
Thu, 23 Jun 2016 21:21:33 +0000 (17:21 -0400)
Keep thread selection and follow CPU when switching traces in CPU Usage
View. The data is saved in a map in the trace context, so if the view
is closed, it will remember the thread selection and the followed CPU
for each trace when reopening.

Change-Id: I8c56d852a133d0615f58cdb3e8e6b965a7c2f73d
Signed-off-by: Jean-Christian Kouame <jean-christian.kouame@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/75600
Reviewed-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Tested-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageComposite.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageView.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/cpuusage/CpuUsageXYViewer.java
analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/resources/ResourcesView.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceContext.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceManager.java

index aa3fed88f1706f78220021182a1057e82c6860b0..429d26364f29837a067f108a7d212b3339a005f8 100644 (file)
@@ -43,6 +43,8 @@ import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
 import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
 import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractTmfTreeViewer;
 import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider;
@@ -372,15 +374,39 @@ public class CpuUsageComposite extends AbstractTmfTreeViewer {
     @Override
     @TmfSignalHandler
     public void traceSelected(TmfTraceSelectedSignal signal) {
-        setSelectedThread(null);
+        initSelection();
+        initCPU();
         super.traceSelected(signal);
     }
 
     @Override
     @TmfSignalHandler
     public void traceOpened(TmfTraceOpenedSignal signal) {
-        setSelectedThread(null);
+        initSelection();
+        initCPU();
         super.traceOpened(signal);
     }
 
+    private void initSelection() {
+        TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
+        String thread = (String) ctx.getData(CpuUsageView.CPU_USAGE_SELECTED_THREAD);
+        setSelectedThread(thread);
+    }
+
+    private void initCPU() {
+        clearCpu();
+        TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
+        Object data =  ctx.getData(CpuUsageView.CPU_USAGE_FOLLOW_CPU);
+        if (data instanceof Set<?>) {
+            Set<?> set = (Set<?>) data;
+            for (Object coreObject : set) {
+                if (coreObject instanceof Integer) {
+                    Integer core = (Integer) coreObject;
+                    if (core >= 0) {
+                        addCpu(core);
+                    }
+                }
+            }
+        }
+    }
 }
index 1ce79b12111e077643ce8e51372107eece5b6976..d1ac399c17cddaa832b88e26cb4374d635279dcd 100644 (file)
 
 package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.cpuusage;
 
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionChangedListener;
@@ -21,14 +27,19 @@ import org.eclipse.swt.events.ControlAdapter;
 import org.eclipse.swt.events.ControlEvent;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.tracecompass.analysis.os.linux.core.signals.TmfCpuSelectedSignal;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Activator;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.ui.viewers.TmfViewer;
 import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.TmfXYChartViewer;
 import org.eclipse.tracecompass.tmf.ui.views.TmfChartView;
 
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
 /**
  * CPU usage view. It contains 2 viewers: one tree viewer showing all the
  * threads who were on the CPU in the time range, and one XY chart viewer
@@ -42,6 +53,12 @@ public class CpuUsageView extends TmfChartView {
     /** ID string */
     public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.views.cpuusage"; //$NON-NLS-1$
 
+    /** ID of the selected thread in the map of data in {@link TmfTraceContext} */
+    public static final @NonNull String CPU_USAGE_SELECTED_THREAD = ID + ".CPU_USAGE_SELECTED_TRHEAD"; //$NON-NLS-1$
+
+    /** ID of the followed CPU in the map data in {@link TmfTraceContext} */
+    public static final @NonNull String CPU_USAGE_FOLLOW_CPU = ID + ".FOLLOW_CPU"; //$NON-NLS-1$
+
     private @Nullable CpuUsageComposite fTreeViewer = null;
     private @Nullable CpuUsageXYViewer fXYViewer = null;
 
@@ -96,6 +113,7 @@ public class CpuUsageView extends TmfChartView {
                         if (fXYViewer != null) {
                             fXYViewer.setSelectedThread(Long.valueOf(entry.getTid()));
                         }
+                        saveData(CPU_USAGE_SELECTED_THREAD, entry.getTid());
                     }
                 }
             }
@@ -112,6 +130,19 @@ public class CpuUsageView extends TmfChartView {
         return fTreeViewer;
     }
 
+    /**
+     * Save a data in the data map of {@link TmfTraceContext}
+     */
+    private static void saveData(@NonNull String key, Object data) {
+        TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
+        ctx.setData(key, checkNotNull(data));
+    }
+
+    private static Object getData(@NonNull String key) {
+        TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
+        return ctx.getData(key);
+    }
+
     @Override
     public void setFocus() {
         if (fXYViewer != null) {
@@ -131,13 +162,29 @@ public class CpuUsageView extends TmfChartView {
         final @Nullable CpuUsageXYViewer xyViewer = fXYViewer;
         final @Nullable CpuUsageComposite treeViewer = fTreeViewer;
         if (xyViewer != null && treeViewer != null) {
-            int core = signal.getCore();
-            if (core >= 0) {
-                xyViewer.addCpu(core);
-                treeViewer.addCpu(core);
+            Object data = getData(CPU_USAGE_FOLLOW_CPU);
+            if (data == null) {
+                data = new TreeSet<Integer>();
+            }
+            if (data instanceof Set<?>) {
+                Set<?> set = (Set<?>) data;
+                int core = signal.getCore();
+                if (core >= 0) {
+                    xyViewer.addCpu(core);
+                    treeViewer.addCpu(core);
+                    if (Iterables.all(set, Predicates.instanceOf(Integer.class))) {
+                        @SuppressWarnings("unchecked")
+                        Set<Integer> intSet = (Set<Integer>) set;
+                        intSet.add(core);
+                    }
+                } else {
+                    xyViewer.clearCpu();
+                    treeViewer.clearCpu();
+                    ((Set<?>) data).clear();
+                }
+                saveData(CPU_USAGE_FOLLOW_CPU, data);
             } else {
-                xyViewer.clearCpu();
-                treeViewer.clearCpu();
+                Activator.getDefault().logError("The followed cores should have been store in a Set"); //$NON-NLS-1$
             }
         }
     }
index 4ec23effaba6d7332c83145f81490da78bc61540..e7b9b8fe73b3a31613e9e7cc183b3d313fe5e6ea 100644 (file)
@@ -33,6 +33,8 @@ import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
 import org.eclipse.tracecompass.tmf.ui.viewers.xycharts.linecharts.TmfCommonXLineChartViewer;
 
@@ -293,15 +295,39 @@ public class CpuUsageXYViewer extends TmfCommonXLineChartViewer {
     @Override
     @TmfSignalHandler
     public void traceSelected(TmfTraceSelectedSignal signal) {
-        setSelectedThread(NOT_SELECTED);
+        initSelection();
+        initCPU();
         super.traceSelected(signal);
     }
 
     @Override
     @TmfSignalHandler
     public void traceOpened(TmfTraceOpenedSignal signal) {
-        setSelectedThread(NOT_SELECTED);
+        initSelection();
+        initCPU();
         super.traceOpened(signal);
     }
 
+    private void initSelection() {
+        TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
+        String data = (String) ctx.getData(CpuUsageView.CPU_USAGE_SELECTED_THREAD);
+        long thread = data != null ? Long.valueOf(data) : NOT_SELECTED;
+        setSelectedThread(thread);
+    }
+
+    private void initCPU() {
+        clearCpu();
+        TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
+        Object data =  ctx.getData(CpuUsageView.CPU_USAGE_FOLLOW_CPU);
+        if (data instanceof Set<?>) {
+            Set<?> set = (Set<?>) data;
+            for (Object coreObject : set) {
+                Integer core = (Integer) coreObject;
+                if (core != null && core >= 0) {
+                    addCpu(core);
+                }
+            }
+        }
+    }
+
 }
index b33a600637e0dbd6b62cc4276299502ffac3aeae..7a24ddc67ba03930b5d4e7d29ca2b265063a7147 100644 (file)
@@ -41,6 +41,8 @@ import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
 import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractStateSystemTimeGraphView;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
@@ -58,12 +60,13 @@ public class ResourcesView extends AbstractStateSystemTimeGraphView {
     /** View ID. */
     public static final String ID = "org.eclipse.tracecompass.analysis.os.linux.views.resources"; //$NON-NLS-1$
 
+    /** ID of the followed CPU in the map data in {@link TmfTraceContext} */
+    public static final @NonNull String RESOURCES_FOLLOW_CPU = ID + ".FOLLOW_CPU"; //$NON-NLS-1$
+
     private static final String[] FILTER_COLUMN_NAMES = new String[] {
             Messages.ResourcesView_stateTypeName
     };
 
-    private int fCurrentCpu = -1;
-
     // Timeout between updates in the build thread in ms
     private static final long BUILD_UPDATE_TIMEOUT = 500;
 
@@ -108,7 +111,10 @@ public class ResourcesView extends AbstractStateSystemTimeGraphView {
             if (sSel.getFirstElement() instanceof ResourcesEntry) {
                 ResourcesEntry resourcesEntry = (ResourcesEntry) sSel.getFirstElement();
                 if (resourcesEntry.getType().equals(ResourcesEntry.Type.CPU)) {
-                    if (fCurrentCpu >= 0) {
+                    TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
+                    Integer data = (Integer) ctx.getData(RESOURCES_FOLLOW_CPU);
+                    int cpu = data != null ? data.intValue() : -1;
+                    if (cpu >= 0) {
                         menuManager.add(new UnfollowCpuAction(ResourcesView.this, resourcesEntry.getId(), resourcesEntry.getTrace()));
                     } else {
                         menuManager.add(new FollowCpuAction(ResourcesView.this, resourcesEntry.getId(), resourcesEntry.getTrace()));
@@ -440,11 +446,9 @@ public class ResourcesView extends AbstractStateSystemTimeGraphView {
      */
     @TmfSignalHandler
     public void listenToCpu(TmfCpuSelectedSignal signal) {
-        if (signal.getCore() >= 0) {
-            fCurrentCpu = signal.getCore();
-        } else {
-            fCurrentCpu = -1;
-        }
+        int data = signal.getCore() >= 0 ? signal.getCore() : -1;
+        TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
+        ctx.setData(RESOURCES_FOLLOW_CPU, data);
     }
 
 }
index a9ae5238746b0d5258cf0937448f2da22f9bbd99..f87a88501b4c6d447b9f508241ea9e704150cc16 100644 (file)
 
 package org.eclipse.tracecompass.tmf.core.trace;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.eclipse.core.resources.IFile;
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
 
+import com.google.common.collect.ImmutableMap;
+
 /**
  * Context of a trace, which is the representation of the "view" the user
  * currently has on this trace (window time range, selected time or time range).
@@ -42,6 +48,7 @@ public class TmfTraceContext implements ITraceContextSignalHandler {
     private final TmfTimeRange fWindowRange;
     private final @Nullable IFile fEditorFile;
     private final @Nullable ITmfFilter fFilter;
+    private final Map<@NonNull String, @NonNull Object> fData = new HashMap<>();
 
     /**
      * Build a new trace context.
@@ -61,6 +68,7 @@ public class TmfTraceContext implements ITraceContextSignalHandler {
         fWindowRange = windowRange;
         fEditorFile = editorFile;
         fFilter = filter;
+        fData.clear();
     }
 
     /**
@@ -99,6 +107,52 @@ public class TmfTraceContext implements ITraceContextSignalHandler {
         return fFilter;
     }
 
+    /**
+     * Store a data for the trace
+     *
+     * @param key
+     *            The id of the data
+     * @param value
+     *            The value of the data
+     * @since 2.1
+     */
+    public synchronized void setData(String key, Object value) {
+        fData.put(key, value);
+    }
+
+    /**
+     * Copy data into the data map
+     *
+     * @param data
+     *            The map of data to copy
+     * @since 2.1
+     */
+    public synchronized void setData(Map<String, Object> data) {
+        fData.putAll(data);
+    }
+
+    /**
+     * Get the data for the specific key
+     *
+     * @param key
+     *            The id of the data
+     * @return The data or null if the key do not exist
+     * @since 2.1
+     */
+    public synchronized @Nullable Object getData(String key) {
+        return fData.get(key);
+    }
+
+    /**
+     * Get a copy of the data map
+     *
+     * @return The data map copy
+     * @since 2.1
+     */
+    public synchronized Map<String, Object> getData() {
+        return ImmutableMap.copyOf(fData);
+    }
+
     @Override
     public String toString() {
         return getClass().getSimpleName() + "[fSelection=" + fSelection + //$NON-NLS-1$
index e819d31b119cf2e24bb6d50e7dba7824d52c904c..eb28f3e157ea961e0193ecf62740b364aeb22976 100644 (file)
@@ -37,11 +37,11 @@ import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.tracecompass.internal.tmf.core.Activator;
 import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
 import org.eclipse.tracecompass.tmf.core.signal.TmfEventFilterAppliedSignal;
-import org.eclipse.tracecompass.tmf.core.signal.TmfTraceModelSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
+import org.eclipse.tracecompass.tmf.core.signal.TmfTraceModelSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
 import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
@@ -334,10 +334,12 @@ public final class TmfTraceManager {
         if (context == null) {
             throw new RuntimeException();
         }
-        fTraces.put(newTrace, newTrace.createTraceContext(context.getSelectionRange(),
+        final TmfTraceContext newContext = newTrace.createTraceContext(context.getSelectionRange(),
                 context.getWindowRange(),
                 context.getEditorFile(),
-                signal.getEventFilter()));
+                signal.getEventFilter());
+        newContext.setData(context.getData());
+        fTraces.put(newTrace, newContext);
     }
 
     /**
@@ -387,6 +389,7 @@ public final class TmfTraceManager {
                         prevCtx.getWindowRange(),
                         prevCtx.getEditorFile(),
                         prevCtx.getFilter());
+                newCtx.setData(prevCtx.getData());
                 entry.setValue(newCtx);
             }
         }
@@ -420,6 +423,7 @@ public final class TmfTraceManager {
             /* Keep the values from the old context, except for the window range */
             TmfTraceContext newCtx = trace.createTraceContext(prevCtx.getSelectionRange(),
                     newWindowTr, prevCtx.getEditorFile(), prevCtx.getFilter());
+            newCtx.setData(prevCtx.getData());
             entry.setValue(newCtx);
         }
     }
This page took 0.032699 seconds and 5 git commands to generate.