예제 #1
0
        /// <summary>
        /// Creates the engine context
        /// </summary>
        internal EngineContext(
            CancellationToken cancellationToken,
            PathTable pathTable,
            SymbolTable symbolTable,
            QualifierTable qualifierTable,
            IFileSystem fileSystem,
            TokenTextTable tokenTextTable,
            CounterCollection <EngineCounter> engineCounters = null,
            HistoricTableSizes historicTableSizes            = null)
            : base(cancellationToken, pathTable.StringTable, pathTable, symbolTable, qualifierTable, tokenTextTable)
        {
            Contract.Requires(pathTable != null);
            Contract.Requires(symbolTable != null);
            Contract.Requires(fileSystem != null);
            Contract.Requires(tokenTextTable != null);
            Contract.Requires(pathTable.StringTable == symbolTable.StringTable);
            Contract.Requires(pathTable.StringTable == qualifierTable.StringTable);

            PipDataBuilderPool = new ObjectPool <PipDataBuilder>(() => new PipDataBuilder(StringTable), builder => builder.Clear());
            EngineCounters     = engineCounters ?? new CounterCollection <EngineCounter>();
            FileSystem         = fileSystem;

            var historicData = (IReadOnlyList <HistoricDataPoint>)historicTableSizes ?? CollectionUtilities.EmptyArray <HistoricDataPoint>();

            HistoricTableSizes = new HistoricTableSizes(historicData);
        }
예제 #2
0
        private EngineState(
            Guid graphId,
            StringTable stringTable,
            PathTable pathTable,
            SymbolTable symbolTable,
            QualifierTable qualifierTable,
            PipTable pipTable,
            PipGraph pipGraph,
            MountPathExpander mountPathExpander,
            SchedulerState schedulerState,
            HistoricTableSizes historicTableSizes,
            FileContentTable fileContentTable)
        {
            Contract.Requires(graphId != default(Guid), "GraphId is not unique enough to be represented in EngineState");
            Contract.Requires(stringTable != null);
            Contract.Requires(pathTable != null);
            Contract.Requires(symbolTable != null);
            Contract.Requires(qualifierTable != null);
            Contract.Requires(stringTable == pathTable.StringTable);
            Contract.Requires(pathTable.StringTable == symbolTable.StringTable);
            Contract.Requires(pathTable.StringTable == qualifierTable.StringTable);
            Contract.Requires(pipTable != null);
            Contract.Requires(!pipTable.IsDisposed);
            Contract.Requires(pipGraph != null);
            Contract.Requires(mountPathExpander != null);
            Contract.Requires(schedulerState != null);
            Contract.Requires(historicTableSizes != null);
            Contract.Requires(fileContentTable != null);

            m_stringTable        = stringTable;
            m_pathTable          = pathTable;
            m_symbolTable        = symbolTable;
            m_qualifierTable     = qualifierTable;
            m_pipTable           = pipTable;
            m_pipGraph           = pipGraph;
            m_mountPathExpander  = mountPathExpander;
            m_schedulerState     = schedulerState;
            m_graphId            = graphId;
            m_historicTableSizes = historicTableSizes;
            m_fileContentTable   = fileContentTable;
        }
예제 #3
0
        private CachedGraphLoader(CancellationToken cancellationToken, EngineSerializer serializer)
        {
            Serializer       = serializer;
            m_pipGraphIdTask = CreateLazyFileDeserialization(
                serializer,
                GraphCacheFile.PipGraph,
                async reader =>
            {
                var graphId = await PipGraph.DeserializeGraphIdAsync(reader);
                return(graphId.Item1);
            });

            var directedGraphTask = CreateLazyFileDeserialization(
                serializer,
                GraphCacheFile.DirectedGraph,
                DeserializedDirectedGraph.DeserializeAsync);

            m_stringTableTask = CreateLazyFileDeserialization(
                serializer,
                GraphCacheFile.StringTable,
                StringTable.DeserializeAsync);

            m_pathTableTask = CreateLazyFileDeserialization(
                serializer,
                GraphCacheFile.PathTable,
                reader => reader.ReadPathTableAsync(m_stringTableTask.Value));

            m_symbolTableTask = CreateLazyFileDeserialization(
                serializer,
                GraphCacheFile.SymbolTable,
                reader => reader.ReadSymbolTableAsync(m_stringTableTask.Value));

            m_qualifierTableTask = CreateLazyFileDeserialization(
                serializer,
                GraphCacheFile.QualifierTable,
                reader => reader.ReadQualifierTableAsync(m_stringTableTask.Value));

            m_pipTableTask = CreateLazyFileDeserialization(
                serializer,
                GraphCacheFile.PipTable,
                (reader) => PipTable.DeserializeAsync(
                    reader,
                    m_pathTableTask.Value,
                    m_symbolTableTask.Value,
                    EngineSchedule.PipTableInitialBufferSize,
                    EngineSchedule.PipTableMaxDegreeOfParallelismDuringConstruction,
                    debug: false));

            m_mountPathExpanderTask = CreateLazyFileDeserialization(
                serializer,
                GraphCacheFile.MountPathExpander,
                reader => MountPathExpander.DeserializeAsync(reader, m_pathTableTask.Value));

            m_pipExecutionContextTask = CreateAsyncLazy(() => Task.Run(
                                                            async() =>
            {
                var stringTable    = await m_stringTableTask.Value;
                var pathTable      = await m_pathTableTask.Value;
                var symbolTable    = await m_symbolTableTask.Value;
                var qualifierTable = await m_qualifierTableTask.Value;

                if (stringTable != null && pathTable != null && symbolTable != null && qualifierTable != null)
                {
                    return((PipExecutionContext) new SchedulerContext(cancellationToken, stringTable, pathTable, symbolTable, qualifierTable));
                }

                return(null);
            }));

            m_historicDataTask = CreateLazyFileDeserialization(
                serializer,
                GraphCacheFile.HistoricTableSizes,
                reader => Task.FromResult(HistoricTableSizes.Deserialize(reader)));

            m_pipGraphTask = CreateLazyFileDeserialization(
                serializer,
                GraphCacheFile.PipGraph,
                reader => PipGraph.DeserializeAsync(
                    reader,
                    serializer.LoggingContext,
                    m_pipTableTask.Value,
                    directedGraphTask.Value,
                    m_pipExecutionContextTask.Value,
                    ToSemanticPathExpander(m_mountPathExpanderTask.Value)));

            m_cachedGraphTask = CreateAsyncLazy(() => CreateCachedGraph(m_pipTableTask.Value, m_pipGraphTask.Value, directedGraphTask.Value, m_pipExecutionContextTask.Value, m_mountPathExpanderTask.Value));
        }
예제 #4
0
        private static bool ShouldReuseReloadedEngineContextGivenHistoricData(LoggingContext loggingContext, HistoricTableSizes historicTableSizes)
        {
            Contract.Requires(historicTableSizes != null);
            Contract.Requires(historicTableSizes.Count > 0);

            var gen = historicTableSizes.Count;

            // no historic data --> reuse
            if (gen == 1)
            {
                Logger.Log.EngineContextHeuristicOutcomeReuse(loggingContext, gen, "first generation context is always reused");
                return(true);
            }

            var leastRecentStats            = historicTableSizes[0];
            var mostRecentStats             = historicTableSizes[historicTableSizes.Count - 1];
            var leastRecentTotalSizeInBytes = leastRecentStats.TotalSizeInBytes();
            var mostRecentTotalsizeInBytes  = mostRecentStats.TotalSizeInBytes();

            // if the total size of all tables has more than doubled --> don't reuse
            if (mostRecentTotalsizeInBytes > leastRecentTotalSizeInBytes * 2)
            {
                Logger.Log.EngineContextHeuristicOutcomeSkip(
                    loggingContext,
                    gen,
                    I($"total size has more than doubled (oldest size = {leastRecentTotalSizeInBytes} bytes, newest size = {mostRecentTotalsizeInBytes} bytes)"));
                return(false);
            }

            Logger.Log.EngineContextHeuristicOutcomeReuse(
                loggingContext,
                gen,
                I($"total size hasn't grown too much (oldest size = {leastRecentTotalSizeInBytes} bytes, newest size = {mostRecentTotalsizeInBytes} bytes)"));
            return(true);
        }