Beispiel #1
0
            public bool VerifyEquals(ProcessFingerprintComputationEventData expected, ProcessFingerprintComputationEventData actual)
            {
                XAssert.AreEqual(expected.PipId, actual.PipId);
                XAssert.AreEqual(expected.WeakFingerprint, actual.WeakFingerprint);
                XAssert.AreEqual(expected.Kind, actual.Kind);

                AssertSequenceEqual(expected.StrongFingerprintComputations, actual.StrongFingerprintComputations,
                                    (expectedStrongComputation, actualStrongComputation) =>
                {
                    XAssert.AreEqual(expectedStrongComputation.PathSetHash, actualStrongComputation.PathSetHash);
                    XAssert.AreEqual(expectedStrongComputation.Succeeded, actualStrongComputation.Succeeded);
                    VerifyEquals(expectedStrongComputation.PathEntries, actualStrongComputation.PathEntries);

                    if (expectedStrongComputation.Succeeded)
                    {
                        XAssert.AreEqual(expectedStrongComputation.IsStrongFingerprintHit, actualStrongComputation.IsStrongFingerprintHit);
                        XAssert.AreEqual(expectedStrongComputation.ComputedStrongFingerprint, actualStrongComputation.ComputedStrongFingerprint);
                        AssertSequenceEqual(
                            expectedStrongComputation.PriorStrongFingerprints,
                            actualStrongComputation.PriorStrongFingerprints,
                            (expectedPrint, actualPrint) => XAssert.AreEqual(expectedPrint, actualPrint));
                        VerifyEquals(expectedStrongComputation.ObservedInputs, actualStrongComputation.ObservedInputs);
                    }
                });

                return(true);
            }
Beispiel #2
0
        private IEnumerable <AbsolutePath> GetInputs(ProcessFingerprintComputationEventData data)
        {
            inputBuffer.Clear();
            var pip = GetPip(data.PipId);

            PipArtifacts.ForEachInput(pip, input =>
            {
                if (input.IsFile)
                {
                    inputBuffer.Add(input.Path);
                }

                return(true);
            },
                                      includeLazyInputs: true);

            foreach (var input in inputBuffer)
            {
                yield return(input);
            }

            if (CacheMissHelpers.TryGetUsedStrongFingerprintComputation(data, out var usedComputation))
            {
                foreach (var observedInput in usedComputation.ObservedInputs)
                {
                    if (observedInput.Type == ObservedInputType.FileContentRead || observedInput.Type == ObservedInputType.ExistingFileProbe)
                    {
                        yield return(observedInput.Path);
                    }
                }
            }
        }
Beispiel #3
0
        /// <inheritdoc />
        public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
        {
            var semistableHash = PipTable.GetPipSemiStableHash(data.PipId);

            if (!m_targetSemistableHashSet.Contains(semistableHash))
            {
                return;
            }

            var    formattedHash = Pip.FormatSemiStableHash(semistableHash);
            string outputFile    = GetOutputFileFromFormattedPipHash(formattedHash);

            using (var sw = new StreamWriter(outputFile, append: true))
            {
                var pipInfo = m_model.GetPipInfo(data.PipId);
                pipInfo.SetFingerprintComputation(data, CurrentEventWorkerId);

                sw.WriteLine(I($"Fingerprint kind: {data.Kind}"));
                WriteWeakFingerprintData(pipInfo, sw);

                foreach (var strongComputation in data.StrongFingerprintComputations)
                {
                    pipInfo.StrongFingerprintComputation = strongComputation;
                    WriteStrongFingerprintData(pipInfo, sw);
                }
            }
        }
Beispiel #4
0
        public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
        {
            if (!IsFailedPipOrDependency(data.PipId))
            {
                // Only record inputs for failed pips or their transitive dependencies
                return;
            }

            if (IsCached(data.PipId) != (data.Kind == FingerprintComputationKind.CacheCheck))
            {
                // Only use cache lookup result when the pip was cached
                return;
            }

            foreach (var path in GetInputs(data))
            {
                m_fileToConsumerMap.AddOrUpdate(
                    path,
                    data.PipId,
                    addValueFactory: (key, pipId) =>
                {
                    return(new CompactSet <PipId>().Add(pipId));
                },
                    updateValueFactory: (key, pipId, pipSet) =>
                {
                    return(pipSet.Add(pipId));
                });
            }
        }
            public void ProcessFingerprintComputedCore(ProcessFingerprintComputationEventData data)
            {
                var computation = data.StrongFingerprintComputations[0];
                var pip         = m_analyzer.GetPip(data.PipId);

                PipArtifacts.ForEachInput(pip, f =>
                {
                    if (f.IsFile && f.FileArtifact.IsOutputFile)
                    {
                        if (m_deployedFiles.TryGetValue(f.Path, out var size))
                        {
                            AddFlag(f.Path, ContentFlag.Static | ContentFlag.Consumed);
                        }
                    }

                    return(true);
                }, includeLazyInputs: false);

                foreach (var input in computation.ObservedInputs)
                {
                    if (input.Type == ObservedInputType.FileContentRead || input.Type == ObservedInputType.ExistingFileProbe)
                    {
                        if (m_deployedFiles.TryGetValue(input.Path, out var size))
                        {
                            var flag = input.Type == ObservedInputType.FileContentRead ? ContentFlag.DynamicContent : ContentFlag.DynamicProbe;
                            AddFlag(input.Path, flag | ContentFlag.Consumed);
                        }
                    }
                }
            }
Beispiel #6
0
            /// <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));
            }
Beispiel #7
0
 public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
 {
     if (data.StrongFingerprintComputations.Any() && data.StrongFingerprintComputations.Last().ObservedInputs.IsValid)
     {
         m_nodesWithObservedInputs.Add(data.PipId.ToNodeId());
         m_fingerprintComputations[data.PipId.Value] = data.StrongFingerprintComputations.Last().ObservedInputs.Where(x => x.Type == ObservedInputType.FileContentRead).ToList();
     }
 }
Beispiel #8
0
        public void ProcessFingerprintComputed(uint workerId, ProcessFingerprintComputationEventData data)
        {
            var pipInfo = GetPipInfo(data.PipId);

            if (pipInfo != null)
            {
                pipInfo.SetFingerprintComputation(Convert(pipInfo, data), workerId);
            }
        }
Beispiel #9
0
 public void SetFingerprintComputation(ProcessFingerprintComputationEventData fingerprintComputation, uint workerId)
 {
     if (!FingerprintComputation.PipId.IsValid || fingerprintComputation.Kind == FingerprintComputationKind.Execution)
     {
         // Execution takes precedence over cache check if set. This is needed because the events may come out of order
         FingerprintComputation = fingerprintComputation;
         WorkerId = workerId;
     }
 }
Beispiel #10
0
        public static bool IsHit(this ProcessFingerprintComputationEventData fingerprintComputation)
        {
            foreach (var item in fingerprintComputation.StrongFingerprintComputations)
            {
                if (item.IsStrongFingerprintHit)
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #11
0
 public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
 {
     if (data.PipId == m_pip.PipId)
     {
         m_sections.Add(
             m_html.CreateBlock(
                 "Process Fingerprint Computed",
                 m_html.CreateEnumRow("Kind", data.Kind),
                 m_html.CreateRow("WeakContentFingerprintHash", data.WeakFingerprint.Hash.ToHex()),
                 m_html.CreateRow("StrongFingerprintComputations", "TODO")));
     }
 }
        public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
        {
            if (data.Kind == FingerprintComputationKind.Execution)
            {
                if ((Interlocked.Increment(ref m_processedPips) % 1000) == 0)
                {
                    Console.WriteLine($"Processing {m_processedPips}");
                }
            }

            GetWorkerAnalyzer().ProcessFingerprintComputed(data);
        }
Beispiel #13
0
            public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
            {
                var semistableHash = CachedGraph.PipTable.GetPipSemiStableHash(data.PipId);

                if (!IsFailedPipOrDependency(semistableHash))
                {
                    // Only record inputs for failed pips or their transitive dependencies
                    return;
                }

                // Save the latest fingerprint event that has all the inputs
                m_processFingerprintComputationEventData[data.PipId.Value] = data;
            }
Beispiel #14
0
        public static bool TryGetUsedStrongFingerprintComputation(this ProcessFingerprintComputationEventData fingerprintComputation, out ProcessStrongFingerprintComputationData strongFingerprintComputationData)
        {
            var strongFingerprintComputations = fingerprintComputation.StrongFingerprintComputations;

            // The last computation is the computation used
            if (strongFingerprintComputations.Count > 0)
            {
                strongFingerprintComputationData = strongFingerprintComputations[strongFingerprintComputations.Count - 1];
                return(true);
            }

            strongFingerprintComputationData = default(ProcessStrongFingerprintComputationData);
            return(false);
        }
        public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
        {
            m_statistics.ProcessFingerprintComputedEventCount++;

            if (data.Kind == FingerprintComputationKind.Execution)
            {
                if ((m_processedPips++ % 1000) == 0)
                {
                    Console.WriteLine($"Processing {m_processedPips}");
                }
            }

            GetWorkerAnalyzer().ProcessFingerprintComputed(data);
        }
            /// <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));
                }
            }
Beispiel #17
0
        /// <summary>
        /// Override event to capture its data and store it in the protobuf
        /// </summary>
        public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
        {
            var value = data.ToProcessFingerprintComputationEvent(WorkerID.Value, PathTable, m_nameExpander);
            var key   = new EventKey
            {
                EventTypeID = Xldb.Proto.ExecutionEventId.ProcessFingerprintComputation,
                PipId       = data.PipId.Value,
                ProcessFingerprintComputationKey = value.Kind,
            };

            var keyArr   = key.ToByteArray();
            var valueArr = value.ToByteArray();

            WriteToDb(keyArr, valueArr, XldbDataStore.EventColumnFamilyName);
            AddToDbStorageDictionary(DBStoredTypes.ProcessFingerprintComputation, keyArr.Length + valueArr.Length);
        }
Beispiel #18
0
        public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
        {
            var lastStrongFingerprintComputation = data
                                                   .StrongFingerprintComputations
                                                   .LastOrDefault();

            if (lastStrongFingerprintComputation.ObservedInputs.IsValid)
            {
                m_nodesWithObservedInputs.Add(data.PipId.ToNodeId());
                m_fingerprintComputations[data.PipId.Value] = lastStrongFingerprintComputation
                                                              .ObservedInputs
                                                              .Where(x => x.Type == ObservedInputType.FileContentRead)
                                                              .Select(observedInput => observedInput.Path)
                                                              .ToList();
            }
        }
Beispiel #19
0
        public static bool TryGetComputationWithPathSet(
            this ProcessFingerprintComputationEventData fingerprintData,
            ContentHash pathSetHash,
            out ProcessStrongFingerprintComputationData match)
        {
            foreach (var computation in fingerprintData.StrongFingerprintComputations)
            {
                if (computation.PathSetHash == pathSetHash)
                {
                    match = computation;
                    return(true);
                }
            }

            match = default(ProcessStrongFingerprintComputationData);
            return(false);
        }
Beispiel #20
0
        public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
        {
            if (data.Kind == FingerprintComputationKind.Execution)
            {
                m_block.Post(() =>
                {
                    using (var wrapper = m_pool.GetInstance())
                    {
                        wrapper.Instance.ProcessFingerprintComputed(data);

                        if ((Interlocked.Increment(ref ProcessedPips) % 10) == 0)
                        {
                            Console.WriteLine($"Processing {ProcessedPips}");
                        }
                    }
                });
            }
        }
        /// <inheritdoc />
        public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
        {
            if (data.Kind == FingerprintComputationKind.CacheCheck)
            {
                ObservedInputCounts?cacheMaxCounts = null;
                if (data.StrongFingerprintComputations != null)
                {
                    foreach (var strongFingerprintComputation in data.StrongFingerprintComputations)
                    {
                        if (strongFingerprintComputation.Succeeded)
                        {
                            var computationCounts = GetObservedInputCount(strongFingerprintComputation.ObservedInputs);
                            cacheMaxCounts = cacheMaxCounts?.Max(computationCounts) ?? computationCounts;
                        }
                    }

                    if (cacheMaxCounts.HasValue)
                    {
                        m_observedInputCounts.TryAdd(data.PipId, cacheMaxCounts.Value);
                    }
                }
            }
            else
            {
                Contract.Assert(data.Kind == FingerprintComputationKind.Execution);

                if (((data.StrongFingerprintComputations?.Count ?? 0) != 0) && data.StrongFingerprintComputations[0].Succeeded)
                {
                    ObservedInputCounts cacheMaxCounts;
                    if (m_observedInputCounts.TryRemove(data.PipId, out cacheMaxCounts))
                    {
                        var executionCounts = GetObservedInputCount(data.StrongFingerprintComputations[0].ObservedInputs);
                        ObservedInputCounts.LogForLowObservedInputs(
                            Events.StaticContext,
                            GetDescription(GetPip(data.PipId)),
                            executionCounts: executionCounts,
                            cacheMaxCounts: cacheMaxCounts);
                    }
                }
            }
        }
Beispiel #22
0
        /// <inheritdoc />
        public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
        {
            var semistableHash = PipTable.GetPipSemiStableHash(data.PipId);

            if (semistableHash != TargetSemistableHash)
            {
                return;
            }

            var pipInfo = m_model.GetPipInfo(data.PipId);

            pipInfo.SetFingerprintComputation(data, CurrentEventWorkerId);

            m_writer.WriteLine(I($"Fingerprint kind: {data.Kind}"));
            WriteWeakFingerprintData(pipInfo, m_writer);

            foreach (var strongComputation in data.StrongFingerprintComputations)
            {
                pipInfo.StrongFingerprintComputation = strongComputation;
                WriteStrongFingerprintData(pipInfo, m_writer);
            }
        }
Beispiel #23
0
        /// <inheritdoc />
        public override void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
        {
            var pipInfo = m_model.GetPipInfo(data.PipId);

            pipInfo.SetFingerprintComputation(data, CurrentEventWorkerId);
        }
Beispiel #24
0
            public void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
            {
                if (data.Kind != FingerprintComputationKind.Execution)
                {
                    return;
                }

                m_consumer = m_analyzer.GetEntry(data.PipId);

                m_consumedFilesByPath.Clear();
                m_dependencyConsumedFileIndex.Clear();
                m_dependencyConsumedFileEndIndex.Clear();
                m_dependencies.Clear();
                m_builder.Clear();
                m_directoryDependenciesFilterMap.Clear();
                m_directoryHasSources.Clear();

                var computation = data.StrongFingerprintComputations[0];
                var pip         = (Process)m_analyzer.GetPip(data.PipId);

                PipArtifacts.ForEachInput(pip, input =>
                {
                    if (input.IsFile)
                    {
                        AddConsumedFile(input.FileArtifact, DirectoryArtifact.Invalid, ContentFlag.Static | ContentFlag.Consumed);
                    }
                    else
                    {
                        foreach (var file in m_analyzer.GetContents(input.DirectoryArtifact))
                        {
                            if (file.IsSourceFile)
                            {
                                m_directoryHasSources.Add(input.DirectoryArtifact);
                            }

                            AddConsumedFile(file, input.DirectoryArtifact, ContentFlag.Dynamic);
                        }
                    }

                    return(true);
                }, includeLazyInputs: false);

                foreach (var input in computation.ObservedInputs)
                {
                    var flag = (ContentFlag)((int)ContentFlag.AbsentPathProbe << (int)input.Type) | ContentFlag.Consumed;
                    if (input.Type == ObservedInputType.FileContentRead || input.Type == ObservedInputType.ExistingFileProbe)
                    {
                        if (m_consumedFilesByPath.TryGetValue(input.Path, out var file))
                        {
                            file.AddFlag(ContentFlag.Consumed);
                            if (file.SourceFile != null)
                            {
                                file.SourceFile.AddFlag(ContentFlag.Consumed);
                            }

                            if (file.FinalFile != null)
                            {
                                file.FinalFile.AddFlag(ContentFlag.Consumed);
                            }
                        }
                        else
                        {
                            AddConsumedFile(FileArtifact.CreateSourceFile(input.Path), m_analyzer.PipGraph.TryGetSealSourceAncestor(input.Path), flag | ContentFlag.Unknown);
                        }
                    }
                    else if (m_analyzer.AllAccesses)
                    {
                        AddConsumedFile(FileArtifact.CreateSourceFile(input.Path), m_analyzer.PipGraph.TryGetSealSourceAncestor(input.Path), flag);
                    }
                }

                var entry = m_consumer;

                // Sort file dependencies for consistent output
                entry.FileDependencies.Sort(s_fileReferenceComparer);

                foreach (var fileDependency in entry.FileDependencies)
                {
                    if (fileDependency.Producer != null)
                    {
                        var reference = entry.PipDependencies.GetOrAdd(fileDependency.Producer.PipId, p => new PipReference());
                        if (reference.Pip == null)
                        {
                            reference.Pip = m_analyzer.GetEntry(fileDependency.Producer.PipId);
                        }

                        reference.Flags |= fileDependency.ConsumedFile.Flags;
                    }
                }

                string describe(PipEntry pe)
                {
                    return($"{pe.SpecFileName}-{m_analyzer.GetDescription(m_analyzer.GetPip(pe.PipId))}");
                }

                m_builder.AppendLine(describe(entry));
                foreach (var fileDependency in entry.FileDependencies)
                {
                    if (fileDependency.Producer != null &&
                        fileDependency.ConsumedFile.File.Artifact.IsOutputFile)
                    {
                        var pipId        = fileDependency.Producer.PipId;
                        var pipReference = entry.PipDependencies[pipId];
                        var directory    = fileDependency.Directory?.Directory ?? DirectoryArtifact.Invalid;
                        if (m_dependencies.Add((pipId, directory)))
                        {
                            if (pipReference.HasFlag(ContentFlag.Consumed))
                            {
                                m_directoryDependenciesFilterMap[directory] = true;
                                m_builder.AppendLine($"{entry.Identifier} -> Retaining pip dependency on '{describe(pipReference.Pip)}' (declared via directory '{ToString(fileDependency.Directory)}') (consumes '{ToString(fileDependency.ConsumedFile.File.Artifact)}')");
                            }
                            else
                            {
                                m_directoryDependenciesFilterMap.TryAdd(directory, false);
                                m_builder.AppendLine($"{entry.Identifier} -> Removing pip dependency on '{describe(pipReference.Pip)}' (declared via directory '{ToString(fileDependency.Directory)}')");
                            }
                        }
                    }
                }

                var trimmedDirectoryDependencies = new List <DirectoryArtifact>();

                foreach (var d in entry.Process.DirectoryDependencies)
                {
                    if (m_directoryDependenciesFilterMap.TryGetValue(d, out var shouldInclude))
                    {
                        if (shouldInclude)
                        {
                            m_builder.AppendLine($"{entry.Identifier} -> Retaining directory dependency on '{ToString(d)}' (used)");
                        }
                        else if (m_directoryHasSources.Contains(d))
                        {
                            m_builder.AppendLine($"{entry.Identifier} -> Retaining directory dependency on '{ToString(d)}' (has sources)");
                        }
                        else
                        {
                            m_builder.AppendLine($"{entry.Identifier} -> Removing directory dependency on '{ToString(d)}'");
                            continue;
                        }
                    }
                    else
                    {
                        var sealId = m_analyzer.PipGraph.GetSealedDirectoryNode(d).ToPipId();
                        if (!m_directoryHasSources.Contains(d) && !m_analyzer.PipTable.GetSealDirectoryKind(sealId).IsSourceSeal())
                        {
                            m_builder.AppendLine($"{entry.Identifier} -> Removing directory dependency on '{ToString(d)}' (unused output directory)");
                            continue;
                        }
                    }

                    entry.PipDependencies.TryAdd(m_analyzer.PipGraph.GetSealedDirectoryNode(d).ToPipId(), default);
                    trimmedDirectoryDependencies.Add(d);
                }

                // Update directory dependencies which trimmed directory dependencies to allow writing
                // a pip into the serialized pip table that can run without the unnecessary dependencies
                entry.Process.UnsafeUpdateDirectoryDependencies(trimmedDirectoryDependencies.ToReadOnlyArray());

                m_builder.AppendLine();

                // Update the graph
                var modifiedGraph = m_analyzer.m_mutableGraph;

                using (var scope = modifiedGraph.AcquireExclusiveIncomingEdgeScope(entry.PipId.ToNodeId()))
                {
                    foreach (var dependency in entry.PipDependencies)
                    {
                        if (dependency.Value == null || dependency.Value.HasFlag(ContentFlag.Consumed))
                        {
                            scope.AddEdge(dependency.Key.ToNodeId());
                        }
                    }

                    entry.AddedEdges = true;
                }

                if (m_analyzer.SemiStableHashes.Contains(entry.SemistableHash))
                {
                    using (var writer = new StreamWriter(Path.Combine(m_analyzer.OutputFilePath,
                                                                      $"{GetFileName(entry.SpecFile)}_Pip{pip.FormattedSemiStableHash}.csv")))
                    {
                        var table = new DisplayTable <Columns>(" , ");

                        foreach (var dependency in entry.FileDependencies)
                        {
                            table.NextRow();
                            table.Set(Columns.Path, ToString(dependency.ConsumedFile.File.Artifact.Path));
                            table.Set(Columns.RwCount, dependency.ConsumedFile.File.Artifact.RewriteCount.ToString());
                            table.Set(Columns.Flags, dependency.ConsumedFile.Flags.ToString());
                            table.Set(Columns.Producer, dependency.Producer?.Identifier);
                            table.Set(Columns.ProducerSpec, GetFileName(dependency.Producer?.SpecFile ?? AbsolutePath.Invalid));
                            table.Set(Columns.Dir, ToString(dependency.Directory));
                            table.Set(Columns.DirId, dependency.Directory?.Id);
                            table.Set(Columns.DirSsh, dependency.Directory?.SemistableHash);
                        }

                        table.Write(writer);
                    }
                }

                if (m_builder.Length != 0)
                {
                    m_analyzer.Write(m_builder);
                }
            }
Beispiel #25
0
        /// <nodoc />
        public static Xldb.ProcessFingerprintComputationEvent ToProcessFingerprintComputationEvent(this ProcessFingerprintComputationEventData data, uint workerID, PathTable pathTable)
        {
            var Uuid = Guid.NewGuid().ToString();

            var processFingerprintComputationEvent = new Xldb.ProcessFingerprintComputationEvent
            {
                UUID            = Uuid,
                WorkerID        = workerID,
                Kind            = (Xldb.FingerprintComputationKind)data.Kind,
                PipID           = data.PipId.Value,
                WeakFingerprint = new Xldb.WeakContentFingerPrint()
                {
                    Hash = data.WeakFingerprint.Hash.ToFingerprint()
                },
            };

            foreach (var strongFingerprintComputation in data.StrongFingerprintComputations)
            {
                var processStrongFingerprintComputationData = new Xldb.ProcessStrongFingerprintComputationData()
                {
                    PathSet     = strongFingerprintComputation.PathSet.ToObservedPathSet(pathTable),
                    PathSetHash = new Xldb.ContentHash()
                    {
                        Value = strongFingerprintComputation.PathSetHash.ToString()
                    },
                    UnsafeOptions             = strongFingerprintComputation.UnsafeOptions.ToUnsafeOptions(),
                    Succeeded                 = strongFingerprintComputation.Succeeded,
                    IsStrongFingerprintHit    = strongFingerprintComputation.IsStrongFingerprintHit,
                    ComputedStrongFingerprint = new Xldb.StrongContentFingerPrint()
                    {
                        Hash = strongFingerprintComputation.ComputedStrongFingerprint.Hash.ToFingerprint()
                    }
                };

                processStrongFingerprintComputationData.PathEntries.AddRange(
                    strongFingerprintComputation.PathEntries.Select(
                        pathEntry => pathEntry.ToObservedPathEntry(pathTable)));
                processStrongFingerprintComputationData.ObservedAccessedFileNames.AddRange(
                    strongFingerprintComputation.ObservedAccessedFileNames.Select(
                        observedAccessedFileName => new Xldb.StringId()
                {
                    Value = observedAccessedFileName.Value
                }));
                processStrongFingerprintComputationData.PriorStrongFingerprints.AddRange(
                    strongFingerprintComputation.PriorStrongFingerprints.Select(
                        priorStrongFingerprint => new Xldb.StrongContentFingerPrint()
                {
                    Hash = priorStrongFingerprint.Hash.ToFingerprint()
                }));

                foreach (var observedInput in strongFingerprintComputation.ObservedInputs)
                {
                    processStrongFingerprintComputationData.ObservedInputs.Add(new Xldb.ObservedInput()
                    {
                        Type = (Xldb.ObservedInputType)observedInput.Type,
                        Hash = new Xldb.ContentHash()
                        {
                            Value = observedInput.Hash.ToString()
                        },
                        PathEntry            = observedInput.PathEntry.ToObservedPathEntry(pathTable),
                        Path                 = observedInput.Path.ToAbsolutePath(pathTable),
                        IsSearchPath         = observedInput.IsSearchPath,
                        IsDirectoryPath      = observedInput.IsDirectoryPath,
                        DirectoryEnumeration = observedInput.DirectoryEnumeration
                    });
                }

                processFingerprintComputationEvent.StrongFingerprintComputations.Add(processStrongFingerprintComputationData);
            }

            return(processFingerprintComputationEvent);
        }
Beispiel #26
0
        /// <nodoc />
        public static ProcessFingerprintComputationEvent ToProcessFingerprintComputationEvent(this ProcessFingerprintComputationEventData data, uint workerID, PathTable pathTable, NameExpander nameExpander)
        {
            var processFingerprintComputationEvent = new ProcessFingerprintComputationEvent
            {
                WorkerID        = workerID,
                Kind            = (Xldb.Proto.FingerprintComputationKind)(data.Kind + 1),
                PipID           = data.PipId.Value,
                WeakFingerprint = new WeakContentFingerprint()
                {
                    Hash = data.WeakFingerprint.Hash.ToFingerprint()
                },
            };

            foreach (var strongFingerprintComputation in data.StrongFingerprintComputations)
            {
                var processStrongFingerprintComputationData = new Xldb.Proto.ProcessStrongFingerprintComputationData()
                {
                    PathSet                   = strongFingerprintComputation.PathSet.ToObservedPathSet(pathTable, nameExpander),
                    PathSetHash               = strongFingerprintComputation.PathSetHash.ToContentHash(),
                    UnsafeOptions             = strongFingerprintComputation.UnsafeOptions.ToUnsafeOptions(),
                    Succeeded                 = strongFingerprintComputation.Succeeded,
                    IsStrongFingerprintHit    = strongFingerprintComputation.IsStrongFingerprintHit,
                    ComputedStrongFingerprint = new StrongContentFingerprint()
                    {
                        Hash = strongFingerprintComputation.ComputedStrongFingerprint.Hash.ToFingerprint()
                    }
                };

                processStrongFingerprintComputationData.PathEntries.AddRange(
                    strongFingerprintComputation.PathEntries.Select(
                        pathEntry => pathEntry.ToObservedPathEntry(pathTable, nameExpander)));
                processStrongFingerprintComputationData.ObservedAccessedFileNames.AddRange(
                    strongFingerprintComputation.ObservedAccessedFileNames.Select(
                        observedAccessedFileName => observedAccessedFileName.ToString(pathTable)));
                processStrongFingerprintComputationData.PriorStrongFingerprints.AddRange(
                    strongFingerprintComputation.PriorStrongFingerprints.Select(
                        priorStrongFingerprint => new StrongContentFingerprint()
                {
                    Hash = priorStrongFingerprint.Hash.ToFingerprint()
                }));

                foreach (var observedInput in strongFingerprintComputation.ObservedInputs)
                {
                    processStrongFingerprintComputationData.ObservedInputs.Add(new ObservedInput()
                    {
                        Type                 = (ObservedInputType)(observedInput.Type + 1),
                        Hash                 = observedInput.Hash.ToContentHash(),
                        PathEntry            = observedInput.PathEntry.ToObservedPathEntry(pathTable, nameExpander),
                        Path                 = observedInput.Path.ToAbsolutePath(pathTable, nameExpander),
                        IsSearchPath         = observedInput.IsSearchPath,
                        IsDirectoryPath      = observedInput.IsDirectoryPath,
                        DirectoryEnumeration = observedInput.DirectoryEnumeration
                    });
                }

                processFingerprintComputationEvent.StrongFingerprintComputations.Add(processStrongFingerprintComputationData);
            }

            return(processFingerprintComputationEvent);
        }
Beispiel #27
0
        private ProcessFingerprintComputationEventData Convert(PipCachingInfo pipInfo, ProcessFingerprintComputationEventData data)
        {
            if (AreGraphsSame)
            {
                return(data);
            }

            data.PipId = pipInfo.PipId;

            // Assuming that under the hood the computations are a mutable list or array
            var computations = (IList <ProcessStrongFingerprintComputationData>)data.StrongFingerprintComputations;

            for (int i = 0; i < computations.Count; i++)
            {
                computations[i] = Convert(computations[i]);
            }

            return(data);
        }
 public void ProcessFingerprintComputed(ProcessFingerprintComputationEventData data)
 {
     m_processingBlock.Post(data);
 }