sysperfana/analyzetoolext/com.nokia.s60tools.analyzetool/src/com/nokia/s60tools/analyzetool/engine/DeferredCallstackManager.java
changeset 6 f65f740e69f9
child 15 0367d2db2c06
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/analyzetoolext/com.nokia.s60tools.analyzetool/src/com/nokia/s60tools/analyzetool/engine/DeferredCallstackManager.java	Wed Apr 21 19:42:48 2010 +0300
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2010 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:  Definitions for the class ReadFile
+ *
+ */
+package com.nokia.s60tools.analyzetool.engine;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.nokia.s60tools.analyzetool.engine.statistic.AllocCallstack;
+import com.nokia.s60tools.analyzetool.engine.statistic.BaseInfo;
+import com.nokia.s60tools.analyzetool.engine.statistic.ProcessInfo;
+
+/**
+ * CallstackManager for reading of callstacks on demand by accessing the .dat file
+ * after the initial parsing of the file has completed.
+ *
+ */
+public class DeferredCallstackManager implements ICallstackManager{
+	/** max number of lines to parse before giving up and forcing the callstack as complete
+	 * This helps to deal with corrupt files */
+	private static final int BAIL_OUT_LIMIT = 100;
+	
+	/** Location of the .dat file */
+	String fileLocation;
+	/** list of processes for this file; this has to contain all DllLoads for each process */
+	private Map<Integer, ProcessInfo> processMap;
+
+	/**
+	 * Contructor
+	 * @param fileLocation full path of the file to read callstacks from
+	 */
+	public DeferredCallstackManager(String fileLocation) {
+		this.fileLocation = fileLocation;
+	}
+	
+	/**
+	 * Setter for all processes valid for this data file. This has to contain
+	 * all DllInfo information for each of the processes
+	 * @param processes List of processes for the file
+	 */
+	public void setProcesses(AbstractList<ProcessInfo> processes){
+		//make a copy
+		if (processMap == null) {
+			processMap = new HashMap<Integer, ProcessInfo>();
+			for (ProcessInfo processInfo : processes) {
+				processMap.put(processInfo.getProcessID(), processInfo);
+			}
+		}
+	}	
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.s60tools.analyzetool.engine.statistic.ICallstackManager#readCallstack(com.nokia.s60tools.analyzetool.engine.statistic.BaseInfo)
+	 */
+	public List<AllocCallstack> readCallstack(BaseInfo baseInfo) throws IOException{
+		//Returns a fully resolved callstack file in .dat format.
+		//The baseInfo's file position points to the beginning of a record where the callstack information starts
+		
+		if (!hasCallstack(baseInfo)){
+			return null;
+		}
+
+		ProcessInfo p = processMap.get(baseInfo.getProcessID());
+		
+		if (p == null){
+			//no matching process found
+			return new ArrayList<AllocCallstack>();
+		}
+		
+		
+		RandomAccessFile fileReader = null;
+		List<AllocCallstack> ret = null;
+		
+		
+		try {
+			// Open .dat file for reading
+			fileReader = new RandomAccessFile(new File(fileLocation), "r");  //$NON-NLS-1$
+
+			// Parsing the ELF header to read the Program Header Offset 'e_phoff' value
+			fileReader.seek(baseInfo.getFilePos());
+			
+			CallstackDataParser parser = new CallstackDataParser(baseInfo, p);
+			int lineCnt = 0; 
+			String line;
+			while((line = fileReader.readLine()) != null){
+				if (parser.parseLine(line)){
+					parser.finaliseCallstack();
+					ret = parser.getCallstack();
+					break;
+				}
+				
+				//let's count the lines we parse and bail out after <n> lines in case the file is corrupt
+				lineCnt ++;
+				if (lineCnt == BAIL_OUT_LIMIT){
+					parser.forceComplete();
+					ret = parser.getCallstack();
+					break;
+				}
+			}
+		} finally {
+			if (fileReader != null){
+				fileReader.close();
+			}
+		}
+		
+		return ret == null ? new ArrayList<AllocCallstack>() : ret;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.s60tools.analyzetool.engine.statistic.ICallstackManager#hasCallstack(com.nokia.s60tools.analyzetool.engine.statistic.BaseInfo)
+	 */
+	public boolean hasCallstack(BaseInfo baseInfo) {
+		return baseInfo.getFilePos() > -1;
+	}
+	
+}