diff -r f65f740e69f9 -r 8e12a575a9b5 sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/model/SWMTLogReaderUtils.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/model/SWMTLogReaderUtils.java Wed Apr 21 20:01:08 2010 +0300
@@ -0,0 +1,1361 @@
+/*
+* 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.model;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+import com.nokia.s60tools.swmtanalyser.data.ChunksData;
+import com.nokia.s60tools.swmtanalyser.data.CycleData;
+import com.nokia.s60tools.swmtanalyser.data.DiskOverview;
+import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks;
+import com.nokia.s60tools.swmtanalyser.data.KernelElements;
+import com.nokia.s60tools.swmtanalyser.data.OverviewData;
+import com.nokia.s60tools.swmtanalyser.data.ParsedData;
+import com.nokia.s60tools.swmtanalyser.data.StackData;
+import com.nokia.s60tools.swmtanalyser.data.SystemData;
+import com.nokia.s60tools.swmtanalyser.data.ThreadData;
+import com.nokia.s60tools.swmtanalyser.data.ThreadSegments;
+import com.nokia.s60tools.swmtanalyser.data.WindowGroupEventData;
+import com.nokia.s60tools.swmtanalyser.data.WindowGroups;
+import com.nokia.s60tools.util.debug.DbgUtility;
+
+/**
+ * Helper class which has some util methods.
+ *
+ */
+public class SWMTLogReaderUtils {
+
+ private static final String CHECK_SUM = "Checksum";
+ private static final String VERSION = "Version";
+
+ /**
+ * Construction
+ */
+ public SWMTLogReaderUtils() {
+ }
+
+ /**
+ * Parse all the given text log files and create store the basic data in CycleData object for each file.
+ * @param inputFiles
+ * @param cycles
+ * @param monitor
+ * @return null
if everything was OK, error message if otherwise.
+ */
+ public String getCycleDataArrayFromLogFiles(ArrayList inputFiles, ArrayList cycles, IProgressMonitor monitor)
+ {
+ int i = 0;
+ for(String path: inputFiles)
+ {
+ i++;
+ if(monitor != null)
+ {
+ if(monitor.isCanceled())
+ return null;
+ if(i == inputFiles.size()/2)
+ monitor.worked(5);
+ }
+ File aFile = new File(path);
+ ArrayList lines = new ArrayList();
+ int lineNum;
+ try {
+ BufferedReader input = new BufferedReader(new FileReader(aFile));
+ try {
+ String line = null;
+ lineNum = 0;
+ while (( line = input.readLine()) != null){
+
+ //Increment line number
+ lineNum++;
+
+ line = line.trim();
+ //Ignoring newlines and lines which are having only spaces
+ if(line.length() == 0)
+ continue;
+
+ //Line must start with test [MemSpy], if not it is invalid input.
+ if(!line.startsWith("[MemSpy]"))
+ {
+ return "Error in the log ("+path+"): at line " + lineNum + "\nLine does not start with [MemSpy].";
+ }
+
+ if(line.contains("Type"))
+ break;
+
+ //Add valid line to array
+ lines.add(line);
+
+ }
+ }
+ finally {
+ input.close();
+ }
+ }
+ catch (IOException ex){
+ ex.printStackTrace();
+ return ex.getMessage();
+ }
+
+ String cycleNumLine = null;
+ String timeLine = null;
+
+ String romCheckSum = null;
+ String romVersion = null;
+
+ for(String str:lines)
+ {
+ if(str.contains("Cycle number"))
+ cycleNumLine = str;
+ if(str.contains("Time"))
+ timeLine = str;
+
+ if(str.contains("ROM") && str.contains(CHECK_SUM))
+ romCheckSum = str;
+ else if(str.contains("ROM") && str.contains(VERSION))
+ romVersion = str;
+ }
+
+ if(cycleNumLine == null || timeLine == null)
+ return "Error in the Log " + path + "\n The log might not contain Cycle number or Time information. Please check";
+
+ if(romCheckSum == null || romVersion == null)
+ return "Error in the Log " + path + "\n The log might not contain ROM information. Please check";
+
+ //Read cycle number
+ String num = cycleNumLine.substring(cycleNumLine.indexOf("Cycle number") + 12).trim();
+ int cycleNo = Integer.parseInt(num);
+
+ //Read Time
+ String time = timeLine.substring(timeLine.indexOf("Time") + 4).trim();
+
+ String checkSum = romCheckSum.substring(romCheckSum.indexOf(CHECK_SUM) + (CHECK_SUM).length()).trim();
+ String romVer = romVersion.substring(romVersion.indexOf(VERSION) + (VERSION).length()).trim();
+
+ CycleData cycleData = new CycleData();
+ cycleData.setTime(time);
+ cycleData.setCycleNumber(cycleNo);
+ cycleData.setFileName(path);
+ cycleData.setRomCheckSum(checkSum);
+ cycleData.setRomVersion(romVer);
+
+ cycles.add(cycleData);
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the overview information till the selected log file.
+ * @param allCyclesData CycleData list
+ * @param toCycle Cycle number till where you want to export
+ * @return OverviewData
+ */
+ public OverviewData getOverviewInformationFromCyclesData(CycleData[] allCyclesData, int toCycle)
+ {
+ OverviewData overview = new OverviewData();
+ overview.noOfcycles = toCycle;
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
+ Date aDate=null;
+ Date bDate=null;
+ try {
+ aDate = sdf.parse(allCyclesData[0].getTime());
+ bDate = sdf.parse(allCyclesData[toCycle-1].getTime());
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ long t1= aDate.getTime();
+ long t2= bDate.getTime();
+ //time difference in seconds
+ overview.duration = (t2-t1)/1000;
+ //Get date and time in the format like : Jan 7, 2008 1:56:44 PM
+ overview.fromTime = DateFormat.getDateTimeInstance().format(aDate);
+ overview.toTime = DateFormat.getDateTimeInstance().format(bDate);
+ overview.durationString = millisecondToDHMS(overview.duration*1000);
+
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Cycle Numbers :" + overview.noOfcycles );
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Time Period :" + overview.fromTime + " to " + overview.toTime );
+ DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Time Duration :" + overview.duration + " sec (" + overview.durationString + ")");
+
+ return overview;
+ }
+
+ /**
+ * Returns the difference between two time strings
+ * @param startTime
+ * @param endTime
+ * @return difference between startTime and endTime in seconds.
+ */
+ public long getDurationInSeconds(String startTime, String endTime)
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
+
+ Date aDate=null;
+ Date bDate=null;
+
+ try {
+ aDate = sdf.parse(startTime);
+ bDate = sdf.parse(endTime);
+ } catch (ParseException e) {
+ return -1;
+ }
+
+ long t1= aDate.getTime();
+ long t2= bDate.getTime();
+ //time difference in seconds
+ return (t2-t1)/1000;
+
+ }
+ /**
+ * converts time (in milliseconds) to
+ * "d, h, min, sec"
+ * @return time in readable format.
+ */
+ public String millisecondToDHMS(long duration) {
+ long ONE_SECOND = 1000;
+ long ONE_MINUTE = ONE_SECOND * 60;
+ long ONE_HOUR = ONE_MINUTE * 60;
+ long ONE_DAY = ONE_HOUR * 24;
+
+ String res = "";
+ long temp = 0;
+ if (duration >= ONE_SECOND) {
+ temp = duration / ONE_DAY;
+ if (temp > 0) {
+ res = temp + " d";
+ duration -= temp * ONE_DAY;
+
+ if (duration >= ONE_MINUTE) {
+ res += ", ";
+ }
+ }
+
+ temp = duration / ONE_HOUR;
+ if (temp > 0) {
+ res += temp + " h";
+ duration -= temp * ONE_HOUR;
+ if (duration >= ONE_MINUTE) {
+ res += ", ";
+ }
+ }
+
+ temp = duration / ONE_MINUTE;
+ if (temp > 0) {
+ res += temp + " min";
+ duration -= temp * ONE_MINUTE;
+
+ if(duration >= ONE_SECOND) {
+ res += ", ";
+ }
+ }
+
+ temp = duration / ONE_SECOND;
+ if (temp > 0) {
+ res += temp + " sec";
+ }
+ return res;
+ }
+ else {
+ return "0 sec";
+ }
+ }
+
+ /**
+ * This will check whether the CycleData objects are in concecutive order and
+ * if not, this will return the reordered list.
+ * @param allCyclesData
+ * @return Reordered list, if any cycle data is missing null will be returned
+ */
+ public ArrayList checkCycleOrder(ArrayList allCyclesData)
+ {
+ ArrayList orderedCycles = new ArrayList();
+
+ /*for(int i=0; i0 && before[0].getCycleNumber() == 1)
+ {
+ int i= 1;
+ for (CycleData data: before) {
+ data.setCycleNumber(i);
+ orderedCycles.add(data);
+ i++;
+ }
+ return orderedCycles;
+ }
+ else
+ return null;
+ }
+
+ /**
+ * This method fetches list of all newly created disk names from all the
+ * cycles. If only one cycle is selected it fetches list of new and updated disk names.
+ * @param data specifies list of CycleData to be parsed
+ * @return list of disknames from all the cycles
+ */
+ public ArrayList getAllDiskNames(ParsedData data)
+ {
+ if(data == null || data.getNumberOfCycles() ==0)
+ return null;
+
+ CycleData [] parsed_cycles = data.getLogData();
+
+ CycleData firstCycle = parsed_cycles[0];
+ firstCycle.parseDisksList();
+ ArrayList totalDisks = new ArrayList(firstCycle.getNewlyCreatedDisks());
+
+ if(parsed_cycles.length == 1)
+ {
+ ArrayList updatedDisks = firstCycle.getUpdatedDisks();
+
+ for(String disk:updatedDisks)
+ {
+ if(!totalDisks.contains(disk))
+ totalDisks.add(disk);
+ }
+
+ return totalDisks;
+ }
+ for(int i=1; i newDisks = cycle.getNewlyCreatedDisks();
+
+ for(String disk:newDisks)
+ {
+ if(!totalDisks.contains(disk))
+ totalDisks.add(disk);
+ }
+ }
+
+ return totalDisks;
+ }
+
+ /**
+ * This method fetches Used Memory and Size data for a given disk from given list of cycledata.
+ * @param diskName name of the disk, whose used memory and size must be fetched.
+ * @param data list of cycledata which needs to be parsed.
+ * @return list of used memory and size values for all cycles.
+ */
+ public ArrayList getUsedMemoryAndSizesForDisk(String diskName, ParsedData parsedData)
+ {
+
+ ArrayList diskTotalData = new ArrayList();
+ DiskOverview prevData = new DiskOverview();
+
+ CycleData [] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ DiskOverview ov = null;
+
+ if(!cycle.getDeletedDisks().contains(diskName)){
+ DiskOverview tmp = cycle.getDiskUsedAndFreeSize(diskName);
+
+ if(tmp != null)
+ ov = new DiskOverview(tmp);
+ else
+ {
+ ov = new DiskOverview(prevData);
+
+ if(prevData.getStatus() == CycleData.New)
+ ov.setStatus(CycleData.Alive);
+ }
+
+ }
+ else
+ ov = new DiskOverview();
+
+ diskTotalData.add(ov);
+ prevData = ov;
+ }
+
+ /*for(int i=0;i getSystemDataFromAllCycles(ParsedData parsedData)
+ {
+
+ ArrayList systemData = new ArrayList();
+ SystemData prevData = new SystemData();
+
+ CycleData [] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ SystemData ov = new SystemData(prevData);
+
+ long freeMem = cycle.getFreeMemory();
+ long totalMem = cycle.getTotalMemory();
+
+ if(freeMem != -1)
+ {
+ ov.setFreeMemory(freeMem);
+ }
+ if(totalMem != -1)
+ ov.setTotalMemory(totalMem);
+
+ systemData.add(ov);
+ prevData = ov;
+ }
+
+ /*for(int i=0;i getAllThreadNames(ParsedData data)
+ {
+ if(data == null || data.getNumberOfCycles() == 0)
+ return null;
+
+ CycleData[] parsed_cycles = data.getLogData();
+ CycleData firstCycle = parsed_cycles[0];
+ firstCycle.parseAllThreads();
+ ArrayList totalThreads = new ArrayList(firstCycle.getNewlyCreatedThreads());
+
+ if(parsed_cycles.length == 1)
+ {
+ ArrayList updatedThreads = firstCycle.getUpdatedThreads();
+
+ for(String thread:updatedThreads)
+ {
+ if(!totalThreads.contains(thread))
+ totalThreads.add(thread);
+ }
+
+ ArrayList threadsFromAllViews = getThreadsFromAllViews(firstCycle);
+
+ for(String thread:threadsFromAllViews)
+ {
+ if(!totalThreads.contains(thread))
+ totalThreads.add(thread);
+ }
+
+ return totalThreads;
+ }
+ for(int i=1; i newThreads = cycle.getNewlyCreatedThreads();
+
+ for(String thread:newThreads)
+ {
+ if(!totalThreads.contains(thread))
+ totalThreads.add(thread);
+ }
+ }
+
+ return totalThreads;
+ }
+
+ /**
+ * This method fetches list of all heap thread names from all the cycles.
+ * If only one cycle is selected it fetches list of new and updated heap thread names.
+ * @param data specifies list of CycleData to be parsed
+ * @return list of those thread names which contain heap information, in one or many cycles.
+ */
+ public ArrayList getAllHeapThreads(ParsedData parsedData)
+ {
+
+ CycleData [] logData = parsedData.getLogData();
+ CycleData firstCycle = logData[0];
+
+ firstCycle.parseAllHeaps();
+ ArrayList totalHeaps = new ArrayList(firstCycle.getNewHeapThreads());
+
+ if(logData.length == 1)
+ {
+ ArrayList updatedHeaps = firstCycle.getAliveHeapThreads();
+
+ for(String thread:updatedHeaps)
+ {
+ if(!totalHeaps.contains(thread))
+ totalHeaps.add(thread);
+ }
+
+ return totalHeaps;
+ }
+ for(int i=1; i newHeaps = cycle.getNewHeapThreads();
+
+ for(String thread:newHeaps)
+ {
+ if(!totalHeaps.contains(thread))
+ totalHeaps.add(thread);
+ }
+ }
+
+ return totalHeaps;
+ }
+
+ /**
+ * This method fetches all the data for a given thread from given list of cycledata.
+ * @param threadName name of the thread whose data is needed.
+ * @param cycles list of cycledata structures to be parsed for the thread data.
+ * @return list of ThreadData structures. Each structure holds values of given thread fields in each cycle.
+ */
+ public ArrayList getHeapDataFromAllCycles(String threadName, ParsedData parsedData)
+ {
+ ArrayList allData = new ArrayList();
+
+ ThreadData prevData = new ThreadData(threadName);
+ CycleData[] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ ThreadData currentData = null;
+
+ cycle.parseAllThreads();
+
+ //Fetch the data for this thread in this cycle.
+ //If no data in this cycle, copy the data from the previous cycle.
+
+ ThreadData tmp = cycle.getHeapData(threadName);
+
+ if(tmp != null)
+ currentData = tmp;
+ else{
+ currentData = new ThreadData(prevData);
+ if(prevData.getStatus() == CycleData.New)
+ currentData.setStatus(CycleData.Alive);
+ }
+
+ StackData stakData = cycle.getStackData(threadName);
+
+ if(stakData != null)
+ {
+ currentData.setStackStatus(stakData.getStatus());
+ currentData.setStackSize(stakData.getSize());
+ }
+ else
+ {
+ if(prevData.getStackStatus() == CycleData.New)
+ currentData.setStackStatus(CycleData.Alive);
+ else
+ currentData.setStackStatus(prevData.getStackStatus());
+
+ currentData.setStackSize(prevData.getStackSize());
+ }
+
+ int openFilesCnt = cycle.getNewOpenFiles(threadName);
+ int closedFilesCnt = cycle.getDeletedFiles(threadName);
+
+ int newPSHandlesCnt = cycle.getNewPSHandles(threadName);
+ int deletedPSHandlesCnt = cycle.getDeletedPSHandles(threadName);
+
+ if(cycles.length == 1)
+ {
+ int updatedFiles = cycle.getUpdatedFiles(threadName);
+ int updatedPSHandles = cycle.getUpdatedPSHandles(threadName);
+
+ currentData.setOpenFiles(openFilesCnt + updatedFiles);
+ currentData.setPsHandles(newPSHandlesCnt + updatedPSHandles);
+ }
+
+ else
+ {
+ openFilesCnt += prevData.getOpenFiles();
+
+ openFilesCnt -= closedFilesCnt;
+ currentData.setOpenFiles(openFilesCnt);
+
+ newPSHandlesCnt += prevData.getPsHandles();
+ newPSHandlesCnt -= deletedPSHandlesCnt;
+
+ currentData.setPsHandles(newPSHandlesCnt);
+ }
+
+ if(cycle.getDeletedThreads().contains(threadName))
+ currentData.setKernelHandleDeleted(true);
+
+ currentData.setCycleNumber(cycle.getCycleNumber());
+ allData.add(currentData);
+ prevData = currentData;
+ }
+
+ return allData;
+ }
+
+ /**
+ * Returns the array of global data chunks list of given chunk
+ * from all the log files data.
+ * @param chunkName
+ * @param cycles
+ * @return List of {@link GlobalDataChunks} with given chunk name
+ */
+ public ArrayList getGLOBDataFromAllCycles(String chunkName, ParsedData logData)
+ {
+
+ ArrayList allData = new ArrayList();
+
+ GlobalDataChunks prevData = new GlobalDataChunks();
+
+ CycleData [] logCycles = logData.getLogData();
+
+ for(CycleData cycle:logCycles)
+ {
+ GlobalDataChunks currentData = null;
+ GlobalDataChunks tmp = cycle.getGlobalChunkDataFor(chunkName);
+ if(tmp != null)
+ currentData = tmp;
+ else{
+ currentData = new GlobalDataChunks(prevData);
+
+ if(prevData.getAttrib() == CycleData.New)
+ currentData.setAttrib(CycleData.Alive);
+ }
+
+ if(cycle.getDeletedChunkNames().contains(chunkName))
+ currentData.setKernelHandleDeleted(true);
+
+ allData.add(currentData);
+ prevData = currentData;
+ }
+
+ return allData;
+ }
+
+ /**
+ * Returns the array of chunks data list of given chunk
+ * from all the log files data.
+ * @param chunkName
+ * @param cycles
+ * @return list of {@link ChunksData} with given name
+ */
+ public ArrayList getChunkDataFromAllCycles(String chunkName, ParsedData logData)
+ {
+ ArrayList allData = new ArrayList();
+
+ ChunksData prevData = new ChunksData();
+
+ CycleData[] cycles = logData.getLogData();
+ for(CycleData cycle:cycles)
+ {
+ ChunksData currentData = null;
+ ChunksData tmp = cycle.getChunkDataFor(chunkName);
+ if(tmp != null)
+ currentData = tmp;
+ else{
+ currentData = new ChunksData(prevData);
+ if(prevData.getAttrib() == CycleData.New)
+ currentData.setAttrib(CycleData.Alive);
+ }
+
+ if(cycle.getDeletedChunkNames().contains(chunkName))
+ currentData.setKernelHandleDeleted(true);
+
+ allData.add(currentData);
+ prevData = currentData;
+ }
+
+ return allData;
+ }
+
+ /**
+ * This method returns the array of kernel elements data from all the given log files data.
+ * @param parsedData
+ * @return array of kernel elements
+ */
+ public ArrayList getKerenelElemsFromAllCycles(ParsedData parsedData)
+ {
+ ArrayList allData = new ArrayList();
+ KernelElements prevData = new KernelElements();
+
+ CycleData [] cycles = parsedData.getLogData();
+ for(CycleData cycle:cycles)
+ {
+ KernelElements currentData = cycle.getAllOpenKernelElements();
+
+ int timers = currentData.getNumberOfTimers();
+ int semaphores = currentData.getNumberOfSemaphores();
+ int servers = currentData.getNumberOfServers();
+ int sessions = currentData.getNumberOfSessions();
+ int processes = currentData.getNumberOfProcesses();
+ int threads = currentData.getNumberOfThreads();
+ int chunks = currentData.getNumberOfChunks();
+ int msgQueues = currentData.getNumberOfMsgQueues();
+
+
+ if(parsedData.getNumberOfCycles() != 1)
+ {
+
+ timers += prevData.getNumberOfTimers();
+ semaphores += prevData.getNumberOfSemaphores();
+ sessions += prevData.getNumberOfSessions();
+ servers += prevData.getNumberOfServers();
+ processes += prevData.getNumberOfProcesses();
+ threads += prevData.getNumberOfThreads();
+ chunks += prevData.getNumberOfChunks();
+ msgQueues += prevData.getNumberOfMsgQueues();
+
+ //newTimers -= closedTimers;
+ currentData.setNumberOfTimers(timers);
+ currentData.setNumberOfSemaphores(semaphores);
+ currentData.setNumberOfProcesses(processes);
+ currentData.setNumberOfSessions(sessions);
+ currentData.setNumberOfServers(servers);
+ currentData.setNumberOfThreads(threads);
+ currentData.setNumberOfChunks(chunks);
+ currentData.setNumberOfMsgQueues(msgQueues);
+
+ }
+ allData.add(currentData);
+ prevData = currentData;
+
+ }
+ return allData;
+ }
+ /**
+ *
+ * @param threadName name of thread whose status is needed.
+ * @param data list of cycledata to be parsed
+ * @return the recent status of the thread from given cycles.
+ */
+ public int getThreadStatusFromAllCycles(String threadName, ParsedData parsedData)
+ {
+ int status = -1;
+
+ CycleData [] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ cycle.parseAllThreads();
+ if(cycle.getNewlyCreatedThreads().contains(threadName))
+ status = CycleData.New;
+ else if(cycle.getUpdatedThreads().contains(threadName))
+ status = CycleData.Alive;
+ else if(cycle.getDeletedThreads().contains(threadName))
+ status = CycleData.Deleted;
+
+ }
+ return status;
+ }
+
+ /**
+ *
+ * @param threadName name of thread whose heap status is needed.
+ * @param data list of cycledata to be parsed
+ * @return the recent status of the given thread's heap.
+ */
+ public int getHeapStatusFromAllCycles(String threadName, ParsedData parsedData)
+ {
+ int status = 0;
+ CycleData [] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ cycle.parseAllHeaps();
+
+ ArrayList newHeapThreads = convertAllStringsToLowerCase(cycle.getNewHeapThreads());
+ ArrayList aliveHeaps = convertAllStringsToLowerCase(cycle.getAliveHeapThreads());
+ ArrayList deletedHeaps = convertAllStringsToLowerCase(cycle.getDeletedHeapThreads());
+
+ if(newHeapThreads.contains(threadName.toLowerCase()) ||
+ aliveHeaps.contains(threadName.toLowerCase()))
+ status = 1;
+ else if(deletedHeaps.contains(threadName.toLowerCase()))
+ status = 0;
+ }
+
+ return status;
+ }
+
+ /**
+ * Get the stack status of a given thread name
+ * @param threadName name of thread whose heap status is needed.
+ * @param data list of cycledata to be parsed
+ * @return the recent status of the given thread's stack.
+ */
+ public int getStackStatusFromAllCycles(String threadName, ParsedData parsedData)
+ {
+ int status = 0;
+ CycleData[] cycles = parsedData.getLogData();
+
+ for(CycleData cycle:cycles)
+ {
+ ArrayList newStacks = convertAllStringsToLowerCase(cycle.getNewStackThreads());
+ ArrayList aliveStacks = convertAllStringsToLowerCase(cycle.getAliveStackThreads());
+ ArrayList deletedStacks = convertAllStringsToLowerCase(cycle.getDeletedStackThreads());
+
+ if(newStacks.contains(threadName.toLowerCase()) ||
+ aliveStacks.contains(threadName.toLowerCase()))
+ status = 1;
+ else if(deletedStacks.contains(threadName.toLowerCase()))
+ status = 0;
+ }
+
+ return status;
+ }
+
+ /**
+ * Get the delta data for the given threadname from all the cycles.
+ * @param threadName name of the thread
+ * @param logData list of cycledata to be parsed.
+ * @return the ThreadData structure which holds the differences for various
+ * fields in the lastCycle and the cycle in which the thread has actually started.
+ */
+ public ThreadData getChangeinHeapData(String threadName, ArrayList allCyclesData, ParsedData logData)
+ {
+ ThreadData heapDataChange = new ThreadData(threadName);
+
+ //If the heap for this thread is already deleted all the
+ //heap related fields will be set to 0.
+ if(getHeapStatusFromAllCycles(threadName, logData) == 0)
+ {
+ //Display zeros for all heap fields
+ heapDataChange.setMaxHeapSize(0);
+ heapDataChange.setHeapChunkSize(0);
+ heapDataChange.setHeapAllocatedSpace(0);
+ heapDataChange.setHeapFreeSpace(0);
+ heapDataChange.setAllocatedCells(0);
+ heapDataChange.setFreeCells(0);
+ heapDataChange.setFreeSlackSize(0);
+ heapDataChange.setLargestAllocCellSize(0);
+ heapDataChange.setLargestFreeCellSize(0);
+
+ }
+ else{
+
+ ThreadData lastHeapData = allCyclesData.get(logData.getNumberOfCycles()-1);
+
+ //Get the heap values from the cycle in which the
+ //thread is started.
+ ThreadData firstHeapData = null;
+
+ for(int i=allCyclesData.size()-2; i>=0; i--)
+ {
+ ThreadData data = allCyclesData.get(i);
+ if(data.getStatus() != CycleData.Deleted){
+ firstHeapData = data;
+ }
+ else
+ break;
+ }
+
+ if(firstHeapData != null)
+ {
+ heapDataChange.setMaxHeapSize(firstHeapData.getMaxHeapSize());
+ long changeInHeapSize = lastHeapData.getHeapChunkSize() - firstHeapData.getHeapChunkSize();
+ long changeInAllocSpace = lastHeapData.getHeapAllocatedSpace() - firstHeapData.getHeapAllocatedSpace();
+ long changeInFreeSpace = lastHeapData.getHeapFreeSpace() - firstHeapData.getHeapFreeSpace();
+ long changeInAllocCells = lastHeapData.getAllocatedCells() - firstHeapData.getAllocatedCells();
+ long changeInFreeCells = lastHeapData.getFreeCells() - firstHeapData.getFreeCells();
+ long changeInSlackSize = lastHeapData.getFreeSlackSize() - firstHeapData.getFreeSlackSize();
+ long changeInLargestAllocCell = lastHeapData.getLargestAllocCellSize() - firstHeapData.getLargestAllocCellSize();
+ long changeInLargestFreeCell = lastHeapData.getLargestFreeCellSize() - firstHeapData.getLargestFreeCellSize();
+
+ heapDataChange.setHeapChunkSize(changeInHeapSize);
+ heapDataChange.setHeapAllocatedSpace(changeInAllocSpace);
+ heapDataChange.setHeapFreeSpace(changeInFreeSpace);
+ heapDataChange.setAllocatedCells(changeInAllocCells);
+ heapDataChange.setFreeCells(changeInFreeCells);
+ heapDataChange.setFreeSlackSize(changeInSlackSize);
+ heapDataChange.setLargestAllocCellSize(changeInLargestAllocCell);
+ heapDataChange.setLargestFreeCellSize(changeInLargestFreeCell);
+
+ }
+ else
+ {
+ heapDataChange.setMaxHeapSize(lastHeapData.getMaxHeapSize());
+ heapDataChange.setHeapChunkSize(lastHeapData.getHeapChunkSize());
+ heapDataChange.setHeapAllocatedSpace(lastHeapData.getHeapAllocatedSpace());
+ heapDataChange.setHeapFreeSpace(lastHeapData.getHeapFreeSpace());
+ heapDataChange.setAllocatedCells(lastHeapData.getAllocatedCells());
+ heapDataChange.setFreeCells(lastHeapData.getFreeCells());
+ heapDataChange.setFreeSlackSize(lastHeapData.getFreeSlackSize());
+ heapDataChange.setLargestAllocCellSize(lastHeapData.getLargestAllocCellSize());
+ heapDataChange.setLargestFreeCellSize(lastHeapData.getLargestFreeCellSize());
+ }
+ }
+
+ ThreadData lastHeapData = allCyclesData.get(logData.getNumberOfCycles()-1);
+
+ if(getStackStatusFromAllCycles(threadName, logData) == 0)
+ {
+ heapDataChange.setStackSize(0);
+ }
+ else
+ {
+ heapDataChange.setStackSize(lastHeapData.getStackSize());
+ }
+
+ heapDataChange.setOpenFiles(lastHeapData.getOpenFiles());
+
+ if(lastHeapData.getPsHandles() == -1)
+ heapDataChange.setPsHandles(0);
+ else
+ heapDataChange.setPsHandles(lastHeapData.getPsHandles());
+
+ return heapDataChange;
+ }
+
+ /**
+ * Returns the start and end cycle numbers for the threads having multiple instances
+ * @param threadData list
+ * @return start and end cycle numbers
+ */
+ public ThreadSegments [] getHeapSegments(ArrayList threadData)
+ {
+ ArrayList thSegments = new ArrayList();
+ boolean is_thread_started = false;
+ ThreadSegments segment = null;
+
+ for(ThreadData data: threadData)
+ {
+ if(data.getStatus() == CycleData.New && !is_thread_started)
+ {
+ segment = new ThreadSegments();
+ is_thread_started = true;
+ segment.setStartCycle(data.getCycleNumber());
+ }
+ if((data.getStatus() == CycleData.Deleted || data.getCycleNumber() == threadData.size()) && is_thread_started)
+ {
+ is_thread_started = false;
+ if(segment != null){
+ segment.setEndCycle(data.getCycleNumber());
+ thSegments.add(segment);
+ }
+ }
+ }
+ return thSegments.toArray(new ThreadSegments[0]);
+ }
+ /**
+ * Returns the delta value for the given global chunk.
+ * @param chunkName
+ * @param logData
+ * @return delta value for the given global chunk
+ */
+ public long getChangeinGlodChunksData(String chunkName, ParsedData logData)
+ {
+
+ ArrayList heapData = getGLOBDataFromAllCycles(chunkName, logData);
+
+
+ if(heapData.get(heapData.size()-1).getAttrib() == CycleData.Deleted)
+ return 0;
+ else
+ {
+ long lastValue = heapData.get(heapData.size()-1).getSize();
+ long firstValue = 0;
+ for(GlobalDataChunks data: heapData)
+ {
+ if(data.getSize() != -1)
+ {
+ firstValue = data.getSize();
+ break;
+ }
+ }
+ return lastValue - firstValue;
+ }
+ }
+
+ /**
+ * Returns the delta value for the given chunk.
+ * @param chunkName
+ * @param logData
+ * @return delta value for the given chunk
+ */
+ public long getChangeinChunksData(String chunkName, ParsedData logData)
+ {
+ ArrayList heapData = getChunkDataFromAllCycles(chunkName, logData);
+
+ if(heapData.get(heapData.size()-1).getAttrib() == CycleData.Deleted)
+ return 0;
+ else
+ {
+ long lastValue = heapData.get(heapData.size()-1).getSize();
+ long firstValue = 0;
+ for(ChunksData data: heapData)
+ {
+ if(data.getSize() != -1)
+ {
+ firstValue = data.getSize();
+ break;
+ }
+ }
+ return lastValue - firstValue;
+ }
+ }
+
+ /**
+ * Return sum of the given delta values.
+ * @param deltaValues
+ * @return the sum of all given values
+ */
+ public long calculateAndGetTotal(long[] deltaValues)
+ {
+ long total = 0;
+
+ for(long value:deltaValues)
+ {
+ total = total + value;
+ }
+ return total;
+ }
+
+ /**
+ * Returns time intervals for all the given cycles.
+ * @param parsedData
+ * @return intervals
+ */
+ public int [] getTimeIntervalsFromLogData(ParsedData parsedData)
+ {
+ CycleData [] cyclesData = parsedData.getLogData();
+
+ if(cyclesData == null)
+ return null;
+
+ int [] timeIntervals = new int[cyclesData.length];
+
+ timeIntervals[0] = 0;
+
+ for(int i=1; i=0;i--)
+ {
+ if(valuesArr[i] != -1)
+ firstValue = valuesArr[i];
+ else
+ break;
+ }
+
+ if(lastValue != -1)
+ {
+ if(firstValue != -1)
+ return lastValue - firstValue;
+ else
+ return lastValue;
+ }
+ else
+ return 0;
+ }
+
+ /**
+ * Returns unique list of global chunk names from all the log files.
+ * @see GlobalDataChunks#getChunkName()
+ * @param data
+ * @return list about global chunk names
+ */
+ public ArrayList getAllGlobalChunkNames(ParsedData data)
+ {
+ if(data == null || data.getNumberOfCycles() == 0)
+ return null;
+
+ CycleData [] parsed_cycles = data.getLogData();
+ ArrayList globalChunkNames = new ArrayList();
+
+ for(CycleData cycle: parsed_cycles)
+ {
+ if(cycle.getGlobalDataChunksList()!=null)
+ for(GlobalDataChunks chunkName:cycle.getGlobalDataChunksList())
+ {
+ if(!globalChunkNames.contains(chunkName.getChunkName()))
+ globalChunkNames.add(chunkName.getChunkName());
+ }
+ }
+
+ return globalChunkNames;
+ }
+
+ /**
+ * Returns unique list of non heap chunk names from all the log files.
+ * @see ChunksData#getChunkName()
+ * @param data
+ * @return List of non heap chunk names
+ */
+ public ArrayList getAllNonHeapChunkNames(ParsedData data)
+ {
+ if(data == null || data.getNumberOfCycles() == 0)
+ return null;
+
+ ArrayList chunkNames = new ArrayList();
+ CycleData [] parsed_cycles = data.getLogData();
+
+ for(CycleData cycle: parsed_cycles)
+ {
+ if(cycle.getChunksList()!=null)
+ for(ChunksData chunkName:cycle.getChunksList())
+ {
+ if(!chunkNames.contains(chunkName.getChunkName()))
+ chunkNames.add(chunkName.getChunkName());
+ }
+ }
+
+ return chunkNames;
+ }
+
+ /**
+ * This method returns unique list of window group names from all the log files.
+ * @param data
+ * @return window group names
+ */
+ public ArrayList getWindowGroupNames(ParsedData data)
+ {
+ if(data == null || data.getNumberOfCycles() == 0)
+ return null;
+
+ ArrayList wndgNames = new ArrayList();
+ CycleData [] parsed_cycles = data.getLogData();
+
+ for(CycleData cycle: parsed_cycles)
+ {
+ for(WindowGroups name:cycle.getWindowGroupsData())
+ {
+ if(!wndgNames.contains(name.getName()))
+ wndgNames.add(name.getName());
+ }
+ }
+
+ return wndgNames;
+ }
+
+ /**
+ * Get {@link WindowGroupEventData} for given window group name
+ * @param windowGroupName
+ * @param logData
+ * @return list of window group data
+ */
+ public ArrayList getAllWindowGroupEvents(String windowGroupName, ParsedData logData)
+ {
+ if(logData == null || logData.getNumberOfCycles() == 0)
+ return null;
+
+ CycleData [] parsed_cycles = logData.getLogData();
+
+ ArrayList eventsData = new ArrayList();
+
+ WindowGroupEventData prevData = null;
+
+ for(CycleData cycle:parsed_cycles)
+ {
+ WindowGroupEventData currentData;
+
+ if(prevData == null)
+ currentData = new WindowGroupEventData();
+ else
+ currentData = new WindowGroupEventData(prevData);
+
+ for(WindowGroups grp: cycle.getWindowGroupsData())
+ {
+ if(grp.getName().equalsIgnoreCase(windowGroupName))
+ {
+ if(grp.getStatus() == CycleData.New || grp.getStatus() == CycleData.Alive)
+ currentData.incrementEventCount(grp.getEvent());
+ else if(grp.getStatus() == CycleData.Deleted)
+ currentData.decrementEventCount(grp.getEvent());
+ }
+ }
+
+ prevData = currentData;
+ eventsData.add(currentData);
+ }
+
+ return eventsData;
+ }
+ /**
+ * Get all threads names from data
+ * @param data
+ * @return List of thread names.
+ */
+ public ArrayList getThreadsFromAllViews(CycleData data)
+ {
+ ArrayList threads = new ArrayList();
+
+ data.parseAllHeaps();
+
+ for(String threadName:data.getNewHeapThreads())
+ {
+ if(!threads.contains(threadName))
+ threads.add(threadName);
+ }
+
+ for(String threadName:data.getAliveHeapThreads())
+ {
+ if(!threads.contains(threadName))
+ threads.add(threadName);
+ }
+
+ for(String threadName:data.getNewStackThreads())
+ {
+ if(!threads.contains(threadName))
+ threads.add(threadName);
+ }
+
+ for(String threadName:data.getAliveStackThreads())
+ {
+ if(!threads.contains(threadName))
+ threads.add(threadName);
+ }
+
+ for(String threadName:data.getFileThreads())
+ {
+ if(!threads.contains(threadName))
+ threads.add(threadName);
+ }
+
+ for(String threadName:data.getHPASThreads())
+ {
+ if(threadName.length() !=0 && !threads.contains(threadName))
+ threads.add(threadName);
+ }
+ return threads;
+ }
+
+ /**
+ * Gets the total for given delta values.
+ * @param deltaValues
+ * @return total delta values counted together
+ */
+ public long getTotal(ArrayList deltaValues)
+ {
+ long total = 0;
+ for(String value:deltaValues)
+ {
+ if(value != "N/A")
+ total = total + Long.parseLong(value);
+ }
+ return total;
+ }
+
+ /**
+ * Converts all given strings to lower case.
+ * @param inputList
+ * @return
+ */
+ private ArrayList convertAllStringsToLowerCase(ArrayList inputList)
+ {
+ ArrayList outputList = new ArrayList();
+ if(inputList != null)
+ {
+ for(int i=0;itrue if ROM Checksum is OK false
otherwise.
+ */
+ public boolean checkRomInfo(ArrayList cycleData)
+ {
+ boolean result = true;
+
+ for(int i = 0; i<=cycleData.size()-2; i++)
+ {
+ String currentCheckSum = cycleData.get(i).getRomCheckSum();
+ String nextCheckSum = cycleData.get(i+1).getRomCheckSum();
+
+ String currentVersion = cycleData.get(i).getRomVersion();
+ String nextVersion = cycleData.get(i+1).getRomVersion();
+
+ if((!currentCheckSum.equals(nextCheckSum)) || (!currentVersion.equals(nextVersion)))
+ {
+ result = false;
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Check timestamps from consecutive cycles
+ * if log n+1 time stamp is lesser than log n then return log n+1 cycle number. else return 0
+ * @param allcycleData
+ * @return Returns cycle number or 0
+ */
+ public int checkTimeStamp(ArrayList allcycleData){
+
+ for(int i=1;i