private void PrintTransitiveImpact(StreamWriter writer) { writer.WriteLine("====================================================================="); writer.WriteLine("Executed Process Analysis Current Execution Log : {0}", m_analyzer.ExecutionLogPath); writer.WriteLine("====================================================================="); writer.WriteLine("This section lists executed process pips in longest pole order in File A."); writer.WriteLine("Reason for execution by comparing to matching pip in File B."); writer.WriteLine("Dependent process pips executed"); writer.WriteLine("Critical path of transitive down dependent pips."); writer.WriteLine("Dependent list of process Pips (optional)"); writer.WriteLine("Reporting Top level executed pips"); writer.WriteLine("====================================================================="); var summariesToReport = m_analyzer.GetDifferecesToReport(); var invalidationReason = new HashSet <string>(); foreach (var pipDiff in summariesToReport.OrderByDescending(a => a.Item1.CriticalPath.Time)) { var pipSummary = pipDiff.pipSummary1; var otherPipSummary = pipDiff.pipSummary2; var pip = pipSummary.Pip; bool weakFingerprintCacheMiss; m_analyzer.TryGetWeakFingerprintCacheMiss(pipSummary.Pip.PipId, out weakFingerprintCacheMiss); var missReason = pipSummary.UncacheablePip ? "Un-cacheable Pip" : weakFingerprintCacheMiss ? "Weak Fingerprint Cache-Miss" : "Strong Fingerprint Cache-Miss"; if (!pipSummary.NewPip) { if (!pipSummary.Fingerprint.Equals(otherPipSummary.Fingerprint)) { missReason = CompareFileDependencySummary( " File Dependency Changes:", pipSummary.DependencySummary, otherPipSummary.DependencySummary); missReason += GetPipEnvironmentMissReport( pipSummary.EnvironmentSummary, otherPipSummary.EnvironmentSummary); } missReason += CompareObservedDependencySummary( " Observed File Dependency Changes:", pipSummary.ObservedInputSummary, otherPipSummary.ObservedInputSummary); } if (invalidationReason.Contains(missReason)) { // This invalidation is known, so cut down the noise on the report continue; } writer.WriteLine(m_analyzer.GetPipDescription(pip)); writer.WriteLine(" Transitive Process invalidated count: {0}", pipSummary.ExecutedDependentProcessCount); writer.WriteLine(" Cache-Miss reason analysis:"); writer.WriteLine(SummaryAnalyzer.GetFingerprintMismatch(pipSummary, otherPipSummary)); writer.WriteLine(missReason); if (!string.IsNullOrEmpty(missReason)) { invalidationReason.Add(missReason); } var executionStart = m_analyzer.GetPipStartTime(pip); var executionStartText = executionStart.Equals(DateTime.MinValue) ? "-" : executionStart.ToString("h:mm:ss.ff", CultureInfo.InvariantCulture); writer.WriteLine(" Start time: {0}", executionStartText); writer.WriteLine( " Critical path (seconds): Duration: ( {0} ) Kernel Time: ( {1} ) User Time: ( {2} )", ToSeconds(pipSummary.CriticalPath.Time), ToSeconds(pipSummary.CriticalPath.KernelTime), ToSeconds(pipSummary.CriticalPath.UserTime)); if (pipSummary.ExecutedDependentProcessCount > 0) { var criticalPathReport = m_analyzer.GetCriticalPathText(pipSummary.CriticalPath); writer.WriteLine(); writer.WriteLine(criticalPathReport); } if (m_analyzer.WriteTransitiveDownPips && pipSummary.ExecutedDependentProcessCount > 0) { writer.WriteLine(WriteDependentProcess(pipSummary.DependentNodes)); } writer.WriteLine("====================================================================="); } }