diff -r 615035072f7e -r 844b047e260d sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceGraph.java --- a/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceGraph.java Tue Apr 20 14:41:43 2010 +0300 +++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/GppTraceGraph.java Wed Apr 21 15:14:16 2010 +0300 @@ -24,11 +24,8 @@ import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; -import java.util.Collection; import java.util.Enumeration; import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedList; import java.util.Vector; import org.eclipse.draw2d.FigureCanvas; @@ -37,9 +34,11 @@ import org.eclipse.draw2d.MouseListener; import org.eclipse.draw2d.MouseMotionListener; import org.eclipse.draw2d.Panel; -import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.action.Action; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; @@ -47,754 +46,871 @@ import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Sash; +import com.nokia.carbide.cpp.internal.pi.address.GppModelAdapter; +import com.nokia.carbide.cpp.internal.pi.address.GppTraceGraphSMP; import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository; import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser; -import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace; import com.nokia.carbide.cpp.internal.pi.model.ProfiledBinary; import com.nokia.carbide.cpp.internal.pi.model.ProfiledFunction; import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric; import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread; import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold; +import com.nokia.carbide.cpp.internal.pi.plugin.model.IContextMenu; +import com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu; import com.nokia.carbide.cpp.internal.pi.visual.Defines; import com.nokia.carbide.cpp.internal.pi.visual.GenericTable; import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph; import com.nokia.carbide.cpp.internal.pi.visual.GraphComposite; import com.nokia.carbide.cpp.internal.pi.visual.PIEvent; -import com.nokia.carbide.cpp.internal.pi.visual.PIEventListener; -import com.nokia.carbide.cpp.internal.pi.visual.PIVisualSharedData; import com.nokia.carbide.cpp.pi.editors.PIPageEditor; import com.nokia.carbide.cpp.pi.util.ColorPalette; +import com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph; +/** + * Each instance of this class represents one trace graph for profiling + * CPU activity. + * + */ +public class GppTraceGraph extends GenericTraceGraph implements IGppTraceGraph, + ActionListener, FocusListener, MouseMotionListener, MouseListener, + MouseMoveListener, ITitleBarMenu, IContextMenu { -public class GppTraceGraph extends GenericTraceGraph implements ActionListener, - FocusListener, - PIEventListener, - MouseMotionListener, - MouseListener, - MouseMoveListener -{ - private GppTraceGraph thisTraceGraph; + /** + * amount of space at bottom of graph to contain things like x-axis units + * and button icons + */ + public static final int X_LEGEND_HEIGHT = 50; + + /** + * When the graph is drawn, this is the finest granularity drawn. E.g., + * assume a granularity of 100, and a sample every ms. If the 1st function + * draw appears in 5 samples from 101ms to 200ms and 10 samples from 200ms + * to 300ms then the graph will show a point at height 5 at time 200 + * connected by a line to a point at height 10 at time 300. + */ + static final int GRANULARITY_VALUE = 100; - // amount of space at bottom of graph to contain things like x-axis units and button icons - public static final int xLegendHeight = 50; - - // When the graph is drawn, this is the finest granularity drawn. E.g., assume - // a granularity of 100, and a sample every ms. If the 1st function draw appears - // in 5 samples from 101ms to 200ms and 10 samples from 200ms to 300ms then the - // graph will show a point at height 5 at time 200 connected by a line to a - // point at height 10 at time 300. - private static int granularityValue = 100; - - private GppVisualiserPanel vPanel; + /** constant to indicate graph is a bar graph */ + public static final int BAR_MODE_ON = 3; + /** constant to indicate graph is stacked-area graph */ + public static final int BAR_MODE_OFF = 4; + + private static final String EMPTY_STRING = "";//$NON-NLS-1$ + + protected GppVisualiserPanel vPanel; + protected String title; + protected String shortTitle; /* - * Depending on this trace graph's graphIndex, one of these will be - * the base table, and others will be derived from its selections. - * The other tables will appear and disappear based on drawMode. - * - * E.g., say that for graphIndex = 0, the base table is threadTable. - * Then this graph can represent the draw modes of: - * THREADS - * THREADS_BINARIES - * THREADS_BINARIES_FUNCTIONS - * THREADS_FUNCTIONS - * THREADS_FUNCTIONS_BINARIES + * Depending on this trace graph's graphIndex, one of these will be the base + * table, and others will be derived from its selections. The other tables + * will appear and disappear based on drawMode. + * + * E.g., say that for graphIndex = 0, the base table is threadTable. Then + * this graph can represent the draw modes of: THREADS THREADS_BINARIES + * THREADS_BINARIES_FUNCTIONS THREADS_FUNCTIONS THREADS_FUNCTIONS_BINARIES */ - private AddrThreadTable threadTable; - private AddrBinaryTable binaryTable; - private AddrFunctionTable functionTable; - + protected AddrThreadTable threadTable; + protected AddrBinaryTable binaryTable; + protected AddrFunctionTable functionTable; + /* - * Depending on this trace graph's graphIndex, one of these will match - * the entire trace's profiled vector, while the others will be derived - * from drilldown selections. The other vectors will only be meaningful - * depending on the drawMode. + * Depending on this trace graph's graphIndex, one of these will match the + * entire trace's profiled vector, while the others will be derived from + * drilldown selections. The other vectors will only be meaningful depending + * on the drawMode. */ - private Vector profiledThreads = new Vector(); - private Vector profiledBinaries = new Vector(); - private Vector profiledFunctions = new Vector(); - - private Vector sortedProfiledThreads = new Vector(); - private Vector sortedProfiledBinaries = new Vector(); + protected Vector profiledThreads = new Vector(); + protected Vector profiledBinaries = new Vector(); + protected Vector profiledFunctions = new Vector(); + + private Vector sortedProfiledThreads = new Vector(); + private Vector sortedProfiledBinaries = new Vector(); private Vector sortedProfiledFunctions = new Vector(); - - private ProfiledThreshold thresholdThread = new ProfiledThreshold("dummy[0]::dummy_0"); //$NON-NLS-1$ - private ProfiledThreshold thresholdBinary = new ProfiledThreshold("\\dummy"); //$NON-NLS-1$ - private ProfiledThreshold thresholdFunction = new ProfiledThreshold("dummy::dummy()"); //$NON-NLS-1$ + + protected ProfiledThreshold thresholdThread; + private ProfiledThreshold thresholdBinary; + private ProfiledThreshold thresholdFunction; // when multiple tables are visible, they are separated by sashes private Sash leftSash; private Sash rightSash; - public static final int NOFILL = 0; - public static final int FILLSELECTED = 1; - public static final int FILLALL = 2; - public static final int BAR_MODE_ON = 3; - public static final int BAR_MODE_OFF = 4; - - private int drawMode = Defines.THREADS; - public int barMode = BAR_MODE_OFF; + protected int drawMode = Defines.THREADS; - private int uid; - - private static class BarGraphData - { + /** current graph drawing mode: either bar or stacked-area graph */ + public int barMode = BAR_MODE_OFF; + + protected int uid; + + private static class BarGraphData { public int x; public Color color; } - + private Vector barGraphData; - - public GppTraceGraph(int graphIndex, GppTrace trace, int uid) - { - super((GenericSampledTrace)trace); - - int granularityValue = trace.samples.size() > GppTraceGraph.granularityValue ? GppTraceGraph.granularityValue : trace.samples.size(); - - this.thisTraceGraph = this; - this.graphIndex = graphIndex; - - // create the graph's 3 table objects - without any table items yet - ProfileVisualiser pV = NpiInstanceRepository.getInstance().getProfilePage(uid, graphIndex); - Composite holdTables = new Composite(pV.getBottomComposite(), SWT.NONE); - holdTables.setLayout(new FormLayout()); + + /** + * The model adapter hides some of the SMP specifics. It must be created + * during initialisation of this graph. + */ + protected GppModelAdapter adapter; + + /** main Composite of legend view */ + private Composite holdTablesComposite; + - this.threadTable = new AddrThreadTable(this, holdTables); - this.binaryTable = new AddrBinaryTable(this, holdTables); - this.functionTable = new AddrFunctionTable(this, holdTables); - + /** + * Constructor + * + * @param graphIndex + * the unique index of this graph + * @param trace + * the trace data model to use + * @param uid + * the Uid of the editor session + */ + public GppTraceGraph(int graphIndex, GppTrace trace, int uid) { + super(trace); + this.graphIndex = graphIndex; this.uid = uid; - Label graphTitle = pV.getTitle(); - Label graphTitle2 = pV.getTitle2(); - if (graphTitle2 != null) - graphTitle2.setText(""); //$NON-NLS-1$ + } + + /** + * Initialises the graph. + * + * @param pageIndex + * page index of the page which displays the graph + * @param trace + * the trace model + */ + public void init(int pageIndex, GppTrace trace) { + doCreateAdapter(); + doSetTitle(); + int granularityValue = trace.samples.size() > GppTraceGraph.GRANULARITY_VALUE ? GppTraceGraph.GRANULARITY_VALUE + : trace.samples.size(); + + // create the graph's 3 table objects - without any table items yet + ProfileVisualiser pV = NpiInstanceRepository.getInstance() + .getProfilePage(uid, pageIndex); + holdTablesComposite = trace.createLegendComposite(pageIndex, graphIndex, pV.getBottomComposite(), getShortTitle()); + holdTablesComposite.setLayout(new FormLayout()); + + createLegendTables(holdTablesComposite); // initialize the threshold counts int totalSampleCount = trace.getSampleAmount(); - NpiInstanceRepository.getInstance().setPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountThread", new Integer(new Double(totalSampleCount * (Double)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadThread") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$ - NpiInstanceRepository.getInstance().setPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountBinary", new Integer(new Double(totalSampleCount * (Double)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadBinary") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$ - NpiInstanceRepository.getInstance().setPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountFunction", new Integer(new Double(totalSampleCount * (Double)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadFunction") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$ - - int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ + + // CH: this is called too many times (those values are global for the + // whole trace) -> can we move it to GppTrace? + NpiInstanceRepository + .getInstance() + .setPersistState( + uid, + "com.nokia.carbide.cpp.pi.address.thresholdCountThread", Integer.valueOf(new Double(totalSampleCount * (Double) NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadThread") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$ + NpiInstanceRepository + .getInstance() + .setPersistState( + uid, + "com.nokia.carbide.cpp.pi.address.thresholdCountBinary", Integer.valueOf(new Double(totalSampleCount * (Double) NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadBinary") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$ + NpiInstanceRepository + .getInstance() + .setPersistState( + uid, + "com.nokia.carbide.cpp.pi.address.thresholdCountFunction", Integer.valueOf(new Double(totalSampleCount * (Double) NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdLoadFunction") + 0.5).intValue())); //$NON-NLS-1$ //$NON-NLS-2$ + + int samplingInterval = (Integer) NpiInstanceRepository.getInstance() + .activeUidGetPersistState( + "com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ // initialize the threshold items - thresholdThread.setColor(trace.getThreadColorPalette().getColor(thresholdThread.getNameString())); - thresholdThread.setActivityMarkCount((trace.samples.size() + granularityValue) / granularityValue + 1); - for (int i = 0; i < trace.samples.size() + granularityValue; i += granularityValue) - { - thresholdThread.zeroActivityMarkValues(i * samplingInterval); - } - thresholdBinary.setColor(trace.getBinaryColorPalette().getColor(thresholdBinary.getNameString())); - thresholdBinary.setActivityMarkCount((trace.samples.size() + granularityValue) / granularityValue + 1); - for (int i = 0; i < trace.samples.size() + granularityValue; i += granularityValue) - { - thresholdBinary.zeroActivityMarkValues(i * samplingInterval); - } - thresholdFunction.setColor(trace.getFunctionColorPalette().getColor(thresholdFunction.getNameString())); - thresholdFunction.setActivityMarkCount((trace.samples.size() + granularityValue) / granularityValue + 1); - for (int i = 0; i < trace.samples.size() + granularityValue; i += granularityValue) - { - thresholdFunction.zeroActivityMarkValues(i * samplingInterval); - } + int bucketDuration = granularityValue * samplingInterval; + int numberOfBuckets = GppTraceUtil.calculateNumberOfBuckets(trace + .getLastSampleTime(), granularityValue); - // all the trace data is known, and you have it sorted 3 different ways - // so set the drawmode, create the page's base table, and set the graph title - if (graphIndex == PIPageEditor.THREADS_PAGE) { - this.drawMode = Defines.THREADS; + thresholdThread = new ProfiledThreshold( + "dummy[0]::dummy_0", trace.getCPUCount(), trace.getGraphCount()); //$NON-NLS-1$ + thresholdBinary = new ProfiledThreshold( + "\\dummy", trace.getCPUCount(), trace.getGraphCount()); //$NON-NLS-1$ + thresholdFunction = new ProfiledThreshold( + "dummy::dummy()", trace.getCPUCount(), trace.getGraphCount()); //$NON-NLS-1$ + thresholdThread.setColor(trace.getThreadColorPalette().getColor( + thresholdThread.getNameString())); + thresholdThread.createBuckets(numberOfBuckets); + thresholdThread.initialiseBuckets(bucketDuration); + thresholdBinary.setColor(trace.getBinaryColorPalette().getColor( + thresholdBinary.getNameString())); + thresholdBinary.createBuckets(numberOfBuckets); + thresholdBinary.initialiseBuckets(bucketDuration); + thresholdFunction.setColor(trace.getFunctionColorPalette().getColor( + thresholdFunction.getNameString())); + thresholdFunction.createBuckets(numberOfBuckets); + thresholdFunction.initialiseBuckets(bucketDuration); + + int graphType = adapter.getGraphType(); - // tables will show threads in decreasing total sample order, but - // then put them back in increasing sample order so that the graph - // shows most common (e.g., EKern) threads on top - this.profiledThreads.clear(); - for (int i = trace.getSortedThreads().size() - 1; i >= 0; i--) - this.profiledThreads.add(trace.getSortedThreads().get(i)); - filterSortedByThreshold(graphIndex, - (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountThread"), //$NON-NLS-1$ - thresholdThread, this.profiledThreads); + if (graphType == PIPageEditor.THREADS_PAGE) { + this.drawMode = Defines.THREADS; + int threshold = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$ + + for (ProfiledGeneric profiled : trace.getSortedThreads()) { + if (adapter.getTotalSampleCount(profiled) > 0){ + if (adapter.getTotalSampleCount(profiled) < threshold){//check below threshold + adapter.addItem(thresholdThread, graphIndex, profiled, adapter.getTotalSampleCount(profiled)); + } else { + profiledThreads.add(profiled); + } + } + } + this.threadTable.setTableViewer(Defines.THREADS); - this.profiledThreads = trace.getSortedThreads(); - graphTitle.setText(Messages.getString("GppTraceGraph.threadLoad")); //$NON-NLS-1$ - } else - if (graphIndex == PIPageEditor.BINARIES_PAGE) { + } else if (graphType == PIPageEditor.BINARIES_PAGE) { this.drawMode = Defines.BINARIES; + int threshold = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$ - // tables will show binaries in decreasing total sample order, but - // then put them back in increasing sample order so that the graph - // shows most common (e.g., EKern) binaries on top - this.profiledBinaries.clear(); - for (int i = trace.getSortedBinaries().size() - 1; i >= 0; i--) - this.profiledBinaries.add(trace.getSortedBinaries().get(i)); - filterSortedByThreshold(graphIndex, (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountBinary"), //$NON-NLS-1$ - thresholdBinary, this.profiledBinaries); + for (ProfiledGeneric profiled : trace.getSortedBinaries()) { + if (adapter.getTotalSampleCount(profiled) > 0){ + if (adapter.getTotalSampleCount(profiled) < threshold){//check below threshold + adapter.addItem(thresholdBinary, graphIndex, profiled, adapter.getTotalSampleCount(profiled)); + } else { + profiledBinaries.add(profiled); + } + + } + } + this.binaryTable.setTableViewer(Defines.BINARIES); this.profiledBinaries = trace.getSortedBinaries(); - graphTitle.setText(Messages.getString("GppTraceGraph.binaryLoad")); //$NON-NLS-1$ - } else - if (graphIndex == PIPageEditor.FUNCTIONS_PAGE) { + } else if (graphType == PIPageEditor.FUNCTIONS_PAGE) { this.drawMode = Defines.FUNCTIONS; + int threshold = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$ - // tables will show functions in decreasing total sample order, but - // then put them back in increasing sample order so that the graph - // shows most common (e.g., EKern) functions on top - this.profiledFunctions.clear(); - for (int i = trace.getSortedFunctions().size() - 1; i >= 0; i--) - this.profiledFunctions.add(trace.getSortedFunctions().get(i)); - filterSortedByThreshold(graphIndex, (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountFunction"), //$NON-NLS-1$ - thresholdFunction, this.profiledFunctions); + for (ProfiledGeneric profiled : trace.getSortedFunctions()) { + if (adapter.getTotalSampleCount(profiled) > 0){ + if (adapter.getTotalSampleCount(profiled) < threshold){//check below threshold + adapter.addItem(thresholdFunction, graphIndex, profiled, adapter.getTotalSampleCount(profiled)); + } else { + profiledFunctions.add(profiled); + } + } + } this.functionTable.setTableViewer(Defines.FUNCTIONS); this.profiledFunctions = trace.getSortedFunctions(); - graphTitle.setText(Messages.getString("GppTraceGraph.FunctionLoad")); //$NON-NLS-1$ - } else - { - try { - throw new Exception(Messages.getString("GppTraceGraph.traceGraphInternalErrorIn")); //$NON-NLS-1$ - } catch (Exception e) { - e.printStackTrace(); - } + } else { + throw new IllegalStateException(Messages + .getString("GppTraceGraph.traceGraphInternalErrorIn")); //$NON-NLS-1$ } - + + // since the trace can be shown any of 3 ways (by thread, by binary, or // by function), make sure that all 3 are ready for display - // Sse sorted vector to be consistent with other call to genericRefreshCumulativeThreadTable() - // fix issue with wrong color on newly opened npi file before a change in the table + // Sse sorted vector to be consistent with other call to + // genericRefreshCumulativeThreadTable() + // fix issue with wrong color on newly opened npi file before a change + // in the table if (this.profiledThreads.size() > 0) { genericRefreshCumulativeThreadTable(this.profiledThreads.elements()); - genericRefreshCumulativeThreadTable(this.sortedProfiledThreads.elements()); + genericRefreshCumulativeThreadTable(this.sortedProfiledThreads + .elements()); } if (this.profiledBinaries.size() > 0) { - genericRefreshCumulativeThreadTable(this.profiledBinaries.elements()); - genericRefreshCumulativeThreadTable(this.sortedProfiledBinaries.elements()); + genericRefreshCumulativeThreadTable(this.profiledBinaries + .elements()); + genericRefreshCumulativeThreadTable(this.sortedProfiledBinaries + .elements()); } if (this.profiledFunctions.size() > 0) { - genericRefreshCumulativeThreadTable(this.profiledFunctions.elements()); - genericRefreshCumulativeThreadTable(this.sortedProfiledFunctions.elements()); + genericRefreshCumulativeThreadTable(this.profiledFunctions + .elements()); + genericRefreshCumulativeThreadTable(this.sortedProfiledFunctions + .elements()); } - - if ( this.profiledThreads.size() <= 0 - && this.profiledBinaries.size() <= 0 - && this.profiledFunctions.size() <= 0) { + + if (this.profiledThreads.size() <= 0 + && this.profiledBinaries.size() <= 0 + && this.profiledFunctions.size() <= 0) { try { - throw new Exception(Messages.getString("GppTraceGraph.traceGraphInternalErrorAt")); //$NON-NLS-1$ + throw new Exception(Messages + .getString("GppTraceGraph.traceGraphInternalErrorAt")); //$NON-NLS-1$ } catch (Exception e) { e.printStackTrace(); } } this.vPanel = new GppVisualiserPanel(this); + } - + + /** + * Sets the graph-specific title + */ + protected void doSetTitle() { + title = Messages.getString("GppTraceGraph.1"); //$NON-NLS-1$ + shortTitle = Messages.getString("GppTraceGraph.0"); //$NON-NLS-1$ + } + + /** + * Creates a GppModelAdapter + */ + protected void doCreateAdapter() { + adapter = new GppModelAdapter(this.graphIndex); + } + + /** + * Creates the three legend tables for this graph (for threads, binaries, + * functions) + * + * @param holdTablesComposite + */ + protected void createLegendTables(Composite holdTablesComposite) { + this.threadTable = new AddrThreadTable(this, holdTablesComposite, adapter); + this.binaryTable = new AddrBinaryTable(this, holdTablesComposite, adapter); + this.functionTable = new AddrFunctionTable(this, holdTablesComposite, adapter); + } + /* - * Combine all vectors elements that are below the threshold into a single - * vector element. Assumes that the input vector is sorted by decreasing sample count. + * (non-Javadoc) + * + * @see com.nokia.carbide.cpp.pi.address.IGppTraceGraph#getGppTrace() + */ + public GppTrace getGppTrace() { + return (GppTrace) this.getTrace(); + } + + /* + * (non-Javadoc) + * + * @see + * com.nokia.carbide.cpp.internal.pi.visual.PIEventListener#piEventReceived + * (com.nokia.carbide.cpp.internal.pi.visual.PIEvent) */ - private void filterSortedByThreshold(int graphIndex, int thresholdCount, ProfiledThreshold pThreshold, Vector pGenerics) - { - // count and remove items below the threshold - for (int i = pGenerics.size() - 1; i >= 0; i--) { - if (pGenerics.elementAt(i).getTotalSampleCount() < thresholdCount) { - pThreshold.addItem(graphIndex, pGenerics.elementAt(i), 0); - pGenerics.removeElementAt(i); - } else { + public void piEventReceived(PIEvent be) { + switch (be.getType()) { + // determine the threads that can be shown, and get rid of all + // drilldowns + case PIEvent.THRESHOLD_THREAD_CHANGED: + if (this.getGraphIndex() == PIPageEditor.THREADS_PAGE) + this.getThreadTable().action("changeThresholdThread"); //$NON-NLS-1$ + switch (this.drawMode) { + case Defines.THREADS: + case Defines.THREADS_FUNCTIONS: + case Defines.THREADS_FUNCTIONS_BINARIES: + case Defines.THREADS_BINARIES: + case Defines.THREADS_BINARIES_FUNCTIONS: + case Defines.BINARIES_THREADS: + case Defines.BINARIES_THREADS_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS_THREADS: + case Defines.FUNCTIONS_THREADS: + case Defines.FUNCTIONS_THREADS_BINARIES: + case Defines.FUNCTIONS_BINARIES_THREADS: + this.setGraphImageChanged(true); + default: + break; + } + break; + case PIEvent.THRESHOLD_BINARY_CHANGED: + if (this.getGraphIndex() == PIPageEditor.BINARIES_PAGE) + this.getBinaryTable().action("changeThresholdBinary"); //$NON-NLS-1$ + switch (this.drawMode) { + case Defines.THREADS_FUNCTIONS_BINARIES: + case Defines.THREADS_BINARIES: + case Defines.THREADS_BINARIES_FUNCTIONS: + case Defines.BINARIES: + case Defines.BINARIES_THREADS: + case Defines.BINARIES_THREADS_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS_THREADS: + case Defines.FUNCTIONS_THREADS_BINARIES: + case Defines.FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_BINARIES_THREADS: + this.setGraphImageChanged(true); + default: + break; + } + break; + case PIEvent.THRESHOLD_FUNCTION_CHANGED: + if (this.getGraphIndex() == PIPageEditor.FUNCTIONS_PAGE) + this.getFunctionTable().action("changeThresholdFunction"); //$NON-NLS-1$ + switch (this.drawMode) { + case Defines.THREADS_FUNCTIONS: + case Defines.THREADS_FUNCTIONS_BINARIES: + case Defines.THREADS_BINARIES_FUNCTIONS: + case Defines.BINARIES_THREADS_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS_THREADS: + case Defines.FUNCTIONS: + case Defines.FUNCTIONS_THREADS: + case Defines.FUNCTIONS_THREADS_BINARIES: + case Defines.FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_BINARIES_THREADS: + this.setGraphImageChanged(true); + default: + break; + } + break; + // when the selection area changes, change the percent loads + // and the sample counts in all tables of this GPP graph + case PIEvent.SELECTION_AREA_CHANGED: + // this is the first GPP graph to be told of the selection area + // change, + // so it gathers the overall trace information + double doubleStartTime = PIPageEditor.currentPageEditor() + .getStartTime(); + double doubleEndTime = PIPageEditor.currentPageEditor() + .getEndTime(); + GppTrace trace = (GppTrace) this.getTrace(); + trace.setSelectedArea(doubleStartTime, doubleEndTime); + + // take care of the threshold members + int sampleCount = 0; + int thresholdCount; + + if (graphIndex == PIPageEditor.THREADS_PAGE) { + thresholdCount = (Integer) NpiInstanceRepository + .getInstance() + .getPersistState(uid, + "com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$ + if (thresholdCount > 0) { + for (int i = 0; i < profiledThreads.size(); i++) + if (profiledThreads.elementAt(i).getTotalSampleCount() < thresholdCount) + sampleCount += profiledThreads.elementAt(i) + .getSampleCount(graphIndex); + thresholdThread + .setSampleCount(this.graphIndex, sampleCount); + } + } else if (graphIndex == PIPageEditor.BINARIES_PAGE) { + thresholdCount = (Integer) NpiInstanceRepository + .getInstance() + .getPersistState(uid, + "com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$ + if (thresholdCount > 0) { + for (int i = 0; i < profiledBinaries.size(); i++) + if (profiledBinaries.elementAt(i).getTotalSampleCount() < thresholdCount) + sampleCount += profiledBinaries.elementAt(i) + .getSampleCount(graphIndex); + thresholdBinary + .setSampleCount(this.graphIndex, sampleCount); + } + } else if (graphIndex == PIPageEditor.FUNCTIONS_PAGE) { + thresholdCount = (Integer) NpiInstanceRepository + .getInstance() + .getPersistState(uid, + "com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$ + if (thresholdCount > 0) { + for (int i = 0; i < profiledFunctions.size(); i++) + if (profiledFunctions.elementAt(i) + .getTotalSampleCount() < thresholdCount) + sampleCount += profiledFunctions.elementAt(i) + .getSampleCount(graphIndex); + thresholdFunction.setSampleCount(this.graphIndex, + sampleCount); + } + } + + double startTime = PIPageEditor.currentPageEditor().getStartTime(); + double endTime = PIPageEditor.currentPageEditor().getEndTime(); + + // send this message to the other GPP graphs + PIEvent be2 = new PIEvent(be.getValueObject(), + PIEvent.SELECTION_AREA_CHANGED2); + + // update the selection area shown + for (int i = 0; i < trace.getGraphCount(); i++) { + IGppTraceGraph graph = trace.getGppGraph(i, getUid()); + + if (graph != this) { + graph.piEventReceived(be2); + // once per graph, update the selection interval shown + graph.getCompositePanel().getVisualiser().updateStatusBarTimeInterval(startTime, endTime); + } + + // change the graph's selected time interval + graph.setSelectionStart(startTime * 1000); + graph.setSelectionEnd(endTime * 1000); + graph.getCompositePanel().setSelectionFields( + (int) (startTime * 1000), (int) (endTime * 1000)); + } + + this.parentComponent.getSashForm().redraw(); + be = be2; + // FALL THROUGH + case PIEvent.SELECTION_AREA_CHANGED2: { + // this code lets each graph's base thread/binary/function table + // update the other tables + switch (drawMode) { + case Defines.THREADS: + case Defines.THREADS_FUNCTIONS: + case Defines.THREADS_FUNCTIONS_BINARIES: + case Defines.THREADS_BINARIES: + case Defines.THREADS_BINARIES_FUNCTIONS: { + this.threadTable.piEventReceived(be); + break; + } + case Defines.BINARIES: + case Defines.BINARIES_THREADS: + case Defines.BINARIES_THREADS_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS_THREADS: { + this.binaryTable.piEventReceived(be); + break; + } + case Defines.FUNCTIONS: + case Defines.FUNCTIONS_THREADS: + case Defines.FUNCTIONS_THREADS_BINARIES: + case Defines.FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_BINARIES_THREADS: { + this.functionTable.piEventReceived(be); break; } + } + + this.vPanel.refreshCumulativeThreadTable(); + this.setGraphImageChanged(true); // any selection change to drill + // down will change graph + this.repaint(); + break; + } + + // in the graph, show all values from the rightmost table + case PIEvent.SET_FILL_ALL_THREADS: + this.setGraphImageChanged(true); // any selection change to drill + // down will change graph + this.vPanel.piEventReceived(be); + break; + + // in the graph, don't fill between the lines will the color of + // the line above + case PIEvent.SET_FILL_OFF: + this.setGraphImageChanged(true); // any selection change to drill + // down will change graph + this.vPanel.piEventReceived(be); + break; + + // in the graph, show bars + case PIEvent.GPP_SET_BAR_GRAPH_ON: + this.vPanel.piEventReceived(be); + break; + + // in the graph, show polylines + case PIEvent.GPP_SET_BAR_GRAPH_OFF: + this.vPanel.piEventReceived(be); + break; + + // in the graph, show only the values from selected rows in the + // rightmost table + case PIEvent.SET_FILL_SELECTED_THREAD: + this.setGraphImageChanged(true); // any selection change to drill + // down will change graph + this.vPanel.piEventReceived(be); + break; + + // Redraw the graph because the thread table's selected values have + // changed. + // The thread table is handled (setting of array of selected threads + // and table redraw) by the table selection listener or mouse listener. + case PIEvent.CHANGED_THREAD_TABLE: + switch (drawMode) { + case Defines.THREADS_BINARIES: + case Defines.THREADS_BINARIES_FUNCTIONS: + case Defines.THREADS_FUNCTIONS: + case Defines.THREADS_FUNCTIONS_BINARIES: { + this.threadTable.piEventReceived(be); + break; + } + case Defines.BINARIES_THREADS_FUNCTIONS: { + this.binaryTable.piEventReceived(be); + break; + } + case Defines.FUNCTIONS_THREADS_BINARIES: { + this.functionTable.piEventReceived(be); + break; + } + case Defines.THREADS: + case Defines.BINARIES: + case Defines.BINARIES_THREADS: + case Defines.BINARIES_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS_THREADS: + case Defines.FUNCTIONS: + case Defines.FUNCTIONS_THREADS: + case Defines.FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_BINARIES_THREADS: + default: + break; + } + + this.vPanel.refreshCumulativeThreadTable(); + this.repaint(); + // if fill selected, the graph is drawn again + this.vPanel.piEventReceived(be); + break; + + // Redraw the graph because the binary table's selected values have + // changed. + // The binary table is handled (setting of array of selected binaries + // and table redraw) by the table selection listener or mouse listener. + case PIEvent.CHANGED_BINARY_TABLE: + switch (drawMode) { + case Defines.BINARIES_THREADS: + case Defines.BINARIES_THREADS_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS_THREADS: { + this.binaryTable.piEventReceived(be); + break; + } + case Defines.THREADS_BINARIES_FUNCTIONS: { + this.threadTable.piEventReceived(be); + break; + } + case Defines.FUNCTIONS_BINARIES_THREADS: { + this.functionTable.piEventReceived(be); + break; + } + case Defines.THREADS: + case Defines.THREADS_BINARIES: + case Defines.THREADS_FUNCTIONS: + case Defines.THREADS_FUNCTIONS_BINARIES: + case Defines.BINARIES: + case Defines.FUNCTIONS: + case Defines.FUNCTIONS_THREADS: + case Defines.FUNCTIONS_THREADS_BINARIES: + case Defines.FUNCTIONS_BINARIES: + default: + break; + } + + this.vPanel.refreshCumulativeThreadTable(); + this.repaint(); + // if fill selected, the graph is drawn again + this.vPanel.piEventReceived(be); + break; + + // Redraw the graph because the function table's selected values have + // changed. + // The function table is handled (setting of array of selected functions + // and table redraw) by the table selection listener or mouse listener. + case PIEvent.CHANGED_FUNCTION_TABLE: + switch (drawMode) { + case Defines.FUNCTIONS_THREADS: + case Defines.FUNCTIONS_THREADS_BINARIES: + case Defines.FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_BINARIES_THREADS: { + this.functionTable.piEventReceived(be); + break; + } + case Defines.THREADS_FUNCTIONS_BINARIES: { + this.threadTable.piEventReceived(be); + break; + } + case Defines.BINARIES_FUNCTIONS_THREADS: { + this.binaryTable.piEventReceived(be); + break; + } + case Defines.THREADS: + case Defines.THREADS_BINARIES: + case Defines.THREADS_BINARIES_FUNCTIONS: + case Defines.THREADS_FUNCTIONS: + case Defines.BINARIES: + case Defines.BINARIES_THREADS: + case Defines.BINARIES_THREADS_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS: + case Defines.FUNCTIONS: + default: + break; + } + + this.vPanel.refreshCumulativeThreadTable(); + this.repaint(); + this.vPanel.piEventReceived(be); + break; + + case PIEvent.MOUSE_PRESSED: + switch (drawMode) { + case Defines.THREADS: { + break; + } + case Defines.BINARIES: { + break; + } + case Defines.FUNCTIONS: { + break; + } + default: { + break; + } + } + this.parentComponent.setActive(this); + break; + + case PIEvent.SCALE_CHANGED: + this.setGraphImageChanged(true); + break; + + default: + break; + } + } + + /* + * (non-Javadoc) + * + * @see + * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) + */ + public void actionPerformed(ActionEvent ae) { + } + + /* + * (non-Javadoc) + * + * @see + * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#action(java + * .lang.String) + */ + @Override + public void action(String actionString) { + System.out + .println(Messages.getString("GppTraceGraph.actionString") + actionString); //$NON-NLS-1$ + + if (actionString.equals("resetToCurrentMode")) //$NON-NLS-1$ + { + if (drawMode == Defines.THREADS_FUNCTIONS) + this.setDrawMode(Defines.THREADS); + else if (drawMode == Defines.BINARIES_FUNCTIONS) + this.setDrawMode(Defines.BINARIES); + else + System.out + .println(Messages.getString("GppTraceGraph.drawMode") + drawMode); //should not print this ever //$NON-NLS-1$ + } else { + switch (drawMode) { + case Defines.THREADS: + case Defines.THREADS_FUNCTIONS: + case Defines.THREADS_FUNCTIONS_BINARIES: + case Defines.THREADS_BINARIES: + case Defines.THREADS_BINARIES_FUNCTIONS: { + this.threadTable.action(actionString); + break; + } + case Defines.BINARIES: + case Defines.BINARIES_THREADS: + case Defines.BINARIES_THREADS_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS_THREADS: { + this.binaryTable.action(actionString); + break; + } + case Defines.FUNCTIONS: + case Defines.FUNCTIONS_THREADS: + case Defines.FUNCTIONS_THREADS_BINARIES: + case Defines.FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_BINARIES_THREADS: { + this.functionTable.action(actionString); + break; + } + } } } - public GppTrace getGppTrace() { - return (GppTrace)this.getTrace(); - } - - public int getGraphIndex() - { - return this.graphIndex; + /* + * (non-Javadoc) + * + * @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent) + */ + public void focusGained(FocusEvent fe) { } - public void piEventReceived(PIEvent be) - { - switch (be.getType()) - { - // determine the threads that can be shown, and get rid of all drilldowns - case PIEvent.THRESHOLD_THREAD_CHANGED: - if (this.getGraphIndex() == PIPageEditor.THREADS_PAGE) - this.getThreadTable().action("changeThresholdThread"); //$NON-NLS-1$ - switch (this.drawMode) { - case Defines.THREADS: - case Defines.THREADS_FUNCTIONS: - case Defines.THREADS_FUNCTIONS_BINARIES: - case Defines.THREADS_BINARIES: - case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.BINARIES_THREADS: - case Defines.BINARIES_THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS_THREADS: - case Defines.FUNCTIONS_THREADS: - case Defines.FUNCTIONS_THREADS_BINARIES: - case Defines.FUNCTIONS_BINARIES_THREADS: - this.setGraphImageChanged(true); - default: - break; - } - break; - case PIEvent.THRESHOLD_BINARY_CHANGED: - if (this.getGraphIndex() == PIPageEditor.BINARIES_PAGE) - this.getBinaryTable().action("changeThresholdBinary"); //$NON-NLS-1$ - switch (this.drawMode) { - case Defines.THREADS_FUNCTIONS_BINARIES: - case Defines.THREADS_BINARIES: - case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.BINARIES: - case Defines.BINARIES_THREADS: - case Defines.BINARIES_THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS_THREADS: - case Defines.FUNCTIONS_THREADS_BINARIES: - case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_BINARIES_THREADS: - this.setGraphImageChanged(true); - default: - break; - } - break; - case PIEvent.THRESHOLD_FUNCTION_CHANGED: - if (this.getGraphIndex() == PIPageEditor.FUNCTIONS_PAGE) - this.getFunctionTable().action("changeThresholdFunction"); //$NON-NLS-1$ - switch (this.drawMode) { - case Defines.THREADS_FUNCTIONS: - case Defines.THREADS_FUNCTIONS_BINARIES: - case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.BINARIES_THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS_THREADS: - case Defines.FUNCTIONS: - case Defines.FUNCTIONS_THREADS: - case Defines.FUNCTIONS_THREADS_BINARIES: - case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_BINARIES_THREADS: - this.setGraphImageChanged(true); - default: - break; - } - break; - // when the selection area changes, change the percent loads - // and the sample counts in all tables of this GPP graph - case PIEvent.SELECTION_AREA_CHANGED: - // this is the first GPP graph to be told of the selection area change, - // so it gathers the overall trace information - GppTrace trace = (GppTrace)this.getTrace(); - trace.setSelectedArea(); - - // take care of the threshold members - int sampleCount = 0; - int thresholdCount; - - if (graphIndex == PIPageEditor.THREADS_PAGE) { - thresholdCount = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$ - if (thresholdCount > 0) { - for (int i = 0; i < profiledThreads.size(); i++) - if (profiledThreads.elementAt(i).getTotalSampleCount() < thresholdCount) - sampleCount += profiledThreads.elementAt(i).getSampleCount(graphIndex); - thresholdThread.setSampleCount(this.graphIndex, sampleCount); - } - } else if (graphIndex == PIPageEditor.BINARIES_PAGE) { - thresholdCount = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$ - if (thresholdCount > 0) { - for (int i = 0; i < profiledBinaries.size(); i++) - if (profiledBinaries.elementAt(i).getTotalSampleCount() < thresholdCount) - sampleCount += profiledBinaries.elementAt(i).getSampleCount(graphIndex); - thresholdBinary.setSampleCount(this.graphIndex, sampleCount); - } - } else if (graphIndex == PIPageEditor.FUNCTIONS_PAGE) { - thresholdCount = (Integer)NpiInstanceRepository.getInstance().getPersistState(uid, "com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$ - if (thresholdCount > 0) { - for (int i = 0; i < profiledFunctions.size(); i++) - if (profiledFunctions.elementAt(i).getTotalSampleCount() < thresholdCount) - sampleCount += profiledFunctions.elementAt(i).getSampleCount(graphIndex); - thresholdFunction.setSampleCount(this.graphIndex, sampleCount); - } - } - - double startTime = PIPageEditor.currentPageEditor().getStartTime(); - double endTime = PIPageEditor.currentPageEditor().getEndTime(); - - // send this message to the 2 other GPP graphs - PIEvent be2 = new PIEvent(be.getValueObject(), - PIEvent.SELECTION_AREA_CHANGED2); - - // update the selection area shown - for (int i = 0; i < 3; i++) - { - GppTraceGraph graph = trace.getGppGraph(i, getUid()); - - if (graph != this) { - graph.piEventReceived(be2); - // once per graph, update the selection interval shown - graph.getCompositePanel().getVisualiser().getTimeString().setText(ProfileVisualiser.getTimeInterval(startTime, endTime)); - } - - // change the graph's selected time interval - graph.setSelectionStart((double) startTime * 1000); - graph.setSelectionEnd((double) endTime * 1000); - graph.parentComponent.setSelectionFields((int)(startTime * 1000), (int)(endTime * 1000)); - } - - this.parentComponent.getSashForm().redraw(); - be = be2; - // FALL THROUGH - case PIEvent.SELECTION_AREA_CHANGED2: - { - // this code lets each graph's base thread/binary/function table update the other tables - switch (drawMode) - { - case Defines.THREADS: - case Defines.THREADS_FUNCTIONS: - case Defines.THREADS_FUNCTIONS_BINARIES: - case Defines.THREADS_BINARIES: - case Defines.THREADS_BINARIES_FUNCTIONS: - { - this.threadTable.piEventReceived(be); - break; - } - case Defines.BINARIES: - case Defines.BINARIES_THREADS: - case Defines.BINARIES_THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS_THREADS: - { - this.binaryTable.piEventReceived(be); - break; - } - case Defines.FUNCTIONS: - case Defines.FUNCTIONS_THREADS: - case Defines.FUNCTIONS_THREADS_BINARIES: - case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_BINARIES_THREADS: - { - this.functionTable.piEventReceived(be); - break; - } - } - - this.vPanel.refreshCumulativeThreadTable(); - this.setGraphImageChanged(true); // any selection change to drill down will change graph - this.repaint(); - break; - } - - // in the graph, show all values from the rightmost table - case PIEvent.SET_FILL_ALL_THREADS: - this.setGraphImageChanged(true); // any selection change to drill down will change graph - this.vPanel.piEventReceived(be); - break; - - // in the graph, don't fill between the lines will the color of - // the line above - case PIEvent.SET_FILL_OFF: - this.setGraphImageChanged(true); // any selection change to drill down will change graph - this.vPanel.piEventReceived(be); - break; - - // in the graph, show bars - case PIEvent.GPP_SET_BAR_GRAPH_ON: - this.vPanel.piEventReceived(be); - break; - - // in the graph, show polylines - case PIEvent.GPP_SET_BAR_GRAPH_OFF: - this.vPanel.piEventReceived(be); - break; - - // in the graph, show only the values from selected rows in the - // rightmost table - case PIEvent.SET_FILL_SELECTED_THREAD: - this.setGraphImageChanged(true); // any selection change to drill down will change graph - this.vPanel.piEventReceived(be); - break; - - // Redraw the graph because the thread table's selected values have changed. - // The thread table is handled (setting of array of selected threads - // and table redraw) by the table selection listener or mouse listener. - case PIEvent.CHANGED_THREAD_TABLE: - switch (drawMode) - { - case Defines.THREADS_BINARIES: - case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.THREADS_FUNCTIONS: - case Defines.THREADS_FUNCTIONS_BINARIES: - { - this.threadTable.piEventReceived(be); - break; - } - case Defines.BINARIES_THREADS_FUNCTIONS: - { - this.binaryTable.piEventReceived(be); - break; - } - case Defines.FUNCTIONS_THREADS_BINARIES: - { - this.functionTable.piEventReceived(be); - break; - } - case Defines.THREADS: - case Defines.BINARIES: - case Defines.BINARIES_THREADS: - case Defines.BINARIES_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS_THREADS: - case Defines.FUNCTIONS: - case Defines.FUNCTIONS_THREADS: - case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_BINARIES_THREADS: - default: - break; - } - - this.vPanel.refreshCumulativeThreadTable(); - this.repaint(); - //if fill selected, the graph is drawn again - this.vPanel.piEventReceived(be); - break; - - // Redraw the graph because the binary table's selected values have changed. - // The binary table is handled (setting of array of selected binaries - // and table redraw) by the table selection listener or mouse listener. - case PIEvent.CHANGED_BINARY_TABLE: - switch(drawMode) - { - case Defines.BINARIES_THREADS: - case Defines.BINARIES_THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS_THREADS: - { - this.binaryTable.piEventReceived(be); - break; - } - case Defines.THREADS_BINARIES_FUNCTIONS: - { - this.threadTable.piEventReceived(be); - break; - } - case Defines.FUNCTIONS_BINARIES_THREADS: - { - this.functionTable.piEventReceived(be); - break; - } - case Defines.THREADS: - case Defines.THREADS_BINARIES: - case Defines.THREADS_FUNCTIONS: - case Defines.THREADS_FUNCTIONS_BINARIES: - case Defines.BINARIES: - case Defines.FUNCTIONS: - case Defines.FUNCTIONS_THREADS: - case Defines.FUNCTIONS_THREADS_BINARIES: - case Defines.FUNCTIONS_BINARIES: - default: - break; - } - - this.vPanel.refreshCumulativeThreadTable(); - this.repaint(); - //if fill selected, the graph is drawn again - this.vPanel.piEventReceived(be); - break; - - // Redraw the graph because the function table's selected values have changed. - // The function table is handled (setting of array of selected functions - // and table redraw) by the table selection listener or mouse listener. - case PIEvent.CHANGED_FUNCTION_TABLE: - switch(drawMode) - { - case Defines.FUNCTIONS_THREADS: - case Defines.FUNCTIONS_THREADS_BINARIES: - case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_BINARIES_THREADS: - { - this.functionTable.piEventReceived(be); - break; - } - case Defines.THREADS_FUNCTIONS_BINARIES: - { - this.threadTable.piEventReceived(be); - break; - } - case Defines.BINARIES_FUNCTIONS_THREADS: - { - this.binaryTable.piEventReceived(be); - break; - } - case Defines.THREADS: - case Defines.THREADS_BINARIES: - case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.THREADS_FUNCTIONS: - case Defines.BINARIES: - case Defines.BINARIES_THREADS: - case Defines.BINARIES_THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS: - case Defines.FUNCTIONS: - default: - break; - } - - this.vPanel.refreshCumulativeThreadTable(); - this.repaint(); - this.vPanel.piEventReceived(be); - break; - - case PIEvent.MOUSE_PRESSED: - switch (drawMode) { - case Defines.THREADS: - { - break; - } - case Defines.BINARIES: - { - break; - } - case Defines.FUNCTIONS: - { - break; - } - default: - { - break; - } - } - this.parentComponent.setActive(this); - break; - - default: - break; - } - } - - public void actionPerformed(ActionEvent ae) - { - } - - public void action(String actionString) - { - System.out.println(Messages.getString("GppTraceGraph.actionString")+actionString); //$NON-NLS-1$ - - if (actionString.equals("resetToCurrentMode")) //$NON-NLS-1$ - { - if (drawMode == Defines.THREADS_FUNCTIONS) - this.setDrawMode(Defines.THREADS); - else if (drawMode == Defines.BINARIES_FUNCTIONS) - this.setDrawMode(Defines.BINARIES); - else - System.out.println(Messages.getString("GppTraceGraph.drawMode") + drawMode); //should not print this ever //$NON-NLS-1$ - } - else - { - switch (drawMode) - { - case Defines.THREADS: - case Defines.THREADS_FUNCTIONS: - case Defines.THREADS_FUNCTIONS_BINARIES: - case Defines.THREADS_BINARIES: - case Defines.THREADS_BINARIES_FUNCTIONS: - { - this.threadTable.action(actionString); - break; - } - case Defines.BINARIES: - case Defines.BINARIES_THREADS: - case Defines.BINARIES_THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS_THREADS: - { - this.binaryTable.action(actionString); - break; - } - case Defines.FUNCTIONS: - case Defines.FUNCTIONS_THREADS: - case Defines.FUNCTIONS_THREADS_BINARIES: - case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_BINARIES_THREADS: - { - this.functionTable.action(actionString); - break; - } - } - } - } - - public void focusGained(FocusEvent fe) - { + /* + * (non-Javadoc) + * + * @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent) + */ + public void focusLost(FocusEvent fe) { } - public void focusLost(FocusEvent fe) - { - } - + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.MouseMotionListener#mouseDragged(org.eclipse.draw2d + * .MouseEvent) + */ public void mouseDragged(MouseEvent me) { } + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.MouseMotionListener#mouseEntered(org.eclipse.draw2d + * .MouseEvent) + */ public void mouseEntered(MouseEvent me) { } + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.MouseMotionListener#mouseExited(org.eclipse.draw2d + * .MouseEvent) + */ public void mouseExited(MouseEvent me) { } + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.MouseMotionListener#mouseHover(org.eclipse.draw2d. + * MouseEvent) + */ public void mouseHover(MouseEvent me) { } + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.MouseListener#mousePressed(org.eclipse.draw2d.MouseEvent + * ) + */ public void mousePressed(MouseEvent me) { } + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.MouseListener#mouseReleased(org.eclipse.draw2d.MouseEvent + * ) + */ public void mouseReleased(MouseEvent me) { } - public void mouseDoubleClicked(MouseEvent me) - { - Object[] result = this.getProfiledGenericUnderMouse(me); - if ((result == null)) - { + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.MouseListener#mouseDoubleClicked(org.eclipse.draw2d + * .MouseEvent) + */ + public void mouseDoubleClicked(MouseEvent me) { + Object[] result = this.getProfiledGenericUnderMouseImproved(me, false); + if ((result == null)) { return; } - - ProfiledGeneric pg = (ProfiledGeneric)result[0]; - GenericTable gtu = null; - switch (drawMode) - { - case Defines.THREADS: - case Defines.BINARIES_THREADS: - case Defines.FUNCTIONS_THREADS: - case Defines.BINARIES_FUNCTIONS_THREADS: - case Defines.FUNCTIONS_BINARIES_THREADS: - { - gtu = this.threadTable; - break; - } - case Defines.BINARIES: - case Defines.THREADS_BINARIES: - case Defines.THREADS_FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_THREADS_BINARIES: - { - gtu = this.binaryTable; - break; - } - case Defines.FUNCTIONS: - case Defines.THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS: - case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.BINARIES_THREADS_FUNCTIONS: - { - gtu = this.functionTable; - break; - } - default: - break; - } + ProfiledGeneric pg = (ProfiledGeneric) result[0]; + GenericTable gtu = getLegendTableForGraph(); - if (pg != null) - { + if (pg != null) { if (gtu.getIndex(pg) == null) return; int[] index = new int[1]; @@ -803,514 +919,640 @@ } } - private Object[] getProfiledGenericUnderMouse(MouseEvent me) - { + /** + * For a stacked-area chart, this method retrieves the ProfiledGeneric + * currently pointed to by the mouse. It also determines the percentage + * activity load of this ProfiledGeneric in the current bucket. The load + * will also be determined if no ProfiledGeneric is currently pointed to + * (unresolved items). + * + * + * @param me + * @return Object[2] of which [0] is the ProfiledGeneric (may be null) and + * [1] is a String containing the load + */ + private Object[] getProfiledGenericUnderMouseImproved(MouseEvent me, boolean includeLoadString) { Object[] result = new Object[2]; - double x = me.x * this.getScale(); + + int adjustedX = me.x; + if (me.x >= (this.getSize().width)) { + adjustedX = this.getSize().width - 1; + } + double x = getTimeForXCoordinate(adjustedX, this.getScale()); + if (x > PIPageEditor.currentPageEditor().getMaxEndTime() * 1000) { + return result; + } + double y = me.y; - - y = y * 100 / (this.getVisualSize().height - GppTraceGraph.xLegendHeight); + + y = y * 100 / (this.getVisualSize().height - GppTraceGraph.X_LEGEND_HEIGHT); y = 100 - y; - if (y <= 0) - return null; + if (y <= 0){ + return result; + } + + int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState( + "com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ + int granularityValue = ((GppTrace) (this.getTrace())).getGranularity(); + + int bucket = getBucketForTime(x); + + //since the value is drawn at bucket mid-point, we need to work out whether + //x is to the left or right of the midpoint, in other words + //whether we need to take into account the gradient from the previous + //bucket or the next bucket + int offset = ((int)(x / samplingInterval)) % granularityValue; //offset into the bucket + int d = offset - (int)(granularityValue/2); //distance in samples off bucket mid-point, negative for left + double prt = Math.abs(d / (granularityValue * 1d)); //expressed as proportion + double saveLastPeak = 0f; - // mouse event may return out of range X, that may - // crash when we use it to index data array - x = x >= 0 ? x : 0; + for (ProfiledGeneric p : getSortedProfiledsForGraph()) { + if (!p.isEnabled(graphIndex)){ + continue; + } + float[] cum = p.getCumulativeList(graphIndex); + float[] val = adapter.getActivityList(p); + if (cum == null || val == null || bucket >= cum.length){ + return result; + } + + float lowCur = cum[bucket]; + float topCur = cum[bucket] + val[bucket]; + + float lowNext = 0; + float topNext = 0; + + double lowDiff = 0; + double topDiff = 0; + + if (d < 0 && bucket > 0) { + // use gradient of previous bucket + lowNext = cum[bucket - 1]; + topNext = cum[bucket - 1] + val[bucket - 1]; + + } else if (d > 0 && bucket < cum.length - 2) { + // use gradient of next bucket + lowNext = cum[bucket + 1]; + topNext = cum[bucket + 1] + val[bucket + 1]; + + } + lowDiff = (lowNext - lowCur) * prt; + topDiff = (topNext - topCur) * prt; + + // check whether y is in the profiled's value range + if (y >= lowCur + lowDiff && y < topCur + topDiff) { + result[0] = p; + if (includeLoadString){ + //round to 2 dec places + result[1] = String.format("%.2f", (topCur + topDiff - lowCur - lowDiff));//$NON-NLS-1$ + } + return result; + } + saveLastPeak = topCur + topDiff; + } - if (x > PIPageEditor.currentPageEditor().getMaxEndTime() * 1000) - return null; - - if (me.x >= (int)(this.getSize().width)) { - x = (this.getSize().width - 1) * this.getScale(); + if (includeLoadString){ + // within the area of not shown profiled items + result[0] = null; + result[1] = String.format("%.2f", (100 - saveLastPeak));//$NON-NLS-1$ } - GppTrace gppTrace = (GppTrace) (this.getTrace()); + return result; + } + + /** + * Returns the bucket index for the given time + * @param time + * @return + */ + private int getBucketForTime(double time) { + return ((int) (time / ((GppTrace) (this.getTrace())).getBucketDuration())); + } + + /** + * @return the sorted collection of ProfiledGeneric appropriate for the + * current draw mode of the graph + */ + public Vector getSortedProfiledsForGraph() { + switch (drawMode) { + case Defines.THREADS: + case Defines.BINARIES_THREADS: + case Defines.FUNCTIONS_THREADS: + case Defines.BINARIES_FUNCTIONS_THREADS: + case Defines.FUNCTIONS_BINARIES_THREADS: { + return sortedProfiledThreads ; + } + case Defines.BINARIES: + case Defines.THREADS_BINARIES: + case Defines.THREADS_FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_THREADS_BINARIES: { + return sortedProfiledBinaries; + } + case Defines.FUNCTIONS: + case Defines.THREADS_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS: + case Defines.THREADS_BINARIES_FUNCTIONS: + case Defines.BINARIES_THREADS_FUNCTIONS: { + return sortedProfiledFunctions; + } + } + throw new IllegalArgumentException(); + } + + /** + * @return the sorted collection of ProfiledGeneric appropriate for the + * current draw mode of the graph + */ + private GenericAddrTable getLegendTableForGraph() { - Enumeration enumer = null; - switch (drawMode) - { + switch (drawMode) { + case Defines.THREADS: + case Defines.BINARIES_THREADS: + case Defines.FUNCTIONS_THREADS: + case Defines.BINARIES_FUNCTIONS_THREADS: + case Defines.FUNCTIONS_BINARIES_THREADS: { + return this.threadTable; + } + case Defines.BINARIES: + case Defines.THREADS_BINARIES: + case Defines.THREADS_FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_THREADS_BINARIES: { + return this.binaryTable; + } + case Defines.FUNCTIONS: + case Defines.THREADS_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS: + case Defines.THREADS_BINARIES_FUNCTIONS: + case Defines.BINARIES_THREADS_FUNCTIONS: { + return this.functionTable; + } + } + throw new IllegalArgumentException(); + } + + /** + * Converts the passed X-coordiate into a time value (in milliseconds) using + * the scale provided. Makes sure the return value is non-negative. + * + * @param x + * the x coordinate to use + * @param scale + * the scale to use + * @return time in milliseconds + */ + protected double getTimeForXCoordinate(int x, double scale) { + double time = x * scale; + // mouse event may return out of range X, that may + // crash when we use it to index data array + time = time >= 0 ? time : 0; + return time; + + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.draw2d.MouseMotionListener#mouseMoved(org.eclipse.draw2d. + * MouseEvent) + */ + public void mouseMoved(MouseEvent me) { + double x = getTimeForXCoordinate(me.x, this.getScale()); + double y = me.y; + + if (y >= this.getVisualSizeY() - GppTraceGraph.X_LEGEND_HEIGHT + || x >= PIPageEditor.currentPageEditor().getMaxEndTime() * 1000) { + //don't set the tooltip to null here since it might affect other plugins, such as button plugin + return; + } + + if (NpiInstanceRepository.getInstance() == null + || NpiInstanceRepository + .getInstance() + .activeUidGetPersistState( + "com.nokia.carbide.cpp.pi.address.samplingInterval") == null) //$NON-NLS-1$) + return; + + int samplingInterval = (Integer) NpiInstanceRepository.getInstance() + .activeUidGetPersistState( + "com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ + + if (this.barMode == GppTraceGraph.BAR_MODE_ON) { + GppSample samp = getSampleUnderMouse(me.x, this.getScale(), + samplingInterval); + if (samp == null) { + this.setToolTipText(null); + return; + } + switch (drawMode) { case Defines.THREADS: case Defines.BINARIES_THREADS: case Defines.FUNCTIONS_THREADS: case Defines.BINARIES_FUNCTIONS_THREADS: - case Defines.FUNCTIONS_BINARIES_THREADS: - { - enumer = gppTrace.getSortedThreadsElements(); - break; + case Defines.FUNCTIONS_BINARIES_THREADS: { + try { + this.setToolTipText(samp.sampleSynchTime + "ms @" + //$NON-NLS-1$ + Long.toHexString(samp.programCounter) + " " + //$NON-NLS-1$ + samp.thread.process.name + "::" + //$NON-NLS-1$ + samp.thread.threadName + "_" + //$NON-NLS-1$ + samp.thread.threadId); + } catch (NullPointerException e2) { + this + .setToolTipText(Messages + .getString("GppTraceGraph.cannotResolveThreadName")); //$NON-NLS-1$ + } + break; } case Defines.BINARIES: case Defines.THREADS_BINARIES: case Defines.THREADS_FUNCTIONS_BINARIES: case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_THREADS_BINARIES: - { - enumer = gppTrace.getSortedBinariesElements(); + case Defines.FUNCTIONS_THREADS_BINARIES: { + try { + if (samp.getCurrentFunctionSym().getFunctionBinary().getBinaryName() + .endsWith(Messages + .getString("GppTraceGraph.NotFound"))) //$NON-NLS-1$ + throw new NullPointerException(); + this.setToolTipText(samp.sampleSynchTime + "ms @" + //$NON-NLS-1$ + Long.toHexString(samp.programCounter) + " " + //$NON-NLS-1$ + samp.getCurrentFunctionSym().getFunctionBinary().getBinaryName()); + } catch (NullPointerException e) { + try { + this + .setToolTipText(samp.sampleSynchTime + "ms @" + //$NON-NLS-1$ + Long.toHexString(samp.programCounter) + + " " + //$NON-NLS-1$ + samp.getCurrentFunctionItt().getFunctionBinary().getBinaryName()); + } catch (NullPointerException e2) { + this + .setToolTipText(Messages + .getString("GppTraceGraph.cannotResolveBinaryName")); //$NON-NLS-1$ + } + } break; } case Defines.FUNCTIONS: case Defines.THREADS_FUNCTIONS: case Defines.BINARIES_FUNCTIONS: case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.BINARIES_THREADS_FUNCTIONS: - { - enumer = gppTrace.getSortedFunctionsElements(); - break; + case Defines.BINARIES_THREADS_FUNCTIONS: { + try { + if (samp.getCurrentFunctionSym().getFunctionBinary().getBinaryName() + .endsWith(Messages + .getString("GppTraceGraph.notFound"))) //$NON-NLS-1$ + throw new NullPointerException(); + + this.setToolTipText(samp.sampleSynchTime + "ms @" + //$NON-NLS-1$ + Long.toHexString(samp.programCounter) + " " + //$NON-NLS-1$ + samp.getCurrentFunctionSym().getFunctionName()); + } catch (NullPointerException e) { + try { + this.setToolTipText(samp.sampleSynchTime + "ms @" + //$NON-NLS-1$ + Long.toHexString(samp.programCounter) + " " + //$NON-NLS-1$ + samp.getCurrentFunctionItt().getFunctionName()); + } catch (NullPointerException e2) { + this + .setToolTipText(Messages + .getString("GppTraceGraph.cannotResolveFunctionName")); //$NON-NLS-1$ + } + } + break; } default: - break; + return; + } + + return; // return for barMode == GppTraceGraph.BAR_MODE_ON } - if (enumer == null) - return null; - - Vector activeThreads = new Vector(); - while(enumer.hasMoreElements()) - { - ProfiledGeneric pg = (ProfiledGeneric)enumer.nextElement(); - if (pg.isEnabled(this.graphIndex)) - { - activeThreads.add(pg); - } - } - - int cumPrev = 0; - int cumNext = 0; - - int topPrev = 0; - int topNext = 0; - - double cumDiff = 0; - double topDiff = 0; - - ProfiledGeneric currentProfiled = null; - - enumer = activeThreads.elements(); - if (enumer.hasMoreElements()) - currentProfiled = enumer.nextElement(); - - int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ - int granularityValue = gppTrace.samples.size() > GppTraceGraph.granularityValue ? GppTraceGraph.granularityValue : gppTrace.samples.size(); - - while (true) - { - if (currentProfiled != null) - { - int[] cum = currentProfiled.getCumulativeList(graphIndex); - int[] val = currentProfiled.getActivityList(); - if (cum == null || val == null) - return null; - - int current = ((int)(x / samplingInterval)) / granularityValue; - - if ((current >= cum.length) || (current + 1 >= cum.length)) - return null; - - cumPrev = cum[current]; - cumNext = cum[current + 1]; - - topPrev = val[current]; - topNext = val[current + 1]; + // barMode == GppTraceGraph.BAR_MODE_OFF - cumDiff = (cumNext - cumPrev) * ((double)((x / samplingInterval) % granularityValue) / (granularityValue * 1d)); - topDiff = (topNext - topPrev) * ((double)((x / samplingInterval) % granularityValue) / (granularityValue * 1d)); - } - else - { - if (y >= cumPrev + topPrev + topDiff + cumDiff) - { - currentProfiled = null; - break; - } - else - { - break; - } - } - - if (y >= cumPrev + cumDiff && y < cumPrev + topPrev + topDiff + cumDiff ) - { - break; - } - else - { - if (enumer.hasMoreElements()) - { - currentProfiled = (ProfiledGeneric)enumer.nextElement(); - } - else - { - currentProfiled = null; - } - } - } - - if (currentProfiled != null) - { - String loadString = "" + (topPrev + topDiff); //$NON-NLS-1$ - int index = loadString.indexOf('.'); - - if (index > 0 && ((index + 2) < loadString.length())) - loadString = loadString.substring(0, index + 2); - - result[0] = currentProfiled; - result[1] = loadString; - } - else - { - String totalString = "" + (100 - (cumPrev + topPrev + topDiff + cumDiff)); //$NON-NLS-1$ - int index = totalString.indexOf('.'); - - if (index > 0 && ((index + 2) < totalString.length())) - totalString = totalString.substring(0, index + 2); - - result[0] = null; - result[1] = totalString; - } - return result; - } - - public void mouseMoved(MouseEvent me) - { - double x = me.x * this.getScale(); - double y = me.y; - - // mouse event may return out of range X, that may - // crash when we use it to index data array - x = x >= 0 ? x : 0; - - if ( y >= this.getVisualSizeY() - GppTraceGraph.xLegendHeight - || x >= PIPageEditor.currentPageEditor().getMaxEndTime() * 1000) - { + Object[] result = this.getProfiledGenericUnderMouseImproved(me, true); + if (result == null || (result[0] == null && result[1] == null)) { this.setToolTipText(null); return; } - if ( NpiInstanceRepository.getInstance() == null - || NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval") == null) //$NON-NLS-1$) - return; - - int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ - - if (this.barMode == GppTraceGraph.BAR_MODE_ON) { - GppSample samp = (GppSample)((GenericSampledTrace)this.getTrace()).getSample(((int)(x + .0005))/samplingInterval); - switch (drawMode) - { - case Defines.THREADS: - case Defines.BINARIES_THREADS: - case Defines.FUNCTIONS_THREADS: - case Defines.BINARIES_FUNCTIONS_THREADS: - case Defines.FUNCTIONS_BINARIES_THREADS: - { - try { - this.setToolTipText(samp.sampleSynchTime+"ms @"+ //$NON-NLS-1$ - Long.toHexString(samp.programCounter)+" "+ //$NON-NLS-1$ - samp.thread.process.name+"::"+ //$NON-NLS-1$ - samp.thread.threadName+"_"+ //$NON-NLS-1$ - samp.thread.threadId);} - catch (NullPointerException e2) - { - this.setToolTipText(Messages.getString("GppTraceGraph.cannotResolveThreadName")); //$NON-NLS-1$ - } - break; - } - case Defines.BINARIES: - case Defines.THREADS_BINARIES: - case Defines.THREADS_FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_THREADS_BINARIES: - { - try { - if (samp.currentFunctionSym.functionBinary.binaryName.endsWith(Messages.getString("GppTraceGraph.NotFound"))) //$NON-NLS-1$ - throw new NullPointerException(); - this.setToolTipText(samp.sampleSynchTime+"ms @"+ //$NON-NLS-1$ - Long.toHexString(samp.programCounter)+" "+ //$NON-NLS-1$ - samp.currentFunctionSym.functionBinary.binaryName); - } catch (NullPointerException e) - { - try { - this.setToolTipText(samp.sampleSynchTime+"ms @"+ //$NON-NLS-1$ - Long.toHexString(samp.programCounter)+" "+ //$NON-NLS-1$ - samp.currentFunctionItt.functionBinary.binaryName);} - catch (NullPointerException e2) - { - this.setToolTipText(Messages.getString("GppTraceGraph.cannotResolveBinaryName")); //$NON-NLS-1$ - } - } - break; - } - case Defines.FUNCTIONS: - case Defines.THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS: - case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.BINARIES_THREADS_FUNCTIONS: - { - try { - if (samp.currentFunctionSym.functionBinary.binaryName.endsWith(Messages.getString("GppTraceGraph.notFound"))) //$NON-NLS-1$ - throw new NullPointerException(); - - this.setToolTipText(samp.sampleSynchTime+"ms @"+ //$NON-NLS-1$ - Long.toHexString(samp.programCounter)+" "+ //$NON-NLS-1$ - samp.currentFunctionSym.functionName);} - catch (NullPointerException e) - { - try{this.setToolTipText(samp.sampleSynchTime+"ms @"+ //$NON-NLS-1$ - Long.toHexString(samp.programCounter)+" "+ //$NON-NLS-1$ - samp.currentFunctionItt.functionName);} - catch (NullPointerException e2) - { - this.setToolTipText(Messages.getString("GppTraceGraph.cannotResolveFunctionName")); //$NON-NLS-1$ - } - } - break; - } - default: - return; - } - - return; // return for barMode == GppTraceGraph.BAR_MODE_ON + if (me.x >= (this.getSize().width)) { + x = (this.getSize().width - 1) * this.getScale(); } - // barMode == GppTraceGraph.BAR_MODE_OFF + ProfiledGeneric pg = (ProfiledGeneric) result[0]; - Object[] result = this.getProfiledGenericUnderMouse(me); - if (result == null) - { - this.setToolTipText(null); - return; - } - - if (me.x >= (int)(this.getSize().width)) { - x = (this.getSize().width - 1) * this.getScale(); - } - - ProfiledGeneric pg = null; - switch (drawMode) - { + String string = (String) result[1]; + if (pg == null) { + switch (drawMode) { case Defines.THREADS: case Defines.BINARIES_THREADS: case Defines.FUNCTIONS_THREADS: case Defines.BINARIES_FUNCTIONS_THREADS: - case Defines.FUNCTIONS_BINARIES_THREADS: - { - pg = (ProfiledThread)result[0]; - break; + case Defines.FUNCTIONS_BINARIES_THREADS: { + this + .setToolTipText(string + + "% " + Messages.getString("GppTraceGraph.unknownOrExcludedThreads")); //$NON-NLS-1$ //$NON-NLS-2$ + break; } case Defines.BINARIES: case Defines.THREADS_BINARIES: case Defines.THREADS_FUNCTIONS_BINARIES: case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_THREADS_BINARIES: - { - pg = (ProfiledBinary)result[0]; + case Defines.FUNCTIONS_THREADS_BINARIES: { + this + .setToolTipText(string + + "% " + Messages.getString("GppTraceGraph.unknownOrExcludedBinaries")); //$NON-NLS-1$ //$NON-NLS-2$ break; } case Defines.FUNCTIONS: case Defines.THREADS_FUNCTIONS: case Defines.BINARIES_FUNCTIONS: case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.BINARIES_THREADS_FUNCTIONS: - { - pg = (ProfiledFunction)result[0]; - break; + case Defines.BINARIES_THREADS_FUNCTIONS: { + this + .setToolTipText(string + + "% " + Messages.getString("GppTraceGraph.unknownOrExcludedFunctions")); //$NON-NLS-1$ //$NON-NLS-2$ + break; } default: break; + } + } else { + this.setToolTipText(string + "% " + pg.getNameString()); //$NON-NLS-1$ + } + } + + /** + * Returns the closest matching sample with the given x-coordinate. May + * return null if there isn't a matching sample in the immediate vicinity of + * x. This method is typically used in bar mode. + * + * @param xPoint + * @param scale + * @param samplingInterval + * @return + */ + protected GppSample getSampleUnderMouse(int xPoint, double scale, + int samplingInterval) { + GppTrace trace = (GppTrace)this.getTrace(); + GppSample match = null; + double x = xPoint * scale; + x = x >= 0 ? x : 0; + double xStart = (xPoint -5 ) * scale; + double xEnd = (xPoint +5) * scale; + + int start = ((int)(xStart + .0005) * trace.getCPUCount())/samplingInterval; + if (start < 0){ + start = 0; + } else if (start >= trace.getSampleAmount()){ + start = trace.getSampleAmount()-1; } - String string = (String)result[1]; - if (pg == null) - { - switch (drawMode) - { - case Defines.THREADS: - case Defines.BINARIES_THREADS: - case Defines.FUNCTIONS_THREADS: - case Defines.BINARIES_FUNCTIONS_THREADS: - case Defines.FUNCTIONS_BINARIES_THREADS: - { - this.setToolTipText(string + "% " + Messages.getString("GppTraceGraph.unknownOrExcludedThreads")); //$NON-NLS-1$ //$NON-NLS-2$ - break; - } - case Defines.BINARIES: - case Defines.THREADS_BINARIES: - case Defines.THREADS_FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_THREADS_BINARIES: - { - this.setToolTipText(string + "% " + Messages.getString("GppTraceGraph.unknownOrExcludedBinaries")); //$NON-NLS-1$ //$NON-NLS-2$ - break; - } - case Defines.FUNCTIONS: - case Defines.THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS: - case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.BINARIES_THREADS_FUNCTIONS: - { - this.setToolTipText(string + "% " + Messages.getString("GppTraceGraph.unknownOrExcludedFunctions")); //$NON-NLS-1$ //$NON-NLS-2$ - break; - } - default: - break; + int end = ((int)(xEnd + .0005) * trace.getCPUCount())/samplingInterval; + if (end >= trace.getSampleAmount()){ + end = trace.getSampleAmount()-1; + } + + //loop through samples with the correct CPU id in close vicinity, and find the closest one to the given x-coordinate + for (int i = start; i <= end; i++) { + GppSample tmp = trace.getSortedGppSamples()[i]; + if (doCheckSampleMatch(tmp) && (match == null || Math.abs(tmp.sampleSynchTime - x) < Math.abs(match.sampleSynchTime - x)) && isSampleEnabled(tmp)){ + match = tmp; } } - else - { - this.setToolTipText(string + "% " + pg.getNameString()); //$NON-NLS-1$ - } + + return match; } - public GenericTable getTableUtils() - { - switch (drawMode) - { - case Defines.THREADS: - case Defines.BINARIES_THREADS: - case Defines.FUNCTIONS_THREADS: - case Defines.BINARIES_FUNCTIONS_THREADS: - case Defines.FUNCTIONS_BINARIES_THREADS: - { - return this.threadTable; - } - case Defines.BINARIES: - case Defines.THREADS_BINARIES: - case Defines.THREADS_FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_BINARIES: - case Defines.FUNCTIONS_THREADS_BINARIES: - { - return this.binaryTable; - } - case Defines.FUNCTIONS: - case Defines.THREADS_FUNCTIONS: - case Defines.BINARIES_FUNCTIONS: - case Defines.THREADS_BINARIES_FUNCTIONS: - case Defines.BINARIES_THREADS_FUNCTIONS: - { - return this.functionTable; - } - default: - break; + /** + * According to current graph index and drawing mode, check whether this + * sample is enabled + * @param sample the sample to use + * @return true, if enabled, false if disabled or cannot be determined + */ + private boolean isSampleEnabled(GppSample sample) { + + switch (drawMode) { + case Defines.THREADS: + return isSampleEnabled(sample, true, false, false); + case Defines.BINARIES: + return isSampleEnabled(sample, false, true, false); + case Defines.FUNCTIONS: + return isSampleEnabled(sample, false, false, true); + case Defines.BINARIES_THREADS: + case Defines.THREADS_BINARIES: + return isSampleEnabled(sample, true, true, false); + case Defines.FUNCTIONS_THREADS: + case Defines.THREADS_FUNCTIONS: + return isSampleEnabled(sample, true, false, true); + case Defines.FUNCTIONS_BINARIES: + case Defines.BINARIES_FUNCTIONS: + return isSampleEnabled(sample, false, true, true); + case Defines.BINARIES_FUNCTIONS_THREADS: + case Defines.FUNCTIONS_BINARIES_THREADS: + case Defines.THREADS_FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_THREADS_BINARIES: + case Defines.THREADS_BINARIES_FUNCTIONS: + case Defines.BINARIES_THREADS_FUNCTIONS: + return isSampleEnabled(sample, true, true, true); + } + throw new IllegalArgumentException(); + } + + /** + * Check whether a combination of thread / function / binary for this sample + * is enabled in the current graph. + * @param sample + * @param checkThreads + * @param checkBinaries + * @param checkFunctions + * @return + */ + private boolean isSampleEnabled(GppSample sample, boolean checkThreads, boolean checkBinaries, + boolean checkFunctions) { + + boolean ret = true; + GppTrace trace = (GppTrace) this.getTrace(); + + if (checkThreads){ + ret &= trace.getIndexedThreads().get(sample.threadIndex).isEnabled(graphIndex); + } + if (checkBinaries){ + ret &= trace.getIndexedBinaries().get(sample.binaryIndex).isEnabled(graphIndex); + } + if (checkFunctions){ + ret &= trace.getIndexedFunctions().get(sample.functionIndex).isEnabled(graphIndex); + } + return ret; + } + + /** + * Check the sample fulfils conditions for getSampleUnderMouse() + * @return true if it fulfils matching conditions, false otherwise + */ + protected boolean doCheckSampleMatch(GppSample sample){ + return true; + } + + public GenericTable getTableUtils() { + switch (drawMode) { + case Defines.THREADS: + case Defines.BINARIES_THREADS: + case Defines.FUNCTIONS_THREADS: + case Defines.BINARIES_FUNCTIONS_THREADS: + case Defines.FUNCTIONS_BINARIES_THREADS: { + return this.threadTable; + } + case Defines.BINARIES: + case Defines.THREADS_BINARIES: + case Defines.THREADS_FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_BINARIES: + case Defines.FUNCTIONS_THREADS_BINARIES: { + return this.binaryTable; + } + case Defines.FUNCTIONS: + case Defines.THREADS_FUNCTIONS: + case Defines.BINARIES_FUNCTIONS: + case Defines.THREADS_BINARIES_FUNCTIONS: + case Defines.BINARIES_THREADS_FUNCTIONS: { + return this.functionTable; + } + default: + break; } - System.out.println(Messages.getString("GppTraceGraph.debugDrawMode") + drawMode); //$NON-NLS-1$ - return null; + System.out + .println(Messages.getString("GppTraceGraph.debugDrawMode") + drawMode); //$NON-NLS-1$ + return null; } - - public GppVisualiserPanel getVisualiserPanel() - { + + public GppVisualiserPanel getVisualiserPanel() { return this.vPanel; } - - public AddrThreadTable getThreadTable() { + + public AddrThreadTable getThreadTable() { return this.threadTable; } - + public AddrBinaryTable getBinaryTable() { return this.binaryTable; } - + public AddrFunctionTable getFunctionTable() { return this.functionTable; } - public void setThreadTableViewer(CheckboxTableViewer tableViewer) { - this.threadTable.setTableViewer(tableViewer); - } - - public void setBinaryTableViewer(CheckboxTableViewer tableViewer) { - this.binaryTable.setTableViewer(tableViewer);; - } - - public void setFunctionTableViewer(CheckboxTableViewer tableViewer) { - this.functionTable.setTableViewer(tableViewer); - } - - public void paint(Panel panel, Graphics graphics) - { + /* + * (non-Javadoc) + * + * @see + * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#paint(org. + * eclipse.draw2d.Panel, org.eclipse.draw2d.Graphics) + */ + @Override + public void paint(Panel panel, Graphics graphics) { this.setSize(panel.getClientArea().width, panel.getClientArea().height); this.vPanel.paintComponent(panel, graphics); } - public void paintLeftLegend(FigureCanvas figureCanvas, GC gc) - { + /* + * (non-Javadoc) + * + * @see + * com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#paintLeftLegend + * (org.eclipse.draw2d.FigureCanvas, org.eclipse.swt.graphics.GC) + */ + @Override + public void paintLeftLegend(FigureCanvas figureCanvas, GC gc) { GC localGC = gc; - + if (gc == null) gc = new GC(PIPageEditor.currentPageEditor().getSite().getShell()); - Rectangle rect = ((GraphComposite) figureCanvas.getParent()).figureCanvas.getClientArea(); - + Rectangle rect = ((GraphComposite) figureCanvas.getParent()).figureCanvas + .getClientArea(); + int visY = rect.height; - - float visYfloat = visY - GppTraceGraph.xLegendHeight; - + + float visYfloat = visY - GppTraceGraph.X_LEGEND_HEIGHT; + if (visYfloat < 0f) visYfloat = 0f; - + gc.setForeground(ColorPalette.getColor(new RGB(100, 100, 100))); gc.setBackground(ColorPalette.getColor(new RGB(255, 255, 255))); - + // write each next number if there is space // float values will be slightly smaller than the actual result // and they will be incremented by one, since rounding to int // discards the remaining decimals int percent = 100; - int previousBottom = 0; // bottom of the previous legend drawn - for (float y = 0f; percent >= 0; y += visYfloat * 10000f / 100001f, percent -= 10) - { + int previousBottom = 0; // bottom of the previous legend drawn + for (float y = 0f; percent >= 0; y += visYfloat * 10000f / 100001f, percent -= 10) { String legend = "" + percent + "%"; //$NON-NLS-1$ //$NON-NLS-2$ Point extent = gc.stringExtent(legend); - - gc.drawLine(GenericTraceGraph.yLegendWidth - 3, (int)y + 1, GenericTraceGraph.yLegendWidth, (int)y + 1); + + gc.drawLine(IGenericTraceGraph.Y_LEGEND_WIDTH - 3, (int) y + 1, + IGenericTraceGraph.Y_LEGEND_WIDTH, (int) y + 1); - if ((int)y >= previousBottom) - { - gc.drawString(legend, GenericTraceGraph.yLegendWidth - extent.x - 4, (int)y); - previousBottom = (int)y + extent.y; + if ((int) y >= previousBottom) { + gc.drawString(legend, IGenericTraceGraph.Y_LEGEND_WIDTH + - extent.x - 4, (int) y); + previousBottom = (int) y + extent.y; } } - + if (localGC == null) { gc.dispose(); figureCanvas.redraw(); } } - - public void repaint() - { + + /* + * (non-Javadoc) + * + * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#repaint() + */ + @Override + public void repaint() { this.parentComponent.repaintComponent(); } - - public void drawBarsGpp(Vector profiledGenerics, Graphics graphics, Object[] selection) - { - if ( this.updateCumulativeThreadTableIsNeeded - || this.barGraphData == null) - { + + /* + * (non-Javadoc) + * + * @see + * com.nokia.carbide.cpp.pi.address.IGppTraceGraph#drawBarsGpp(java.util + * .Vector, org.eclipse.draw2d.Graphics, java.lang.Object[]) + */ + public void drawBarsGpp(Vector profiledGenerics, + Graphics graphics, Object[] selection) { + if (this.updateCumulativeThreadTableIsNeeded + || this.barGraphData == null) { this.updateBarGraphData(profiledGenerics); } - + this.updateIfNeeded(profiledGenerics); - + Enumeration barEnum = this.barGraphData.elements(); int drawX = -1; int lastDrawX = -10; double scale = this.getScale(); int y = this.getVisualSizeY() - 51; - org.eclipse.draw2d.geometry.Rectangle visibleArea = this.getVisibleArea(graphics); + org.eclipse.draw2d.geometry.Rectangle visibleArea = this + .getVisibleArea(graphics); - while(barEnum.hasMoreElements()) - { + while (barEnum.hasMoreElements()) { BarGraphData bgd = barEnum.nextElement(); - drawX = (int)(((double)bgd.x) / scale); - - if ( drawX >= visibleArea.x - && drawX < visibleArea.x + visibleArea.width ) - { + drawX = (int) ((bgd.x) / scale); + + if (drawX >= visibleArea.x + && drawX < visibleArea.x + visibleArea.width) { if (debug) - System.out.println(Messages.getString("GppTraceGraph.draw") + drawX + " " + scale + " " + bgd.x); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - if (drawX != lastDrawX) - { + System.out + .println(Messages.getString("GppTraceGraph.draw") + drawX + " " + scale + " " + bgd.x); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (drawX != lastDrawX) { graphics.setForegroundColor(bgd.color); graphics.drawLine(drawX, 0, drawX, y); lastDrawX = drawX; @@ -1319,985 +1561,577 @@ } } - public void updateBarGraphData(Vector profiledGenerics) - { + /** + * Updates this.barGraphData. + * + * @param profiledGenerics + * Vector of either sortedThreads / sortedBinaries / + * sortedFunctions + */ + private void updateBarGraphData(Vector profiledGenerics) { if (this.barGraphData == null) this.barGraphData = new Vector(); this.barGraphData.clear(); int x = 0; - + // find the first enabled profiled generic int firstEnabled; for (firstEnabled = 0; firstEnabled < profiledGenerics.size(); firstEnabled++) - if (((ProfiledGeneric)profiledGenerics.get(firstEnabled)).isEnabled(this.graphIndex)) + if (((ProfiledGeneric) profiledGenerics.get(firstEnabled)) + .isEnabled(this.graphIndex)) break; - + // return if there are no enabled profiled generics if (firstEnabled == profiledGenerics.size()) return; - - int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ - Enumeration samples = ((GenericSampledTrace)this.getTrace()).getSamples(); - while (samples.hasMoreElements()) - { - GppSample gs = (GppSample)samples.nextElement(); - - // for each of the tens of thousands of samples, loop through each of the - // perhaps thousands of functions, hundreds of binaries, or tens of threads - for (int i = firstEnabled; i < profiledGenerics.size(); i++) - { + + int samplingInterval = (Integer) NpiInstanceRepository.getInstance() + .activeUidGetPersistState( + "com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ + for (GppSample gs : ((GppTrace) this + .getTrace()).getSortedGppSamples()) { + if (!sampleInChart(gs)) { + continue; + } + + // for each of the tens of thousands of samples, loop through each + // of the + // perhaps thousands of functions, hundreds of binaries, or tens of + // threads + // CH: the following is inefficient and needs refactoring (GppTrace + // has a Vector profiledThreads etc. which are + // already sorted by index) + for (int i = firstEnabled; i < profiledGenerics.size(); i++) { // find the next enabled profiled generic, if any - while ( (i < profiledGenerics.size() - && !((ProfiledGeneric)profiledGenerics.get(i)).isEnabled(this.graphIndex))) + while ((i < profiledGenerics.size() && !((ProfiledGeneric) profiledGenerics + .get(i)).isEnabled(this.graphIndex))) i++; if (i >= profiledGenerics.size()) break; - ProfiledGeneric pg = (ProfiledGeneric)profiledGenerics.get(i); + ProfiledGeneric pg = (ProfiledGeneric) profiledGenerics.get(i); - if ( ((pg instanceof ProfiledThread) && (pg.getIndex() == gs.threadIndex)) - || ((pg instanceof ProfiledBinary) && (pg.getIndex() == gs.binaryIndex)) - || ((pg instanceof ProfiledFunction) && (pg.getIndex() == gs.functionIndex))) { + if (((pg instanceof ProfiledThread) && (pg.getIndex() == gs.threadIndex)) + || ((pg instanceof ProfiledBinary) && (pg.getIndex() == gs.binaryIndex)) + || ((pg instanceof ProfiledFunction) && (pg.getIndex() == gs.functionIndex))) { BarGraphData bgd = new BarGraphData(); bgd.color = pg.getColor(); - bgd.x = x; + //bgd.x = x; + bgd.x = (int)gs.sampleSynchTime; this.barGraphData.add(bgd); break; } } x += samplingInterval; + } - } + + } + + /** + * Returns true if this sample is applicable to this chart. This method is + * intended to be overridden, for example for SMP charts where samples + * belong to the chart with the matching CPU number. + * + * @param gs + * the sample to check + * @return true, if sample belongs to chart, false otherwise + */ + protected boolean sampleInChart(GppSample gs) { + return true; + } - public void refreshDataFromTrace() - { - refreshDataFromTrace((GppTrace)this.getTrace()); + // /* + // * Because a table to the left of a function table has changed, update + // * the function table. + // * If there is no table to the right of this one, redraw the graph based + // * on the changed data. + // */ + // public void refreshProfiledThreadData(int drawMode) + // { + // // Must have a table to its left + // if ( (drawMode != Defines.BINARIES_THREADS) + // && (drawMode != Defines.BINARIES_THREADS_FUNCTIONS) + // && (drawMode != Defines.BINARIES_FUNCTIONS_THREADS) + // && (drawMode != Defines.FUNCTIONS_THREADS) + // && (drawMode != Defines.FUNCTIONS_THREADS_BINARIES) + // && (drawMode != Defines.FUNCTIONS_BINARIES_THREADS) + // ) + // { + // System.out.println(Messages.getString("GppTraceGraph.wrongDrawMode")); //$NON-NLS-1$ + // return; + // } + // + // // boolean to use inside loops (should trust a compiler to optimize this + // out of the loop...) + // boolean basedOnBinaries = (drawMode == Defines.BINARIES_THREADS) + // || (drawMode == Defines.BINARIES_THREADS_FUNCTIONS) + // || (drawMode == Defines.FUNCTIONS_BINARIES_THREADS); + // + // Hashtable profiledThreads = new + // Hashtable(); + // + // GenericSampledTrace trace = (GenericSampledTrace)this.getTrace(); + // int granularityValue = trace.samples.size() > + // GppTraceGraph.GRANULARITY_VALUE ? GppTraceGraph.GRANULARITY_VALUE : + // trace.samples.size(); + // + // String[] selectedItems; + // int[] selectedFunctionHashCodes = null; + // int[] selectedBinaryHashCodes = null; + // int count = 0; + // int timeStamp = 0; + // int stepValue = granularityValue; + // int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ + // boolean exit = false; + // + // Hashtable percentages = new + // Hashtable(); + // PIVisualSharedData shared = this.getSharedDataInstance(); + // + // if (basedOnBinaries) + // { + // selectedItems = shared.GPP_SelectedBinaryNames; + // if (selectedItems == null) + // { + // selectedItems = new String[0]; + // } + // int[] tmpHashCodes = new int[selectedItems.length]; + // for (int i = 0; i < selectedItems.length; i++) + // { + // String tmp = selectedItems[i]; + // tmpHashCodes[i] = tmp.hashCode(); + // } + // selectedBinaryHashCodes = tmpHashCodes; + // } + // else + // { + // selectedItems = shared.GPP_SelectedFunctionNames; + // if (selectedItems == null) + // { + // selectedItems = new String[0]; + // } + // int[] tmpHashCodes = new int[selectedItems.length]; + // for (int i = 0; i < selectedItems.length; i++) + // { + // String tmp = selectedItems[i]; + // tmpHashCodes[i] = tmp.hashCode(); + // } + // selectedFunctionHashCodes = tmpHashCodes; + // } + // + // for (Enumeration enumer = trace.getSamples(); !exit;) + // { + // exit = !enumer.hasMoreElements(); + // if (exit) + // { + // // for the final samples, modify the step value + // // so that they will also be included + // // now there are no new samples, so proceed directly to + // // adding the final values to the percent list + // stepValue = count; + // } + // else + // { + // count++; + // int compareValue = 0; + // boolean match = false; + // GppSample sample = (GppSample)enumer.nextElement(); + // if (basedOnBinaries) + // { + // compareValue = GppTraceGraphUtil.getBinaryName(sample).hashCode(); + // for (int i = 0; i < selectedBinaryHashCodes.length; i++) + // { + // if (compareValue == selectedBinaryHashCodes[i]) + // { + // match = true; + // break; + // } + // } + // } + // else + // { + // compareValue = GppTraceGraphUtil.getFunctionName(sample).hashCode(); + // for (int i = 0; i < selectedFunctionHashCodes.length; i++) + // { + // if (compareValue == selectedFunctionHashCodes[i]) + // { + // match = true; + // break; + // } + // } + // } + // + // if (match) + // { + // ProfiledThread pt = null; + // String name = sample.thread.threadName; + // if (profiledThreads.containsKey(name)) + // { + // pt = profiledThreads.get(name); + // } + // + // if (pt == null) + // { + // pt = new ProfiledThread(); + // + // pt.setNameString(name); + // pt.setColor(((GppTrace)this.getTrace()).getThreadColorPalette().getColor(name)); + // pt.setThreadId(sample.thread.threadId.intValue()); + // + // pt.setActivityMarkCount((trace.samples.size() + granularityValue) / + // granularityValue + 1); + // for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += + // stepValue * samplingInterval) + // { + // pt.zeroActivityMarkValues(i); + // } + // pt.setEnabled(this.graphIndex, true); + // profiledThreads.put(name, pt); + // } + // + // if (percentages.containsKey(pt)) + // { + // Integer value = percentages.get(pt); + // value = Integer.valueOf(value.intValue()+1); + // percentages.remove(pt); + // percentages.put(pt,value); + // } + // else + // { + // percentages.put(pt,Integer.valueOf(1)); + // } + // } + // } + // + // if (stepValue != 0 && count == stepValue) + // { + // Vector v = new + // Vector(profiledThreads.values()); + // Enumeration pfEnum = v.elements(); + // while (pfEnum.hasMoreElements()) + // { + // ProfiledThread updatePt = (ProfiledThread)pfEnum.nextElement(); + // if (percentages.containsKey(updatePt)) + // { + // int samples = ((percentages.get(updatePt))).intValue(); + // int finalPerc = (samples * 100) / stepValue; + // updatePt.addActivityMarkValues(timeStamp + stepValue * samplingInterval, + // finalPerc, samples); + // } + // else + // { + // updatePt.zeroActivityMarkValues(timeStamp + stepValue * + // samplingInterval); + // } + // } + // + // percentages.clear(); + // count = 0; + // timeStamp += stepValue * samplingInterval; + // } + // } + // + // this.threadTable.getTable().deselectAll(); + // this.threadTable.updateProfiledAndItemData(true); + // this.threadTable.getTable().redraw(); + // + // // if this is not the last table, set the selected names to set up + // // the next table + // if ( (drawMode == Defines.BINARIES_THREADS_FUNCTIONS) + // || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES)) + // { + // this.threadTable.setSelectedNames(); + // } + // else + // { + // // This may not be needed needed + // shared.GPP_SelectedThreadNames = new String[0]; + // } + // } + // + // /* + // * Because a table to the left of a binary table has changed, update + // * the binary table. + // * If there is no table to the right of this one, redraw the graph based + // * on the changed data. + // */ + // public void refreshProfiledBinaryData(int drawMode) + // { + // // Must have a table to its left + // if ( (drawMode != Defines.THREADS_BINARIES) + // && (drawMode != Defines.THREADS_BINARIES_FUNCTIONS) + // && (drawMode != Defines.THREADS_FUNCTIONS_BINARIES) + // && (drawMode != Defines.FUNCTIONS_BINARIES) + // && (drawMode != Defines.FUNCTIONS_BINARIES_THREADS) + // && (drawMode != Defines.FUNCTIONS_THREADS_BINARIES) + // ) + // { + // System.out.println(Messages.getString("GppTraceGraph.wrongDrawMode")); //$NON-NLS-1$ + // return; + // } + // + // // boolean to use inside loops (never trust a compiler...) + // boolean basedOnThreads = (drawMode == Defines.THREADS_BINARIES) + // || (drawMode == Defines.THREADS_BINARIES_FUNCTIONS) + // || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES); + // + // Hashtable profiledBinaries = new + // Hashtable(); + // + // GenericSampledTrace trace = (GenericSampledTrace)this.getTrace(); + // int granularityValue = trace.samples.size() > + // GppTraceGraph.GRANULARITY_VALUE ? GppTraceGraph.GRANULARITY_VALUE : + // trace.samples.size(); + // + // String[] selectedItems; + // int[] selectedThreadIds = null; + // int[] selectedFunctionHashCodes = null; + // int count = 0; + // int timeStamp = 0; + // int stepValue = granularityValue; + // int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ + // boolean exit = false; + // + // Hashtable percentages = new + // Hashtable(); + // PIVisualSharedData shared = this.getSharedDataInstance(); + // + // if (basedOnThreads) + // { + // selectedItems = shared.GPP_SelectedThreadNames; + // if (selectedItems == null) + // { + // selectedItems = new String[0]; + // } + // int[] tmpThreadIds = new int[selectedItems.length]; + // for (int i = 0; i < selectedItems.length; i++) + // { + // String tmp = selectedItems[i].substring(selectedItems[i].lastIndexOf('_') + // + 1, + // selectedItems[i].length()); + // tmpThreadIds[i] = Integer.parseInt(tmp); + // } + // selectedThreadIds = tmpThreadIds; + // } + // else + // { + // selectedItems = shared.GPP_SelectedFunctionNames; + // if (selectedItems == null) + // { + // selectedItems = new String[0]; + // } + // int[] tmpHashCodes = new int[selectedItems.length]; + // for (int i = 0; i < selectedItems.length; i++) + // { + // String tmp = selectedItems[i]; + // tmpHashCodes[i] = tmp.hashCode(); + // } + // selectedFunctionHashCodes = tmpHashCodes; + // } + // + // for (Enumeration enumer = trace.getSamples(); !exit;) + // { + // exit = !enumer.hasMoreElements(); + // if (exit) + // { + // // for the final samples, modify the step value + // // so that they will also be included + // // now there are no new samples, so proceed directly to + // // adding the final values to the percent list + // stepValue = count; + // } + // else + // { + // count++; + // int compareValue = 0; + // boolean match = false; + // GppSample sample = (GppSample)enumer.nextElement(); + // if (basedOnThreads) + // { + // compareValue = sample.thread.threadId.intValue(); + // for (int i = 0; i < selectedThreadIds.length; i++) + // { + // if (compareValue == selectedThreadIds[i]) + // { + // match = true; + // break; + // } + // } + // } + // else + // { + // compareValue = GppTraceGraphUtil.getFunctionName(sample).hashCode(); + // for (int i = 0; i < selectedFunctionHashCodes.length; i++) + // { + // if (compareValue == selectedFunctionHashCodes[i]) + // { + // match = true; + // break; + // } + // } + // } + // + // if (match) + // { + // ProfiledBinary pb = null; + // String name = GppTraceGraphUtil.getFunctionName(sample); + // if (profiledBinaries.containsKey(name)) + // { + // pb = profiledBinaries.get(name); + // } + // + // if (pb == null) + // { + // pb = new ProfiledBinary(); + // + // pb.setNameString(name); + // pb.setColor(((GppTrace)this.getTrace()).getBinaryColorPalette().getColor(name)); + // + // pb.setActivityMarkCount((trace.samples.size() + granularityValue) / + // granularityValue + 1); + // for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += + // stepValue * samplingInterval) + // { + // pb.zeroActivityMarkValues(i); + // } + // profiledBinaries.put(name, pb); + // } + // + // if (percentages.containsKey(pb)) + // { + // Integer value = percentages.get(pb); + // value = Integer.valueOf(value.intValue()+1); + // percentages.remove(pb); + // percentages.put(pb,value); + // } + // else + // { + // percentages.put(pb,Integer.valueOf(1)); + // } + // } + // } + // + // if (stepValue != 0 && count == stepValue) + // { + // Vector v = new + // Vector(profiledBinaries.values()); + // Enumeration pfEnum = v.elements(); + // while (pfEnum.hasMoreElements()) + // { + // ProfiledFunction updatePf = (ProfiledFunction)pfEnum.nextElement(); + // if (percentages.containsKey(updatePf)) + // { + // int samples = ((percentages.get(updatePf))).intValue(); + // int finalPerc = (samples * 100) / stepValue; + // updatePf.addActivityMarkValues(timeStamp + stepValue * samplingInterval, + // finalPerc, samples); + // } + // else + // { + // updatePf.zeroActivityMarkValues(timeStamp + stepValue * + // samplingInterval); + // } + // } + // + // percentages.clear(); + // count = 0; + // timeStamp += stepValue * samplingInterval; + // } + // } + // + // this.binaryTable.getTable().deselectAll(); + // this.binaryTable.updateProfiledAndItemData(true); + // this.binaryTable.getTable().redraw(); + // + // // if this is not the last table, set the selected names to set up + // // the next table + // if ( (drawMode == Defines.THREADS_BINARIES_FUNCTIONS) + // || (drawMode == Defines.FUNCTIONS_BINARIES_THREADS)) + // { + // this.binaryTable.setSelectedNames(); + // } + // else + // { + // // This may not be needed + // shared.GPP_SelectedBinaryNames = new String[0]; + // } + // } - if (this.vPanel != null) - { - this.vPanel.refreshCumulativeThreadTable(); + // public void updateGraph() + // { + // if (drawMode == Defines.BINARIES) + // { + // vPanel.refreshCumulativeThreadTable(); + // } + // else if (drawMode == Defines.THREADS) + // { + // vPanel.refreshCumulativeThreadTable(); + // } + // + // this.repaint(); + // } + + public void updateThreadTablePriorities( + Hashtable priorities) { + this.threadTable.addPriorityColumn(priorities); + } + + public int getDrawMode() { + return drawMode; + } + + public void setDrawMode(int drawMode) { + if ((drawMode == Defines.THREADS) + || (drawMode == Defines.THREADS_FUNCTIONS) + || (drawMode == Defines.THREADS_FUNCTIONS_BINARIES) + || (drawMode == Defines.THREADS_BINARIES) + || (drawMode == Defines.THREADS_BINARIES_FUNCTIONS) + || (drawMode == Defines.BINARIES) + || (drawMode == Defines.BINARIES_THREADS) + || (drawMode == Defines.BINARIES_THREADS_FUNCTIONS) + || (drawMode == Defines.BINARIES_FUNCTIONS) + || (drawMode == Defines.BINARIES_FUNCTIONS_THREADS) + || (drawMode == Defines.FUNCTIONS) + || (drawMode == Defines.FUNCTIONS_THREADS) + || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES) + || (drawMode == Defines.FUNCTIONS_BINARIES) + || (drawMode == Defines.FUNCTIONS_BINARIES_THREADS)) { + if (this.drawMode != drawMode) { + this.setGraphImageChanged(true); + this.drawMode = drawMode; + refreshMode(); + if (this.graphChangeListener != null){ + graphChangeListener.onTitleChange(getTitle()); + } + } + } else { + throw new IllegalArgumentException(Messages + .getString("GppTraceGraph.unknownDrawMode")); //$NON-NLS-1$ } } - public static void refreshDataFromTrace(GppTrace gppTrace) - { - Enumeration enumer = gppTrace.getSamples(); - - int granularityValue = gppTrace.samples.size() > GppTraceGraph.granularityValue ? GppTraceGraph.granularityValue : gppTrace.samples.size(); - - Hashtable profiledThreads = new Hashtable(); - Hashtable profiledBinaries = new Hashtable(); - Hashtable profiledFunctions = new Hashtable(); - - Hashtable threadPercentages = new Hashtable(); - Hashtable binaryPercentages = new Hashtable(); - Hashtable functionPercentages = new Hashtable(); - - int threadCount = 0; - int binaryCount = 0; - int functionCount = 0; - int count = 0; - int timeStamp = 0; - int stepValue = granularityValue; - char threadSymbol = 'A'; - int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ - - Vector sortedProfiledThreads = gppTrace.getSortedThreads(); - Vector sortedProfiledBinaries = gppTrace.getSortedBinaries(); - Vector sortedProfiledFunctions = gppTrace.getSortedFunctions(); - - Vector unsortedProfiledThreads = gppTrace.getIndexedThreads(); - Vector unsortedProfiledBinaries = gppTrace.getIndexedBinaries(); - Vector unsortedProfiledFunctions = gppTrace.getIndexedFunctions(); - - // reset these list so we can call refreshDataFromTrace mulitple times (e.g. import) while keeping size consistent - sortedProfiledThreads.clear(); - sortedProfiledBinaries.clear(); - sortedProfiledFunctions.clear(); - - unsortedProfiledThreads.clear(); - unsortedProfiledBinaries.clear(); - unsortedProfiledFunctions.clear(); - - boolean exit = false; - while (exit == false) - { - exit = !enumer.hasMoreElements(); - if (exit == true) - { - // for the final samples, modify the step value - // so that they will also be included - // now there are no new samples, so proceed directly to - // adding the final values to the percent list - stepValue = count; - } - else - { - count++; - - // there is at least one new sample in the enumeration, so resolve it - GppSample sample = (GppSample)enumer.nextElement(); - String threadName = sample.thread.process.name + "::" + sample.thread.threadName + "_" + sample.thread.threadId; //$NON-NLS-1$ //$NON-NLS-2$ - String binaryName = getBinaryName(sample); - String functionName = getFunctionName(sample); - - ProfiledThread pThread = null; - ProfiledBinary pBinary = null; - ProfiledFunction pFunction = null; - - // handle new thread names - if (profiledThreads.containsKey(threadName)) - { - pThread = (ProfiledThread)profiledThreads.get(threadName); - if (pThread.getThreadId() != sample.thread.threadId.intValue()) - { - // this was not the same thread, even though the - // name was the same - pThread = null; - } - } - - if (pThread == null) - { - pThread = new ProfiledThread(); - - pThread.setIndex(threadCount++); - pThread.setNameValues(threadSymbol++, threadName); - pThread.setColor(gppTrace.getThreadColorPalette().getColor(threadName)); - - pThread.setThreadId(sample.thread.threadId.intValue()); - - pThread.setActivityMarkCount((gppTrace.samples.size() + granularityValue) / granularityValue + 1); - for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += stepValue * samplingInterval) - { - pThread.zeroActivityMarkValues(i); - } - profiledThreads.put(threadName, pThread); - sortedProfiledThreads.add((ProfiledGeneric)pThread); - unsortedProfiledThreads.add((ProfiledGeneric)pThread); - } - - pThread.incTotalSampleCount(); - sample.threadIndex = pThread.getIndex(); - - if (threadPercentages.containsKey(pThread)) - { - Integer value = (Integer)threadPercentages.get(pThread); - value = new Integer(value.intValue()+1); - threadPercentages.remove(pThread); - threadPercentages.put(pThread, value); - } - else - { - threadPercentages.put(pThread, new Integer(1)); - } - - // handle new binary names - if (profiledBinaries.containsKey(binaryName)) - { - pBinary = (ProfiledBinary)profiledBinaries.get(binaryName); - } - - if (pBinary == null) - { - pBinary = new ProfiledBinary(); - - pBinary.setIndex(binaryCount++); - pBinary.setNameString(binaryName); - pBinary.setColor(gppTrace.getBinaryColorPalette().getColor(binaryName)); - - pBinary.setActivityMarkCount((gppTrace.samples.size() + granularityValue) / granularityValue + 1); - for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += stepValue * samplingInterval) - { - pBinary.zeroActivityMarkValues(i); - } - profiledBinaries.put(binaryName,pBinary); - sortedProfiledBinaries.add((ProfiledGeneric)pBinary); - unsortedProfiledBinaries.add((ProfiledGeneric)pBinary); - } - - pBinary.incTotalSampleCount(); - sample.binaryIndex = pBinary.getIndex(); - - if (binaryPercentages.containsKey(pBinary)) - { - Integer value = (Integer)binaryPercentages.get(pBinary); - value = new Integer(value.intValue()+1); - binaryPercentages.remove(pBinary); - binaryPercentages.put(pBinary,value); - } - else - { - binaryPercentages.put(pBinary, new Integer(1)); - } - - // handle new function names - if (profiledFunctions.containsKey(functionName)) - { - pFunction = (ProfiledFunction)profiledFunctions.get(functionName); - } - - if (pFunction == null) - { - pFunction = new ProfiledFunction(); - - pFunction.setIndex(functionCount++); - pFunction.setNameString(functionName); - pFunction.setFunctionAddress(getFunctionAddress(sample)); - pFunction.setFunctionBinaryName(binaryName); - pFunction.setColor(gppTrace.getFunctionColorPalette().getColor(functionName)); - - pFunction.setActivityMarkCount((gppTrace.samples.size() + granularityValue) / granularityValue + 1); - for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += stepValue * samplingInterval) - { - pFunction.zeroActivityMarkValues(i); - } - profiledFunctions.put(functionName,pFunction); - sortedProfiledFunctions.add((ProfiledGeneric)pFunction); - unsortedProfiledFunctions.add((ProfiledGeneric)pFunction); - } - - pFunction.incTotalSampleCount(); - sample.functionIndex = pFunction.getIndex(); - - if (functionPercentages.containsKey(pFunction)) - { - Integer value = (Integer)functionPercentages.get(pFunction); - value = new Integer(value.intValue()+1); - functionPercentages.remove(pFunction); - functionPercentages.put(pFunction,value); - } - else - { - functionPercentages.put(pFunction, new Integer(1)); - } - } - - // for each stepValue (or final values) samples - // add the data to the profiled threads, binaries, functions - if (stepValue != 0 && count == stepValue) - { - Vector tmpVector; - - tmpVector = new Vector(profiledThreads.values()); - Enumeration ptEnum = tmpVector.elements(); - while (ptEnum.hasMoreElements()) - { - ProfiledThread updatePt = (ProfiledThread)ptEnum.nextElement(); - if (threadPercentages.containsKey(updatePt)) - { - int samples = ((Integer)(threadPercentages.get(updatePt))).intValue(); - int finalPerc = (samples * 100) / stepValue; - updatePt.addActivityMarkValues(timeStamp + stepValue * samplingInterval, finalPerc, samples); - } - else - { - updatePt.zeroActivityMarkValues(timeStamp + stepValue * samplingInterval); - } - } - - tmpVector = new Vector(profiledBinaries.values()); - Enumeration pbEnum = tmpVector.elements(); - while (pbEnum.hasMoreElements()) - { - ProfiledBinary updatePb = (ProfiledBinary)pbEnum.nextElement(); - if (binaryPercentages.containsKey(updatePb)) - { - int samples = ((Integer)(binaryPercentages.get(updatePb))).intValue(); - int finalPerc = (samples * 100) / stepValue; - updatePb.addActivityMarkValues(timeStamp + stepValue * samplingInterval, finalPerc, samples); - } - else - { - updatePb.zeroActivityMarkValues(timeStamp + stepValue * samplingInterval); - } - } - - tmpVector = new Vector(profiledFunctions.values()); - Enumeration pfEnum = tmpVector.elements(); - while (pfEnum.hasMoreElements()) - { - ProfiledFunction updatePf = (ProfiledFunction)pfEnum.nextElement(); - if (functionPercentages.containsKey(updatePf)) - { - int samples = ((Integer)(functionPercentages.get(updatePf))).intValue(); - int finalPerc = (samples * 100) / stepValue; - updatePf.addActivityMarkValues(timeStamp + stepValue * samplingInterval, finalPerc, samples); - } - else - { - updatePf.zeroActivityMarkValues(timeStamp + stepValue * samplingInterval); - } - } - - threadPercentages.clear(); - binaryPercentages.clear(); - functionPercentages.clear(); - count = 0; - timeStamp += stepValue * samplingInterval; - } - } - - // if there is no end point for a profiled element with samples, set the end to the last sample in the trace - for (Enumeration e = profiledThreads.elements(); e.hasMoreElements(); ) { - ProfiledGeneric pg = e.nextElement(); - - if (pg.getRealLastSample() == -1 && pg.getTotalSampleCount() != 0) - pg.setLastSample(gppTrace.samples.size() * samplingInterval); - } - - for (Enumeration e = profiledBinaries.elements(); e.hasMoreElements(); ) { - ProfiledGeneric pg = e.nextElement(); - - if (pg.getRealLastSample() == -1 && pg.getTotalSampleCount() != 0) - pg.setLastSample(gppTrace.samples.size() * samplingInterval); - } - - for (Enumeration e = profiledFunctions.elements(); e.hasMoreElements(); ) { - ProfiledGeneric pg = e.nextElement(); - - if (pg.getRealLastSample() == -1 && pg.getTotalSampleCount() != 0) - pg.setLastSample(gppTrace.samples.size() * samplingInterval); - } - - // sort the thread, binary, and function vectors by load - sortProfiledGenerics(profiledThreads, gppTrace); - sortProfiledGenerics(profiledBinaries, gppTrace); - sortProfiledGenerics(profiledFunctions, gppTrace); - - // the trace-level count arrays are initialized to 0 - gppTrace.setThreadSampleCounts(new int[profiledThreads.size()]); - gppTrace.setBinarySampleCounts(new int[profiledBinaries.size()]); - gppTrace.setFunctionSampleCounts(new int[profiledFunctions.size()]); + private void refreshMode() { + this.vPanel.refreshCumulativeThreadTable(); } - - /* - * Because a table to the left of a function table has changed, update - * the function table. - * If there is no table to the right of this one, redraw the graph based - * on the changed data. - */ - public void refreshProfiledThreadData(int drawMode) - { - // Must have a table to its left - if ( (drawMode != Defines.BINARIES_THREADS) - && (drawMode != Defines.BINARIES_THREADS_FUNCTIONS) - && (drawMode != Defines.BINARIES_FUNCTIONS_THREADS) - && (drawMode != Defines.FUNCTIONS_THREADS) - && (drawMode != Defines.FUNCTIONS_THREADS_BINARIES) - && (drawMode != Defines.FUNCTIONS_BINARIES_THREADS) - ) - { - System.out.println(Messages.getString("GppTraceGraph.wrongDrawMode")); //$NON-NLS-1$ - return; - } - - // boolean to use inside loops (should trust a compiler to optimize this out of the loop...) - boolean basedOnBinaries = (drawMode == Defines.BINARIES_THREADS) - || (drawMode == Defines.BINARIES_THREADS_FUNCTIONS) - || (drawMode == Defines.FUNCTIONS_BINARIES_THREADS); - - Hashtable profiledThreads = new Hashtable(); - - GenericSampledTrace trace = (GenericSampledTrace)this.getTrace(); - int granularityValue = trace.samples.size() > GppTraceGraph.granularityValue ? GppTraceGraph.granularityValue : trace.samples.size(); - - String[] selectedItems; - int[] selectedFunctionHashCodes = null; - int[] selectedBinaryHashCodes = null; - int count = 0; - int timeStamp = 0; - int stepValue = granularityValue; - int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ - boolean exit = false; - - Hashtable percentages = new Hashtable(); - PIVisualSharedData shared = this.getSharedDataInstance(); - - if (basedOnBinaries) - { - selectedItems = shared.GPP_SelectedBinaryNames; - if (selectedItems == null) - { - selectedItems = new String[0]; - } - int[] tmpHashCodes = new int[selectedItems.length]; - for (int i = 0; i < selectedItems.length; i++) - { - String tmp = selectedItems[i]; - tmpHashCodes[i] = tmp.hashCode(); - } - selectedBinaryHashCodes = tmpHashCodes; - } - else - { - selectedItems = shared.GPP_SelectedFunctionNames; - if (selectedItems == null) - { - selectedItems = new String[0]; - } - int[] tmpHashCodes = new int[selectedItems.length]; - for (int i = 0; i < selectedItems.length; i++) - { - String tmp = selectedItems[i]; - tmpHashCodes[i] = tmp.hashCode(); - } - selectedFunctionHashCodes = tmpHashCodes; - } - - for (Enumeration enumer = trace.getSamples(); !exit;) - { - exit = !enumer.hasMoreElements(); - if (exit) - { - // for the final samples, modify the step value - // so that they will also be included - // now there are no new samples, so proceed directly to - // adding the final values to the percent list - stepValue = count; - } - else - { - count++; - int compareValue = 0; - boolean match = false; - GppSample sample = (GppSample)enumer.nextElement(); - if (basedOnBinaries) - { - compareValue = getBinaryName(sample).hashCode(); - for (int i = 0; i < selectedBinaryHashCodes.length; i++) - { - if (compareValue == selectedBinaryHashCodes[i]) - { - match = true; - break; - } - } - } - else - { - compareValue = getFunctionName(sample).hashCode(); - for (int i = 0; i < selectedFunctionHashCodes.length; i++) - { - if (compareValue == selectedFunctionHashCodes[i]) - { - match = true; - break; - } - } - } - - if (match) - { - ProfiledThread pt = null; - String name = sample.thread.threadName; - if (profiledThreads.containsKey(name)) - { - pt = (ProfiledThread)profiledThreads.get(name); - } - - if (pt == null) - { - pt = new ProfiledThread(); - - pt.setNameString(name); - pt.setColor(((GppTrace)this.getTrace()).getThreadColorPalette().getColor(name)); - pt.setThreadId(sample.thread.threadId.intValue()); - - pt.setActivityMarkCount((trace.samples.size() + granularityValue) / granularityValue + 1); - for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += stepValue * samplingInterval) - { - pt.zeroActivityMarkValues(i); - } - pt.setEnabled(this.graphIndex, true); - profiledThreads.put(name, pt); - } - - if (percentages.containsKey(pt)) - { - Integer value = (Integer)percentages.get(pt); - value = new Integer(value.intValue()+1); - percentages.remove(pt); - percentages.put(pt,value); - } - else - { - percentages.put(pt,new Integer(1)); - } - } - } - - if (stepValue != 0 && count == stepValue) - { - Vector v = new Vector(profiledThreads.values()); - Enumeration pfEnum = v.elements(); - while (pfEnum.hasMoreElements()) - { - ProfiledThread updatePt = (ProfiledThread)pfEnum.nextElement(); - if (percentages.containsKey(updatePt)) - { - int samples = ((Integer)(percentages.get(updatePt))).intValue(); - int finalPerc = (samples * 100) / stepValue; - updatePt.addActivityMarkValues(timeStamp + stepValue * samplingInterval, finalPerc, samples); - } - else - { - updatePt.zeroActivityMarkValues(timeStamp + stepValue * samplingInterval); - } - } - - percentages.clear(); - count = 0; - timeStamp += stepValue * samplingInterval; - } - } - - this.threadTable.getTable().deselectAll(); - this.threadTable.updateProfiledAndItemData(true); - this.threadTable.getTable().redraw(); - - // if this is not the last table, set the selected names to set up - // the next table - if ( (drawMode == Defines.BINARIES_THREADS_FUNCTIONS) - || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES)) - { - this.threadTable.setSelectedNames(); - } - else - { - // This may not be needed needed - shared.GPP_SelectedThreadNames = new String[0]; - } - } - - /* - * Because a table to the left of a binary table has changed, update - * the binary table. - * If there is no table to the right of this one, redraw the graph based - * on the changed data. - */ - public void refreshProfiledBinaryData(int drawMode) - { - // Must have a table to its left - if ( (drawMode != Defines.THREADS_BINARIES) - && (drawMode != Defines.THREADS_BINARIES_FUNCTIONS) - && (drawMode != Defines.THREADS_FUNCTIONS_BINARIES) - && (drawMode != Defines.FUNCTIONS_BINARIES) - && (drawMode != Defines.FUNCTIONS_BINARIES_THREADS) - && (drawMode != Defines.FUNCTIONS_THREADS_BINARIES) - ) - { - System.out.println(Messages.getString("GppTraceGraph.wrongDrawMode")); //$NON-NLS-1$ - return; - } - - // boolean to use inside loops (never trust a compiler...) - boolean basedOnThreads = (drawMode == Defines.THREADS_BINARIES) - || (drawMode == Defines.THREADS_BINARIES_FUNCTIONS) - || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES); - - Hashtable profiledBinaries = new Hashtable(); - - GenericSampledTrace trace = (GenericSampledTrace)this.getTrace(); - int granularityValue = trace.samples.size() > GppTraceGraph.granularityValue ? GppTraceGraph.granularityValue : trace.samples.size(); - - String[] selectedItems; - int[] selectedThreadIds = null; - int[] selectedFunctionHashCodes = null; - int count = 0; - int timeStamp = 0; - int stepValue = granularityValue; - int samplingInterval = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.samplingInterval"); //$NON-NLS-1$ - boolean exit = false; - - Hashtable percentages = new Hashtable(); - PIVisualSharedData shared = this.getSharedDataInstance(); - - if (basedOnThreads) - { - selectedItems = shared.GPP_SelectedThreadNames; - if (selectedItems == null) - { - selectedItems = new String[0]; - } - int[] tmpThreadIds = new int[selectedItems.length]; - for (int i = 0; i < selectedItems.length; i++) - { - String tmp = selectedItems[i].substring(selectedItems[i].lastIndexOf('_') + 1, - selectedItems[i].length()); - tmpThreadIds[i] = Integer.parseInt(tmp); - } - selectedThreadIds = tmpThreadIds; - } - else - { - selectedItems = shared.GPP_SelectedFunctionNames; - if (selectedItems == null) - { - selectedItems = new String[0]; - } - int[] tmpHashCodes = new int[selectedItems.length]; - for (int i = 0; i < selectedItems.length; i++) - { - String tmp = selectedItems[i]; - tmpHashCodes[i] = tmp.hashCode(); - } - selectedFunctionHashCodes = tmpHashCodes; - } - - for (Enumeration enumer = trace.getSamples(); !exit;) - { - exit = !enumer.hasMoreElements(); - if (exit) - { - // for the final samples, modify the step value - // so that they will also be included - // now there are no new samples, so proceed directly to - // adding the final values to the percent list - stepValue = count; - } - else - { - count++; - int compareValue = 0; - boolean match = false; - GppSample sample = (GppSample)enumer.nextElement(); - if (basedOnThreads) - { - compareValue = sample.thread.threadId.intValue(); - for (int i = 0; i < selectedThreadIds.length; i++) - { - if (compareValue == selectedThreadIds[i]) - { - match = true; - break; - } - } - } - else - { - compareValue = getFunctionName(sample).hashCode(); - for (int i = 0; i < selectedFunctionHashCodes.length; i++) - { - if (compareValue == selectedFunctionHashCodes[i]) - { - match = true; - break; - } - } - } - - if (match) - { - ProfiledBinary pb = null; - String name = getFunctionName(sample); - if (profiledBinaries.containsKey(name)) - { - pb = (ProfiledBinary)profiledBinaries.get(name); - } - - if (pb == null) - { - pb = new ProfiledBinary(); - - pb.setNameString(name); - pb.setColor(((GppTrace)this.getTrace()).getBinaryColorPalette().getColor(name)); - - pb.setActivityMarkCount((trace.samples.size() + granularityValue) / granularityValue + 1); - for (int i = 0; i < timeStamp + stepValue * samplingInterval; i += stepValue * samplingInterval) - { - pb.zeroActivityMarkValues(i); - } - profiledBinaries.put(name, pb); - } - - if (percentages.containsKey(pb)) - { - Integer value = (Integer)percentages.get(pb); - value = new Integer(value.intValue()+1); - percentages.remove(pb); - percentages.put(pb,value); - } - else - { - percentages.put(pb,new Integer(1)); - } - } - } - - if (stepValue != 0 && count == stepValue) - { - Vector v = new Vector(profiledBinaries.values()); - Enumeration pfEnum = v.elements(); - while (pfEnum.hasMoreElements()) - { - ProfiledFunction updatePf = (ProfiledFunction)pfEnum.nextElement(); - if (percentages.containsKey(updatePf)) - { - int samples = ((Integer)(percentages.get(updatePf))).intValue(); - int finalPerc = (samples * 100) / stepValue; - updatePf.addActivityMarkValues(timeStamp + stepValue * samplingInterval, finalPerc, samples); - } - else - { - updatePf.zeroActivityMarkValues(timeStamp + stepValue * samplingInterval); - } - } - - percentages.clear(); - count = 0; - timeStamp += stepValue * samplingInterval; - } - } - - this.binaryTable.getTable().deselectAll(); - this.binaryTable.updateProfiledAndItemData(true); - this.binaryTable.getTable().redraw(); - - // if this is not the last table, set the selected names to set up - // the next table - if ( (drawMode == Defines.THREADS_BINARIES_FUNCTIONS) - || (drawMode == Defines.FUNCTIONS_BINARIES_THREADS)) - { - this.binaryTable.setSelectedNames(); - } - else - { - // This may not be needed - shared.GPP_SelectedBinaryNames = new String[0]; - } - } - - // sort profiled generics by decreasing total sample count - private static void sortProfiledGenerics(Hashtable prof, GppTrace gppTrace) - { - // use an insertion sort to create a sorted linked list - // from the hashtable values - Collection values = prof.values(); - Vector unsorted = new Vector(values); - LinkedList sorted = new LinkedList(); - - Enumeration prEnum = unsorted.elements(); - while (prEnum.hasMoreElements()) - { - ProfiledGeneric pg = prEnum.nextElement(); - if (sorted.size() == 0) - { - sorted.addFirst(pg); - } - else - { - Iterator i = sorted.iterator(); - boolean ok = false; - while (i.hasNext()) - { - ProfiledGeneric next = (ProfiledGeneric)i.next(); - if (next.getTotalSampleCount() < pg.getTotalSampleCount()) - { - sorted.add(sorted.indexOf(next), pg); - ok = true; - break; - } - } - if (!ok) - sorted.addLast(pg); - } - } - - // Add the sorted data - Iterator iterator = sorted.iterator(); - if (sorted.size() > 0) - { - Vector v = null; - if (sorted.get(0) instanceof ProfiledThread) - { - v = gppTrace.getSortedThreads(); - } - else if (sorted.get(0) instanceof ProfiledBinary) - { - v = gppTrace.getSortedBinaries(); - } - else if (sorted.get(0) instanceof ProfiledFunction) - { - v = gppTrace.getSortedFunctions(); - } - if (v != null) - { - v.clear(); - while (iterator.hasNext()) - v.add(0, iterator.next()); - } - } - } - - public void updateGraph() - { - if (drawMode == Defines.BINARIES) - { - vPanel.refreshCumulativeThreadTable(); - } - else if (drawMode == Defines.THREADS) - { - vPanel.refreshCumulativeThreadTable(); - } - - this.repaint(); - } - - public void updateThreadTablePriorities(Hashtable priorities) - { - this.threadTable.addPriorityColumn(priorities); - } - - static private String stringNotFound = Messages.getString("GppTraceGraph.notFound"); //$NON-NLS-1$ - - static private String stringBinaryAt = Messages.getString("GppTraceGraph.binaryAt"); //$NON-NLS-1$ - static private String stringBinaryForAddress = Messages.getString("GppTraceGraph.binaryForAddress"); //$NON-NLS-1$ - static private String stringBinaryNotFound = Messages.getString("GppTraceGraph.binaryNotFound"); //$NON-NLS-1$ - - static private String stringFunctionAt = Messages.getString("GppTraceGraph.functionAt"); //$NON-NLS-1$ - static private String stringFunctionForAddress = Messages.getString("GppTraceGraph.functionForAddress"); //$NON-NLS-1$ - static private String stringFunctionNotFound = Messages.getString("GppTraceGraph.functionNotFound"); //$NON-NLS-1$ - - public static String getBinaryName(GppSample s) - { - String name = null; - - if (s.currentFunctionSym != null) - name = s.currentFunctionSym.functionBinary.binaryName; - - if ( (s.currentFunctionItt != null) - && ((name == null) || name.endsWith(stringNotFound))) - { - name = s.currentFunctionItt.functionBinary.binaryName; - } - - if ( name == null - || name.startsWith(stringBinaryAt) - || name.startsWith(stringBinaryForAddress)) - { - name = stringBinaryNotFound; - } - return name; - } - - public static String getFunctionName(GppSample s) - { - String name = null; - if (s.currentFunctionSym != null) - name = s.currentFunctionSym.functionName; - - if ( (s.currentFunctionItt != null) - && ((name == null) || name.endsWith(stringNotFound))) - { - name = s.currentFunctionItt.functionName; - } - - if ( (name == null) - || (name.startsWith(stringFunctionAt)) - || (name.startsWith(stringFunctionForAddress))) - { - name = stringFunctionNotFound; - } - - return name; - } - - public static long getFunctionAddress(GppSample s) - { - if (s.currentFunctionSym != null) - { - String name = s.currentFunctionSym.functionName; - if ( (s.currentFunctionItt != null) - && (name == null || name.endsWith(Messages.getString("GppTraceGraph.notFound")))) //$NON-NLS-1$ - { - return s.currentFunctionItt.startAddress.longValue(); - } - else - { - return s.currentFunctionSym.startAddress.longValue(); - } - } - else if (s.currentFunctionItt != null) - { - if (s.currentFunctionItt.functionName == null) - { - if (s.currentFunctionSym != null) - return s.currentFunctionSym.startAddress.longValue(); - } - else - { - return s.currentFunctionItt.startAddress.longValue(); - } - } - - return 0; - } - - public int getDrawMode() - { - return drawMode; - } - - public void setDrawMode(int drawMode) - { - if ( - (drawMode == Defines.THREADS) - || (drawMode == Defines.THREADS_FUNCTIONS) - || (drawMode == Defines.THREADS_FUNCTIONS_BINARIES) - || (drawMode == Defines.THREADS_BINARIES) - || (drawMode == Defines.THREADS_BINARIES_FUNCTIONS) - || (drawMode == Defines.BINARIES) - || (drawMode == Defines.BINARIES_THREADS) - || (drawMode == Defines.BINARIES_THREADS_FUNCTIONS) - || (drawMode == Defines.BINARIES_FUNCTIONS) - || (drawMode == Defines.BINARIES_FUNCTIONS_THREADS) - || (drawMode == Defines.FUNCTIONS) - || (drawMode == Defines.FUNCTIONS_THREADS) - || (drawMode == Defines.FUNCTIONS_THREADS_BINARIES) - || (drawMode == Defines.FUNCTIONS_BINARIES) - || (drawMode == Defines.FUNCTIONS_BINARIES_THREADS)) - { - if (this.drawMode != drawMode) { - this.setGraphImageChanged(true); - } - this.drawMode = drawMode; - refreshMode(); - } - else - { - System.out.println(Messages.getString("GppTraceGraph.unknownDrawMode")); //$NON-NLS-1$ - this.drawMode = Defines.THREADS; - refreshMode(); - } - } - - private void refreshMode() - { - this.vPanel.refreshCumulativeThreadTable(); - } public int getUid() { return this.uid; } - - public GppTraceGraph getTraceGraph() { - return this.thisTraceGraph; - } - + public void setLeftSash(Sash leftSash) { this.leftSash = leftSash; } - + public Sash getLeftSash() { return this.leftSash; } - + public void setRightSash(Sash rightSash) { this.rightSash = rightSash; } - + public Sash getRightSash() { return this.rightSash; } @@ -2305,11 +2139,11 @@ public void setProfiledThreads(Vector profiledThreads) { this.profiledThreads = profiledThreads; } - + public Vector getProfiledThreads() { return this.profiledThreads; } - + public Vector getSortedThreads() { return this.sortedProfiledThreads; } @@ -2317,11 +2151,11 @@ public void setProfiledBinaries(Vector profiledBinaries) { this.profiledBinaries = profiledBinaries; } - + public Vector getProfiledBinaries() { return this.profiledBinaries; } - + public Vector getSortedBinaries() { return this.sortedProfiledBinaries; } @@ -2329,27 +2163,206 @@ public void setProfiledFunctions(Vector profiledFunctions) { this.profiledFunctions = profiledFunctions; } - + public Vector getProfiledFunctions() { return this.profiledFunctions; } - + public Vector getSortedFunctions() { return this.sortedProfiledFunctions; } - + public ProfiledThreshold getThresholdThread() { return thresholdThread; } - + public ProfiledThreshold getThresholdBinary() { return thresholdBinary; } - + public ProfiledThreshold getThresholdFunction() { return thresholdFunction; } + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events + * .MouseEvent) + */ public void mouseMove(org.eclipse.swt.events.MouseEvent e) { } + + /* (non-Javadoc) + * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#graphVisibilityChanged(boolean) + */ + @Override + public void graphVisibilityChanged(boolean visible){ + getGppTrace().setLegendVisible(graphIndex, visible, holdTablesComposite); + } + + /* (non-Javadoc) + * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#graphMaximized(boolean) + */ + @Override + public void graphMaximized(boolean value){ + //TODO this needs to be re-implemented probably using setVisible() on all graphs (rather than calling max on one graph) + getGppTrace().setLegendMaximised(graphIndex, value, holdTablesComposite); + } + + /* + * (non-Javadoc) + * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#graphMaximized(boolean) + */ + public void refreshColoursFromTrace() { + if (graphIndex == PIPageEditor.THREADS_PAGE) { + getThreadTable().addColor(Defines.THREADS); + } else if (graphIndex == PIPageEditor.BINARIES_PAGE) { + getBinaryTable().addColor(Defines.BINARIES); + } else if (graphIndex == PIPageEditor.FUNCTIONS_PAGE) { + getFunctionTable().addColor(Defines.FUNCTIONS); + } + } + + /* (non-Javadoc) + * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#doGetActivityList(com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric) + */ + @Override + protected float[] doGetActivityList(ProfiledGeneric pg) { + return adapter.getActivityList(pg); + } + + /* (non-Javadoc) + * @see com.nokia.carbide.cpp.pi.visual.IGenericTraceGraph#getTitle() + */ + @Override + public String getTitle() { + return String.format(Messages.getString("GppTraceGraph.2"), title, getTranslatedDrawMode()); //$NON-NLS-1$ + } + + private String getTranslatedDrawMode() { + String s = EMPTY_STRING; + + switch (this.drawMode) { + case Defines.THREADS: { + s = Messages.getString("GppTraceGraph.3"); //$NON-NLS-1$ + break; + } + case Defines.THREADS_FUNCTIONS: { + s = Messages.getString("GppTraceGraph.4"); //$NON-NLS-1$ + break; + } + case Defines.THREADS_FUNCTIONS_BINARIES: { + s = Messages.getString("GppTraceGraph.5"); //$NON-NLS-1$ + break; + } + case Defines.THREADS_BINARIES: { + s = Messages.getString("GppTraceGraph.6"); //$NON-NLS-1$ + break; + } + case Defines.THREADS_BINARIES_FUNCTIONS: { + s = Messages.getString("GppTraceGraph.7"); //$NON-NLS-1$ + break; + } + case Defines.BINARIES: { + s = Messages.getString("GppTraceGraph.8"); //$NON-NLS-1$ + break; + } + case Defines.BINARIES_THREADS: { + s = Messages.getString("GppTraceGraph.9"); //$NON-NLS-1$ + break; + } + case Defines.BINARIES_THREADS_FUNCTIONS: { + s = Messages.getString("GppTraceGraph.10"); //$NON-NLS-1$ + break; + } + case Defines.BINARIES_FUNCTIONS: { + s = Messages.getString("GppTraceGraph.11"); //$NON-NLS-1$ + break; + } + case Defines.BINARIES_FUNCTIONS_THREADS: { + s = Messages.getString("GppTraceGraph.12"); //$NON-NLS-1$ + break; + } + case Defines.FUNCTIONS: { + s = Messages.getString("GppTraceGraph.13"); //$NON-NLS-1$ + break; + } + case Defines.FUNCTIONS_THREADS: { + s = Messages.getString("GppTraceGraph.14"); //$NON-NLS-1$ + break; + } + case Defines.FUNCTIONS_THREADS_BINARIES: { + s = Messages.getString("GppTraceGraph.15"); //$NON-NLS-1$ + break; + } + case Defines.FUNCTIONS_BINARIES: { + s = Messages.getString("GppTraceGraph.16"); //$NON-NLS-1$ + break; + } + case Defines.FUNCTIONS_BINARIES_THREADS: { + s = Messages.getString("GppTraceGraph.17"); //$NON-NLS-1$ + break; + } + default: + break; + } + return s; + } + + /* (non-Javadoc) + * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#getShortTitle() + */ + @Override + public String getShortTitle() { + return shortTitle; + } + + public Action[] addTitleBarMenuItems() { + return null; + } + + /* (non-Javadoc) + * @see com.nokia.carbide.cpp.internal.pi.plugin.model.ITitleBarMenu#getContextHelpId() + */ + public String getContextHelpId() { + return AddressPlugin.getPageHelpContextId(GppTraceUtil.getPageIndex(graphIndex)); + } + + /* (non-Javadoc) + * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#setVisible(boolean) + */ + @Override + public void setVisible(boolean show) { + super.setVisible(show); //this sets visibility of the graph component + } + + /* (non-Javadoc) + * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph#isGraphMinimizedWhenOpened() + */ + @Override + public boolean isGraphMinimizedWhenOpened(){ + // CPU load graph is shown when view is opened + return false; + } + + public void addContextMenuItems(Menu menu, + org.eclipse.swt.events.MouseEvent me) { + if (getGppTrace() != null && getGppTrace().getCPUCount() > 1){ + new MenuItem(menu, SWT.SEPARATOR); + + final boolean isSeparate = this instanceof GppTraceGraphSMP; + + MenuItem changeViewAction = new MenuItem(menu, SWT.PUSH); + changeViewAction.setText(isSeparate ? Messages.getString("GppTraceGraph.18") : Messages.getString("GppTraceGraph.19")); //$NON-NLS-1$ //$NON-NLS-2$ + changeViewAction.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + AddressPlugin.getDefault().receiveSelectionEvent(isSeparate ? AddressPlugin.ACTION_COMBINED_CPU_VIEW : AddressPlugin.ACTION_SEPARATE_CPU_VIEW); + } + }); + } + + } + }