Esempio n. 1
0
        /// <summary>
        /// Thread safe GetOrAdd method. We use concurrent dictionaries for backing, therefore no lock is needed.
        /// </summary>
        /// <param name="pipId">The pip Id to be used when creating a new pip descriptor</param>
        /// <param name="pipName">The pip name to be used when creating a new pip descriptor</param>
        /// <returns>New PipDescriptor instance that stores the data from the specified pip</returns>
        internal PipDescriptor SynchronizedGetOrAdd(Process fullPip, CachedGraph buildGraph,
                                                    ExecutionLogLoadOptions loadOptions, ConcurrentHashSet <FileDescriptor> emptyConcurrentHashSetOfFileDescriptor,
                                                    ConcurrentHashSet <PipDescriptor> emptyConcurrentHashSetOfPipDescriptor, ConcurrentHashSet <ProcessInstanceDescriptor> emptyConcurrentHashSetOfReportedProcesses,
                                                    StringIdEnvVarDictionary emptyStringIDEnvVarDictionary, AbsolutePathConcurrentHashSet emptyAbsolutePathConcurrentHashSet)
        {
            PipDescriptor newItem = m_pipIdDictionary.GetOrAdd(fullPip.PipId.Value, (p) => { return(new PipDescriptor(fullPip, buildGraph, loadOptions, emptyConcurrentHashSetOfFileDescriptor, emptyConcurrentHashSetOfPipDescriptor, emptyConcurrentHashSetOfReportedProcesses, emptyStringIDEnvVarDictionary, emptyAbsolutePathConcurrentHashSet)); });

            IReadOnlyCollection <PipDescriptor> pipList = m_pipNameDictionary.GetOrAdd(fullPip.Provenance.OutputValueSymbol, new ConcurrentHashSet <PipDescriptor>());

            // This is pretty ugly: Doing down casting here so we can add elements to our read only collection
            // The collection is read only because we do no want to allow the Users of the SDK to change it. Unfortunately the only way .NET allows me to define such dictionary
            // is to specify its elements as a IReadOnlyCollection and down cast every time I need to modify it.
            // Down casting here is pretty safe though. The collection is only created in this method and we know that it is always a ConcurrentDictionary.
            (pipList as ConcurrentHashSet <PipDescriptor>).Add(newItem);

            return(newItem);
        }
Esempio n. 2
0
        /// <summary>
        /// Internal constructor
        /// </summary>
        /// <param name="pipId">The pipId of the pip that this descriptor is assigned to</param>
        internal PipDescriptor(Process fullPip, CachedGraph buildGraph, ExecutionLogLoadOptions loadOptions, ConcurrentHashSet <FileDescriptor> emptyConcurrentHashSetOfFileDescriptor, ConcurrentHashSet <PipDescriptor> emptyConcurrentHashSetOfPipDescriptor,
                               ConcurrentHashSet <ProcessInstanceDescriptor> emptyConcurrentHashSetOfReportedProcesses, StringIdEnvVarDictionary emptyStringIDEnvVarDictionary, AbsolutePathConcurrentHashSet emptyAbsolutePathConcurrentHashSet)
        {
            Contract.Requires(fullPip != null);
            Contract.Requires(buildGraph != null);

            // IsInitializedFlag will be set to non 0 when all the pip properties have been set
            IsInitializedFlag         = 0;
            PipExecutionPerformance   = null;
            m_transitiveDependentPips = Lazy.Create(() => GetTransitiveDependentPips());
            m_criticalPathBasedOnNumberOfPipsProducedFromCache = Lazy.Create(() => FindCriticalPathBasedOnNumberOfPipsProducedFromCache());
            m_numberOfFilesProducedFromCacheOnCriticalPath     = Lazy.Create(() => FindNumberOfFilesProducedFromCacheOnCriticalPath());

            m_criticalPathBasedOnExecutionTime = Lazy.Create(() => FindCriticalPathBasedOnExecutionTime());
            m_dependencyChainLength            = Lazy.Create(() => FindDependencyChainLength());
            m_criticalPathLength = Lazy.Create(() => FindCriticalPathLength());
            m_buildGraph         = buildGraph;
            m_fullPip            = fullPip;

            PipTags = new StringIdConcurrentHashSet(m_buildGraph.Context.StringTable);
            foreach (var tag in m_fullPip.Tags)
            {
                if (tag.IsValid)
                {
                    PipTags.Add(tag);
                }
            }

            if ((loadOptions & ExecutionLogLoadOptions.DoNotLoadOutputFiles) == 0)
            {
                OutputFilesHashset = new ConcurrentHashSet <FileDescriptor>();
            }
            else
            {
                OutputFilesHashset = emptyConcurrentHashSetOfFileDescriptor;
            }

            if ((loadOptions & ExecutionLogLoadOptions.DoNotLoadSourceFiles) == 0)
            {
                DependentFilesHashset = new ConcurrentHashSet <FileDescriptor>();
                ProbedFilesHashset    = new ConcurrentHashSet <FileDescriptor>();
            }
            else
            {
                DependentFilesHashset = emptyConcurrentHashSetOfFileDescriptor;
                ProbedFilesHashset    = emptyConcurrentHashSetOfFileDescriptor;
            }

            if ((loadOptions & ExecutionLogLoadOptions.LoadObservedInputs) == 0)
            {
                ObservedInputsHashset = emptyConcurrentHashSetOfFileDescriptor;
            }
            else
            {
                ObservedInputsHashset = new ConcurrentHashSet <FileDescriptor>();
            }

            if ((loadOptions & ExecutionLogLoadOptions.LoadBuildGraph) == 0)
            {
                AdjacentInNodesHashset  = emptyConcurrentHashSetOfPipDescriptor;
                AdjacentOutNodesHashset = emptyConcurrentHashSetOfPipDescriptor;
            }
            else
            {
                AdjacentInNodesHashset  = new ConcurrentHashSet <PipDescriptor>();
                AdjacentOutNodesHashset = new ConcurrentHashSet <PipDescriptor>();
            }

            if ((loadOptions & ExecutionLogLoadOptions.LoadProcessMonitoringData) == 0)
            {
                ReportedProcessesHashset = emptyConcurrentHashSetOfReportedProcesses;
            }
            else
            {
                ReportedProcessesHashset = new ConcurrentHashSet <ProcessInstanceDescriptor>();
            }

            if ((loadOptions & ExecutionLogLoadOptions.DoNotLoadRarelyUsedPipProperties) == 0)
            {
                UntrackedPathsHashset          = new AbsolutePathConcurrentHashSet(m_buildGraph.Context.PathTable);
                UntrackedScopesHashset         = new AbsolutePathConcurrentHashSet(m_buildGraph.Context.PathTable);
                EnvironmentVariablesDictionary = new StringIdEnvVarDictionary(m_buildGraph.Context);
                foreach (var d in m_fullPip.UntrackedPaths)
                {
                    if (d.IsValid)
                    {
                        UntrackedPathsHashset.Add(d);
                    }
                }

                foreach (var d in m_fullPip.UntrackedScopes)
                {
                    if (d.IsValid)
                    {
                        UntrackedScopesHashset.Add(d);
                    }
                }
            }
            else
            {
                EnvironmentVariablesDictionary = emptyStringIDEnvVarDictionary;
                UntrackedPathsHashset          = emptyAbsolutePathConcurrentHashSet;
                UntrackedScopesHashset         = emptyAbsolutePathConcurrentHashSet;
            }
        }