private void ReportCacheHitEstimates(IIncrementalSchedulingState incrementalSchedulingState) { var allDirtyNodes = incrementalSchedulingState.DirtyNodeTracker.AllDirtyNodes.Union( incrementalSchedulingState.DirtyNodeTracker.AllPerpertuallyDirtyNodes); var allDirtyProcesses = allDirtyNodes.Where(nodeId => incrementalSchedulingState.PipGraph.PipTable.GetPipType(nodeId.ToPipId()) == PipType.Process); var allDirtyProcessesCount = allDirtyProcesses.Count(); var allProcesses = incrementalSchedulingState.PipGraph.PipTable.Keys.Where( pipId => incrementalSchedulingState.PipGraph.PipTable.GetPipType(pipId) == PipType.Process); var allProcessesCount = allProcesses.Count(); Console.WriteLine(I($"Total processes: {allProcessesCount}.")); Console.WriteLine(I($"Dirty processes: {allDirtyProcessesCount}.")); Console.WriteLine(I($"Estimated cache hit rate for an unfiltered build: {(double)(allProcessesCount - allDirtyProcessesCount) / allProcessesCount * 100:0.##}%.")); if (Input.ExecutionLogPath != null) { var allDirtyProcessesToExecute = allDirtyProcesses.Where(process => m_executedPips.Contains(process.ToPipId())); var allDirtyProcessesToExecuteCount = allDirtyProcessesToExecute.Count(); Console.WriteLine(I($"Dirty processes included in the filter: {allDirtyProcessesToExecuteCount}.")); Console.WriteLine( I($"Estimated cache hit rate for build with same filter: {(double)(allProcessesCount - allDirtyProcessesToExecuteCount) / allProcessesCount * 100:0.##}%.")); } else { Console.WriteLine($"Execution log not available. If next time you provide the execution log (using /executionLog), an additional estimation can be provided including the cached build filter."); } }
/// <summary> /// Creates an instance of <see cref="PipOutputMaterializationTracker" />. /// </summary> public PipOutputMaterializationTracker(IFileContentManagerHost fileContentManagerHost, IIncrementalSchedulingState incrementalSchedulingState) { Contract.Requires(fileContentManagerHost != null); m_fileContentManagerHost = fileContentManagerHost; m_incrementalSchedulingState = incrementalSchedulingState; }
private IIncrementalSchedulingState LoadOrReuseInternal( FileEnvelopeId atomicSaveToken, PipGraph pipGraph, IConfiguration configuration, ContentHash preserveOutputSalt, string incrementalSchedulingStatePath, SchedulerState schedulerState) { Contract.Requires(pipGraph != null); Contract.Requires(!string.IsNullOrWhiteSpace(incrementalSchedulingStatePath)); Contract.Assert(m_analysisMode || configuration != null); if (!m_analysisMode && schedulerState != null && schedulerState.IncrementalSchedulingState != null) { IIncrementalSchedulingState reusedState = schedulerState.IncrementalSchedulingState.Reuse(m_loggingContext, pipGraph, configuration, preserveOutputSalt, m_tempDirectoryCleaner); if (reusedState != null) { return(reusedState); } } return(GraphAgnosticIncrementalSchedulingState.Load( m_loggingContext, atomicSaveToken, pipGraph, configuration, preserveOutputSalt, incrementalSchedulingStatePath, analysisModeOnly: m_analysisMode, tempDirectoryCleaner: m_tempDirectoryCleaner)); }
/// <summary> /// Creates the scheduler state /// </summary> public SchedulerState(Scheduler scheduler) { // If the filter is not applied, rootFilter and filterPassingNodes are null. m_rootFilter = scheduler.RootFilter; m_filterPassingNodes = scheduler.FilterPassingNodes; m_incrementalSchedulingState = scheduler.IncrementalSchedulingState; }
/// <summary> /// Validates incremental scheduling state after journal scan. /// </summary> internal void ValidateIncrementalSchedulingStateAfterJournalScan(IIncrementalSchedulingState incrementalSchedulingState) { Contract.Requires(incrementalSchedulingState != null); IncrementalSchedulingStateAfterJournalScanAction?.Invoke(incrementalSchedulingState); }