/// <summary> /// Really handle the incoming fingerprint computation. /// </summary> public void ProcessFingerprintComputedCore(ProcessFingerprintComputationEventData data) { var pip = m_exporter.GetPip(data.PipId) as Process; Contract.Assert(pip != null); // only interested in the events generated after a corresponding pip was executed // however, we still need to save pip description so there would be no missing entries in pips.csv if (data.Kind != FingerprintComputationKind.Execution) { return; } // part 1: collect requested inputs // count only output files/directories var declaredInputFiles = pip.Dependencies.Where(f => f.IsOutputFile).Select(f => f.Path).ToList(); var declaredInputDirs = pip.DirectoryDependencies.Where(d => d.IsOutputDirectory()).ToList(); var packedExecution = m_exporter.m_packedExecution; var fileTable = packedExecution.FileTable; var pathsToFiles = m_exporter.m_pathsToFiles; // part 2: collect actual inputs var consumedPaths = data.StrongFingerprintComputations.Count == 0 ? new List <AbsolutePath>() : data.StrongFingerprintComputations[0].ObservedInputs .Where(input => input.Type == ObservedInputType.FileContentRead || input.Type == ObservedInputType.ExistingFileProbe) .Select(input => input.Path) .Where(path => pathsToFiles.TryGetValue(path, out var tuple) && fileTable[tuple.fileId].SizeInBytes > 0) .ToList(); P_PipId packedPipId = new P_PipId((int)data.PipId.Value); ProcessPipInfoList.Add(new ProcessPipInfo(packedPipId, declaredInputFiles, declaredInputDirs, consumedPaths, m_workerId)); }
/// <summary> /// Really handle the incoming fingerprint computation. /// </summary> /// <remarks> /// This is a concurrent method, not a serial method, so beware of shared mutable state. /// </remarks> internal void ProcessFingerprintComputedCore(ProcessFingerprintComputationEventData data) { var pip = m_exporter.GetPip(data.PipId) as Process; Contract.Assert(pip != null); P_PipId packedPipId = new P_PipId((int)data.PipId.Value); if (data.Kind != FingerprintComputationKind.Execution) { return; } Interlocked.Increment(ref m_exporter.m_statistics.ProcessFingerprintComputedExecutionCount); // part 1: collect requested inputs // count only output files/directories // TODO: use a builder here? 400K or so objects seems livable though.... var declaredInputFiles = pip.Dependencies.ToList(); var declaredInputDirs = pip.DirectoryDependencies.ToList(); // part 2: collect actual inputs ICollection <AbsolutePath> consumedPaths = data.StrongFingerprintComputations.Count == 0 ? s_noPaths : data .StrongFingerprintComputations[0] .ObservedInputs .Where(input => input.Type == ObservedInputType.FileContentRead || input.Type == ObservedInputType.ExistingFileProbe) .Select(input => input.Path) .ToList(); Interlocked.Add( ref m_exporter.m_statistics.ProcessFingerprintComputedStrongFingerprintCount, data.StrongFingerprintComputations.Count); Interlocked.Add( ref m_exporter.m_statistics.ProcessFingerprintComputedConsumedPathCount, consumedPaths.Count); lock (ProcessPipInfoList) { ProcessPipInfoList.Add(new ProcessPipInfo( packedPipId, pip.SemiStableHash, declaredInputFiles, declaredInputDirs, consumedPaths)); } }