lttng: Add System Call Analysis benchmarks
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / statesystem / TmfStateSystemViewer.java
CommitLineData
17c73d10
GB
1/*******************************************************************************
2 * Copyright (c) 2014 École 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 * Contributors:
10 * Florian Wininger - Initial API and implementation
11 * Alexandre Montplaisir - Refactoring, performance tweaks
12 * Bernd Hufmann - Updated signal handling
13 * Marc-Andre Laperle - Add time zone preference
14 * Geneviève Bastien - Moved state system explorer to use the abstract tree viewer
7c246810 15 * Patrick Tasse - Refactoring
17c73d10
GB
16 *******************************************************************************/
17
2bdf0193 18package org.eclipse.tracecompass.tmf.ui.views.statesystem;
17c73d10
GB
19
20import java.util.ArrayList;
21import java.util.List;
22
23import org.eclipse.jdt.annotation.NonNull;
24import org.eclipse.jface.viewers.AbstractTreeViewer;
25import org.eclipse.jface.viewers.Viewer;
26import org.eclipse.jface.viewers.ViewerComparator;
17c73d10
GB
27import org.eclipse.swt.SWT;
28import org.eclipse.swt.graphics.Color;
29import org.eclipse.swt.widgets.Composite;
30import org.eclipse.swt.widgets.Display;
e894a508
AM
31import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
32import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
33import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
34import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
35import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
36import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
860b39d1 37import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
2bdf0193
AM
38import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
39import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal;
40import org.eclipse.tracecompass.tmf.core.statesystem.ITmfAnalysisModuleWithStateSystems;
2bdf0193
AM
41import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
42import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
43import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
21852dfa 44import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext;
2bdf0193
AM
45import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
46import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractTmfTreeViewer;
47import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider;
48import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeViewerEntry;
49import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeColumnData;
50import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeViewerEntry;
17c73d10
GB
51
52/**
53 * Displays the content of the state systems at the current time
54 *
55 * @author Florian Wininger
56 * @author Alexandre Montplaisir
57 * @author Geneviève Bastien
17c73d10
GB
58 */
59public class TmfStateSystemViewer extends AbstractTmfTreeViewer {
60
61 private static final String EMPTY_STRING = ""; //$NON-NLS-1$
17c73d10 62 private static final int DEFAULT_AUTOEXPAND = 2;
7c246810
PT
63 private boolean fFilterStatus = false;
64 private long fSelection = 0;
17c73d10
GB
65
66 /* Order of columns */
67 private static final int ATTRIBUTE_NAME_COL = 0;
68 private static final int QUARK_COL = 1;
69 private static final int VALUE_COL = 2;
70 private static final int TYPE_COL = 3;
71 private static final int START_TIME_COL = 4;
72 private static final int END_TIME_COL = 5;
73 private static final int ATTRIBUTE_FULLPATH_COL = 6;
74
75 /**
76 * Base class to provide the labels for the tree viewer. Views extending
77 * this class typically need to override the getColumnText method if they
78 * have more than one column to display
79 */
80 protected static class StateSystemTreeLabelProvider extends TreeLabelProvider {
81
82 @Override
83 public String getColumnText(Object element, int columnIndex) {
7c246810
PT
84 if (element instanceof StateEntry) {
85 StateEntry entry = (StateEntry) element;
17c73d10
GB
86 switch (columnIndex) {
87 case ATTRIBUTE_NAME_COL:
88 return entry.getName();
89 case QUARK_COL:
90 return String.valueOf(entry.getQuark());
91 case VALUE_COL:
92 return entry.getValue();
93 case TYPE_COL:
94 return entry.getType();
95 case START_TIME_COL:
96 return entry.getStartTime();
97 case END_TIME_COL:
98 return entry.getEndTime();
99 case ATTRIBUTE_FULLPATH_COL:
100 return entry.getFullPath();
101 default:
102 return EMPTY_STRING;
103 }
104 }
105 return super.getColumnText(element, columnIndex);
106 }
107
108 @Override
109 public Color getBackground(Object element, int columnIndex) {
7c246810
PT
110 if (element instanceof StateEntry) {
111 if (((StateEntry) element).isModified()) {
17c73d10
GB
112 return Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW);
113 }
114 }
115 return super.getBackground(element, columnIndex);
116 }
117 }
118
119 /**
120 * Constructor
121 *
122 * @param parent
123 * The parent containing this viewer
124 */
125 public TmfStateSystemViewer(Composite parent) {
126 super(parent, false);
127 this.setLabelProvider(new StateSystemTreeLabelProvider());
128 getTreeViewer().setAutoExpandLevel(DEFAULT_AUTOEXPAND);
129 }
130
131 @Override
132 protected ITmfTreeColumnDataProvider getColumnDataProvider() {
133 return new ITmfTreeColumnDataProvider() {
134
135 @Override
136 public List<TmfTreeColumnData> getColumnData() {
137 List<TmfTreeColumnData> columns = new ArrayList<>();
138 TmfTreeColumnData column = new TmfTreeColumnData(Messages.TreeNodeColumnLabel);
139 columns.add(column);
140 column.setComparator(new ViewerComparator() {
141 @Override
142 public int compare(Viewer viewer, Object e1, Object e2) {
143 TmfTreeViewerEntry n1 = (TmfTreeViewerEntry) e1;
144 TmfTreeViewerEntry n2 = (TmfTreeViewerEntry) e2;
145
146 return n1.getName().compareTo(n2.getName());
147 }
148 });
149 columns.add(new TmfTreeColumnData(Messages.QuarkColumnLabel));
150 columns.add(new TmfTreeColumnData(Messages.ValueColumnLabel));
151 columns.add(new TmfTreeColumnData(Messages.TypeColumnLabel));
152 columns.add(new TmfTreeColumnData(Messages.StartTimeColumLabel));
153 columns.add(new TmfTreeColumnData(Messages.EndTimeColumLabel));
154 columns.add(new TmfTreeColumnData(Messages.AttributePathColumnLabel));
155 return columns;
156 }
157
158 };
159 }
160
161 // ------------------------------------------------------------------------
162 // Operations
163 // ------------------------------------------------------------------------
164
165 @Override
59c8ff34 166 protected ITmfTreeViewerEntry updateElements(long start, long end, boolean selection) {
7c246810
PT
167
168 if (selection) {
169 fSelection = start;
170 } else {
21852dfa 171 TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext();
16801c72 172 fSelection = ctx.getSelectionRange().getStartTime().toNanos();
7c246810
PT
173 }
174
17c73d10
GB
175 if (getTrace() == null) {
176 return null;
177 }
178
59c8ff34 179 ITmfTreeViewerEntry root = getInput();
17c73d10 180
7c246810
PT
181 if (root == null) {
182 root = createRoot();
183 } else if (fFilterStatus) {
184 clearStateSystemEntries(root);
17c73d10
GB
185 }
186
187 /*
7c246810
PT
188 * Update the values of the elements of the state systems at the
189 * selection start time
17c73d10 190 */
7c246810 191 boolean changed = updateStateSystemEntries(root, fSelection);
17c73d10 192
7c246810 193 return selection || changed ? root : null;
17c73d10
GB
194 }
195
7c246810 196 private ITmfTreeViewerEntry createRoot() {
59c8ff34 197 // 'Fake' root node
7c246810 198 TmfTreeViewerEntry rootEntry = new TmfTreeViewerEntry("root"); //$NON-NLS-1$
59c8ff34 199
0f8687b4 200 for (final ITmfTrace trace : TmfTraceManager.getTraceSetWithExperiment(getTrace())) {
7c246810
PT
201 if (trace != null) {
202 rootEntry.addChild(createTraceEntry(trace));
17c73d10
GB
203 }
204 }
7c246810 205 return rootEntry;
17c73d10
GB
206 }
207
7c246810 208 private static TmfTreeViewerEntry createTraceEntry(ITmfTrace trace) {
17c73d10 209 TmfTreeViewerEntry traceEntry = new TmfTreeViewerEntry(trace.getName());
860b39d1
MK
210 Iterable<IAnalysisModule> modules = trace.getAnalysisModules();
211 for (IAnalysisModule module : modules) {
212 if (module instanceof ITmfAnalysisModuleWithStateSystems) {
213 ITmfAnalysisModuleWithStateSystems moduleWithStateSystem = (ITmfAnalysisModuleWithStateSystems) module;
214 /*
215 * Just schedule the module, the data will be filled when
216 * available
217 */
218 moduleWithStateSystem.schedule();
219 if (!moduleWithStateSystem.waitForInitialization()) {
220 continue;
221 }
222 for (ITmfStateSystem ss : moduleWithStateSystem.getStateSystems()) {
223 traceEntry.addChild(new StateSystemEntry(ss));
224 }
17c73d10
GB
225 }
226 }
227 return traceEntry;
228 }
229
7c246810
PT
230 private static void clearStateSystemEntries(ITmfTreeViewerEntry root) {
231 for (ITmfTreeViewerEntry traceEntry : root.getChildren()) {
232 for (ITmfTreeViewerEntry ssEntry : traceEntry.getChildren()) {
233 ssEntry.getChildren().clear();
234 }
235 }
17c73d10
GB
236 }
237
7c246810
PT
238 private boolean updateStateSystemEntries(ITmfTreeViewerEntry root, long timestamp) {
239 boolean changed = false;
240 for (ITmfTreeViewerEntry traceEntry : root.getChildren()) {
241 for (ITmfTreeViewerEntry ssEntry : traceEntry.getChildren()) {
242 StateSystemEntry stateSystemEntry = (StateSystemEntry) ssEntry;
243 ITmfStateSystem ss = stateSystemEntry.getSS();
244 try {
245 List<ITmfStateInterval> fullState = ss.queryFullState(timestamp);
246 changed |= updateStateEntries(ss, fullState, stateSystemEntry, -1, timestamp);
247 } catch (TimeRangeException e) {
248 markOutOfRange(stateSystemEntry);
249 changed = true;
250 } catch (StateSystemDisposedException e) {
251 /* Ignored */
252 }
253 }
17c73d10 254 }
7c246810 255 return changed;
17c73d10
GB
256 }
257
7c246810
PT
258 private boolean updateStateEntries(ITmfStateSystem ss, List<ITmfStateInterval> fullState, TmfTreeViewerEntry parent, int parentQuark, long timestamp) {
259 boolean changed = false;
17c73d10 260 try {
7c246810
PT
261 for (int quark : ss.getSubAttributes(parentQuark, false)) {
262 if (quark >= fullState.size()) {
263 // attribute was created after the full state query
264 continue;
265 }
17c73d10 266 ITmfStateInterval interval = fullState.get(quark);
7c246810
PT
267 StateEntry stateEntry = findStateEntry(parent, quark);
268 if (stateEntry == null) {
269 boolean modified = fFilterStatus ?
270 interval.getStartTime() == timestamp :
271 !interval.getStateValue().isNull();
272 stateEntry = new StateEntry(ss.getAttributeName(quark), quark, ss.getFullAttributePath(quark),
273 interval.getStateValue(),
b2c971ec
MK
274 TmfTimestamp.fromNanos(interval.getStartTime()),
275 TmfTimestamp.fromNanos(interval.getEndTime()),
7c246810
PT
276 modified);
277
278 // update children first to know if parent is really needed
279 updateStateEntries(ss, fullState, stateEntry, quark, timestamp);
280
281 /*
282 * Add this entry to parent if filtering is off, or
283 * if the entry has children to display, or
284 * if there is a state change at the current timestamp
285 */
286 if (!fFilterStatus || stateEntry.hasChildren() || interval.getStartTime() == timestamp) {
287 parent.addChild(stateEntry);
288 changed = true;
289 }
290 } else {
291 stateEntry.update(interval.getStateValue(),
b2c971ec
MK
292 TmfTimestamp.fromNanos(interval.getStartTime()),
293 TmfTimestamp.fromNanos(interval.getEndTime()));
17c73d10 294
7c246810
PT
295 // update children recursively
296 updateStateEntries(ss, fullState, stateEntry, quark, timestamp);
17c73d10 297 }
17c73d10 298
7c246810 299 }
17c73d10
GB
300 } catch (AttributeNotFoundException e) {
301 /* Should not happen, we're iterating on known attributes */
17c73d10 302 }
7c246810 303 return changed;
17c73d10
GB
304 }
305
7c246810
PT
306 private static StateEntry findStateEntry(TmfTreeViewerEntry parent, int quark) {
307 for (ITmfTreeViewerEntry child : parent.getChildren()) {
308 StateEntry stateEntry = (StateEntry) child;
309 if (stateEntry.getQuark() == quark) {
310 return stateEntry;
17c73d10
GB
311 }
312 }
7c246810 313 return null;
17c73d10 314 }
17c73d10
GB
315 /**
316 * Set the entries as out of range
317 */
7c246810
PT
318 private static void markOutOfRange(ITmfTreeViewerEntry parent) {
319 for (ITmfTreeViewerEntry entry : parent.getChildren()) {
320 if (entry instanceof StateEntry) {
321 ((StateEntry) entry).setOutOfRange();
17c73d10
GB
322
323 /* Update this node's children recursively */
324 markOutOfRange(entry);
325 }
326 }
327 }
328
329 /**
330 * Set the filter status of the viewer. By default, all entries of all state
331 * system are present, and the values that changed since last refresh are
332 * shown in yellow. When the filter status is true, only the entries with
333 * values modified at current time are displayed.
334 */
335 public void changeFilterStatus() {
336 fFilterStatus = !fFilterStatus;
337 if (fFilterStatus) {
338 getTreeViewer().setAutoExpandLevel(AbstractTreeViewer.ALL_LEVELS);
339 } else {
340 getTreeViewer().setAutoExpandLevel(DEFAULT_AUTOEXPAND);
341 clearContent();
342 }
343 updateContent(getSelectionBeginTime(), getSelectionEndTime(), true);
344 }
345
346 /**
347 * Update the display to use the updated timestamp format
348 *
349 * @param signal
350 * the incoming signal
351 */
352 @TmfSignalHandler
353 public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) {
354 updateContent(getSelectionBeginTime(), getSelectionEndTime(), true);
355 }
356
7c246810
PT
357 private static class StateSystemEntry extends TmfTreeViewerEntry {
358 private final @NonNull ITmfStateSystem fSS;
359
360 public StateSystemEntry(@NonNull ITmfStateSystem ss) {
361 super(ss.getSSID());
362 fSS = ss;
363 }
364
365 public @NonNull ITmfStateSystem getSS() {
366 return fSS;
367 }
368 }
369
370 private class StateEntry extends TmfTreeViewerEntry {
17c73d10
GB
371
372 private final int fQuark;
373 private final String fFullPath;
b2c971ec
MK
374 private @NonNull ITmfTimestamp fStart;
375 private @NonNull ITmfTimestamp fEnd;
17c73d10 376 private ITmfStateValue fValue;
7c246810 377 private boolean fModified;
17c73d10
GB
378 private boolean fOutOfRange = false;
379
b2c971ec 380 public StateEntry(String name, int quark, String fullPath, ITmfStateValue value, @NonNull ITmfTimestamp start, @NonNull ITmfTimestamp end, boolean modified) {
17c73d10
GB
381 super(name);
382 fQuark = quark;
383 fFullPath = fullPath;
384 fStart = start;
385 fEnd = end;
386 fValue = value;
7c246810 387 fModified = modified;
17c73d10
GB
388 }
389
390 public int getQuark() {
391 return fQuark;
392 }
393
394 public String getFullPath() {
395 return fFullPath;
396 }
397
398 public String getStartTime() {
399 if (fOutOfRange) {
400 return EMPTY_STRING;
401 }
402 return fStart.toString();
403 }
404
405 public String getEndTime() {
406 if (fOutOfRange) {
407 return EMPTY_STRING;
408 }
409 return fEnd.toString();
410 }
411
412 public String getValue() {
413 if (fOutOfRange) {
414 return Messages.OutOfRangeMsg;
415 }
416 switch (fValue.getType()) {
417 case INTEGER:
418 case LONG:
419 case DOUBLE:
420 case STRING:
7ef85bff 421 case CUSTOM:
17c73d10
GB
422 return fValue.toString();
423 case NULL:
424 default:
425 return EMPTY_STRING;
426 }
427 }
428
429 public String getType() {
430 if (fOutOfRange) {
431 return EMPTY_STRING;
432 }
433 switch (fValue.getType()) {
434 case INTEGER:
435 return Messages.TypeInteger;
436 case LONG:
437 return Messages.TypeLong;
438 case DOUBLE:
439 return Messages.TypeDouble;
440 case STRING:
441 return Messages.TypeString;
7ef85bff
GB
442 case CUSTOM:
443 return Messages.TypeCustom;
17c73d10
GB
444 case NULL:
445 default:
446 return EMPTY_STRING;
447 }
448 }
449
450 public boolean isModified() {
451 return fModified;
452 }
453
b2c971ec 454 public void update(ITmfStateValue value, @NonNull ITmfTimestamp start, @NonNull ITmfTimestamp end) {
17c73d10
GB
455 fModified = false;
456 fOutOfRange = false;
457 if (!start.equals(fStart)) {
458 fModified = true;
459 fStart = start;
460 fEnd = end;
461 fValue = value;
462 }
463 }
464
465 public void setOutOfRange() {
466 fModified = false;
467 fOutOfRange = true;
468 }
469 }
470}
This page took 0.101212 seconds and 5 git commands to generate.