sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ChunksGraph.java
changeset 7 8e12a575a9b5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/ui/graphs/ChunksGraph.java	Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,440 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+package com.nokia.s60tools.swmtanalyser.ui.graphs;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Polyline;
+import org.eclipse.draw2d.geometry.PointList;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.widgets.Display;
+
+import com.nokia.s60tools.swmtanalyser.data.ChunksData;
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks;
+import com.nokia.s60tools.swmtanalyser.model.SWMTLogReaderUtils;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * This class contains all needed logic to paint data related to Global and Non-Heap chunks. 
+ *
+ */
+public class ChunksGraph extends GenericGraph {
+	
+	private HashMap<String, ArrayList<GlobalDataChunks>> chunksData = new HashMap<String, ArrayList<GlobalDataChunks>>();
+	private HashMap<String, ArrayList<ChunksData>> nonHeapChunksData = new HashMap<String, ArrayList<ChunksData>>();
+	
+	private HashMap<String, Polyline> pointsData = new HashMap<String, Polyline>();
+	
+	private double visY;
+	private double multiplier;
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paint(org.eclipse.draw2d.Graphics)
+	 */
+	public void paint(Graphics graphics) {
+		
+		DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint START");
+
+		ArrayList<String> chunksList = this.getUserSelectedItems();
+				
+		 if(chunksList == null)
+			 return;
+
+		// Storing original settings before graphs are painted with case-specific settings
+		int origLineWidth = graphics.getLineWidth();		
+		Color origColor = graphics.getForegroundColor();
+		int origLineStyle = graphics.getLineStyle();
+					 
+		// Setting graph drawing specific settings
+		graphics.setLineWidth(CommonGraphConstants.DEFAULT_GRAPH_LINE_WIDTH);		
+		graphics.setLineStyle(SWT.LINE_SOLID);
+		
+		 int [] listX = this.calculateTimeIntervals();
+		 this.lastSampleTime = listX[listX.length-1];
+				 
+		 int k=0;
+		 
+		 for(String chnk: chunksList)
+		 { 
+			 if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
+				 valuesToBePlotted = getGlobalChnkSizeData(chnk);
+			 else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
+				 valuesToBePlotted = getNonHeapChnkSizeData(chnk);
+			
+			 int [] points = new int[valuesToBePlotted.length *2];
+			
+			 double visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE;
+			 boolean handleDeleted = false;
+			 
+			 List<List<Integer>> ListOfSolidLinePoints = new ArrayList<List<Integer>>();			 
+			 ArrayList<Integer> solidLinePoints = new ArrayList<Integer>();
+			 
+			 for (int i = 0, j = 0; i < valuesToBePlotted.length; i++, j++)
+			 {
+				if (valuesToBePlotted[i] <= 0){
+					// Not showing zero values to a user, not meaningful data 
+					DbgUtility.println(DbgUtility.PRIORITY_LOOP, "continued because value <= 0");
+					continue;
+				}				 
+				 
+				 int x_point = (int)(listX[i]/getScale());
+			     int y_point =(int) (visY - valuesToBePlotted[i] /multiplier);
+
+			     points[j] = x_point;
+				 points[++j] = y_point;
+			
+				 if(!handleDeleted){						
+					 if(y_point > 0){
+						 solidLinePoints.add(x_point);
+						 solidLinePoints.add(y_point);
+							 DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 1: x_point: " + x_point + ", y_point: " + y_point);
+						 }
+						 else{
+						    DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value");
+						 }
+				 }
+				 
+				 boolean handleStatus = getHandleStatus(i+1, chnk);
+				 
+				 if(handleStatus && !handleDeleted){
+					 handleDeleted = true;
+
+					 if(solidLinePoints.size() > 0)
+						 ListOfSolidLinePoints.add(solidLinePoints);
+					 
+					 solidLinePoints = new ArrayList<Integer>();
+				 }
+				 
+				 if(handleDeleted && getChunkStatus(i+1, chnk)== CycleData.New )
+				 {
+					 handleDeleted = false;					 
+					 if(y_point > 0){
+						 // Graphing only positive values
+						 solidLinePoints.add(x_point);
+						 solidLinePoints.add(y_point);					 
+						 DbgUtility.println(DbgUtility.PRIORITY_LOOP, "add 2:x_point: " + x_point + ", y_point: " + y_point);
+					 }
+					 else{
+					    DbgUtility.println(DbgUtility.PRIORITY_LOOP, "skipped because zero value");
+					 }					 
+				 }
+				 
+				 points[i] = x_point;
+				 points[i+1] = y_point;
+			 }
+			 
+			 if(solidLinePoints.size() > 0)
+				 ListOfSolidLinePoints.add(solidLinePoints);
+			 
+			 graphics.setForegroundColor(this.getColors().get(k));
+			 graphics.setLineWidth(2);
+			 			
+			 for(int i=0; i < ListOfSolidLinePoints.size(); i++)
+			 {
+				int [] solidPts = GraphsUtils.CreateIntArrayFromIntegerList(ListOfSolidLinePoints.get(i));
+						
+				if(solidPts != null)
+				{
+					if(ListOfSolidLinePoints.size() > 1)
+					{
+						int instance_id = i+1;
+						graphics.drawString("(0" + instance_id + ")", solidPts[0]+2, solidPts[1] - 15);
+					}
+					graphics.setLineStyle(SWT.LINE_SOLID);
+					graphics.drawPolyline(solidPts);
+					
+					// Drawing markers to the data points
+					GraphsUtils.drawMarkers(graphics, solidPts);
+				}
+			}
+			
+			 Polyline line = new Polyline();
+			 line.setPoints(new PointList(points)); 
+			 			
+			 pointsData.put(chnk, line);
+			 		 
+			 k++;
+		}
+			 
+			// Restoring original settings before paint call
+			graphics.setLineStyle(origLineStyle);
+			graphics.setForegroundColor(origColor);
+			graphics.setLineWidth(origLineWidth);
+
+			DbgUtility.println(DbgUtility.PRIORITY_OPERATION, this.getClass().getSimpleName() + "/paint END");
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#paintYAxis(org.eclipse.swt.graphics.GC)
+	 */
+	public void paintYAxis(GC gc) {
+	
+		visY = visualSizeY - CommonGraphConstants.XLEGENDSPACE; 
+		multiplier = GraphsUtils.prettyMaxBytes(maxBytes) / visY;
+		
+		double yIncrement = visY / 10;
+		int previousBottom = 0;
+		
+		for (int k = 10; k >= 0; k--)
+		{
+			// location for the value indicator is k * 1/10 the height of the display
+			int y = (int) (visY - (yIncrement * k));
+		
+			int bytes = (int)(yIncrement * multiplier) * k;  	
+
+			String legend = "";
+			
+			if (maxBytes < 10000)
+			{
+				legend += bytes + " B"; //$NON-NLS-1$
+			}
+			else if (maxBytes <= 500 * 1024)
+			{
+				legend += (bytes / 1024) + " KB"; //$NON-NLS-1$
+			}
+			else
+			{
+				legend +=  MBformat.format(((float) bytes / (1024 * 1024)))  + " MB"; //$NON-NLS-1$
+			}
+			Point extent = gc.stringExtent(legend);
+			
+			gc.drawLine(CommonGraphConstants.YLEGENDSPACE - 3, (int)y + 1, CommonGraphConstants.YLEGENDSPACE, (int)y + 1);
+			
+			if (y >= previousBottom)
+			{
+				gc.drawString(legend, CommonGraphConstants.YLEGENDSPACE - extent.x -2, (int)y);
+				previousBottom = (int)y + extent.y;
+			}
+		}
+
+		final Image image = this.getVerticalLabel("Bytes");
+		gc.setAdvanced(true);
+		final org.eclipse.swt.graphics.Rectangle rect2 = image.getBounds();
+		Transform transform = new Transform(Display.getDefault());
+
+		transform.translate(rect2.height / 2f, rect2.width / 2f);
+		transform.rotate(-90);
+		transform.translate(-rect2.width / 2f, -rect2.height / 2f);
+
+		gc.setTransform(transform);
+		gc.drawImage(image, -(int)visY/3, 1);
+
+		transform.dispose();
+		gc.dispose();				
+
+	}
+
+	private void fetchEntireDataForSelectedChunks()
+	{
+		ArrayList<String> selectedChunks = this.getUserSelectedItems();
+		
+		SWMTLogReaderUtils utils = new SWMTLogReaderUtils();
+		
+		if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
+		{
+			for(String chunk:selectedChunks)
+			{
+				ArrayList<GlobalDataChunks> chnkData = utils.getGLOBDataFromAllCycles(chunk, this.getCyclesData());
+				chunksData.put(chunk, chnkData);
+			}
+		}
+		else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
+		{
+			for(String chunk:selectedChunks)
+			{
+				ArrayList<ChunksData> chnkData = utils.getChunkDataFromAllCycles(chunk, this.getCyclesData());
+				nonHeapChunksData.put(chunk, chnkData);
+			}
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#prepareData()
+	 */
+	public void prepareData() {
+		fetchEntireDataForSelectedChunks();
+		 
+		 for(String chnk:getUserSelectedItems())
+		 {
+			 int [] valuesToBePlotted = null;
+			 
+			 switch(this.getEvent())
+			 {
+			 	case GLOBAL_DATA_SIZE:
+			 		valuesToBePlotted = getGlobalChnkSizeData(chnk);
+			 		break;
+			 	case NON_HEAP_CHUNK_SIZE:
+			 		valuesToBePlotted = getNonHeapChnkSizeData(chnk);
+			 		break;
+			 }
+			
+			 if(valuesToBePlotted == null)
+				 continue;
+			 
+			 int maxValue = calculateMaxValue(valuesToBePlotted);
+				 
+			 if(maxValue > maxBytes)
+				 maxBytes = maxValue;
+			 }
+				
+	}
+	
+	private boolean getHandleStatus(int cycleNo, String chunkName)
+	{
+		boolean status = false;
+		
+		if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
+		{
+			ArrayList<GlobalDataChunks> glod_data = chunksData.get(chunkName);
+			
+			status = glod_data.get(cycleNo -1).isKernelHandleDeleted();
+		}
+		else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
+		{
+			ArrayList<ChunksData> chunks_data = nonHeapChunksData.get(chunkName);
+			
+			status = chunks_data.get(cycleNo -1).isKernelHandleDeleted();
+		}
+		
+		return status;
+	}
+	
+	private int getChunkStatus(int cycleNo, String chunkName)
+	{
+		int status = 0;
+		
+		if(this.getEvent().equals(GenericGraph.EventTypes.GLOBAL_DATA_SIZE))
+		{
+			ArrayList<GlobalDataChunks> glod_data = chunksData.get(chunkName);
+			
+			status = glod_data.get(cycleNo -1).getAttrib();
+		}
+		else if(this.getEvent().equals(GenericGraph.EventTypes.NON_HEAP_CHUNK_SIZE))
+		{
+			ArrayList<ChunksData> chunks_data = nonHeapChunksData.get(chunkName);
+			
+			status = chunks_data.get(cycleNo -1).getAttrib();
+		}
+		
+		return status;
+	}
+	private int [] getGlobalChnkSizeData(String chnkName)
+	{
+		ArrayList<GlobalDataChunks> data = chunksData.get(chnkName);
+		
+		int [] values = new int[data.size()];
+		
+		for(int i=0; i<data.size(); i++)
+		{
+			if(data.get(i).getAttrib() == CycleData.Deleted)
+				values[i] = 0;
+			else
+				values [i] = (int)data.get(i).getSize();
+		}
+		
+		return values;
+	}
+	private int [] getNonHeapChnkSizeData(String chnkName)
+	{
+		ArrayList<ChunksData> data = nonHeapChunksData.get(chnkName);
+		
+		int [] values = new int[data.size()];
+		
+		for(int i=0; i<data.size(); i++)
+		{
+			if(data.get(i).getAttrib() == CycleData.Deleted)
+				values[i] = 0;
+			else
+				values [i] = (int)data.get(i).getSize();
+		}
+		
+		return values;
+	}
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.s60tools.swmtanalyser.ui.graphs.GenericGraph#getToolTipText(int, int)
+	 */
+	public String getToolTipText(int x, int y)
+	{
+		if(y > (int)visY)
+			return null;
+		
+		String text = "";
+		
+		double xValue = x + timeOffset;
+		int scaledX = (int)(xValue * getScale());
+		
+		double valY = visY - y;
+		double bytes =  valY * multiplier;			
+		
+		String scaledY = "";
+		
+		if (bytes < 10000)
+		{
+			scaledY += Bytes_Format.format(bytes) + " B"; //$NON-NLS-1$
+		}
+		else if (bytes <= 500 * 1024)
+		{
+			scaledY += Bytes_Format.format(bytes / 1024) + " KB"; //$NON-NLS-1$
+		}
+		else
+		{
+			scaledY +=  MBformat.format(((float) bytes / (1024 * 1024)))  + " MB"; //$NON-NLS-1$
+		}
+		
+		text += scaledX + " s, " + scaledY;
+		for(String chnk: getUserSelectedItems())
+		{
+			Polyline line = pointsData.get(chnk);
+		
+			if(line != null && line.containsPoint(x, y))
+				text += "\n" + chnk;
+		}
+		
+		return text;
+	}
+	
+	/**
+	 * Get {@link GlobalDataChunks} for given chunk name
+	 * @param chnkName
+	 * @return List of chunks with given name
+	 */
+	public ArrayList<GlobalDataChunks> getGlobalChunkData(String chnkName)
+	{
+		return chunksData.get(chnkName);
+	}
+	
+	/**
+	 * Get {@link ChunksData} for given chunk name
+	 * @param chnkName
+	 * @return List of data with given name
+	 */
+	public ArrayList<ChunksData> getNonHeapChunkData(String chnkName)
+	{
+		return nonHeapChunksData.get(chnkName);
+	}
+	
+}