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