for ( Iterator i = callIDs.iterator(); i.hasNext(); ) { CallID callID = (CallID)i.next(); if ( callID != null && callID.getParentRCC() != null && !parents.contains(callID.getRCC())) { CallID parent = (CallID)callIDs.get(callID.getParentRCC().getKey()); while ( parent != null ) { parent.getRCC().adjustTime(callID.getRCC().getTime()); if ( parent.getParentRCC() != null ) parent = (CallID)callIDs.get(parent.getParentRCC().getKey()); else parent = null; } } }
	public void execute() throws ParseException	{		try		{			if ( !readHeader )				checkHeader();			seek("THREAD START (", true);			String line = seek("TRACE", true);			final HashMap stackTracesByID = new HashMap();			line = parseSamples(line, stackTracesByID);			if ( line.startsWith("CPU SAMPLES BEGIN") )			{				// eat the header line				seek("rank", true);				final ArrayList rccList = new ArrayList();				class ParseSamples				{					int key = 1;					public void execute() throws ParseException, IOException					{						String line;						while ( !( line = nextLine(true) ).startsWith("CPU SAMPLES END") )						{							StringTokenizer tok = new StringTokenizer(line, " ");							String rank = nextToken(tok, true);							String self = nextToken(tok, true);							String accum = nextToken(tok, true);							int count = Integer.parseInt(nextToken(tok, true));							Integer traceID = Integer.valueOf(nextToken(tok, true));							String method = nextToken(tok, true);							StackTrace st = (StackTrace)stackTracesByID.get(traceID);							RCC rcc = new RCC(st, count, count, key++);							rccList.add(rcc);						}					}				}							new ParseSamples().execute();				/*				 * In general, the parent of a stack trace (the 'leaf') may only have a sub-set of the				 *   parent calls that are listed in the leaf.				 * This algorithm matches each stack trace up with its parent traces in a greedy manner,				 *   finding all parents which match 'n' calls in the leaf before moving to 'n - 1'.				 * Each time, the algorithm is only run on the RCCs which are still marked as being 'roots'				 * Some of these roots may get matched to a parent, the rest will be tried again during				 *   the next iteration				 */				ArrayList rootRCCList = new ArrayList(rccList.size());				rootRCCList.addAll(rccList);				ConstructCallsAlgorithm algorithm = new ConstructCallsAlgorithm(rccList.size());				int maxSize = maxStackSize - 1;				for ( int size = maxSize; size > 0; )				{					// System.out.println("Size : " + size);					// System.out.println("Looking for " + rootRCCList);					Map rccListByCallee = mapByCallee(rccList, size);					// System.out.println("Callee map " + rccListByCallee);					algorithm.execute(rootRCCList, rccListByCallee, size);					callIDs = algorithm.getCallIDs();					--size;					// Don't bother to re-build the root list on the last time through					if ( size > 0 )					{						rootRCCList.clear();						for ( Iterator j = rccList.iterator(); j.hasNext(); )						{							RCC rcc = (RCC)j.next();							int key = rcc.getKey();							CallID callID = (CallID)callIDs.get(key);							if ( callID != null && callID.getParentRCC() == null )								rootRCCList.add(callID.getRCC());						}					}				}				for ( Iterator i = callIDs.iterator(); i.hasNext(); )				{					CallID callID = (CallID)i.next();					while ( callID != null && callID.getParentRCC() != null )					{						callID.getParentRCC().adjustTime(callID.getRCC().getTime());						callID = (CallID)callIDs.get(callID.getParentRCC().getKey());					}				}								/*				System.out.println(callIDs);				for ( Iterator i = callIDs.iterator(); i.hasNext(); )				{					CallID callID = (CallID)i.next();					if ( callID != null && callID.getParentRCC() == null )						System.out.println("Root : " + callID);				}				*/			}		}		catch (IOException x)		{			throw new ParseException("IOException at line " + lineNumber() + " : " + x.getMessage());		}	}