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