package org.eclipse.tracecompass.internal.analysis.timing.ui.flamegraph;
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Deque;
import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.tracecompass.common.core.NonNullUtils;
+
import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.AggregatedCalledFunction;
import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.ThreadNode;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
-import com.google.common.collect.Lists;
-
/**
* Content provider for the flame graph view
*
private List<FlamegraphDepthEntry> fFlameGraphEntries = new ArrayList<>();
private long fThreadDuration;
private ITmfTrace fActiveTrace;
+ private SortOption fSortOption = SortOption.BY_NAME;
+ private @NonNull Comparator<FlamegraphDepthEntry> fThreadComparator = new ThreadNameComparator();
+
/**
* Parse the aggregated tree created by the callGraphAnalysis and creates
childrenEntries.add(entry);
}
}
- FlamegraphDepthEntry firstEntry = NonNullUtils.checkNotNull(childrenEntries.get(0));
+ FlamegraphDepthEntry firstEntry = checkNotNull(childrenEntries.get(0));
firstEntry.addEvent(new FlamegraphEvent(firstEntry, timestampStack.peek(), firstNode));
// Build the event list for next entries (next depth)
addEvent(firstNode, childrenEntries, timestampStack);
timestampStack.pop();
});
}
- FlamegraphDepthEntry entry = NonNullUtils.checkNotNull(childrenEntries.get(node.getDepth()));
+ FlamegraphDepthEntry entry = checkNotNull(childrenEntries.get(node.getDepth()));
// Create the event corresponding to the function using the caller's
// timestamp
entry.addEvent(new FlamegraphEvent(entry, timestampStack.peek(), node));
}
}
}
- // Reverse the order of threads
- fFlameGraphEntries = Lists.reverse(fFlameGraphEntries);
+ // Sort the threads
+ fFlameGraphEntries.sort(fThreadComparator);
return fFlameGraphEntries.toArray(new ITimeGraphEntry[fFlameGraphEntries.size()]);
}
// Do nothing
}
+
+ /**
+ * Get the sort option
+ *
+ * @return the sort option.
+ */
+ public SortOption getSortOption() {
+ return fSortOption;
+ }
+
+ /**
+ * Set the sort option for sorting the thread entries
+ *
+ * @param sortOption
+ * the sort option to set
+ *
+ */
+ public void setSortOption(SortOption sortOption) {
+ fSortOption = sortOption;
+ switch (sortOption) {
+ case BY_NAME:
+ fThreadComparator = new ThreadNameComparator();
+ break;
+ case BY_NAME_REV:
+ fThreadComparator = checkNotNull(new ThreadNameComparator().reversed());
+ break;
+ case BY_ID:
+ fThreadComparator = new ThreadIdComparator();
+ break;
+ case BY_ID_REV:
+ fThreadComparator = checkNotNull(new ThreadIdComparator().reversed());
+ break;
+ default:
+ break;
+ }
+ }
}
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
+import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.CallGraphAnalysis;
+import org.eclipse.tracecompass.internal.analysis.timing.ui.Activator;
import org.eclipse.tracecompass.internal.analysis.timing.ui.callgraph.CallGraphAnalysisUI;
import org.eclipse.tracecompass.segmentstore.core.ISegment;
import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphPresentationProvider;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphViewer;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
+import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchActionConstants;
*/
public static final String ID = FlameGraphView.class.getPackage().getName() + ".flamegraphView"; //$NON-NLS-1$
+ private static final String SORT_OPTION_KEY = "sort.option"; //$NON-NLS-1$
+ private static final ImageDescriptor SORT_BY_NAME_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_alpha.gif"); //$NON-NLS-1$
+ private static final ImageDescriptor SORT_BY_NAME_REV_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_alpha_rev.gif"); //$NON-NLS-1$
+ private static final ImageDescriptor SORT_BY_ID_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_num.gif"); //$NON-NLS-1$
+ private static final ImageDescriptor SORT_BY_ID_REV_ICON = Activator.getDefault().getImageDescripterFromPath("icons/etool16/sort_num_rev.gif"); //$NON-NLS-1$
+
+
private TimeGraphViewer fTimeGraphViewer;
private FlameGraphContentProvider fTimeGraphContentProvider;
private ITmfTrace fTrace;
private final @NonNull MenuManager fEventMenuManager = new MenuManager();
+ private Action fSortByNameAction;
+ private Action fSortByIdAction;
/**
* Constructor
traceSelected(new TmfTraceSelectedSignal(this, trace));
}
}
+ contributeToActionBars();
+ loadSortOption();
+
getSite().setSelectionProvider(fTimeGraphViewer.getSelectionProvider());
createTimeEventContextMenu();
}
+
/**
* Handler for the trace opened signal
*
fTimeGraphViewer.setFocus();
}
+ // ------------------------------------------------------------------------
+ // Helper methods
+ // ------------------------------------------------------------------------
+
private void createTimeEventContextMenu() {
fEventMenuManager.setRemoveAllWhenShown(true);
TimeGraphControl timeGraphControl = fTimeGraphViewer.getTimeGraphControl();
}
}
}
+
+ private void contributeToActionBars() {
+ IActionBars bars = getViewSite().getActionBars();
+ fillLocalToolBar(bars.getToolBarManager());
+ }
+
+ private void fillLocalToolBar(IToolBarManager manager) {
+ manager.add(getSortByNameAction());
+ manager.add(getSortByIdAction());
+ manager.add(new Separator());
+ }
+
+ private Action getSortByNameAction() {
+ if (fSortByNameAction == null) {
+ fSortByNameAction = new Action(Messages.FlameGraph_SortByThreadName, IAction.AS_CHECK_BOX) {
+ @Override
+ public void run() {
+ SortOption sortOption = fTimeGraphContentProvider.getSortOption();
+ if (sortOption == SortOption.BY_NAME) {
+ setSortOption(SortOption.BY_NAME_REV);
+ } else {
+ setSortOption(SortOption.BY_NAME);
+ }
+ }
+ };
+ fSortByNameAction.setToolTipText(Messages.FlameGraph_SortByThreadName);
+ fSortByNameAction.setImageDescriptor(SORT_BY_NAME_ICON);
+ }
+ return fSortByNameAction;
+ }
+
+ private Action getSortByIdAction() {
+ if (fSortByIdAction == null) {
+ fSortByIdAction = new Action(Messages.FlameGraph_SortByThreadId, IAction.AS_CHECK_BOX) {
+ @Override
+ public void run() {
+ SortOption sortOption = fTimeGraphContentProvider.getSortOption();
+ if (sortOption == SortOption.BY_ID) {
+ setSortOption(SortOption.BY_ID_REV);
+ } else {
+ setSortOption(SortOption.BY_ID);
+ }
+ }
+ };
+ fSortByIdAction.setToolTipText(Messages.FlameGraph_SortByThreadId);
+ fSortByIdAction.setImageDescriptor(SORT_BY_ID_ICON);
+ }
+ return fSortByIdAction;
+ }
+
+ private void setSortOption(SortOption sortOption) {
+ // reset defaults
+ getSortByNameAction().setChecked(false);
+ getSortByNameAction().setImageDescriptor(SORT_BY_NAME_ICON);
+ getSortByIdAction().setChecked(false);
+ getSortByIdAction().setImageDescriptor(SORT_BY_ID_ICON);
+
+ if (sortOption.equals(SortOption.BY_NAME)) {
+ fTimeGraphContentProvider.setSortOption(SortOption.BY_NAME);
+ getSortByNameAction().setChecked(true);
+ } else if (sortOption.equals(SortOption.BY_NAME_REV)) {
+ fTimeGraphContentProvider.setSortOption(SortOption.BY_NAME_REV);
+ getSortByNameAction().setChecked(true);
+ getSortByNameAction().setImageDescriptor(SORT_BY_NAME_REV_ICON);
+ } else if (sortOption.equals(SortOption.BY_ID)) {
+ fTimeGraphContentProvider.setSortOption(SortOption.BY_ID);
+ getSortByIdAction().setChecked(true);
+ } else if (sortOption.equals(SortOption.BY_ID_REV)) {
+ fTimeGraphContentProvider.setSortOption(SortOption.BY_ID_REV);
+ getSortByIdAction().setChecked(true);
+ getSortByIdAction().setImageDescriptor(SORT_BY_ID_REV_ICON);
+ }
+ saveSortOption();
+ fTimeGraphViewer.refresh();
+ }
+
+ private void saveSortOption() {
+ SortOption sortOption = fTimeGraphContentProvider.getSortOption();
+ IDialogSettings settings = Activator.getDefault().getDialogSettings();
+ IDialogSettings section = settings.getSection(getClass().getName());
+ if (section == null) {
+ section = settings.addNewSection(getClass().getName());
+ }
+ section.put(SORT_OPTION_KEY, sortOption.name());
+ }
+
+ private void loadSortOption() {
+ IDialogSettings settings = Activator.getDefault().getDialogSettings();
+ IDialogSettings section = settings.getSection(getClass().getName());
+ if (section == null) {
+ return;
+ }
+ String sortOption = section.get(SORT_OPTION_KEY);
+ if (sortOption == null) {
+ return;
+ }
+ setSortOption(SortOption.fromName(sortOption));
+ }
+
}
--- /dev/null
+/*******************************************************************************
+ * 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.internal.analysis.timing.ui.flamegraph;
+
+/**
+ * The sort option enum
+ *
+ * @author Bernd Hufmann
+ */
+enum SortOption {
+ /** Sort by thread name*/
+ BY_NAME,
+ /** Sort by thread name reverse */
+ BY_NAME_REV,
+ /** Sort by thread ID */
+ BY_ID,
+ /** Sort by thread ID reverse*/
+ BY_ID_REV;
+
+ public static SortOption fromName(String name) {
+ if (name.equals(SortOption.BY_NAME.name())) {
+ return SortOption.BY_NAME;
+ } else if (name.equals(SortOption.BY_NAME_REV.name())) {
+ return SortOption.BY_NAME_REV;
+ } else if (name.equals(SortOption.BY_ID.name())) {
+ return SortOption.BY_ID;
+ } else if (name.equals(SortOption.BY_ID_REV.name())) {
+ return SortOption.BY_ID_REV;
+ }
+ return SortOption.BY_NAME;
+ }
+}