sysperfana/memspyext/com.nokia.s60tools.swmtanalyser/src/com/nokia/s60tools/swmtanalyser/model/SWMTLogReaderUtils.java
changeset 7 8e12a575a9b5
equal deleted inserted replaced
6:f65f740e69f9 7:8e12a575a9b5
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 package com.nokia.s60tools.swmtanalyser.model;
       
    18 
       
    19 import java.io.BufferedReader;
       
    20 import java.io.File;
       
    21 import java.io.FileReader;
       
    22 import java.io.IOException;
       
    23 import java.text.DateFormat;
       
    24 import java.text.ParseException;
       
    25 import java.text.SimpleDateFormat;
       
    26 import java.util.ArrayList;
       
    27 import java.util.Arrays;
       
    28 import java.util.Date;
       
    29 
       
    30 import org.eclipse.core.runtime.IProgressMonitor;
       
    31 
       
    32 import com.nokia.s60tools.swmtanalyser.data.ChunksData;
       
    33 import com.nokia.s60tools.swmtanalyser.data.CycleData;
       
    34 import com.nokia.s60tools.swmtanalyser.data.DiskOverview;
       
    35 import com.nokia.s60tools.swmtanalyser.data.GlobalDataChunks;
       
    36 import com.nokia.s60tools.swmtanalyser.data.KernelElements;
       
    37 import com.nokia.s60tools.swmtanalyser.data.OverviewData;
       
    38 import com.nokia.s60tools.swmtanalyser.data.ParsedData;
       
    39 import com.nokia.s60tools.swmtanalyser.data.StackData;
       
    40 import com.nokia.s60tools.swmtanalyser.data.SystemData;
       
    41 import com.nokia.s60tools.swmtanalyser.data.ThreadData;
       
    42 import com.nokia.s60tools.swmtanalyser.data.ThreadSegments;
       
    43 import com.nokia.s60tools.swmtanalyser.data.WindowGroupEventData;
       
    44 import com.nokia.s60tools.swmtanalyser.data.WindowGroups;
       
    45 import com.nokia.s60tools.util.debug.DbgUtility;
       
    46 
       
    47 /**
       
    48  * Helper class which has some util methods.
       
    49  *
       
    50  */
       
    51 public class SWMTLogReaderUtils {
       
    52 
       
    53 	private static final String CHECK_SUM = "Checksum";
       
    54 	private static final String VERSION = "Version";
       
    55 
       
    56 	/**
       
    57 	 * Construction
       
    58 	 */
       
    59 	public SWMTLogReaderUtils() {
       
    60 	}
       
    61 
       
    62 	/**
       
    63 	 * Parse all the given text log files and create store the basic data in CycleData object for each file.
       
    64 	 * @param inputFiles
       
    65 	 * @param cycles
       
    66 	 * @param monitor
       
    67 	 * @return <code>null</code> if everything was OK, error message if otherwise.
       
    68 	 */
       
    69 	public String getCycleDataArrayFromLogFiles(ArrayList<String> inputFiles, ArrayList<CycleData> cycles, IProgressMonitor monitor)
       
    70 	{
       
    71 		int i = 0;
       
    72 		for(String path: inputFiles)
       
    73 		{
       
    74 			i++;
       
    75 			if(monitor != null)
       
    76 			{
       
    77 				if(monitor.isCanceled())
       
    78 					return null;
       
    79 				if(i == inputFiles.size()/2)
       
    80 					monitor.worked(5);
       
    81 			}
       
    82 			File aFile = new File(path); 
       
    83 			ArrayList<String> lines = new ArrayList<String>();
       
    84 			int lineNum;
       
    85 			try {
       
    86 				BufferedReader input =  new BufferedReader(new FileReader(aFile));
       
    87 				try {
       
    88 					String line = null;
       
    89 					lineNum = 0;
       
    90 					while (( line = input.readLine()) != null){
       
    91 
       
    92 						//Increment line number 
       
    93 						lineNum++;
       
    94 
       
    95 						line = line.trim();
       
    96 						//Ignoring newlines and lines which are having only spaces
       
    97 						if(line.length() == 0)
       
    98 							continue;
       
    99 
       
   100 						//Line must start with test [MemSpy], if not it is invalid input.
       
   101 						if(!line.startsWith("[MemSpy]"))
       
   102 						{
       
   103 							return "Error in the log ("+path+"): at line " + lineNum + "\nLine does not start with [MemSpy].";
       
   104 						}
       
   105 
       
   106 						if(line.contains("Type"))
       
   107 							break;
       
   108 
       
   109 						//Add valid line to array
       
   110 						lines.add(line);	
       
   111 
       
   112 					}
       
   113 				}
       
   114 				finally {
       
   115 					input.close();
       
   116 				}
       
   117 			}
       
   118 			catch (IOException ex){
       
   119 				ex.printStackTrace();
       
   120 				return ex.getMessage();
       
   121 			}
       
   122 
       
   123 			String cycleNumLine = null;
       
   124 			String timeLine = null;
       
   125 
       
   126 			String romCheckSum = null;
       
   127 			String romVersion = null;
       
   128 
       
   129 			for(String str:lines)
       
   130 			{
       
   131 				if(str.contains("Cycle number"))
       
   132 					cycleNumLine = str;
       
   133 				if(str.contains("Time"))
       
   134 					timeLine = str;
       
   135 
       
   136 				if(str.contains("ROM") && str.contains(CHECK_SUM))
       
   137 					romCheckSum = str;
       
   138 				else if(str.contains("ROM") && str.contains(VERSION))
       
   139 					romVersion = str;
       
   140 			}
       
   141 
       
   142 			if(cycleNumLine == null || timeLine == null)
       
   143 				return "Error in the Log " + path + "\n The log might not contain Cycle number or Time information. Please check";
       
   144 
       
   145 			if(romCheckSum == null || romVersion == null)
       
   146 				return "Error in the Log " + path + "\n The log might not contain ROM information. Please check";
       
   147 
       
   148 			//Read cycle number
       
   149 			String num = cycleNumLine.substring(cycleNumLine.indexOf("Cycle number") + 12).trim();
       
   150 			int cycleNo = Integer.parseInt(num);
       
   151 
       
   152 			//Read Time
       
   153 			String time = timeLine.substring(timeLine.indexOf("Time") + 4).trim();
       
   154 
       
   155 			String checkSum = romCheckSum.substring(romCheckSum.indexOf(CHECK_SUM) + (CHECK_SUM).length()).trim();
       
   156 			String romVer = romVersion.substring(romVersion.indexOf(VERSION) + (VERSION).length()).trim();
       
   157 
       
   158 			CycleData cycleData = new CycleData();
       
   159 			cycleData.setTime(time);
       
   160 			cycleData.setCycleNumber(cycleNo);
       
   161 			cycleData.setFileName(path);
       
   162 			cycleData.setRomCheckSum(checkSum);
       
   163 			cycleData.setRomVersion(romVer);
       
   164 
       
   165 			cycles.add(cycleData);	
       
   166 		}
       
   167 
       
   168 		return null;
       
   169 	}
       
   170 
       
   171 	/**
       
   172 	 * Gets the overview information till the selected log file.
       
   173 	 * @param allCyclesData CycleData list
       
   174 	 * @param toCycle Cycle number till where you want to export
       
   175 	 * @return OverviewData
       
   176 	 */
       
   177 	public OverviewData getOverviewInformationFromCyclesData(CycleData[] allCyclesData, int toCycle)
       
   178 	{	
       
   179 		OverviewData overview = new OverviewData();
       
   180 		overview.noOfcycles = toCycle;
       
   181 
       
   182 		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
       
   183 		Date aDate=null;
       
   184 		Date bDate=null;
       
   185 		try {
       
   186 			aDate = sdf.parse(allCyclesData[0].getTime());
       
   187 			bDate = sdf.parse(allCyclesData[toCycle-1].getTime());
       
   188 		} catch (ParseException e) {
       
   189 			e.printStackTrace();
       
   190 		}
       
   191 
       
   192 		long t1= aDate.getTime();
       
   193 		long t2= bDate.getTime();
       
   194 		//time difference in seconds
       
   195 		overview.duration = (t2-t1)/1000;
       
   196 		//Get date and time in the format like : Jan 7, 2008 1:56:44 PM
       
   197 		overview.fromTime = DateFormat.getDateTimeInstance().format(aDate);
       
   198 		overview.toTime = DateFormat.getDateTimeInstance().format(bDate);
       
   199 		overview.durationString = millisecondToDHMS(overview.duration*1000);
       
   200 
       
   201 		DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Cycle Numbers	:" + overview.noOfcycles );
       
   202 		DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Time Period	:" + overview.fromTime + " to " + overview.toTime );
       
   203 		DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Time Duration	:" + overview.duration + " sec (" + overview.durationString + ")");
       
   204 
       
   205 		return overview;
       
   206 	}
       
   207 
       
   208 	/**
       
   209 	 * Returns the difference between two time strings
       
   210 	 * @param startTime 
       
   211 	 * @param endTime
       
   212 	 * @return difference between startTime and endTime in seconds.
       
   213 	 */
       
   214 	public long getDurationInSeconds(String startTime, String endTime)
       
   215 	{
       
   216 		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
       
   217 
       
   218 		Date aDate=null;
       
   219 		Date bDate=null;
       
   220 
       
   221 		try {
       
   222 			aDate = sdf.parse(startTime);
       
   223 			bDate = sdf.parse(endTime);
       
   224 		} catch (ParseException e) {
       
   225 			return -1;
       
   226 		}
       
   227 
       
   228 		long t1= aDate.getTime();
       
   229 		long t2= bDate.getTime();
       
   230 		//time difference in seconds
       
   231 		return (t2-t1)/1000;
       
   232 
       
   233 	}
       
   234 	/**
       
   235 	 * converts time (in milliseconds) to
       
   236 	 *  "d, h, min, sec"
       
   237 	 *  @return time in readable format.
       
   238 	 */
       
   239 	public String millisecondToDHMS(long duration) {
       
   240 		long ONE_SECOND = 1000;
       
   241 		long ONE_MINUTE = ONE_SECOND * 60;
       
   242 		long ONE_HOUR   = ONE_MINUTE * 60;
       
   243 		long ONE_DAY    = ONE_HOUR * 24;
       
   244 
       
   245 		String res = "";
       
   246 		long temp = 0;
       
   247 		if (duration >= ONE_SECOND) {
       
   248 			temp = duration / ONE_DAY;
       
   249 			if (temp > 0) {
       
   250 				res = temp + " d";
       
   251 				duration -= temp * ONE_DAY;
       
   252 
       
   253 				if (duration >= ONE_MINUTE) {
       
   254 					res += ", ";
       
   255 				}
       
   256 			}
       
   257 
       
   258 			temp = duration / ONE_HOUR;
       
   259 			if (temp > 0) {
       
   260 				res += temp + " h";
       
   261 				duration -= temp * ONE_HOUR;
       
   262 				if (duration >= ONE_MINUTE) {
       
   263 					res += ", ";
       
   264 				}
       
   265 			}
       
   266 
       
   267 			temp = duration / ONE_MINUTE;
       
   268 			if (temp > 0) {
       
   269 				res += temp + " min";
       
   270 				duration -= temp * ONE_MINUTE;
       
   271 
       
   272 				if(duration >= ONE_SECOND) {
       
   273 					res += ", ";
       
   274 				}
       
   275 			}
       
   276 
       
   277 			temp = duration / ONE_SECOND;
       
   278 			if (temp > 0) {
       
   279 				res += temp + " sec";
       
   280 			}
       
   281 			return res;
       
   282 		}
       
   283 		else {
       
   284 			return "0 sec";
       
   285 		}
       
   286 	}
       
   287 
       
   288 	/**
       
   289 	 * This will check whether the CycleData objects are in concecutive order and 
       
   290 	 * if not, this will return the reordered list. 
       
   291 	 * @param allCyclesData
       
   292 	 * @return Reordered list, if any cycle data is missing null will be returned 
       
   293 	 */
       
   294 	public ArrayList<CycleData> checkCycleOrder(ArrayList<CycleData> allCyclesData)
       
   295 	{
       
   296 		ArrayList<CycleData> orderedCycles = new ArrayList<CycleData>();
       
   297 
       
   298 		/*for(int i=0; i<allCyclesData.size(); i++) {
       
   299 			for (CycleData cycledata : allCyclesData) {
       
   300 				if(cycledata.getCycleNumber() == i+1)
       
   301 				{
       
   302 					orderedCycles.add(cycledata);
       
   303 					break;
       
   304 				}
       
   305 			}
       
   306 			if(orderedCycles.size() != i+1)
       
   307 				return null;
       
   308 		}*/
       
   309 		CycleData[] before = allCyclesData.toArray(new CycleData[0]);
       
   310 		Arrays.sort(before);
       
   311 		if(before!=null && before.length>0 && before[0].getCycleNumber() == 1)
       
   312 		{	
       
   313 			int i= 1;
       
   314 			for (CycleData data: before) {
       
   315 				data.setCycleNumber(i);
       
   316 				orderedCycles.add(data);
       
   317 				i++;			
       
   318 			}
       
   319 			return orderedCycles;
       
   320 		}
       
   321 		else
       
   322 			return null;
       
   323 	}
       
   324 
       
   325 	/**
       
   326 	 * This method fetches list of all newly created disk names from all the 
       
   327 	 * cycles. If only one cycle is selected it fetches list of new and updated disk names.
       
   328 	 * @param data specifies list of CycleData to be parsed
       
   329 	 * @return list of disknames from all the cycles
       
   330 	 */
       
   331 	public ArrayList<String> getAllDiskNames(ParsedData data)
       
   332 	{
       
   333 		if(data == null || data.getNumberOfCycles() ==0)
       
   334 			return null;
       
   335 
       
   336 		CycleData [] parsed_cycles = data.getLogData();
       
   337 
       
   338 		CycleData firstCycle = parsed_cycles[0];
       
   339 		firstCycle.parseDisksList();
       
   340 		ArrayList<String> totalDisks = new ArrayList<String>(firstCycle.getNewlyCreatedDisks());
       
   341 
       
   342 		if(parsed_cycles.length == 1)
       
   343 		{
       
   344 			ArrayList<String> updatedDisks = firstCycle.getUpdatedDisks();
       
   345 
       
   346 			for(String disk:updatedDisks)
       
   347 			{
       
   348 				if(!totalDisks.contains(disk))
       
   349 					totalDisks.add(disk);
       
   350 			}
       
   351 
       
   352 			return totalDisks;
       
   353 		}
       
   354 		for(int i=1; i<parsed_cycles.length;i++)
       
   355 		{
       
   356 			CycleData cycle = parsed_cycles[i];
       
   357 			cycle.parseDisksList();
       
   358 			ArrayList<String> newDisks = cycle.getNewlyCreatedDisks();
       
   359 
       
   360 			for(String disk:newDisks)
       
   361 			{
       
   362 				if(!totalDisks.contains(disk))
       
   363 					totalDisks.add(disk);
       
   364 			}
       
   365 		}
       
   366 
       
   367 		return totalDisks;
       
   368 	}	
       
   369 
       
   370 	/**
       
   371 	 * This method fetches Used Memory and Size data for a given disk from given list of cycledata.
       
   372 	 * @param diskName name of the disk, whose used memory and size must be fetched.
       
   373 	 * @param data list of cycledata which needs to be parsed.
       
   374 	 * @return list of used memory and size values for all cycles.
       
   375 	 */
       
   376 	public ArrayList<DiskOverview> getUsedMemoryAndSizesForDisk(String diskName, ParsedData parsedData)
       
   377 	{
       
   378 
       
   379 		ArrayList<DiskOverview> diskTotalData = new ArrayList<DiskOverview>();
       
   380 		DiskOverview prevData = new DiskOverview();
       
   381 
       
   382 		CycleData [] cycles = parsedData.getLogData();
       
   383 
       
   384 		for(CycleData cycle:cycles)
       
   385 		{
       
   386 			DiskOverview ov = null;
       
   387 
       
   388 			if(!cycle.getDeletedDisks().contains(diskName)){
       
   389 				DiskOverview tmp = cycle.getDiskUsedAndFreeSize(diskName);
       
   390 
       
   391 				if(tmp != null)
       
   392 					ov = new DiskOverview(tmp);
       
   393 				else
       
   394 				{
       
   395 					ov = new DiskOverview(prevData);
       
   396 
       
   397 					if(prevData.getStatus() == CycleData.New)
       
   398 						ov.setStatus(CycleData.Alive);
       
   399 				}
       
   400 
       
   401 			}
       
   402 			else
       
   403 				ov = new DiskOverview();
       
   404 
       
   405 			diskTotalData.add(ov);
       
   406 			prevData = ov;
       
   407 		}
       
   408 
       
   409 		/*for(int i=0;i<diskTotalData.size();i++)
       
   410 			{
       
   411 				System.out.print("Variation for DISK " + diskName + " in Cycle " + i);
       
   412 				DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "USED: " + diskTotalData.get(i).getUsedSize() + " FREE: " + diskTotalData.get(i).getFreeSize());
       
   413 			}*/
       
   414 
       
   415 		return diskTotalData;
       
   416 	}
       
   417 
       
   418 	/**
       
   419 	 * This method fetches System Used Memory and Size for each cycle from given list of cycledata.
       
   420 	 * @param data list of cycledata which needs to be parsed.
       
   421 	 * @return list of system used memory and size values for all cycles.
       
   422 	 */
       
   423 	public ArrayList<SystemData> getSystemDataFromAllCycles(ParsedData parsedData)
       
   424 	{
       
   425 
       
   426 		ArrayList<SystemData> systemData = new ArrayList<SystemData>();
       
   427 		SystemData prevData = new SystemData();
       
   428 
       
   429 		CycleData [] cycles = parsedData.getLogData();
       
   430 
       
   431 		for(CycleData cycle:cycles)
       
   432 		{
       
   433 			SystemData ov = new SystemData(prevData);
       
   434 
       
   435 			long freeMem = cycle.getFreeMemory();
       
   436 			long totalMem = cycle.getTotalMemory();
       
   437 
       
   438 			if(freeMem != -1)
       
   439 			{
       
   440 				ov.setFreeMemory(freeMem);
       
   441 			}
       
   442 			if(totalMem != -1)
       
   443 				ov.setTotalMemory(totalMem);
       
   444 
       
   445 			systemData.add(ov);
       
   446 			prevData = ov;
       
   447 		}
       
   448 
       
   449 		/*for(int i=0;i<diskTotalData.size();i++)
       
   450 			{
       
   451 				System.out.print("Variation for DISK " + diskName + " in Cycle " + i);
       
   452 				DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "USED: " + diskTotalData.get(i).getUsedSize() + " FREE: " + diskTotalData.get(i).getFreeSize());
       
   453 			}*/
       
   454 
       
   455 		return systemData;
       
   456 	}
       
   457 	/**
       
   458 	 * The method creates a union list of newly created threads in each cycle.
       
   459 	 * @param data list of Cycle data structures to be parsed
       
   460 	 * @return union list of thread names from all the cycles.
       
   461 	 */
       
   462 	public ArrayList<String> getAllThreadNames(ParsedData data)
       
   463 	{
       
   464 		if(data == null || data.getNumberOfCycles() == 0)
       
   465 			return null;
       
   466 
       
   467 		CycleData[] parsed_cycles = data.getLogData();
       
   468 		CycleData firstCycle = parsed_cycles[0];
       
   469 		firstCycle.parseAllThreads();
       
   470 		ArrayList<String> totalThreads = new ArrayList<String>(firstCycle.getNewlyCreatedThreads());
       
   471 
       
   472 		if(parsed_cycles.length == 1)
       
   473 		{
       
   474 			ArrayList<String> updatedThreads = firstCycle.getUpdatedThreads();
       
   475 
       
   476 			for(String thread:updatedThreads)
       
   477 			{
       
   478 				if(!totalThreads.contains(thread))
       
   479 					totalThreads.add(thread);
       
   480 			}
       
   481 
       
   482 			ArrayList<String> threadsFromAllViews = getThreadsFromAllViews(firstCycle);
       
   483 
       
   484 			for(String thread:threadsFromAllViews)
       
   485 			{
       
   486 				if(!totalThreads.contains(thread))
       
   487 					totalThreads.add(thread);
       
   488 			}
       
   489 
       
   490 			return totalThreads;
       
   491 		}
       
   492 		for(int i=1; i<parsed_cycles.length;i++)
       
   493 		{
       
   494 			CycleData cycle = parsed_cycles[i];
       
   495 			cycle.parseAllThreads();
       
   496 			ArrayList<String> newThreads = cycle.getNewlyCreatedThreads();
       
   497 
       
   498 			for(String thread:newThreads)
       
   499 			{
       
   500 				if(!totalThreads.contains(thread))
       
   501 					totalThreads.add(thread);
       
   502 			}
       
   503 		}
       
   504 
       
   505 		return totalThreads;
       
   506 	}	
       
   507 
       
   508 	/**
       
   509 	 * This method fetches list of all heap thread names from all the cycles. 
       
   510 	 * If only one cycle is selected it fetches list of new and updated heap thread names.
       
   511 	 * @param data specifies list of CycleData to be parsed
       
   512 	 * @return list of those thread names which contain heap information, in one or many cycles.
       
   513 	 */
       
   514 	public ArrayList<String> getAllHeapThreads(ParsedData parsedData)
       
   515 	{
       
   516 
       
   517 		CycleData [] logData = parsedData.getLogData();
       
   518 		CycleData firstCycle = logData[0];
       
   519 
       
   520 		firstCycle.parseAllHeaps();
       
   521 		ArrayList<String> totalHeaps = new ArrayList<String>(firstCycle.getNewHeapThreads());
       
   522 
       
   523 		if(logData.length == 1)
       
   524 		{
       
   525 			ArrayList<String> updatedHeaps = firstCycle.getAliveHeapThreads();
       
   526 
       
   527 			for(String thread:updatedHeaps)
       
   528 			{
       
   529 				if(!totalHeaps.contains(thread))
       
   530 					totalHeaps.add(thread);
       
   531 			}
       
   532 
       
   533 			return totalHeaps;
       
   534 		}
       
   535 		for(int i=1; i<logData.length;i++)
       
   536 		{
       
   537 			CycleData cycle = logData[i];
       
   538 
       
   539 			cycle.parseAllHeaps();
       
   540 			ArrayList<String> newHeaps = cycle.getNewHeapThreads();
       
   541 
       
   542 			for(String thread:newHeaps)
       
   543 			{
       
   544 				if(!totalHeaps.contains(thread))
       
   545 					totalHeaps.add(thread);
       
   546 			}
       
   547 		}
       
   548 
       
   549 		return totalHeaps;
       
   550 	}
       
   551 
       
   552 	/**
       
   553 	 * This method fetches all the data for a given thread from given list of cycledata.
       
   554 	 * @param threadName name of the thread whose data is needed.
       
   555 	 * @param cycles list of cycledata structures to be parsed for the thread data.
       
   556 	 * @return list of ThreadData structures. Each structure holds values of given thread fields in each cycle.
       
   557 	 */
       
   558 	public ArrayList<ThreadData> getHeapDataFromAllCycles(String threadName, ParsedData parsedData)
       
   559 	{
       
   560 		ArrayList<ThreadData> allData = new ArrayList<ThreadData>();
       
   561 
       
   562 		ThreadData prevData = new ThreadData(threadName);
       
   563 		CycleData[] cycles = parsedData.getLogData();
       
   564 
       
   565 		for(CycleData cycle:cycles)
       
   566 		{
       
   567 			ThreadData currentData = null; 
       
   568 
       
   569 			cycle.parseAllThreads();
       
   570 
       
   571 			//Fetch the data for this thread in this cycle.
       
   572 			//If no data in this cycle, copy the data from the previous cycle.	
       
   573 
       
   574 			ThreadData tmp = cycle.getHeapData(threadName);
       
   575 
       
   576 			if(tmp != null)
       
   577 				currentData = tmp;
       
   578 			else{
       
   579 				currentData = new ThreadData(prevData);
       
   580 				if(prevData.getStatus() == CycleData.New)
       
   581 					currentData.setStatus(CycleData.Alive);
       
   582 			}
       
   583 
       
   584 			StackData stakData = cycle.getStackData(threadName);
       
   585 
       
   586 			if(stakData != null)
       
   587 			{
       
   588 				currentData.setStackStatus(stakData.getStatus());
       
   589 				currentData.setStackSize(stakData.getSize());
       
   590 			}
       
   591 			else
       
   592 			{
       
   593 				if(prevData.getStackStatus() == CycleData.New)
       
   594 					currentData.setStackStatus(CycleData.Alive);
       
   595 				else
       
   596 					currentData.setStackStatus(prevData.getStackStatus());
       
   597 
       
   598 				currentData.setStackSize(prevData.getStackSize());
       
   599 			}
       
   600 
       
   601 			int openFilesCnt = cycle.getNewOpenFiles(threadName);
       
   602 			int closedFilesCnt = cycle.getDeletedFiles(threadName);
       
   603 
       
   604 			int newPSHandlesCnt = cycle.getNewPSHandles(threadName);
       
   605 			int deletedPSHandlesCnt = cycle.getDeletedPSHandles(threadName);
       
   606 
       
   607 			if(cycles.length == 1)
       
   608 			{
       
   609 				int updatedFiles = cycle.getUpdatedFiles(threadName);
       
   610 				int updatedPSHandles = cycle.getUpdatedPSHandles(threadName);
       
   611 
       
   612 				currentData.setOpenFiles(openFilesCnt + updatedFiles);
       
   613 				currentData.setPsHandles(newPSHandlesCnt + updatedPSHandles);
       
   614 			}
       
   615 
       
   616 			else
       
   617 			{
       
   618 				openFilesCnt += prevData.getOpenFiles();
       
   619 
       
   620 				openFilesCnt -= closedFilesCnt;
       
   621 				currentData.setOpenFiles(openFilesCnt);
       
   622 
       
   623 				newPSHandlesCnt += prevData.getPsHandles();
       
   624 				newPSHandlesCnt -= deletedPSHandlesCnt;
       
   625 
       
   626 				currentData.setPsHandles(newPSHandlesCnt);
       
   627 			}
       
   628 
       
   629 			if(cycle.getDeletedThreads().contains(threadName))
       
   630 				currentData.setKernelHandleDeleted(true);
       
   631 
       
   632 			currentData.setCycleNumber(cycle.getCycleNumber());	
       
   633 			allData.add(currentData);
       
   634 			prevData = currentData;
       
   635 		}
       
   636 
       
   637 		return allData;
       
   638 	}
       
   639 
       
   640 	/**
       
   641 	 * Returns the array of global data chunks list of given chunk 
       
   642 	 * from all the log files data.
       
   643 	 * @param chunkName
       
   644 	 * @param cycles
       
   645 	 * @return List of {@link GlobalDataChunks} with given chunk name
       
   646 	 */
       
   647 	public ArrayList<GlobalDataChunks> getGLOBDataFromAllCycles(String chunkName, ParsedData logData)
       
   648 	{
       
   649 
       
   650 		ArrayList<GlobalDataChunks> allData = new ArrayList<GlobalDataChunks>();
       
   651 
       
   652 		GlobalDataChunks prevData = new GlobalDataChunks();
       
   653 
       
   654 		CycleData [] logCycles = logData.getLogData();
       
   655 
       
   656 		for(CycleData cycle:logCycles)
       
   657 		{
       
   658 			GlobalDataChunks currentData = null;
       
   659 			GlobalDataChunks tmp = cycle.getGlobalChunkDataFor(chunkName);
       
   660 			if(tmp != null)
       
   661 				currentData = tmp;
       
   662 			else{
       
   663 				currentData = new GlobalDataChunks(prevData);
       
   664 
       
   665 				if(prevData.getAttrib() == CycleData.New)
       
   666 					currentData.setAttrib(CycleData.Alive);
       
   667 			}
       
   668 
       
   669 			if(cycle.getDeletedChunkNames().contains(chunkName))
       
   670 				currentData.setKernelHandleDeleted(true);
       
   671 
       
   672 			allData.add(currentData);
       
   673 			prevData = currentData;
       
   674 		}
       
   675 
       
   676 		return allData;
       
   677 	}
       
   678 
       
   679 	/**
       
   680 	 * Returns the array of chunks data list of given chunk 
       
   681 	 * from all the log files data.
       
   682 	 * @param chunkName
       
   683 	 * @param cycles
       
   684 	 * @return list of {@link ChunksData} with given name
       
   685 	 */
       
   686 	public ArrayList<ChunksData> getChunkDataFromAllCycles(String chunkName, ParsedData logData)
       
   687 	{
       
   688 		ArrayList<ChunksData> allData = new ArrayList<ChunksData>();
       
   689 
       
   690 		ChunksData prevData = new ChunksData();
       
   691 
       
   692 		CycleData[] cycles = logData.getLogData();
       
   693 		for(CycleData cycle:cycles)
       
   694 		{
       
   695 			ChunksData currentData = null;
       
   696 			ChunksData tmp = cycle.getChunkDataFor(chunkName);
       
   697 			if(tmp != null)
       
   698 				currentData = tmp;
       
   699 			else{
       
   700 				currentData = new ChunksData(prevData);
       
   701 				if(prevData.getAttrib() == CycleData.New)
       
   702 					currentData.setAttrib(CycleData.Alive);
       
   703 			}
       
   704 
       
   705 			if(cycle.getDeletedChunkNames().contains(chunkName))
       
   706 				currentData.setKernelHandleDeleted(true);
       
   707 
       
   708 			allData.add(currentData);
       
   709 			prevData = currentData;
       
   710 		}
       
   711 
       
   712 		return allData;
       
   713 	}
       
   714 
       
   715 	/**
       
   716 	 * This method returns the array of kernel elements data from all the given log files data.
       
   717 	 * @param parsedData
       
   718 	 * @return array of kernel elements
       
   719 	 */
       
   720 	public ArrayList<KernelElements> getKerenelElemsFromAllCycles(ParsedData parsedData)
       
   721 	{
       
   722 		ArrayList<KernelElements> allData = new ArrayList<KernelElements>();
       
   723 		KernelElements prevData = new KernelElements();
       
   724 
       
   725 		CycleData [] cycles = parsedData.getLogData();
       
   726 		for(CycleData cycle:cycles)
       
   727 		{
       
   728 			KernelElements currentData = cycle.getAllOpenKernelElements();
       
   729 
       
   730 			int timers = currentData.getNumberOfTimers();
       
   731 			int semaphores = currentData.getNumberOfSemaphores();
       
   732 			int servers = currentData.getNumberOfServers();
       
   733 			int sessions = currentData.getNumberOfSessions();
       
   734 			int processes = currentData.getNumberOfProcesses();
       
   735 			int threads = currentData.getNumberOfThreads();
       
   736 			int chunks = currentData.getNumberOfChunks();
       
   737 			int msgQueues = currentData.getNumberOfMsgQueues();
       
   738 
       
   739 
       
   740 			if(parsedData.getNumberOfCycles() != 1)
       
   741 			{
       
   742 
       
   743 				timers += prevData.getNumberOfTimers();
       
   744 				semaphores += prevData.getNumberOfSemaphores();
       
   745 				sessions += prevData.getNumberOfSessions();
       
   746 				servers += prevData.getNumberOfServers();
       
   747 				processes += prevData.getNumberOfProcesses();
       
   748 				threads += prevData.getNumberOfThreads();
       
   749 				chunks += prevData.getNumberOfChunks();
       
   750 				msgQueues += prevData.getNumberOfMsgQueues();
       
   751 
       
   752 				//newTimers -= closedTimers;
       
   753 				currentData.setNumberOfTimers(timers);
       
   754 				currentData.setNumberOfSemaphores(semaphores);
       
   755 				currentData.setNumberOfProcesses(processes);
       
   756 				currentData.setNumberOfSessions(sessions);
       
   757 				currentData.setNumberOfServers(servers);
       
   758 				currentData.setNumberOfThreads(threads);
       
   759 				currentData.setNumberOfChunks(chunks);
       
   760 				currentData.setNumberOfMsgQueues(msgQueues);
       
   761 
       
   762 			}
       
   763 			allData.add(currentData);
       
   764 			prevData = currentData;
       
   765 
       
   766 		}
       
   767 		return allData;
       
   768 	}
       
   769 	/**
       
   770 	 * 
       
   771 	 * @param threadName name of thread whose status is needed.
       
   772 	 * @param data list of cycledata to be parsed
       
   773 	 * @return the recent status of the thread from given cycles. 
       
   774 	 */
       
   775 	public int getThreadStatusFromAllCycles(String threadName, ParsedData parsedData)
       
   776 	{
       
   777 		int status = -1;
       
   778 
       
   779 		CycleData [] cycles = parsedData.getLogData();
       
   780 
       
   781 		for(CycleData cycle:cycles)
       
   782 		{
       
   783 			cycle.parseAllThreads();
       
   784 			if(cycle.getNewlyCreatedThreads().contains(threadName))
       
   785 				status = CycleData.New;
       
   786 			else if(cycle.getUpdatedThreads().contains(threadName))
       
   787 				status = CycleData.Alive;
       
   788 			else if(cycle.getDeletedThreads().contains(threadName))
       
   789 				status = CycleData.Deleted;
       
   790 
       
   791 		}
       
   792 		return status;
       
   793 	}
       
   794 
       
   795 	/**
       
   796 	 * 
       
   797 	 * @param threadName name of thread whose heap status is needed.
       
   798 	 * @param data list of cycledata to be parsed
       
   799 	 * @return the recent status of the given thread's heap.
       
   800 	 */
       
   801 	public int getHeapStatusFromAllCycles(String threadName, ParsedData parsedData)
       
   802 	{
       
   803 		int status = 0;
       
   804 		CycleData [] cycles = parsedData.getLogData();
       
   805 
       
   806 		for(CycleData cycle:cycles)
       
   807 		{
       
   808 			cycle.parseAllHeaps();
       
   809 
       
   810 			ArrayList<String> newHeapThreads = convertAllStringsToLowerCase(cycle.getNewHeapThreads());
       
   811 			ArrayList<String> aliveHeaps = convertAllStringsToLowerCase(cycle.getAliveHeapThreads());
       
   812 			ArrayList<String> deletedHeaps = convertAllStringsToLowerCase(cycle.getDeletedHeapThreads());
       
   813 
       
   814 			if(newHeapThreads.contains(threadName.toLowerCase()) ||
       
   815 					aliveHeaps.contains(threadName.toLowerCase()))
       
   816 				status = 1;
       
   817 			else if(deletedHeaps.contains(threadName.toLowerCase()))
       
   818 				status = 0;
       
   819 		}
       
   820 
       
   821 		return status;
       
   822 	}
       
   823 
       
   824 	/**
       
   825 	 * Get the stack status of a given thread name
       
   826 	 * @param threadName name of thread whose heap status is needed.
       
   827 	 * @param data list of cycledata to be parsed
       
   828 	 * @return the recent status of the given thread's stack.
       
   829 	 */
       
   830 	public int getStackStatusFromAllCycles(String threadName, ParsedData parsedData)
       
   831 	{
       
   832 		int status = 0;
       
   833 		CycleData[] cycles = parsedData.getLogData();
       
   834 
       
   835 		for(CycleData cycle:cycles)
       
   836 		{
       
   837 			ArrayList<String> newStacks = convertAllStringsToLowerCase(cycle.getNewStackThreads());
       
   838 			ArrayList<String> aliveStacks = convertAllStringsToLowerCase(cycle.getAliveStackThreads());
       
   839 			ArrayList<String> deletedStacks = convertAllStringsToLowerCase(cycle.getDeletedStackThreads());
       
   840 
       
   841 			if(newStacks.contains(threadName.toLowerCase()) ||
       
   842 					aliveStacks.contains(threadName.toLowerCase()))
       
   843 				status = 1;
       
   844 			else if(deletedStacks.contains(threadName.toLowerCase()))
       
   845 				status = 0;	
       
   846 		}
       
   847 
       
   848 		return status;
       
   849 	}
       
   850 
       
   851 	/**
       
   852 	 * Get the delta data for the given threadname from all the cycles.
       
   853 	 * @param threadName name of the thread
       
   854 	 * @param logData list of cycledata to be parsed.
       
   855 	 * @return the ThreadData structure which holds the differences for various
       
   856 	 * fields in the lastCycle and the cycle in which the thread has actually started.  
       
   857 	 */
       
   858 	public ThreadData getChangeinHeapData(String threadName, ArrayList<ThreadData> allCyclesData, ParsedData logData)
       
   859 	{
       
   860 		ThreadData heapDataChange = new ThreadData(threadName);
       
   861 
       
   862 		//If the heap for this thread is already deleted all the
       
   863 		//heap related fields will be set to 0.
       
   864 		if(getHeapStatusFromAllCycles(threadName, logData) == 0)
       
   865 		{
       
   866 			//Display zeros for all heap fields
       
   867 			heapDataChange.setMaxHeapSize(0);
       
   868 			heapDataChange.setHeapChunkSize(0);
       
   869 			heapDataChange.setHeapAllocatedSpace(0);
       
   870 			heapDataChange.setHeapFreeSpace(0);
       
   871 			heapDataChange.setAllocatedCells(0);
       
   872 			heapDataChange.setFreeCells(0);
       
   873 			heapDataChange.setFreeSlackSize(0);
       
   874 			heapDataChange.setLargestAllocCellSize(0);
       
   875 			heapDataChange.setLargestFreeCellSize(0);
       
   876 
       
   877 		}
       
   878 		else{
       
   879 
       
   880 			ThreadData lastHeapData = allCyclesData.get(logData.getNumberOfCycles()-1);
       
   881 
       
   882 			//Get the heap values from the cycle in which the
       
   883 			//thread is started.
       
   884 			ThreadData firstHeapData = null;
       
   885 
       
   886 			for(int i=allCyclesData.size()-2; i>=0; i--)
       
   887 			{
       
   888 				ThreadData data = allCyclesData.get(i);
       
   889 				if(data.getStatus() != CycleData.Deleted){
       
   890 					firstHeapData = data;
       
   891 				}
       
   892 				else
       
   893 					break;
       
   894 			}
       
   895 
       
   896 			if(firstHeapData != null)
       
   897 			{
       
   898 				heapDataChange.setMaxHeapSize(firstHeapData.getMaxHeapSize());
       
   899 				long changeInHeapSize = lastHeapData.getHeapChunkSize() - firstHeapData.getHeapChunkSize();
       
   900 				long changeInAllocSpace = lastHeapData.getHeapAllocatedSpace() - firstHeapData.getHeapAllocatedSpace();
       
   901 				long changeInFreeSpace = lastHeapData.getHeapFreeSpace() - firstHeapData.getHeapFreeSpace();
       
   902 				long changeInAllocCells = lastHeapData.getAllocatedCells() - firstHeapData.getAllocatedCells();
       
   903 				long changeInFreeCells = lastHeapData.getFreeCells() - firstHeapData.getFreeCells();
       
   904 				long changeInSlackSize = lastHeapData.getFreeSlackSize() - firstHeapData.getFreeSlackSize();
       
   905 				long changeInLargestAllocCell = lastHeapData.getLargestAllocCellSize() - firstHeapData.getLargestAllocCellSize();
       
   906 				long changeInLargestFreeCell = lastHeapData.getLargestFreeCellSize() - firstHeapData.getLargestFreeCellSize();
       
   907 
       
   908 				heapDataChange.setHeapChunkSize(changeInHeapSize);
       
   909 				heapDataChange.setHeapAllocatedSpace(changeInAllocSpace);
       
   910 				heapDataChange.setHeapFreeSpace(changeInFreeSpace);
       
   911 				heapDataChange.setAllocatedCells(changeInAllocCells);
       
   912 				heapDataChange.setFreeCells(changeInFreeCells);
       
   913 				heapDataChange.setFreeSlackSize(changeInSlackSize);
       
   914 				heapDataChange.setLargestAllocCellSize(changeInLargestAllocCell);
       
   915 				heapDataChange.setLargestFreeCellSize(changeInLargestFreeCell);
       
   916 
       
   917 			}
       
   918 			else
       
   919 			{
       
   920 				heapDataChange.setMaxHeapSize(lastHeapData.getMaxHeapSize());
       
   921 				heapDataChange.setHeapChunkSize(lastHeapData.getHeapChunkSize());
       
   922 				heapDataChange.setHeapAllocatedSpace(lastHeapData.getHeapAllocatedSpace());
       
   923 				heapDataChange.setHeapFreeSpace(lastHeapData.getHeapFreeSpace());
       
   924 				heapDataChange.setAllocatedCells(lastHeapData.getAllocatedCells());
       
   925 				heapDataChange.setFreeCells(lastHeapData.getFreeCells());
       
   926 				heapDataChange.setFreeSlackSize(lastHeapData.getFreeSlackSize());
       
   927 				heapDataChange.setLargestAllocCellSize(lastHeapData.getLargestAllocCellSize());
       
   928 				heapDataChange.setLargestFreeCellSize(lastHeapData.getLargestFreeCellSize());
       
   929 			}
       
   930 		}
       
   931 
       
   932 		ThreadData lastHeapData = allCyclesData.get(logData.getNumberOfCycles()-1);
       
   933 
       
   934 		if(getStackStatusFromAllCycles(threadName, logData) == 0)
       
   935 		{
       
   936 			heapDataChange.setStackSize(0);
       
   937 		}
       
   938 		else
       
   939 		{
       
   940 			heapDataChange.setStackSize(lastHeapData.getStackSize());
       
   941 		}
       
   942 
       
   943 		heapDataChange.setOpenFiles(lastHeapData.getOpenFiles());
       
   944 
       
   945 		if(lastHeapData.getPsHandles() == -1)
       
   946 			heapDataChange.setPsHandles(0);
       
   947 		else
       
   948 			heapDataChange.setPsHandles(lastHeapData.getPsHandles());
       
   949 
       
   950 		return heapDataChange;
       
   951 	}
       
   952 
       
   953 	/**
       
   954 	 * Returns the start and end cycle numbers for the threads having multiple instances 
       
   955 	 * @param threadData list
       
   956 	 * @return start and end cycle numbers 
       
   957 	 */
       
   958 	public ThreadSegments [] getHeapSegments(ArrayList<ThreadData> threadData)
       
   959 	{
       
   960 		ArrayList<ThreadSegments> thSegments = new ArrayList<ThreadSegments>();
       
   961 		boolean is_thread_started = false;
       
   962 		ThreadSegments segment = null;
       
   963 
       
   964 		for(ThreadData data: threadData)
       
   965 		{
       
   966 			if(data.getStatus() == CycleData.New && !is_thread_started)
       
   967 			{
       
   968 				segment = new ThreadSegments();
       
   969 				is_thread_started = true;
       
   970 				segment.setStartCycle(data.getCycleNumber());
       
   971 			}
       
   972 			if((data.getStatus() == CycleData.Deleted || data.getCycleNumber() == threadData.size()) && is_thread_started)
       
   973 			{
       
   974 				is_thread_started = false;
       
   975 				if(segment != null){
       
   976 					segment.setEndCycle(data.getCycleNumber());
       
   977 					thSegments.add(segment);
       
   978 				}
       
   979 			}
       
   980 		}
       
   981 		return thSegments.toArray(new ThreadSegments[0]);
       
   982 	}
       
   983 	/**
       
   984 	 * Returns the delta value for the given global chunk.
       
   985 	 * @param chunkName
       
   986 	 * @param logData
       
   987 	 * @return delta value for the given global chunk
       
   988 	 */
       
   989 	public long getChangeinGlodChunksData(String chunkName, ParsedData logData)
       
   990 	{
       
   991 
       
   992 		ArrayList<GlobalDataChunks> heapData = getGLOBDataFromAllCycles(chunkName, logData);
       
   993 
       
   994 
       
   995 		if(heapData.get(heapData.size()-1).getAttrib() == CycleData.Deleted)
       
   996 			return 0;
       
   997 		else
       
   998 		{
       
   999 			long lastValue = heapData.get(heapData.size()-1).getSize();
       
  1000 			long firstValue = 0;
       
  1001 			for(GlobalDataChunks data: heapData)
       
  1002 			{
       
  1003 				if(data.getSize() != -1)
       
  1004 				{
       
  1005 					firstValue = data.getSize();
       
  1006 					break;
       
  1007 				}
       
  1008 			}
       
  1009 			return lastValue - firstValue;
       
  1010 		}		
       
  1011 	}
       
  1012 
       
  1013 	/**
       
  1014 	 * Returns the delta value for the given chunk.
       
  1015 	 * @param chunkName
       
  1016 	 * @param logData
       
  1017 	 * @return delta value for the given chunk
       
  1018 	 */
       
  1019 	public long getChangeinChunksData(String chunkName, ParsedData logData)
       
  1020 	{
       
  1021 		ArrayList<ChunksData> heapData = getChunkDataFromAllCycles(chunkName, logData);
       
  1022 
       
  1023 		if(heapData.get(heapData.size()-1).getAttrib() == CycleData.Deleted)
       
  1024 			return 0;
       
  1025 		else
       
  1026 		{
       
  1027 			long lastValue = heapData.get(heapData.size()-1).getSize();
       
  1028 			long firstValue = 0;
       
  1029 			for(ChunksData data: heapData)
       
  1030 			{
       
  1031 				if(data.getSize() != -1)
       
  1032 				{
       
  1033 					firstValue = data.getSize();
       
  1034 					break;
       
  1035 				}
       
  1036 			}
       
  1037 			return lastValue - firstValue;
       
  1038 		}		
       
  1039 	}
       
  1040 
       
  1041 	/**
       
  1042 	 * Return sum of the given delta values.
       
  1043 	 * @param deltaValues
       
  1044 	 * @return the sum of all given values
       
  1045 	 */
       
  1046 	public long calculateAndGetTotal(long[] deltaValues)
       
  1047 	{
       
  1048 		long total = 0;
       
  1049 
       
  1050 		for(long value:deltaValues)
       
  1051 		{
       
  1052 			total = total + value;
       
  1053 		}		
       
  1054 		return total;
       
  1055 	}
       
  1056 
       
  1057 	/**
       
  1058 	 * Returns time intervals for all the given cycles.
       
  1059 	 * @param parsedData
       
  1060 	 * @return intervals
       
  1061 	 */
       
  1062 	public int [] getTimeIntervalsFromLogData(ParsedData parsedData)
       
  1063 	{
       
  1064 		CycleData [] cyclesData = parsedData.getLogData();
       
  1065 
       
  1066 		if(cyclesData == null)
       
  1067 			return null;
       
  1068 
       
  1069 		int [] timeIntervals = new int[cyclesData.length];
       
  1070 
       
  1071 		timeIntervals[0] = 0;
       
  1072 
       
  1073 		for(int i=1; i<timeIntervals.length; i++)
       
  1074 			timeIntervals[i] = (int)getDurationInSeconds(cyclesData[i-1].getTime(), cyclesData[i].getTime()) + timeIntervals[i-1];
       
  1075 
       
  1076 		return timeIntervals;
       
  1077 	}
       
  1078 	/**
       
  1079 	 * 
       
  1080 	 * @param valuesArr
       
  1081 	 * @return the difference between the last value and the first value, if the given set does not contain -1.
       
  1082 	 * If the set contains -1, the value after that would be treated as the first value.
       
  1083 	 */
       
  1084 	public long calculateDeltaForGivenSet(long [] valuesArr)
       
  1085 	{
       
  1086 		int length = valuesArr.length;
       
  1087 
       
  1088 		long lastValue = valuesArr[length-1];
       
  1089 		long firstValue = -1;
       
  1090 
       
  1091 		for(int i = length-2; i>=0;i--)
       
  1092 		{
       
  1093 			if(valuesArr[i] != -1)
       
  1094 				firstValue = valuesArr[i];
       
  1095 			else
       
  1096 				break;
       
  1097 		}
       
  1098 
       
  1099 		if(lastValue != -1)
       
  1100 		{
       
  1101 			if(firstValue != -1)
       
  1102 				return lastValue - firstValue;
       
  1103 			else
       
  1104 				return lastValue;
       
  1105 		}
       
  1106 		else
       
  1107 			return 0;
       
  1108 	}
       
  1109 
       
  1110 	/**
       
  1111 	 * Returns unique list of global chunk names from all the log files.
       
  1112 	 * @see GlobalDataChunks#getChunkName()
       
  1113 	 * @param data
       
  1114 	 * @return list about global chunk names
       
  1115 	 */
       
  1116 	public ArrayList<String> getAllGlobalChunkNames(ParsedData data)
       
  1117 	{
       
  1118 		if(data == null || data.getNumberOfCycles() == 0)
       
  1119 			return null;
       
  1120 
       
  1121 		CycleData [] parsed_cycles = data.getLogData();
       
  1122 		ArrayList<String> globalChunkNames = new ArrayList<String>();
       
  1123 
       
  1124 		for(CycleData cycle: parsed_cycles)
       
  1125 		{
       
  1126 			if(cycle.getGlobalDataChunksList()!=null)
       
  1127 				for(GlobalDataChunks chunkName:cycle.getGlobalDataChunksList())
       
  1128 				{
       
  1129 					if(!globalChunkNames.contains(chunkName.getChunkName()))
       
  1130 						globalChunkNames.add(chunkName.getChunkName());
       
  1131 				}
       
  1132 		}
       
  1133 
       
  1134 		return globalChunkNames;
       
  1135 	}
       
  1136 
       
  1137 	/**
       
  1138 	 * Returns unique list of non heap chunk names from all the log files.
       
  1139 	 * @see ChunksData#getChunkName()
       
  1140 	 * @param data
       
  1141 	 * @return List of non heap chunk names
       
  1142 	 */
       
  1143 	public ArrayList<String> getAllNonHeapChunkNames(ParsedData data)
       
  1144 	{
       
  1145 		if(data == null || data.getNumberOfCycles() == 0)
       
  1146 			return null;
       
  1147 
       
  1148 		ArrayList<String> chunkNames = new ArrayList<String>();
       
  1149 		CycleData [] parsed_cycles = data.getLogData();
       
  1150 
       
  1151 		for(CycleData cycle: parsed_cycles)
       
  1152 		{
       
  1153 			if(cycle.getChunksList()!=null)
       
  1154 				for(ChunksData chunkName:cycle.getChunksList())
       
  1155 				{
       
  1156 					if(!chunkNames.contains(chunkName.getChunkName()))
       
  1157 						chunkNames.add(chunkName.getChunkName());
       
  1158 				}
       
  1159 		}
       
  1160 
       
  1161 		return chunkNames;
       
  1162 	}
       
  1163 
       
  1164 	/**
       
  1165 	 * This method returns unique list of window group names from all the log files.
       
  1166 	 * @param data
       
  1167 	 * @return window group names
       
  1168 	 */
       
  1169 	public ArrayList<String> getWindowGroupNames(ParsedData data)
       
  1170 	{
       
  1171 		if(data == null || data.getNumberOfCycles() == 0)
       
  1172 			return null;
       
  1173 		
       
  1174 		ArrayList<String> wndgNames = new ArrayList<String>();
       
  1175 		CycleData [] parsed_cycles = data.getLogData();
       
  1176 		
       
  1177 		for(CycleData cycle: parsed_cycles)
       
  1178 		{
       
  1179 			for(WindowGroups name:cycle.getWindowGroupsData())
       
  1180 			{
       
  1181 				if(!wndgNames.contains(name.getName()))
       
  1182 						wndgNames.add(name.getName());
       
  1183 			}
       
  1184 		}
       
  1185 		
       
  1186 		return wndgNames;
       
  1187 	}
       
  1188 	
       
  1189 	/**
       
  1190 	 * Get {@link WindowGroupEventData} for given window group name
       
  1191 	 * @param windowGroupName
       
  1192 	 * @param logData
       
  1193 	 * @return list of window group data
       
  1194 	 */
       
  1195 	public ArrayList<WindowGroupEventData> getAllWindowGroupEvents(String windowGroupName, ParsedData logData)
       
  1196 	{
       
  1197 		if(logData == null || logData.getNumberOfCycles() == 0)
       
  1198 			return null;
       
  1199 		
       
  1200 		CycleData [] parsed_cycles = logData.getLogData();
       
  1201 		
       
  1202 		ArrayList<WindowGroupEventData> eventsData = new ArrayList<WindowGroupEventData>();
       
  1203 		
       
  1204 		WindowGroupEventData prevData = null;
       
  1205 		
       
  1206 		for(CycleData cycle:parsed_cycles)
       
  1207 		{
       
  1208 			WindowGroupEventData currentData;
       
  1209 			
       
  1210 			if(prevData == null)
       
  1211 				currentData = new WindowGroupEventData();
       
  1212 			else
       
  1213 				currentData = new WindowGroupEventData(prevData);
       
  1214 			
       
  1215 			for(WindowGroups grp: cycle.getWindowGroupsData())
       
  1216 			{
       
  1217 				if(grp.getName().equalsIgnoreCase(windowGroupName))
       
  1218 				{
       
  1219 					if(grp.getStatus() == CycleData.New || grp.getStatus() == CycleData.Alive)
       
  1220 						currentData.incrementEventCount(grp.getEvent());
       
  1221 					else if(grp.getStatus() == CycleData.Deleted)
       
  1222 						currentData.decrementEventCount(grp.getEvent());
       
  1223 				}
       
  1224 			}
       
  1225 			
       
  1226 			prevData = currentData;
       
  1227 			eventsData.add(currentData);
       
  1228 		}
       
  1229 		
       
  1230 		return eventsData;
       
  1231 	}
       
  1232 	/**
       
  1233 	 * Get all threads names from data
       
  1234 	 * @param data
       
  1235 	 * @return List of thread names.
       
  1236 	 */
       
  1237 	public ArrayList<String> getThreadsFromAllViews(CycleData data)
       
  1238 	{
       
  1239 		ArrayList<String> threads = new ArrayList<String>();
       
  1240 
       
  1241 		data.parseAllHeaps();
       
  1242 
       
  1243 		for(String threadName:data.getNewHeapThreads())
       
  1244 		{
       
  1245 			if(!threads.contains(threadName))
       
  1246 				threads.add(threadName);
       
  1247 		}
       
  1248 
       
  1249 		for(String threadName:data.getAliveHeapThreads())
       
  1250 		{
       
  1251 			if(!threads.contains(threadName))
       
  1252 				threads.add(threadName);
       
  1253 		}
       
  1254 
       
  1255 		for(String threadName:data.getNewStackThreads())
       
  1256 		{
       
  1257 			if(!threads.contains(threadName))
       
  1258 				threads.add(threadName);
       
  1259 		}
       
  1260 
       
  1261 		for(String threadName:data.getAliveStackThreads())
       
  1262 		{
       
  1263 			if(!threads.contains(threadName))
       
  1264 				threads.add(threadName);
       
  1265 		}
       
  1266 
       
  1267 		for(String threadName:data.getFileThreads())
       
  1268 		{
       
  1269 			if(!threads.contains(threadName))
       
  1270 				threads.add(threadName);
       
  1271 		}
       
  1272 
       
  1273 		for(String threadName:data.getHPASThreads())
       
  1274 		{
       
  1275 			if(threadName.length() !=0 && !threads.contains(threadName))
       
  1276 				threads.add(threadName);
       
  1277 		}
       
  1278 		return threads;
       
  1279 	}
       
  1280 
       
  1281 	/**
       
  1282 	 * Gets the total for given delta values.
       
  1283 	 * @param deltaValues
       
  1284 	 * @return total delta values counted together
       
  1285 	 */
       
  1286 	public long getTotal(ArrayList<String> deltaValues)
       
  1287 	{
       
  1288 		long total = 0;
       
  1289 		for(String value:deltaValues)
       
  1290 		{
       
  1291 			if(value != "N/A")
       
  1292 				total = total + Long.parseLong(value);
       
  1293 		}		
       
  1294 		return total;
       
  1295 	}
       
  1296 
       
  1297 	/**
       
  1298 	 * Converts all given strings to lower case.
       
  1299 	 * @param inputList
       
  1300 	 * @return
       
  1301 	 */
       
  1302 	private ArrayList<String> convertAllStringsToLowerCase(ArrayList<String> inputList)
       
  1303 	{
       
  1304 		ArrayList<String> outputList = new ArrayList<String>();
       
  1305 		if(inputList != null)
       
  1306 		{
       
  1307 			for(int i=0;i<inputList.size();i++)
       
  1308 				outputList.add(inputList.get(i).toLowerCase());
       
  1309 
       
  1310 		}
       
  1311 		return outputList;
       
  1312 	}
       
  1313 
       
  1314 	/**
       
  1315 	 * Checks whether the ROM version and ROM Checksum of all log files are same or not.
       
  1316 	 * @param cycleData
       
  1317 	 * @return <code>true</code> if ROM Checksum is OK <code>false</code> otherwise.
       
  1318 	 */
       
  1319 	public boolean checkRomInfo(ArrayList<CycleData> cycleData)
       
  1320 	{
       
  1321 		boolean result = true;
       
  1322 
       
  1323 		for(int i = 0; i<=cycleData.size()-2; i++)
       
  1324 		{
       
  1325 			String currentCheckSum = cycleData.get(i).getRomCheckSum();
       
  1326 			String nextCheckSum = cycleData.get(i+1).getRomCheckSum();
       
  1327 
       
  1328 			String currentVersion = cycleData.get(i).getRomVersion();
       
  1329 			String nextVersion = cycleData.get(i+1).getRomVersion();
       
  1330 
       
  1331 			if((!currentCheckSum.equals(nextCheckSum)) || (!currentVersion.equals(nextVersion)))
       
  1332 			{
       
  1333 				result = false;
       
  1334 				break;
       
  1335 			}
       
  1336 		}
       
  1337 
       
  1338 		return result;
       
  1339 	}
       
  1340 
       
  1341 	/**
       
  1342 	 * Check timestamps from consecutive cycles
       
  1343 	 * if log n+1 time stamp is lesser than log n then return log n+1 cycle number. else return 0
       
  1344 	 * @param allcycleData
       
  1345 	 * @return Returns cycle number or 0   
       
  1346 	 */
       
  1347 	public int checkTimeStamp(ArrayList<CycleData> allcycleData){
       
  1348 
       
  1349 		for(int i=1;i<allcycleData.size();i++){
       
  1350 			String currentTime = allcycleData.get(i).getTime();
       
  1351 			String prevTime = allcycleData.get(i-1).getTime();
       
  1352 			long timeDiff = getDurationInSeconds(prevTime, currentTime);
       
  1353 			if(timeDiff < 0){
       
  1354 				// if time stamp of log n+1 is lesser than log n
       
  1355 				return allcycleData.get(i).getCycleNumber();  
       
  1356 			}
       
  1357 
       
  1358 		}
       
  1359 		return 0;// if time stamp of log n+1 is greater than log n 
       
  1360 	}
       
  1361 }