Esempio n. 1
0
        /// <summary>
        /// Gets events from the DB based on the eventKey.
        /// </summary>
        /// <remarks>
        /// Since 0 isn't serialized by Protobuf, a PrefixSearch for RewriteCount = 0 would match everything.
        /// Thus to avoid that, we set it to -1 to "match everything", else we look for specific rewrite counts.
        /// Similarly, a PrefixSearch for WorkerID = 0 would match everything.
        /// Thus to avoid that, we set it to uint.MaxValue to "match everything", else we look for specific rewrite counts.
        /// </remarks>
        /// <returns>List of events, empty if no such events exist</returns>
        private IEnumerable <IMessage> GetEventsByKey(EventKey eventKey)
        {
            Contract.Requires(m_accessor != null, "XldbDataStore is not initialized");

            var storedEvents = new List <IMessage>();

            if (!m_eventParserDictionary.TryGetValue(eventKey.EventTypeID, out var parser))
            {
                Contract.Assert(false, "No parser found for EventTypeId passed in");
            }

            var matchAllRewriteCounts = false;
            var matchAllWorkerIDs     = false;

            if (eventKey.FileRewriteCount == s_fileRewriteCountDefaultValue)
            {
                matchAllRewriteCounts = true;
                // Set it to 0 to match everything
                eventKey.FileRewriteCount = 0;
            }

            if (eventKey.WorkerID == s_workerIDDefaultValue)
            {
                matchAllWorkerIDs = true;
                // Set it to 0 to match everything
                eventKey.WorkerID = 0;
            }

            var maybeFound = m_accessor.Use(database =>
            {
                foreach (var kvp in database.PrefixSearch(eventKey.ToByteArray(), EventColumnFamilyName))
                {
                    var kvpKey = EventKey.Parser.ParseFrom(kvp.Key);
                    // MatchAllWorker IDs and MatchAllRewriteCounts are true, so just add everything
                    if (matchAllWorkerIDs && matchAllRewriteCounts)
                    {
                        storedEvents.Add(parser.ParseFrom(kvp.Value));
                    }
                    // Else if matching all WorkerIDs, check for specific RewriteCounts OR
                    // if matching all RewriteCounts, check for specific worker ID
                    else if ((matchAllWorkerIDs && kvpKey.FileRewriteCount == eventKey.FileRewriteCount) ||
                             (matchAllRewriteCounts && kvpKey.WorkerID == eventKey.WorkerID))
                    {
                        storedEvents.Add(parser.ParseFrom(kvp.Value));
                    }
                    // Else both worker ID and RewriteCounts are unique so the prefix search matches the right one
                    else
                    {
                        storedEvents.Add(parser.ParseFrom(kvp.Value));
                    }
                }
            });

            if (!maybeFound.Succeeded)
            {
                maybeFound.Failure.Throw();
            }

            return(storedEvents);
        }
Esempio n. 2
0
        /// <summary>
        /// Ingest all of the pips to RocksDB
        /// </summary>
        private void IngestAllPips()
        {
            var totalNumberOfPips = CachedGraph.PipTable.StableKeys.Count;
            var pipIds            = CachedGraph.PipTable.StableKeys;
            var concurrency       = (int)(Environment.ProcessorCount * s_innerConcurrencyMultiplier);
            var partitionSize     = totalNumberOfPips / concurrency;

            Console.WriteLine("Ingesting pips now ...");

            Parallel.For(0, concurrency, i =>
            {
                // Hold only one lock while inserting all of these keys into the DB
                var maybeInserted = m_accessor.Use(database =>
                {
                    var start            = i * partitionSize;
                    var end              = (i + 1) == concurrency ? totalNumberOfPips : (i + 1) * partitionSize;
                    var pipsIngested     = 0;
                    var pipSemistableMap = new Dictionary <byte[], byte[]>();
                    var pipIdMap         = new Dictionary <byte[], byte[]>();

                    for (int j = start; j < end; j++)
                    {
                        var pipId = pipIds[j];
                        pipsIngested++;

                        if (pipsIngested % s_pipOutputBatchLogSize == 0)
                        {
                            Console.Write(".");
                            database.ApplyBatch(pipSemistableMap);
                            database.ApplyBatch(pipIdMap, XldbDataStore.PipColumnFamilyName);

                            pipSemistableMap.Clear();
                            pipIdMap.Clear();
                        }

                        var hydratedPip = CachedGraph.PipTable.HydratePip(pipId, BuildXL.Pips.PipQueryContext.PipGraphRetrieveAllPips);
                        var pipType     = hydratedPip.PipType;

                        if (pipType == PipType.Value || pipType == PipType.HashSourceFile || pipType == PipType.SpecFile || pipType == PipType.Module)
                        {
                            continue;
                        }

                        var xldbPip  = hydratedPip.ToPip(CachedGraph);
                        var pipIdKey = new PipIdKey()
                        {
                            PipId   = hydratedPip.PipId.Value,
                            PipType = (Xldb.Proto.PipType)(pipType + 1)
                        };
                        var pipIdKeyArr          = pipIdKey.ToByteArray();
                        IMessage xldbSpecificPip = xldbPip;

                        if (pipType == PipType.Ipc)
                        {
                            var ipcPip      = (Pips.Operations.IpcPip)hydratedPip;
                            xldbSpecificPip = ipcPip.ToIpcPip(PathTable, xldbPip, m_nameExpander);

                            foreach (var fileArtifact in ipcPip.FileDependencies)
                            {
                                AddToFileConsumerMap(fileArtifact, pipId);
                            }

                            foreach (var directoryArtifact in ipcPip.DirectoryDependencies)
                            {
                                AddToDirectoryConsumerMap(directoryArtifact, pipId);
                            }

                            AddToDbStorageDictionary(DBStoredTypes.IpcPip, pipIdKeyArr.Length + xldbSpecificPip.ToByteArray().Length);
                        }
                        else if (pipType == PipType.SealDirectory)
                        {
                            var sealDirectoryPip = (Pips.Operations.SealDirectory)hydratedPip;
                            xldbSpecificPip      = sealDirectoryPip.ToSealDirectory(PathTable, xldbPip, m_nameExpander);

                            // If it is a shared opaque, then flatten the list of composted directories
                            if (sealDirectoryPip.Kind == Pips.Operations.SealDirectoryKind.SharedOpaque)
                            {
                                var directoryQueue = new Queue <Utilities.DirectoryArtifact>();

                                foreach (var initialDirectory in sealDirectoryPip.ComposedDirectories)
                                {
                                    directoryQueue.Enqueue(initialDirectory);
                                }

                                while (directoryQueue.Count > 0)
                                {
                                    var nestedDirectory = directoryQueue.Dequeue();
                                    var nestedPipId     = CachedGraph.PipGraph.GetSealedDirectoryNode(nestedDirectory).ToPipId();

                                    if (CachedGraph.PipTable.IsSealDirectoryComposite(nestedPipId))
                                    {
                                        var nestedPip = (Pips.Operations.SealDirectory)CachedGraph.PipGraph.GetSealedDirectoryPip(nestedDirectory, BuildXL.Pips.PipQueryContext.SchedulerExecuteSealDirectoryPip);
                                        foreach (var pendingDirectory in nestedPip.ComposedDirectories)
                                        {
                                            directoryQueue.Enqueue(pendingDirectory);
                                        }
                                    }
                                    else
                                    {
                                        Contract.Assert(nestedDirectory.IsOutputDirectory());
                                        AddToDirectoryConsumerMap(nestedDirectory, pipId);
                                    }
                                }
                            }

                            foreach (var fileArtifact in sealDirectoryPip.Contents)
                            {
                                AddToFileConsumerMap(fileArtifact, pipId);
                            }

                            AddToDbStorageDictionary(DBStoredTypes.SealDirectoryPip, pipIdKeyArr.Length + xldbSpecificPip.ToByteArray().Length);
                        }
                        else if (pipType == PipType.CopyFile)
                        {
                            var copyFilePip = (Pips.Operations.CopyFile)hydratedPip;
                            xldbSpecificPip = copyFilePip.ToCopyFile(PathTable, xldbPip, m_nameExpander);
                            AddToFileConsumerMap(copyFilePip.Source, pipId);
                            AddToDbStorageDictionary(DBStoredTypes.CopyFilePip, pipIdKeyArr.Length + xldbSpecificPip.ToByteArray().Length);
                        }
                        else if (pipType == PipType.WriteFile)
                        {
                            var writeFilePip = (Pips.Operations.WriteFile)hydratedPip;
                            xldbSpecificPip  = writeFilePip.ToWriteFile(PathTable, xldbPip, m_nameExpander);
                            AddToDbStorageDictionary(DBStoredTypes.WriteFilePip, pipIdKeyArr.Length + xldbSpecificPip.ToByteArray().Length);
                        }
                        else if (pipType == PipType.Process)
                        {
                            var processPip  = (Pips.Operations.Process)hydratedPip;
                            xldbSpecificPip = processPip.ToProcessPip(PathTable, xldbPip, m_nameExpander);

                            AddToFileConsumerMap(processPip.StandardInputFile, pipId);
                            AddToFileConsumerMap(processPip.Executable, pipId);

                            foreach (var fileArtifact in processPip.Dependencies)
                            {
                                AddToFileConsumerMap(fileArtifact, pipId);
                            }

                            foreach (var directoryArtifact in processPip.DirectoryDependencies)
                            {
                                AddToDirectoryConsumerMap(directoryArtifact, pipId);
                            }

                            AddToDbStorageDictionary(DBStoredTypes.ProcessPip, pipIdKeyArr.Length + xldbSpecificPip.ToByteArray().Length);
                        }
                        else
                        {
                            Contract.Assert(false, "Unknown pip type parsed");
                        }

                        // If the SemiStableHash != 0, then we want to create the SemistableHash -> PipId indirection.
                        // Else we do not want that since the key would no longer be unique
                        if (hydratedPip.SemiStableHash != 0)
                        {
                            var pipSemistableHashKey = new PipSemistableHashKey()
                            {
                                SemiStableHash = hydratedPip.SemiStableHash,
                            };

                            pipSemistableMap.Add(pipSemistableHashKey.ToByteArray(), pipIdKeyArr);
                        }

                        pipIdMap.Add(pipIdKeyArr, xldbSpecificPip.ToByteArray());
                    }

                    database.ApplyBatch(pipSemistableMap);
                    database.ApplyBatch(pipIdMap, XldbDataStore.PipColumnFamilyName);
                });

                if (!maybeInserted.Succeeded)
                {
                    Console.WriteLine("Failed to insert pip data into RocksDb. Exiting analyzer now ...");
                    maybeInserted.Failure.Throw();
                }
            });
        }