analysis: bug 494786. Clear process selection when switching trace
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.os.linux.ui / src / org / eclipse / tracecompass / internal / analysis / os / linux / ui / views / kernelmemoryusage / KernelMemoryUsageTreeViewer.java
1 /**********************************************************************
2 * Copyright (c) 2016 Polytechnique de Montréal
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 **********************************************************************/
9 package org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.kernelmemoryusage;
10
11 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
12
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18
19 import org.eclipse.jface.viewers.Viewer;
20 import org.eclipse.jface.viewers.ViewerComparator;
21 import org.eclipse.swt.widgets.Composite;
22 import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
23 import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelThreadInformationProvider;
24 import org.eclipse.tracecompass.analysis.os.linux.core.kernelmemoryusage.KernelMemoryAnalysisModule;
25 import org.eclipse.tracecompass.analysis.os.linux.core.kernelmemoryusage.KernelMemoryStateProvider;
26 import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Activator;
27 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
28 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
29 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
30 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
31 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
32 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal;
33 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
34 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
35 import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractTmfTreeViewer;
36 import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider;
37 import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeViewerEntry;
38 import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeColumnData;
39 import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeViewerEntry;
40
41 /**
42 * Tree viewer to select which process to display in the kernel memory usage
43 * chart.
44 *
45 * @author Mahdi Zolnouri
46 * @author Wassim Nasrallah
47 * @author Najib Arbaoui
48 */
49 public class KernelMemoryUsageTreeViewer extends AbstractTmfTreeViewer {
50
51 private KernelMemoryAnalysisModule fModule = null;
52 private String fSelectedThread = null;
53 private static final String[] COLUMN_NAMES = new String[] {
54 Messages.KernelMemoryUsageComposite_ColumnTID,
55 Messages.KernelMemoryUsageComposite_ColumnProcess
56 };
57
58 /* A map that saves the mapping of a thread ID to its executable name */
59 private final Map<String, String> fProcessNameMap = new HashMap<>();
60
61 /** Provides label for the Kernel memory usage tree viewer cells */
62 protected static class KernelMemoryLabelProvider extends TreeLabelProvider {
63
64 @Override
65 public String getColumnText(Object element, int columnIndex) {
66 KernelMemoryUsageEntry obj = (KernelMemoryUsageEntry) element;
67 if (columnIndex == 0) {
68 return obj.getTid();
69 } else if (columnIndex == 1) {
70 return obj.getProcessName();
71 }
72 return element.toString();
73 }
74 }
75
76 /**
77 * Constructor
78 *
79 * @param parent
80 * The parent composite that holds this viewer
81 */
82 public KernelMemoryUsageTreeViewer(Composite parent) {
83 super(parent, false);
84 setLabelProvider(new KernelMemoryLabelProvider());
85 }
86
87 @Override
88 protected ITmfTreeColumnDataProvider getColumnDataProvider() {
89 return new ITmfTreeColumnDataProvider() {
90
91 @Override
92 public List<TmfTreeColumnData> getColumnData() {
93 /* All columns are sortable */
94 List<TmfTreeColumnData> columns = new ArrayList<>();
95 TmfTreeColumnData column = new TmfTreeColumnData(COLUMN_NAMES[0]);
96 column.setComparator(new ViewerComparator() {
97 @Override
98 public int compare(Viewer viewer, Object e1, Object e2) {
99 KernelMemoryUsageEntry n1 = (KernelMemoryUsageEntry) e1;
100 KernelMemoryUsageEntry n2 = (KernelMemoryUsageEntry) e2;
101
102 return n1.getTid().compareTo(n2.getTid());
103 }
104 });
105 columns.add(column);
106 column = new TmfTreeColumnData(COLUMN_NAMES[1]);
107 column.setComparator(new ViewerComparator() {
108 @Override
109 public int compare(Viewer viewer, Object e1, Object e2) {
110 KernelMemoryUsageEntry n1 = (KernelMemoryUsageEntry) e1;
111 KernelMemoryUsageEntry n2 = (KernelMemoryUsageEntry) e2;
112
113 return n1.getProcessName().compareTo(n2.getProcessName());
114 }
115 });
116 columns.add(column);
117 return columns;
118 }
119 };
120 }
121
122 // ------------------------------------------------------------------------
123 // Operations
124 // ------------------------------------------------------------------------
125
126 @Override
127 protected void contentChanged(ITmfTreeViewerEntry rootEntry) {
128 String selectedThread = fSelectedThread;
129 if (selectedThread != null) {
130 /* Find the selected thread among the inputs */
131 for (ITmfTreeViewerEntry entry : rootEntry.getChildren()) {
132 if (entry instanceof KernelMemoryUsageEntry) {
133 if (selectedThread.equals(((KernelMemoryUsageEntry) entry).getTid())) {
134 List<ITmfTreeViewerEntry> list = Collections.singletonList(entry);
135 super.setSelection(list);
136 return;
137 }
138 }
139 }
140 }
141 }
142
143 @Override
144 public void initializeDataSource() {
145 /* Should not be called while trace is still null */
146 ITmfTrace trace = checkNotNull(getTrace());
147
148 fModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelMemoryAnalysisModule.class, KernelMemoryAnalysisModule.ID);
149 if (fModule == null) {
150 return;
151 }
152 fModule.schedule();
153 fModule.waitForInitialization();
154 fProcessNameMap.clear();
155 }
156
157 @Override
158 protected ITmfTreeViewerEntry updateElements(long start, long end, boolean isSelection) {
159 if (isSelection || (start == end)) {
160 return null;
161 }
162 KernelMemoryAnalysisModule module = fModule;
163 if (getTrace() == null || module == null) {
164 return null;
165 }
166 module.waitForInitialization();
167 ITmfStateSystem ss = module.getStateSystem();
168 if (ss == null) {
169 return null;
170 }
171 ss.waitUntilBuilt();
172 TmfTreeViewerEntry root = new TmfTreeViewerEntry(""); //$NON-NLS-1$
173 List<ITmfTreeViewerEntry> entryList = root.getChildren();
174
175 try {
176 long newStart = Math.max(start, ss.getStartTime());
177 long newEnd = Math.min(end, ss.getCurrentEndTime());
178 if (ss.getStartTime() > newEnd || ss.getCurrentEndTime() < start) {
179 return root;
180 }
181 List<ITmfStateInterval> memoryStates = ss.queryFullState(newStart);
182 List<Integer> threadQuarkList = ss.getSubAttributes(ITmfStateSystem.ROOT_ATTRIBUTE, false);
183
184 for (Integer threadQuark : threadQuarkList) {
185 ITmfStateInterval threadMemoryInterval = memoryStates.get(threadQuark);
186 if (threadMemoryInterval.getEndTime() < end) {
187 String tid = ss.getAttributeName(threadQuark);
188 String procname = getProcessName(tid);
189 KernelMemoryUsageEntry obj = new KernelMemoryUsageEntry(tid, procname);
190 entryList.add(obj);
191 }
192 }
193 } catch (StateSystemDisposedException e) {
194 Activator.getDefault().logError(e.getMessage(), e);
195 }
196 return root;
197 }
198
199 /*
200 * Get the process name from its TID by using the LTTng kernel analysis
201 * module
202 */
203 private String getProcessName(String tid) {
204 String execName = fProcessNameMap.get(tid);
205 if (execName != null) {
206 return execName;
207 }
208 if (tid.equals(KernelMemoryStateProvider.OTHER_TID)) {
209 fProcessNameMap.put(tid, tid);
210 return tid;
211 }
212 ITmfTrace trace = checkNotNull(getTrace());
213 KernelAnalysisModule kernelModule = TmfTraceUtils.getAnalysisModuleOfClass(trace, KernelAnalysisModule.class, KernelAnalysisModule.ID);
214 if (kernelModule == null) {
215 return tid;
216 }
217 execName = KernelThreadInformationProvider.getExecutableName(kernelModule, Integer.parseInt(tid));
218 if (execName == null) {
219 return tid;
220 }
221 fProcessNameMap.put(tid, execName);
222 return execName;
223 }
224
225 /**
226 * Set the currently selected thread ID
227 *
228 * @param tid
229 * The selected thread ID
230 */
231 public void setSelectedThread(String tid) {
232 fSelectedThread = tid;
233 }
234
235 @Override
236 @TmfSignalHandler
237 public void traceSelected(TmfTraceSelectedSignal signal) {
238 setSelectedThread(null);
239 super.traceSelected(signal);
240 }
241
242 @Override
243 @TmfSignalHandler
244 public void traceOpened(TmfTraceOpenedSignal signal) {
245 setSelectedThread(null);
246 super.traceOpened(signal);
247 }
248 }
This page took 0.039248 seconds and 5 git commands to generate.