import java.text.DecimalFormat;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.Set;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
-import org.eclipse.linuxtools.lttng.request.ILttngSyntEventRequest;
-import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventToHandlerResolver;
+import org.eclipse.linuxtools.lttng.core.control.LttngCoreProviderFactory;
+import org.eclipse.linuxtools.lttng.core.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.core.model.LTTngTreeNode;
+import org.eclipse.linuxtools.lttng.core.request.ILttngSyntEventRequest;
+import org.eclipse.linuxtools.lttng.core.state.evProcessor.AbsEventToHandlerResolver;
+import org.eclipse.linuxtools.lttng.core.state.experiment.StateManagerFactory;
import org.eclipse.linuxtools.lttng.ui.TraceDebug;
import org.eclipse.linuxtools.lttng.ui.model.trange.ItemContainer;
import org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView;
import org.eclipse.linuxtools.lttng.ui.views.common.ParamsUpdater;
import org.eclipse.linuxtools.lttng.ui.views.statistics.evProcessor.StatsTimeCountHandlerFactory;
+import org.eclipse.linuxtools.lttng.ui.views.statistics.model.KernelStatisticsData;
import org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsTreeNode;
import org.eclipse.linuxtools.lttng.ui.views.statistics.model.StatisticsTreeRootFactory;
-import org.eclipse.linuxtools.tmf.event.TmfEvent;
-import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
-import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
-import org.eclipse.linuxtools.tmf.request.ITmfDataRequest.ExecutionType;
-import org.eclipse.linuxtools.tmf.signal.TmfExperimentSelectedSignal;
-import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
-import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.core.experiment.TmfExperiment;
+import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType;
+import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
* observer of the model.
*/
public class StatisticsView extends AbsTimeUpdateView {
- public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.statistics";
+ public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.statistics"; //$NON-NLS-1$
private TreeViewer treeViewer;
// Table column names
- private final String LEVEL_COLUMN = "Level";
- private final String EVENTS_COUNT_COLUMN = "Number of Events";
- private final String CPU_TIME_COLUMN = "CPU Time";
- private final String CUMULATIVE_CPU_TIME_COLUMN = "Cumulative CPU Time";
- private final String ELAPSED_TIME_COLUMN = "Elapsed Time";
+ private final String LEVEL_COLUMN = Messages.StatisticsView_LevelColumn;
+ private final String EVENTS_COUNT_COLUMN = Messages.StatisticsView_NbEventsColumn;
+ private final String CPU_TIME_COLUMN = Messages.StatisticsView_CPUTimeColumn;
+ private final String CUMULATIVE_CPU_TIME_COLUMN = Messages.StatisticsView_CumCPUTimeColumn;
+ private final String ELAPSED_TIME_COLUMN = Messages.StatisticsView_ElapsedTimeColumn;
// Table column tooltips
- private final String LEVEL_COLUMN_TIP = "Level at which statistics apply.";
- private final String EVENTS_COUNT_COLUMN_TIP = "Total amount of events that are tied to given resource.";
- private final String CPU_TIME_COLUMN_TIP = "Total amount of time the CPU was used excluding wait times(I/O, etc.) at that level.";
- private final String CUMULATIVE_CPU_TIME_COLUMN_TIP = "Total amount of time between the first and last event excluding wait times in a level.";
- private final String ELAPSED_TIME_COLUMN_TIP = "Total amount of time the CPU was used including wait times(I/O, etc.) at that level.";
+ private final String LEVEL_COLUMN_TIP = Messages.StatisticsView_LevelColumnTip;
+ private final String EVENTS_COUNT_COLUMN_TIP = Messages.StatisticsView_NbEventsTip;
+ private final String CPU_TIME_COLUMN_TIP = Messages.StatisticsView_CPUTimeTip;
+ private final String CUMULATIVE_CPU_TIME_COLUMN_TIP = Messages.StatisticsView_CumCPUTimeTip;
+ private final String ELAPSED_TIME_COLUMN_TIP = Messages.StatisticsView_ElapsedTimeTip;
// Level for which statistics should not be displayed.
- private Set<String> folderLevels = new HashSet<String>(Arrays
- .asList(new String[] { "Event Types", "Modes", "Submodes", "CPUs",
- "Processes", "Functions" }));
+ private Set<Integer> folderLevels = new HashSet<Integer>(Arrays
+ .asList(new Integer[] { KernelStatisticsData.HEADER_CPUS_INT,
+ KernelStatisticsData.HEADER_EVENT_TYPES_INT,
+ KernelStatisticsData.HEADER_FUNCTIONS_INT,
+ KernelStatisticsData.HEADER_MODES_INT,
+ KernelStatisticsData.HEADER_PROCESSES_INT,
+ KernelStatisticsData.HEADER_SUBMODES_INT }));
// Levels for which sub-levels should not contain time-related statistics.
- private Set<String> levelsWithEmptyTime = new HashSet<String>(Arrays
- .asList(new String[] { "Event Types" }));
+ private Set<Integer> levelsWithEmptyTime = new HashSet<Integer>(Arrays
+ .asList(new Integer[] { KernelStatisticsData.HEADER_EVENT_TYPES_INT }));
+
+ private DecimalFormat decimalFormat = new DecimalFormat("0.#########"); //$NON-NLS-1$
- private DecimalFormat decimalFormat = new DecimalFormat("0.#########");
private Cursor fwaitCursor = null;
+ private static final Long STATS_INPUT_CHANGED_REFRESH = 5000L;
+
// Used to draw bar charts in columns.
private interface ColumnPercentageProvider {
public double getPercentage(StatisticsTreeNode node);
}
+ private boolean fStatisticsUpdateBusy = false;
+ private boolean fStatisticsUpdatePending = false;
+ private TmfTimeRange fStatisticsUpdateRange = null;
+ private final Object fStatisticsUpdateSyncObj = new Object();
+
/**
* Contains all the information necessary to build a column of the table.
*/
new ColumnLabelProvider() {
@Override
public String getText(Object element) {
- return ((StatisticsTreeNode) element).getKey();
+ StatisticsTreeNode node = (StatisticsTreeNode) element;
+ if (folderLevels.contains(node.getKey())) {
+ return (KernelStatisticsData.getCategoryFromId(node.getKey().intValue()));
+ } else {
+ return node.getName();
+ }
}
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
StatisticsTreeNode n1 = (StatisticsTreeNode) e1;
StatisticsTreeNode n2 = (StatisticsTreeNode) e2;
-
- return n1.getKey().compareTo(n2.getKey());
+
+// return n1.getKey().compareTo(n2.getKey());
+ return n1.compareTo(n2);
}
}, null),
new ColumnData(EVENTS_COUNT_COLUMN, 125, SWT.LEFT,
if (!folderLevels.contains(node.getKey())) {
return Long.toString(node.getValue().nbEvents);
} else {
- return "";
+ return ""; //$NON-NLS-1$
}
}
}, new ViewerComparator() {
.getValue().nbEvents);
}
}, new ColumnPercentageProvider() {
+ @Override
public double getPercentage(StatisticsTreeNode node) {
StatisticsTreeNode parent = node;
do {
StatisticsTreeNode node = (StatisticsTreeNode) element;
if (folderLevels.contains(node.getKey())) {
- return "";
+ return ""; //$NON-NLS-1$
} else if (node.getParent() != null
&& levelsWithEmptyTime.contains(node
.getParent().getKey())) {
- return "";
+ return ""; //$NON-NLS-1$
} else {
return decimalFormat
.format(node.getValue().cpuTime
public String getText(Object element) {
StatisticsTreeNode node = (StatisticsTreeNode) element;
if (folderLevels.contains(node.getKey())) {
- return "";
+ return ""; //$NON-NLS-1$
} else if (node.getParent() != null
&& levelsWithEmptyTime.contains(node
.getParent().getKey())) {
- return "";
+ return ""; //$NON-NLS-1$
} else {
return decimalFormat
.format(node.getValue().cumulativeCpuTime
public String getText(Object element) {
StatisticsTreeNode node = (StatisticsTreeNode) element;
if (folderLevels.contains(node.getKey())) {
- return "";
+ return ""; //$NON-NLS-1$
} else if (node.getParent() != null
&& levelsWithEmptyTime.contains(node
.getParent().getKey())) {
- return "";
+ return ""; //$NON-NLS-1$
} else {
return decimalFormat
.format(node.getValue().elapsedTime
* org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang
* .Object)
*/
+ @Override
public Object[] getChildren(Object parentElement) {
return ((StatisticsTreeNode) parentElement).getChildren().toArray();
}
* org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang
* .Object)
*/
+ @Override
public Object getParent(Object element) {
return ((StatisticsTreeNode) element).getParent();
}
* org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang
* .Object)
*/
+ @Override
public boolean hasChildren(Object element) {
return ((StatisticsTreeNode) element).hasChildren();
}
* org.eclipse.jface.viewers.IStructuredContentProvider#getElements(
* java.lang.Object)
*/
+ @Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
*
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
+ @Override
public void dispose() {
}
* .jface.viewers.Viewer, java.lang.Object, java.lang.Object)
*/
// @Override
+ @Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
super(viewName);
}
+ private static final String STATISTICS_VIEW = "StatisticsView"; //$NON-NLS-1$
public StatisticsView() {
- this("StatisticsView");
+ this(STATISTICS_VIEW);
}
/*
// Handler that will draw the bar charts.
treeViewer.getTree().addListener(SWT.EraseItem, new Listener() {
// @Override
+ @Override
public void handleEvent(Event event) {
if (columnDataList[event.index].percentageProvider != null) {
StatisticsTreeNode node = (StatisticsTreeNode) event.item
// Read current data if any available
TmfExperiment<?> experiment = TmfExperiment.getCurrentExperiment();
if (experiment != null) {
- requestData(experiment);
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ TmfExperimentSelectedSignal<?> signal = new TmfExperimentSelectedSignal(this, experiment);
+ experimentSelected(signal);
+
} else {
- TraceDebug.debug("No selected experiment information available");
+ TraceDebug.debug("No selected experiment information available"); //$NON-NLS-1$
}
}
treeViewer.getTree().setFocus();
}
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#getInputChangedRefresh()
+ */
+ @Override
+ protected Long getInputChangedRefresh() {
+ return STATS_INPUT_CHANGED_REFRESH;
+ }
/**
* @return
*/
@Override
protected void waitCursor(final boolean waitInd) {
- if (treeViewer == null) {
+ if ((treeViewer == null) || (treeViewer.getTree().isDisposed())) {
return;
}
// Perform the updates on the UI thread
display.asyncExec(new Runnable() {
+ @Override
public void run() {
- Cursor cursor = null; /* indicates default */
- if (waitInd) {
- cursor = fwaitCursor;
+ if ((treeViewer != null) && (!treeViewer.getTree().isDisposed())) {
+ Cursor cursor = null; /* indicates default */
+ if (waitInd) {
+ cursor = fwaitCursor;
+ }
+ treeViewer.getControl().setCursor(cursor);
}
- treeViewer.getControl().setCursor(cursor);
}
});
}
@Override
public void ModelUpdatePrep(TmfTimeRange timeRange, boolean clearAllData) {
Object input = treeViewer.getInput();
- if (input != null && input instanceof StatisticsTreeNode) {
- ((StatisticsTreeNode) input).reset();
+ if ((input != null) && (input instanceof StatisticsTreeNode) && (!treeViewer.getTree().isDisposed())) {
+ if (clearAllData) {
+ ((StatisticsTreeNode) input).reset();
+ }
treeViewer.getTree().getDisplay().asyncExec(new Runnable() {
// @Override
+ @Override
public void run() {
- treeViewer.refresh();
+ if (!treeViewer.getTree().isDisposed())
+ treeViewer.refresh();
}
});
}
@Override
public void modelInputChanged(ILttngSyntEventRequest request, boolean complete) {
+ // Ignore update if disposed
+ if (treeViewer.getTree().isDisposed()) return;
+
+ if(TraceDebug.isSV() && complete) {
+ // print results
+
+ TmfExperiment<?> experiment = TmfExperiment.getCurrentExperiment();
+ if(experiment != null) {
+ StatisticsTreeNode node = StatisticsTreeRootFactory.getStatTreeRoot(experiment.getName());
+ printRecursively(node);
+
+ }
+ }
+
treeViewer.getTree().getDisplay().asyncExec(new Runnable() {
// @Override
+ @Override
public void run() {
- treeViewer.refresh();
+ if (!treeViewer.getTree().isDisposed())
+ treeViewer.refresh();
}
});
+
+ if (complete) {
+ synchronized (fStatisticsUpdateSyncObj) {
+ fStatisticsUpdateBusy = false;
+ if (fStatisticsUpdatePending) {
+ fStatisticsUpdatePending = false;
+ requestData(TmfExperiment.getCurrentExperiment(), fStatisticsUpdateRange, false);
+ }
+ }
+ }
+
}
+ private static int level = 0;
+ private void printRecursively(StatisticsTreeNode node) {
+ String tab = ""; //$NON-NLS-1$
+ for (int i = 0; i < level; i++) {
+ tab += "\t"; //$NON-NLS-1$
+ }
+ level++;
+ TraceDebug.traceSV(tab + node.getContent());
+ if (node.hasChildren()) {
+ LinkedList<StatisticsTreeNode> childreen = (LinkedList<StatisticsTreeNode>)node.getChildren();
+ Collections.sort(childreen);
+
+ for (Iterator<StatisticsTreeNode> iterator = childreen.iterator(); iterator.hasNext();) {
+ StatisticsTreeNode statisticsTreeNode = (StatisticsTreeNode) iterator.next();
+ printRecursively(statisticsTreeNode);
+ }
+ }
+ level--;
+ }
+
/*
* (non-Javadoc)
*
if (input != null && input instanceof StatisticsTreeNode) {
// The data from this experiment is invalid and shall be removed to
// refresh upon next selection
- String name = ((StatisticsTreeNode) input).getKey();
+ String name = request.getExperimentName();
StatisticsTreeRootFactory.removeStatTreeRoot(name);
}
}
StatisticsTreeNode experimentTreeNode = StatisticsTreeRootFactory.getStatTreeRoot(experimentName);
ITmfTrace[] traces = experiment.getTraces();
-
+
+ LTTngTreeNode expNode = StateManagerFactory.getExperimentManager().getSelectedExperiment();
+
// check if there is partial data loaded in the experiment
int numTraces = experiment.getTraces().length;
int numNodeTraces = experimentTreeNode.getNbChildren();
// previously selected
for (int i = 0; i < numTraces; i++) {
String traceName = traces[i].getName();
- if (!experimentTreeNode.containsChild(traceName)) {
+ LTTngTreeNode child = expNode.getChildByName(traceName);
+ if ((child == null) || (!experimentTreeNode.containsChild(child.getId().intValue()))) {
same = false;
break;
}
if (same) {
// no need to reload data, all traces are already loaded
treeViewer.setInput(experimentTreeNode);
+ synchronized (fStatisticsUpdateSyncObj) {
+ fStatisticsUpdateBusy = false;
+ fStatisticsUpdatePending = false;
+ }
return;
}
}
}
+ StatisticsTreeNode treeModelRoot = StatisticsTreeRootFactory.getStatTreeRoot(experiment.getName());
+
+ // if the model has contents, clear to start over
+ if (treeModelRoot.hasChildren()) {
+ treeModelRoot.reset();
+ }
+
+ // set input to a clean data model
+ treeViewer.setInput(treeModelRoot);
+
+ synchronized (fStatisticsUpdateSyncObj) {
+ fStatisticsUpdateBusy = false;
+ fStatisticsUpdatePending = false;
+ }
+
// if the data is not available or has changed, reload it
- requestData(experiment);
+ requestData(experiment, experiment.getTimeRange(), true);
}
}
+ /**
+ * @param signal
+ */
+ @SuppressWarnings("unchecked")
+ @TmfSignalHandler
+ public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal) {
+ TmfExperiment<LttngEvent> experiment = (TmfExperiment<LttngEvent>) signal.getExperiment();
+ // validate
+ if (! experiment.equals(TmfExperiment.getCurrentExperiment())) {
+ return;
+ }
+
+ requestData(experiment, signal.getRange(), false);
+ }
+
/**
* @param experiment
*/
- private void requestData(TmfExperiment<?> experiment) {
+ private void requestData(TmfExperiment<?> experiment, TmfTimeRange range, boolean clearingData) {
if (experiment != null) {
- StatisticsTreeNode treeModelRoot = StatisticsTreeRootFactory.getStatTreeRoot(experiment.getName());
-
- // if the model has contents, clear to start over
- if (treeModelRoot.hasChildren()) {
- treeModelRoot.reset();
+ synchronized (fStatisticsUpdateSyncObj) {
+ if (fStatisticsUpdateBusy) {
+ fStatisticsUpdatePending = true;
+ fStatisticsUpdateRange = range;
+ return;
+ } else {
+ fStatisticsUpdateBusy = true;
+ }
}
- // set input to a clean data model
- treeViewer.setInput(treeModelRoot);
- TmfTimeRange experimentTRange = experiment.getTimeRange();
+ int index = 0;
+ for (StatisticsTreeNode node : ((StatisticsTreeNode) treeViewer.getInput()).getChildren()) {
+ index += (int) node.getValue().nbEvents;
+ }
// send the initial request, to start filling up model
- dataRequest(experimentTRange, experimentTRange, true, ExecutionType.LONG);
+ //eventRequest(fStatisticsUpdateIndex, nbRequested, fStatisticsUpdateStartTime, clearingData, ExecutionType.BACKGROUND);
+ eventRequest(index, range, clearingData, ExecutionType.BACKGROUND);
} else {
- TraceDebug.debug("No selected experiment information available");
+ TraceDebug.debug("No selected experiment information available"); //$NON-NLS-1$
}
}
// Not applicable to statistics view
return null;
}
-}
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#getProviderId()
+ */
+ @Override
+ protected int getProviderId() {
+ return LttngCoreProviderFactory.STATISTICS_LTTNG_SYTH_EVENT_PROVIDER;
+ }
+}
\ No newline at end of file