public static PlotResult CalculatePlot(double aspectRatio, DependencyGraph<string> graph, AssemblyFilterPreferences filterPreferences)
        {
            const double widthInches = 100;
            var heightInches = (double)(int)(widthInches / aspectRatio);

            // node [color=lightblue2, style=filled];
            // page=""8.5,11""
            // size=""7.5, 10""
            // ratio=All
            //                widthInches = 75;
            //                heightInches = 100;

            var extraCommands = $"size=\"{widthInches},{heightInches}\"\r\n    center=\"\"\r\n    ratio=All\r\n    node[width=.25,hight=.375,fontsize=12,color=lightblue2,style=filled]";
            var dotCommand = DotCommandBuilder.Generate(graph, filterPreferences, extraCommands);

            // a temp file to store image
            var tempFile = TemporaryFileManager.CreateTemporaryFile();

            // generate dot image
            var dot = new DOTClass();
            dot.ToPNG(dotCommand).Save(tempFile);
            var dotImage = Image.FromFile(tempFile);

            // generate SVG
            var svgXml = dot.ToSvg(dotCommand);

            return new PlotResult { DotCommand = dotCommand, Image = dotImage, SvgXml = svgXml };
        }
Example #2
0
		public DependencyGraph BuildDependencyGraph()
		{
			if (_graphCache != null)
				return _graphCache;

			var g = new DependencyGraph();

			foreach (var ns in Namespaces)
			{
				g.AddVertex(new DependencyVertex(ns));
			}

			foreach (var ns in Namespaces)
			{
				foreach (var type in ns.Types)
				{
					var types = type.GetUses();

					foreach (var dependType in types)
					{
						if (dependType != type && dependType.Namespace.Module == type.Namespace.Module)
							g.AddEdge(new DependencyEdge(new DependencyVertex(type.Namespace),
							                             new DependencyVertex(dependType.Namespace)));
					}
				}
			}

			_graphCache = g;
			return g;
		}
        public void CircularReferences3()
        {
            var dependencies = new DependencyGraph<string>();
            dependencies.AddDependency("1", "2");
            dependencies.AddDependency("1", "3");
            dependencies.AddDependency("3", "2");
            dependencies.AddDependency("3", "10");
            dependencies.AddDependency("3", "1");
            dependencies.AddDependency("4", "2");

            dependencies.AddDependency("4", "3");
            dependencies.AddDependency("4", "1");
            dependencies.AddDependency("5", "3");
            dependencies.AddDependency("5", "2");
            dependencies.AddDependency("6", "2");
            dependencies.AddDependency("7", "2");
            dependencies.AddDependency("8", "2");
            dependencies.AddDependency("8", "8");
            dependencies.AddDependency("9", "2");
            dependencies.AddDependency("9", "3");
            dependencies.AddDependency("10", "2");
            dependencies.AddDependency("11", "2");
            dependencies.AddDependency("12", "2");

            var allNodes = dependencies.Nodes;
            var startNodes = allNodes.Where(x => !allNodes.Any(y => dependencies.GetDependenciesForNode(y).Contains(x)));
            var endNodes = allNodes.Where(x => dependencies.GetDependenciesForNode(x).Count() == 0);

            var circularReferences = CircularReferencesHelper.FindCircularReferences(dependencies, startNodes, endNodes);
            Assert.IsTrue(circularReferences.Count() == 1);
            Assert.IsTrue(circularReferences[0][0] == "1");
            Assert.IsTrue(circularReferences[0][1] == "");
        }
        public override List<OutputEntry> Process(DependencyGraph graph, Library element)
        {
            var proj = element as Project;
            if (proj == null)
                return null;

            var result = new List<OutputEntry>();

            var same = graph.OutEdges(proj)
                .Where(d => filter(d, Matchers.NullReporter))
                .GroupBy(d => d.Target)
                .Where(g => g.Count() > 1);

            same.ForEach(g =>
            {
                var message = new OutputMessage();
                message.Append("The project ")
                    .Append(proj, OutputMessage.ProjInfo.Name)
                    .Append(" has multiple dependencies with ")
                    .Append(g.Key, OutputMessage.ProjInfo.Name);

                result.Add(new UniqueDependencyOutputEntry(Severity, message, this, g));
            });

            return result;
        }
Example #5
0
        private static void RunCommand(string line, DependencyGraph graph)
        {
            if (line == "help" || line == "?")
            {
                Console.WriteLine("Commands: " + string.Join(", ", commands.Select(c => c.Name)));
                Console.WriteLine("(you can also use only the first letter of the command)");
                return;
            }

            try
            {
                var handled = commands.Any(c => c.Handle(line, graph));

                if (!handled)
                {
                    Console.WriteLine("Unknown command: " + line);
                    Console.WriteLine("Type ? for help");
                }
            }
            catch (ConfigParserException e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine("Type ? for help");
            }
        }
        private bool OutputPath(Output result, DependencyGraph graph, Library source, Library target)
        {
            var tryGetPaths = graph.ShortestPathsDijkstra(e => 1, source);
            IEnumerable<Dependency> path;
            if (!tryGetPaths(target, out path))
                return false;

            try
            {
                result.AppendLine("Path between {0} and {1}:", GetName(source), GetName(target));
                result.IncreaseIndent();

                Output.LineOutput line = result.StartLine();

                line.Append(GetName(source));
                foreach (Dependency edge in path)
                    line.Append(" -> ")
                        .Append(GetName(edge.Target));

                line.EndLine();
            }
            finally
            {
                result.DecreaseIndent();
                result.AppendLine();
            }

            return true;
        }
        public void CircularReferences()
        {
            var dependencies = new DependencyGraph<string>();
            dependencies.AddDependency("A", "C");
            dependencies.AddDependency("A", "D");
            dependencies.AddDependency("A", "F");
            dependencies.AddDependency("D", "F");
            dependencies.AddDependency("D", "G");
            dependencies.AddDependency("B", "D");
            dependencies.AddDependency("B", "G");
            dependencies.AddDependency("E", "G");
            dependencies.AddDependency("G", "F");
            dependencies.AddDependency("G", "H");
            dependencies.AddDependency("G", "A");

            var allNodes = dependencies.Nodes;
            var startNodes = allNodes.Where(x => !allNodes.Any(y => dependencies.GetDependenciesForNode(y).Contains(x)));
            var endNodes = allNodes.Where(x => dependencies.GetDependenciesForNode(x).Count() == 0);

            Assert.IsFalse(startNodes.Contains("A"));
            Assert.IsTrue(startNodes.Contains("B"));
            Assert.IsTrue(startNodes.Contains("E"));

            Assert.IsFalse(endNodes.Contains("A"));
            Assert.IsTrue(endNodes.Contains("C"));
            Assert.IsTrue(endNodes.Contains("F"));
            Assert.IsTrue(endNodes.Contains("H"));

            var circularReferences = CircularReferencesHelper.FindCircularReferences(dependencies, startNodes, endNodes);
            Assert.IsTrue(circularReferences.Count() > 0);
        }
 public void Output(DependencyGraph graph, ArchitectureGraph architecture, List<OutputEntry> warnings)
 {
     var result = new StringBuilder();
     AppendProjects(result, graph);
     AppendDependencies(result, graph);
     File.WriteAllText(file, result.ToString());
 }
        private void OutputReferences(Output result, DependencyGraph graph, Library lib, string type)
        {
            result.AppendLine(GetName(lib) + ":");

            var directDeps = new HashSet<Library>(graph.OutEdges(lib)
                .Select(d => d.Target));

            result.IncreaseIndent();
            result.AppendLine("Direct " + type + ":");

            result.IncreaseIndent();
            Output(result, directDeps);
            result.DecreaseIndent();

            result.DecreaseIndent();

            if (directDeps.Any())
            {
                var indirectDeps = ComputeIndirectDeps(graph, lib)
                    .Where(d => !directDeps.Contains(d))
            // ReSharper disable once PossibleUnintendedReferenceComparison
                    .Where(d => d != lib);

                result.IncreaseIndent();
                result.AppendLine("Indirect " + type + ":");

                result.IncreaseIndent();
                Output(result, indirectDeps);
                result.DecreaseIndent();

                result.DecreaseIndent();
            }

            result.AppendLine();
        }
        protected override void InternalHandle(Output result, string args, DependencyGraph graph)
        {
            var projectsFiltered = new HashSet<Library>(FilterLibs(graph, args));

            var projs = graph.Edges.Where(e => e.Source.Equals(e.Target))
                .Select(e => e.Source)
                .Where(projectsFiltered.Contains)
                .ToList();

            if (!projs.Any())
            {
                result.AppendLine("No project/library that depends on itself found");
            }
            else
            {
                projs.ForEach(lib =>
                {
                    var proj = lib as Project;
                    if (proj != null)
                        result.AppendLine("{0} (project path: {1})", GetName(proj), proj.ProjectPath);
                    else
                        result.AppendLine(GetName(lib));
                });
            }
        }
        public PackageDependencyProcessor(IEnumerable<IPackageInfo> packages)
        {
            _packages = packages;

            _graph = new DependencyGraph<IPackageInfo>(pak => pak.Name, pak => pak.GetDependencies().Select(x => x.Name));
            _packages.OrderBy(p => p.Name).Each(p => _graph.RegisterItem(p));
        }
        public void AddDependencyTest()
        {
            var graph = new DependencyGraph<string>();
            graph.AddDependency("A", "B");

            TestHelper.AssertEqualArrays(new[] { "A", "B" }, graph.GetNodes().ToArray());
            TestHelper.AssertEqualArrays(new[] { "B" }, graph.GetDependenciesForNode("A").ToArray());
        }
Example #13
0
		public void Items_are_added_to_a_dependency_graph()
		{
			_dependencyGraph = new DependencyGraph<string>();

			_dependencyGraph.Add("A", "B");
			_dependencyGraph.Add("B", "C");
			_dependencyGraph.Add("D", "E");
		}
        public void AddDependencyTest()
        {
            var graph = new DependencyGraph<string>();
            graph.AddDependency("A", "B");

            CollectionAssert.AreEqual(new[] { "A", "B" }, graph.Nodes);
            CollectionAssert.AreEqual(new[] { "B" }, graph.GetDependenciesForNode("A"));
        }
        public ContainerRegistrationCatalog(RegistrationConvention convention, ConfigureContainer configureContainer)
        {
            _types = new DictionaryCache<Type, CatalogRegistration>(x => x.Registration.RegistrationType);
            _graph = new DependencyGraph<Type>();

            _convention = convention;
            _configureContainer = configureContainer;
        }
        protected override void InternalHandle(Output result, string args, DependencyGraph graph)
        {
            if (args == "")
            {
                result.AppendLine("You need to specify a filter for the libraries");
                return;
            }

            OutputReferences(result, args, graph, "references");
        }
        protected void OutputReferences(Output result, string args, DependencyGraph graph, string type)
        {
            var libs = FilterLibs(graph, args);

            if (!libs.Any())
                result.AppendLine("No libraries found");
            else
                libs.SortBy(Library.NaturalOrdering)
                    .ForEach(l => OutputReferences(result, graph, l, type));
        }
        public void Output(DependencyGraph graph, ArchitectureGraph architecture, List<OutputEntry> warnings)
        {
            var xdoc = new XDocument();
            var xroot = new XElement("DependencyChecker-Depedencies");
            xdoc.Add(xroot);

            XMLHelper.ToXML(xroot, graph);

            File.WriteAllText(file, xdoc.ToString());
        }
        public BottleDependencyProcessor(IEnumerable<IPackageInfo> packages)
        {
            _packages = packages;

            guardAgainstMalformedPackages();

            _graph = new DependencyGraph<IPackageInfo>(pak => pak.Name, pak => pak.Dependencies.Select(x => x.Name));

            _packages.OrderBy(p => p.Name).Each(p => _graph.RegisterItem(p));
        }
Example #20
0
        protected override void InternalHandle(Output result, string args, DependencyGraph graph)
        {
            var libs = FilterLibs(graph, args);

            if (!libs.Any())
                result.AppendLine("No libraries found");
            else
                libs.SortBy(Library.NaturalOrdering)
                    .ForEach(l => result.AppendLine(GetName(l)));
        }
Example #21
0
		public void Items_are_added_to_a_dependency_graph()
		{
			var dependencyGraph = new DependencyGraph<string>();

			dependencyGraph.Add("A", "B");
			dependencyGraph.Add("B", "C");
			dependencyGraph.Add("C", "D");

			_dependencyOrder = dependencyGraph.GetItemsInDependencyOrder();
		}
        private static List<Library> ComputeIndirectDeps(DependencyGraph graph, Library lib)
        {
            var indirectDeps = new List<Library>();

            var dfs = new DepthFirstSearchAlgorithm<Library, Dependency>(graph);
            dfs.SetRootVertex(lib);
            dfs.DiscoverVertex += indirectDeps.Add;
            dfs.Compute();

            return indirectDeps;
        }
 private DependencyGraph InvertGraph(DependencyGraph graph)
 {
     var result = new DependencyGraph();
     result.AddVertexRange(graph.Vertices);
     result.AddEdgeRange(graph.Edges.Select(d =>
     {
         var tmp = d.Source;
         return d.WithSource(d.Target)
             .WithTarget(tmp);
     }));
     return result;
 }
        public bool Handle(string line, DependencyGraph graph)
        {
            if (!line.StartsWith(Name))
                return false;

            var result = new Output("    ");
            InternalHandle(result, new ConfigParser().ParseLines("-", new[] { line }), graph);

            result.ToConsole();

            return true;
        }
        public void TransitiveReduceCascade()
        {
            var graph = new DependencyGraph<char>();

            for (var c1 = 'a'; c1 < 'f'; c1++)
                for (var c2 = (char)(c1 + 1); c2 < 'f'; c2++)
                    graph.AddDependency(c1, c2);

            graph.TransitiveReduce();

            for (var c = 'a'; c < 'f' - 1; c++)
                CollectionAssert.AreEqual(new[] { (char)(c + 1) }, graph.GetDependenciesForNode(c), $"Dep of {c} should be {(char)(c+1)}");
        }
        public void TransitiveReduceThreeNodes()
        {
            var graph = new DependencyGraph<char>();
            graph.AddDependency('a', 'b');
            graph.AddDependency('b', 'c');
            graph.AddDependency('a', 'c');

            graph.TransitiveReduce();

            CollectionAssert.AreEqual(new[] { 'a', 'b', 'c' }, graph.Nodes);
            CollectionAssert.AreEqual(new[] { 'b' }, graph.GetDependenciesForNode('a'));
            CollectionAssert.AreEqual(new[] { 'c' }, graph.GetDependenciesForNode('b'));
        }
Example #27
0
        protected List<Library> FilterLibs(DependencyGraph graph, string search)
        {
            var libs = graph.Vertices;

            if (search != "")
            {
                LibraryMatcher matcher = ParseLibraryOrGroupMatcher(search);

                libs = libs.Where(l => matcher(l, Matchers.NullReporter));
            }

            return libs.ToList();
        }
        public static DependencyGraph Filter(DependencyGraph graph, List<OutputEntry> warnings)
        {
            var projs = new HashSet<Library>(warnings.SelectMany(w => w.Projects)
                .Concat(warnings.SelectMany(w => w.Dependencies.SelectMany(d => new[] { d.Source, d.Target }))));

            var deps = new HashSet<Dependency>(warnings.SelectMany(w => w.Dependencies));

            var filtered = new DependencyGraph();
            filtered.AddVertexRange(projs);
            //filtered.AddEdgeRange(graph.Edges.Where(d => projs.Contains(d.Source) && projs.Contains(d.Target)));
            filtered.AddEdgeRange(deps);
            return filtered;
        }
        public string GenerateDotCommand(DependencyGraph<string> graph, AssemblyFilterPreferences filterPreferences, string extraCommands)
        {
            var nodes = graph.GetNodes();

            // TODO can this first loop be replaced with LINQ, maybe with a zip?
            var idsByNameMap = new Dictionary<string, int>();
            var id = 1;
            foreach (var nodeName in nodes)
            {
                idsByNameMap.Add(nodeName, id);
                id++;
            }

            var commandText = new StringBuilder();
            commandText.Append("digraph G {\r\n");

            // handle extra commands
            if (extraCommands.Trim().Length > 0)
            {
                commandText.Append("    ");
                commandText.Append(extraCommands.Trim());
                commandText.Append("\r\n");
            }

            var nodeLabels = new StringBuilder();

            foreach (var dependant in nodes)
            {
                // make sure the dependant should be plotted
                if (!filterPreferences.IncludeInPlot(dependant))
                    continue;

                var dependantId = idsByNameMap[dependant];

                // 1 [label="SampleProject",shape=circle,hight=0.12,width=0.12,fontsize=1];
                nodeLabels.AppendFormat("    {0} [label=\"{1}\"];\r\n", dependantId, dependant);

                foreach (var dependency in graph.GetDependenciesForNode(dependant))
                {
                    var dependencyId = idsByNameMap[dependency];
                    if (!filterPreferences.IncludeInPlot(dependency))
                        continue;
                    commandText.AppendFormat("    {0} -> {1};\r\n", dependantId, dependencyId);
                }
            }

            commandText.Append(nodeLabels.ToString());
            commandText.Append("}");

            return commandText.ToString();
        }
Example #30
0
        public static DependencyGraph Graph(params object[] os)
        {
            var graph = new DependencyGraph();

            graph.AddVertexRange(os.OfType<Library>());
            graph.AddVertexRange(os.OfType<IEnumerable<Library>>()
                .SelectMany(e => e));

            graph.AddEdgeRange(os.OfType<Dependency>());
            graph.AddEdgeRange(os.OfType<IEnumerable<Dependency>>()
                .SelectMany(e => e));

            return graph;
        }
Example #31
0
        public void EmptyIndexer()
        {
            DependencyGraph t = new DependencyGraph();

            Assert.AreEqual(0, t["a"]);
        }
Example #32
0
 public NodeArg(string name, DependencyGraph graph)
 {
     _name  = name;
     _graph = graph;
 }
Example #33
0
        public void IndexerWithUndefinedString()
        {
            DependencyGraph t = new DependencyGraph();

            Assert.AreEqual(0, t["A"]);
        }
Example #34
0
        protected virtual void SortReferences()
        {
            var graph = new DependencyGraph();

            foreach (var t in References)
            {
                var tProcess = graph.Processes.FirstOrDefault(p => p.Name == t.Name.Name);

                if (tProcess == null)
                {
                    tProcess = new OrderedProcess(graph, t.Name.Name);
                }

                foreach (var xref in t.MainModule.AssemblyReferences)
                {
                    var dProcess = graph.Processes.FirstOrDefault(p => p.Name == xref.Name);

                    if (dProcess == null)
                    {
                        dProcess = new OrderedProcess(graph, xref.Name);
                    }

                    tProcess.After(dProcess);
                }
            }

            if (graph.ProcessCount > 0)
            {
                AssemblyDefinition asmDef = null;

                try
                {
                    var list = new List <AssemblyDefinition>(References.Count());

                    Logger.ZLogTrace("Sorting references...");

                    Logger.ZLogTrace("\t\tCalculate sorting references...");
                    //IEnumerable<IEnumerable<OrderedProcess>> sorted = graph.CalculateSort();
                    TopologicalSort sorted = graph.CalculateSort();
                    Logger.ZLogTrace("\t\tCalculate sorting references done");

                    // The fix required for Mono 5.0.0.94
                    // It does not "understand" TopologicalSort's Enumerator in foreach
                    // foreach (var processes in sorted)
                    // The code is modified to get it "directly" and "typed"
                    var sortedISetEnumerable = sorted as IEnumerable <ISet <OrderedProcess> >;
                    Logger.ZLogTrace("\t\tGot Enumerable<ISet<OrderedProcess>>");

                    var sortedISetEnumerator = sortedISetEnumerable.GetEnumerator();
                    Logger.ZLogTrace("\t\tGot Enumerator<ISet<OrderedProcess>>");

                    //foreach (var processes in sorted)
                    while (sortedISetEnumerator.MoveNext())
                    {
                        var processes = sortedISetEnumerator.Current;

                        foreach (var process in processes)
                        {
                            Logger.ZLogTrace("\tHandling " + process.Name);

                            asmDef = References.FirstOrDefault(r => r.Name.Name == process.Name);

                            if (asmDef != null && list.All(r => r.Name.Name != asmDef.Name.Name))
                            {
                                list.Add(asmDef);
                            }
                        }
                    }

                    References = list;

                    Logger.ZLogTrace("Sorting references done:");

                    for (int i = 0; i < list.Count; i++)
                    {
                        Logger.ZLogTrace("\t" + list[i].Name);
                    }
                }
                catch (Exception ex)
                {
                    Logger.ZLogWarning("Topological sort failed {0} with error {1}", asmDef != null ? "at reference " + asmDef.FullName : string.Empty, ex);
                }
            }
        }
        public void Test1()
        {
            DependencyGraph graph = new DependencyGraph();

            Assert.AreEqual(0, graph.Size);
        }
        // Demonstrate how to use the dependency grap. Also checks it can be
        // executed with no deadlocks.
        private async Task SimulateAsyncRequestsAsync(DependencyGraph g)
        {
            // Keep track of the partial sets credentials to present. Requests
            // that are keys in this dictionary are still waiting to be sent.
            var pendingCredentialsToPresent = g.Vertices.ToDictionary(v => v, _ => DependencyGraph.CredentialTypes.ToDictionary(t => t, _ => new List <long>()));

            // A waiting request is blocked if either set of credentials that
            // need to be presented is incomplete. Since input registrations and
            // connection confirmation are modeled as a single node with in
            // degree 0, they are never blocked.
            ImmutableArray <RequestNode> UnblockedRequests() => pendingCredentialsToPresent.Keys.Where(node => DependencyGraph.CredentialTypes.All(t => g.InDegree(node, t) == pendingCredentialsToPresent[node][t].Count)).ToImmutableArray();

            // Also keep track of the in-flight requests
            var inFlightRequests = new List <(Task <ImmutableSortedDictionary <CredentialType, IEnumerable <long> > > Task, ImmutableSortedDictionary <CredentialType, IEnumerable <CredentialDependency> > Dependencies)>();

            // And all sent requests, for testing purposes.
            var sent = new HashSet <RequestNode>();

            var rng = new Random();

            // Simulate sending a request. Instead of actual Credential objects,
            // credentials are just represented as longs.
            async Task <ImmutableSortedDictionary <CredentialType, IEnumerable <long> > > SimulateRequest(
                RequestNode node,
                ImmutableSortedDictionary <CredentialType, IEnumerable <long> > presented,
                ImmutableSortedDictionary <CredentialType, IEnumerable <long> > requested)
            {
                foreach (var credentialType in presented.Keys)
                {
                    Assert.Equal(g.InEdges(node, credentialType).Select(e => e.Value).OrderBy(x => x), presented[credentialType].OrderBy(x => x));
                    Assert.Equal(g.OutEdges(node, credentialType).Select(e => e.Value).OrderBy(x => x), requested[credentialType].OrderBy(x => x));
                }

                Assert.DoesNotContain(node, sent);
                sent.Add(node);

                await Task.Delay(1 + rng.Next(10));

                return(requested);
            }

            var ct = new CancellationTokenSource(new TimeSpan(0, 2, 0));

            for (var remainingSteps = 2 * pendingCredentialsToPresent.Count; remainingSteps > 0 && pendingCredentialsToPresent.Count + inFlightRequests.Count > 0; remainingSteps--)
            {
                // Clear unblocked but waiting requests. Not very efficient
                // (quadratic complexity), but good enough for demonstration
                // purposes.
                foreach (var node in UnblockedRequests())
                {
                    // FIXME this is a little ugly, how should it look in the real code? seems like we're missing an abstraction
                    var edgesByType          = DependencyGraph.CredentialTypes.ToImmutableSortedDictionary(t => t, t => g.OutEdges(node, t));
                    var credentialsToRequest = edgesByType.ToImmutableSortedDictionary(kvp => kvp.Key, kvp => kvp.Value.Select(e => e.Value));
                    var credentialsToPresent = pendingCredentialsToPresent[node].ToImmutableSortedDictionary(kvp => kvp.Key, kvp => kvp.Value.AsEnumerable());

                    Assert.NotEmpty(edgesByType);

                    var task = SimulateRequest(node, credentialsToPresent, credentialsToRequest);

                    inFlightRequests.Add((Task: task, Dependencies: edgesByType));
                    Assert.True(pendingCredentialsToPresent.Remove(node));
                }

                // At this point at least one task must be in progress.
                Assert.True(inFlightRequests.Count > 0);

                // Wait for a response to arrive
                var i = Task.WaitAny(inFlightRequests.Select(x => x.Task).ToArray(), ct.Token);
                Assert.InRange(i, 0, inFlightRequests.Count);
                var entry = inFlightRequests[i];
                inFlightRequests.RemoveAt(i);

                var issuedCredentials = await entry.Task;

                // Unblock the requests that depend on the issued credentials from this response
                foreach ((var credentialType, var edges) in entry.Dependencies)
                {
                    Assert.Equal(edges.Count(), issuedCredentials[credentialType].Count());
                    foreach ((var credential, var edge) in issuedCredentials[credentialType].Zip(edges))
                    {
                        // Ignore the fact that credential is the same as
                        // edge.Value, it's meant to represent the real thing
                        // since it's returned from the task.
                        Assert.Equal(edge.Value, credential);
                        pendingCredentialsToPresent[edge.To][credentialType].Add(credential);
                    }
                }
            }

            Assert.Empty(inFlightRequests);
            Assert.Empty(pendingCredentialsToPresent);

            Assert.True(g.Vertices.All(v => sent.Contains(v)));

            ct.Dispose();
        }
Example #37
0
 public void Construct03()
 {
     DependencyGraph d1 = new DependencyGraph(null);
 }
Example #38
0
        public void Construct01()
        {
            DependencyGraph d1 = new DependencyGraph();

            Assert.AreEqual(0, d1.Size);
        }
Example #39
0
        public void EmptyTest5()
        {
            DependencyGraph t = new DependencyGraph();

            Assert.IsFalse(t.GetDependees("x").GetEnumerator().MoveNext());
        }
Example #40
0
        public void Generate(string dest)
        {
            if (dest == null)
            {
                throw new ArgumentNullException(nameof(dest));
            }
            Directory.CreateDirectory(dest);
            this.SourceFiles = new List <string>();

            foreach (var eocObjectClass in EocObjectClassMap.Values)
            {
                eocObjectClass.ParseCode();
            }
            foreach (var eocStaticClass in EocStaticClassMap.Values)
            {
                eocStaticClass.ParseCode();
            }

            foreach (var eocObjectClass in EocObjectClassMap.Values)
            {
                eocObjectClass.Optimize();
            }
            foreach (var eocStaticClass in EocStaticClassMap.Values)
            {
                eocStaticClass.Optimize();
            }

            //分析依赖图
            foreach (var x in EocConstantMap.Values)
            {
                x?.AnalyzeDependencies(DependencyGraph);
            }
            foreach (var x in EocStructMap.Values)
            {
                x.AnalyzeDependencies(DependencyGraph);
            }
            foreach (var x in EocGlobalVariableMap.Values)
            {
                x.AnalyzeDependencies(DependencyGraph);
            }
            foreach (var x in EocDllDeclareMap.Values)
            {
                x.AnalyzeDependencies(DependencyGraph);
            }
            foreach (var x in EocObjectClassMap.Values)
            {
                x.AnalyzeDependencies(DependencyGraph);
            }
            foreach (var x in EocStaticClassMap.Values)
            {
                x.AnalyzeDependencies(DependencyGraph);
            }
            if (EocDllExportMap != null)
            {
                foreach (var x in EocDllExportMap.Values)
                {
                    x.AnalyzeDependencies(DependencyGraph);
                }
            }
            if (Source.InitEcSectionInfo != null)
            {
                DependencyGraph.AddVerticesAndEdgeRange(Source.InitEcSectionInfo.InitMethod.Select(x => new Edge <string>("[Root]", GetCppMethodName(x))));
            }
            if (Source.Code.MainMethod != 0)
            {
                DependencyGraph.AddVerticesAndEdge(new Edge <string>("[Root]", GetCppMethodName(Source.Code.MainMethod)));
            }
            else
            {
                DependencyGraph.AddVerticesAndEdge(new Edge <string>("[Root]", "e::user::cmd::EocUser__启动子程序"));
            }

            //生成依赖列表
            this.Dependencies = new HashSet <string>();
            GraphUtils.AnalyzeDependencies(DependencyGraph, "[Root]", this.Dependencies);

            //删除未使用代码
            EocConstantMap       = EocConstantMap.FilterSortedDictionary(x => Dependencies.Contains(x.Value?.RefId));
            EocStructMap         = EocStructMap.FilterSortedDictionary(x => Dependencies.Contains(x.Value.RefId));
            EocGlobalVariableMap = EocGlobalVariableMap.FilterSortedDictionary(x => Dependencies.Contains(x.Value.RefId));
            EocDllDeclareMap     = EocDllDeclareMap.FilterSortedDictionary(x => Dependencies.Contains(x.Value.RefId));
            EocObjectClassMap    = EocObjectClassMap.FilterSortedDictionary(x => Dependencies.Contains(x.Value.RefId));
            foreach (var x in EocObjectClassMap.Values)
            {
                x.RemoveUnusedCode(Dependencies);
            }
            foreach (var x in EocStaticClassMap.Values)
            {
                x.RemoveUnusedCode(Dependencies);
            }
            EocStaticClassMap = EocStaticClassMap.FilterSortedDictionary(x => x.Value.Method.Count != 0);

            //依赖信息
            File.WriteAllText(Path.Combine(dest, "Dependencies.txt"), string.Join("\r\n", this.Dependencies), Encoding.UTF8);
            File.WriteAllBytes(Path.Combine(dest, "DependencyGraph.gv"), Encoding.UTF8.GetBytes(GraphUtils.WriteGraphvizScript(DependencyGraph, "DependencyGraph")));

            string fileName;

            //常量
            using (var writer = NewCodeFileByCppName(dest, ConstantNamespace, "h"))
                EocConstant.Define(this, writer, EocConstantMap);
            using (var writer = NewCodeFileByCppName(dest, ConstantNamespace, "cpp"))
                EocConstant.Implement(this, writer, EocConstantMap);

            //声明自定义数据类型(结构/对象类)
            using (var writer = NewCodeFileByCppName(dest, TypeNamespace, "h"))
            {
                DefineAllTypes(writer);
            }

            //实现 对象类
            foreach (var item in EocObjectClassMap.Values)
            {
                using (var writer = NewCodeFileByCppName(dest, item.CppName, "cpp"))
                    item.ImplementRawObjectClass(writer);
            }

            //静态类
            foreach (var item in EocStaticClassMap.Values)
            {
                using (var writer = NewCodeFileByCppName(dest, item.CppName, "h"))
                    item.Define(writer);
                using (var writer = NewCodeFileByCppName(dest, item.CppName, "cpp"))
                    item.Implement(writer);
            }

            //全局变量
            using (var writer = NewCodeFileByCppName(dest, GlobalNamespace, "h"))
                EocGlobalVariable.Define(this, writer, EocGlobalVariableMap);
            using (var writer = NewCodeFileByCppName(dest, GlobalNamespace, "cpp"))
                EocGlobalVariable.Implement(this, writer, EocGlobalVariableMap);

            //DLL
            using (var writer = NewCodeFileByCppName(dest, DllNamespace, "h"))
                EocDll.Define(this, writer, EocDllDeclareMap);
            using (var writer = NewCodeFileByCppName(dest, DllNamespace, "cpp"))
                EocDll.Implement(this, writer, EocDllDeclareMap);

            //预编译头
            using (var writer = NewCodeFileByCppName(dest, "stdafx", "h"))
                MakeStandardHeader(writer);

            //程序入口
            using (var writer = NewCodeFileByCppName(dest, "entry", "cpp"))
                MakeProgramEntry(writer);

            //Dll导出
            if (EocDllExportMap != null)
            {
                using (var writer = NewCodeFileByCppName(dest, "dll_export", "cpp"))
                    EocDllExport.Implement(this, writer, EocDllExportMap);
                fileName = Path.Combine(dest, "dll_export.def");
                using (var writer = new StreamWriter(File.Create(fileName), Encoding.UTF8))
                {
                    EocDllExport.MakeDef(this, writer, EocDllExportMap);
                }
            }

            //CMake项目配置文件
            fileName = Path.Combine(dest, "CMakeLists.txt");
            using (var writer = new StreamWriter(File.Create(fileName), Encoding.UTF8))
                MakeCMakeLists(writer);

            //VSCode配置文件
            fileName = Path.Combine(dest, ".vscode", "settings.json");
            Directory.CreateDirectory(Path.GetDirectoryName(fileName));
            using (var writer = new StreamWriter(File.Create(fileName), Encoding.UTF8))
                MakeVSCodeSettings(writer);
        }
        private void AssertResolvedGraphInvariants(DependencyGraph graph, IEnumerable <IEnumerable <long> > inputValues, IEnumerable <IEnumerable <long> > outputValues)
        {
            foreach (var credentialType in DependencyGraph.CredentialTypes)
            {
                // Input nodes
                foreach (var node in graph.Vertices.Take(inputValues.Count()))
                {
                    var balance = graph.Balance(node, credentialType);

                    Assert.True(balance >= 0);
                    if (credentialType == CredentialType.Vsize)
                    {
                        Assert.InRange(balance, 0, ProtocolConstants.MaxVsizeCredentialValue);
                    }
                    Assert.Equal(0, node.MaxInDegree);
                    Assert.Equal(node.MaxInDegree, graph.InDegree(node, credentialType));

                    var outDegree = graph.OutDegree(node, credentialType);
                    Assert.InRange(outDegree, 0, DependencyGraph.K - (balance == 0 ? 0 : 1));                     // for amount creds, 1..K?
                }

                // Output nodes
                foreach (var node in graph.Vertices.Skip(inputValues.Count()).Take(outputValues.Count()))
                {
                    var balance = graph.Balance(node, credentialType);

                    Assert.Equal(0, balance);

                    Assert.Equal(DependencyGraph.K, node.MaxInDegree);
                    Assert.Equal(node.MaxInDegree, graph.InDegree(node, credentialType));

                    Assert.Equal(0, node.MaxOutDegree);
                    Assert.Equal(0, node.MaxZeroOnlyOutDegree);
                    Assert.Equal(0, graph.OutDegree(node, credentialType));
                }

                // Reissuance nodes
                foreach (var node in graph.Vertices.Skip(inputValues.Count() + outputValues.Count()))
                {
                    var balance = graph.Balance(node, credentialType);

                    Assert.True(balance >= 0);
                    if (credentialType == CredentialType.Vsize)
                    {
                        Assert.InRange(balance, 0, ProtocolConstants.MaxVsizeCredentialValue);
                    }

                    Assert.Equal(DependencyGraph.K, node.MaxInDegree);
                    Assert.Equal(node.MaxInDegree, graph.InDegree(node, credentialType));

                    var outDegree = graph.OutDegree(node, credentialType);
                    Assert.InRange(outDegree, 0, DependencyGraph.K - (balance == 0 ? 0 : 1));
                }
            }

            // Ensure that vsize credentials do not exceed the range proof width
            foreach (var edge in graph.EdgeSets[CredentialType.Vsize].Successors.Values.SelectMany(x => x))
            {
                Assert.InRange <long>(edge.Value, 0, ProtocolConstants.MaxVsizeCredentialValue);
            }

            // TODO add InlineData param for max depth?

            // TODO assert max depth < ceil(log count)?
        }
        public void HasDependentsTestEmpty()
        {
            DependencyGraph t = new DependencyGraph();

            Assert.AreEqual(false, t.HasDependents("a"));
        }
Example #43
0
        /// <summary>
        /// Builds join tuple composer.
        /// </summary>
        /// <param name="statementName">Name of the statement.</param>
        /// <param name="statementId">The statement identifier.</param>
        /// <param name="outerJoinDescList">list of descriptors for outer join criteria</param>
        /// <param name="optionalFilterNode">filter tree for analysis to build indexes for fast access</param>
        /// <param name="streamTypes">types of streams</param>
        /// <param name="streamNames">names of streams</param>
        /// <param name="streamJoinAnalysisResult">The stream join analysis result.</param>
        /// <param name="queryPlanLogging">if set to <c>true</c> [query plan logging].</param>
        /// <param name="statementContext">The statement context.</param>
        /// <param name="historicalViewableDesc">The historical viewable desc.</param>
        /// <param name="exprEvaluatorContext">The expr evaluator context.</param>
        /// <param name="selectsRemoveStream">if set to <c>true</c> [selects remove stream].</param>
        /// <param name="hasAggregations">if set to <c>true</c> [has aggregations].</param>
        /// <param name="tableService">The table service.</param>
        /// <param name="isOnDemandQuery">if set to <c>true</c> [is on demand query].</param>
        /// <param name="allowIndexInit">if set to <c>true</c> [allow index initialize].</param>
        /// <returns>
        /// composer implementation
        /// </returns>
        /// <throws>com.espertech.esper.epl.expression.core.ExprValidationException is thrown to indicate thatvalidation of view use in joins failed.
        /// {D255958A-8513-4226-94B9-080D98F904A1}</throws>
        public static JoinSetComposerPrototype MakeComposerPrototype(string statementName, int statementId, OuterJoinDesc[] outerJoinDescList, ExprNode optionalFilterNode, EventType[] streamTypes, string[] streamNames, StreamJoinAnalysisResult streamJoinAnalysisResult, bool queryPlanLogging, StatementContext statementContext, HistoricalViewableDesc historicalViewableDesc, ExprEvaluatorContext exprEvaluatorContext, bool selectsRemoveStream, bool hasAggregations, TableService tableService, bool isOnDemandQuery, bool allowIndexInit)
        {
            // Determine if there is a historical stream, and what dependencies exist
            var historicalDependencyGraph = new DependencyGraph(streamTypes.Length, false);

            for (var i = 0; i < streamTypes.Length; i++)
            {
                if (historicalViewableDesc.Historical[i])
                {
                    var streamsThisStreamDependsOn = historicalViewableDesc.DependenciesPerHistorical[i];
                    historicalDependencyGraph.AddDependency(i, streamsThisStreamDependsOn);
                }
            }

            if (log.IsDebugEnabled)
            {
                log.Debug("Dependency graph: " + historicalDependencyGraph);
            }

            // Handle a join with a database or other historical data source for 2 streams
            if ((historicalViewableDesc.HasHistorical) && (streamTypes.Length == 2))
            {
                return(MakeComposerHistorical2Stream(outerJoinDescList, optionalFilterNode, streamTypes, historicalViewableDesc, queryPlanLogging, exprEvaluatorContext, statementContext, streamNames, allowIndexInit));
            }

            var isOuterJoins = !OuterJoinDesc.ConsistsOfAllInnerJoins(outerJoinDescList);

            // Query graph for graph relationships between streams/historicals
            // For outer joins the query graph will just contain outer join relationships
            var hint       = ExcludePlanHint.GetHint(streamNames, statementContext);
            var queryGraph = new QueryGraph(streamTypes.Length, hint, false);

            if (outerJoinDescList.Length > 0)
            {
                OuterJoinAnalyzer.Analyze(outerJoinDescList, queryGraph);
                if (log.IsDebugEnabled)
                {
                    log.Debug(".makeComposer After outer join queryGraph=\n" + queryGraph);
                }
            }

            // Let the query graph reflect the where-clause
            if (optionalFilterNode != null)
            {
                // Analyze relationships between streams using the optional filter expression.
                // Relationships are properties in AND and EQUALS nodes of joins.
                FilterExprAnalyzer.Analyze(optionalFilterNode, queryGraph, isOuterJoins);
                if (log.IsDebugEnabled)
                {
                    log.Debug(".makeComposer After filter expression queryGraph=\n" + queryGraph);
                }

                // Add navigation entries based on key and index property equivalency (a=b, b=c follows a=c)
                QueryGraph.FillEquivalentNav(streamTypes, queryGraph);
                if (log.IsDebugEnabled)
                {
                    log.Debug(".makeComposer After fill equiv. nav. queryGraph=\n" + queryGraph);
                }
            }

            // Historical index lists
            var historicalStreamIndexLists = new HistoricalStreamIndexList[streamTypes.Length];

            var queryPlan = QueryPlanBuilder.GetPlan(streamTypes, outerJoinDescList, queryGraph, streamNames,
                                                     historicalViewableDesc, historicalDependencyGraph, historicalStreamIndexLists,
                                                     streamJoinAnalysisResult, queryPlanLogging, statementContext.Annotations, exprEvaluatorContext);

            // remove unused indexes - consider all streams or all unidirectional
            var usedIndexes = new HashSet <TableLookupIndexReqKey>();
            var indexSpecs  = queryPlan.IndexSpecs;

            for (var streamNum = 0; streamNum < queryPlan.ExecNodeSpecs.Length; streamNum++)
            {
                var planNode = queryPlan.ExecNodeSpecs[streamNum];
                if (planNode != null)
                {
                    planNode.AddIndexes(usedIndexes);
                }
            }
            foreach (var indexSpec in indexSpecs)
            {
                if (indexSpec == null)
                {
                    continue;
                }
                var items      = indexSpec.Items;
                var indexNames = items.Keys.ToArray();
                foreach (var indexName in indexNames)
                {
                    if (!usedIndexes.Contains(indexName))
                    {
                        items.Remove(indexName);
                    }
                }
            }

            var hook = QueryPlanIndexHookUtil.GetHook(statementContext.Annotations);

            if (queryPlanLogging && (QueryPlanLog.IsInfoEnabled || hook != null))
            {
                QueryPlanLog.Info("Query plan: " + queryPlan.ToQueryPlan());
                if (hook != null)
                {
                    hook.Join(queryPlan);
                }
            }

            // register index-use references for tables
            if (!isOnDemandQuery)
            {
                foreach (var usedIndex in usedIndexes)
                {
                    if (usedIndex.TableName != null)
                    {
                        tableService.GetTableMetadata(usedIndex.TableName).AddIndexReference(usedIndex.Name, statementName);
                    }
                }
            }

            var joinRemoveStream = selectsRemoveStream || hasAggregations;

            return(new JoinSetComposerPrototypeImpl(
                       statementName,
                       statementId,
                       outerJoinDescList,
                       optionalFilterNode,
                       streamTypes,
                       streamNames,
                       streamJoinAnalysisResult,
                       statementContext.Annotations,
                       historicalViewableDesc,
                       exprEvaluatorContext,
                       indexSpecs,
                       queryPlan,
                       historicalStreamIndexLists,
                       joinRemoveStream,
                       isOuterJoins,
                       tableService,
                       statementContext.EventTableIndexService));
        }
Example #44
0
        public void testReallyLongChain()
        {
            DependencyGraph DG = new DependencyGraph();

            // Check size of empty
            Assert.AreEqual(0, DG.Size);

            int N = 10000;

            // Create chain s0 -> s1 -> s2 -> ... -> sN
            string s;
            string t;

            for (int i = 0; i < N; i++)
            {
                s = "" + i;
                t = "" + (i + 1);
                DG.AddDependency(s, t);
            }


            // Check size after adding values
            Assert.AreEqual(DG.Size, N);


            // Check that Nodes s1 through sN have dependees
            for (int i = 1; i < N; i++)
            {
                Assert.IsTrue(DG.HasDependees("" + i));
            }
            // Check that Nodes s0 through s(N-1) have dependencies
            for (int i = 0; i < N - 1; i++)
            {
                Assert.IsTrue(DG.HasDependents("" + i));
            }


            // Check that number of dependees and dependents of node each matches size
            int numDependees  = 0;
            int numDependents = 0;

            for (int i = 0; i <= N; i++)
            {
                foreach (string x in DG.GetDependees("" + i))
                {
                    numDependees++;
                }
            }
            for (int i = 0; i <= N; i++)
            {
                foreach (string x in DG.GetDependents("" + i))
                {
                    numDependents++;
                }
            }
            Assert.AreEqual(N, numDependees);
            Assert.AreEqual(N, numDependents);


            // Remove first dependency
            DG.RemoveDependency("0", "1");
            Assert.AreEqual(N - 1, DG.Size);

            // Add first dependency back
            DG.AddDependency("0", "1");
            Assert.AreEqual(N, DG.Size);

            // Swap dependee "0" with "00"
            List <string> arr = new List <string>();

            arr.Add("00");
            DG.ReplaceDependees("1", arr);
            Assert.AreEqual(N, DG.Size);

            // undo last swap
            arr.Clear();
            arr.Add("0");
            DG.ReplaceDependees("1", arr);

            // Perform ReplaceDependees, but without replacement, only addition
            arr.Clear();
            for (int i = 0; i <= N; i++)
            {
                arr.Add(i + "" + i);
            }
            arr.Add("0");
            DG.ReplaceDependees("1", arr);
            Assert.AreEqual(2 * N + 1, DG.Size);
        }
Example #45
0
        public void Null1()
        {
            DependencyGraph d = new DependencyGraph();

            d.AddDependency("a", null);
        }
Example #46
0
        public void StressTest1()
        {
            // Dependency graph
            DependencyGraph t = new DependencyGraph();

            // A bunch of strings to use
            const int SIZE = 200;

            string[] letters = new string[SIZE];
            for (int i = 0; i < SIZE; i++)
            {
                letters[i] = ("" + (char)('a' + i));
            }

            // The correct answers
            HashSet <string>[] dents = new HashSet <string> [SIZE];
            HashSet <string>[] dees  = new HashSet <string> [SIZE];
            for (int i = 0; i < SIZE; i++)
            {
                dents[i] = new HashSet <string>();
                dees[i]  = new HashSet <string>();
            }

            // Add a bunch of dependencies
            for (int i = 0; i < SIZE; i++)
            {
                for (int j = i + 1; j < SIZE; j++)
                {
                    t.AddDependency(letters[i], letters[j]);
                    dents[i].Add(letters[j]);
                    dees[j].Add(letters[i]);
                }
            }

            // Remove a bunch of dependencies
            for (int i = 0; i < SIZE; i++)
            {
                for (int j = i + 4; j < SIZE; j += 4)
                {
                    t.RemoveDependency(letters[i], letters[j]);
                    dents[i].Remove(letters[j]);
                    dees[j].Remove(letters[i]);
                }
            }

            // Add some back
            for (int i = 0; i < SIZE; i++)
            {
                for (int j = i + 1; j < SIZE; j += 2)
                {
                    t.AddDependency(letters[i], letters[j]);
                    dents[i].Add(letters[j]);
                    dees[j].Add(letters[i]);
                }
            }

            // Remove some more
            for (int i = 0; i < SIZE; i += 2)
            {
                for (int j = i + 3; j < SIZE; j += 3)
                {
                    t.RemoveDependency(letters[i], letters[j]);
                    dents[i].Remove(letters[j]);
                    dees[j].Remove(letters[i]);
                }
            }

            // Make sure everything is right
            for (int i = 0; i < SIZE; i++)
            {
                Assert.IsTrue(dents[i].SetEquals(new HashSet <string>(t.GetDependents(letters[i]))));
                Assert.IsTrue(dees[i].SetEquals(new HashSet <string>(t.GetDependees(letters[i]))));
            }
        }
Example #47
0
        /// <summary>
        /// Compute a deployment order among the modules passed in considering their uses-dependency declarations.
        /// <para />The operation also checks and reports circular dependencies.
        /// <para />Pass in @{link ModuleOrderOptions} to customize the behavior if this method. When passing no options
        /// or passing default options, the default behavior checks uses-dependencies and circular dependencies.
        /// </summary>
        /// <param name="modules">to determine ordering for</param>
        /// <param name="options">operation options or null for default options</param>
        /// <param name="deployedModules">deployed modules</param>
        /// <returns>ordered modules</returns>
        /// <throws>ModuleOrderException when any module dependencies are not satisfied</throws>
        public static ModuleOrder GetModuleOrder(
            ICollection<Module> modules,
            ISet<string> deployedModules,
            ModuleOrderOptions options)
        {
            if (options == null) {
                options = new ModuleOrderOptions();
            }

            IList<Module> proposedModules = new List<Module>();
            proposedModules.AddAll(modules);

            ISet<string> availableModuleNames = new HashSet<string>();
            foreach (Module proposedModule in proposedModules) {
                if (proposedModule.Name != null) {
                    availableModuleNames.Add(proposedModule.Name);
                }
            }

            // Collect all deployed modules
            ISet<string> allDeployedModules = new HashSet<string>();
            allDeployedModules.AddAll(deployedModules);
            foreach (Module proposedModule in proposedModules) {
                allDeployedModules.Add(proposedModule.Name);
            }

            // Collect uses-dependencies of proposed modules
            IDictionary<string, ISet<string>> usesPerModuleName = new Dictionary<string, ISet<string>>();
            foreach (Module proposedModule in proposedModules) {
                // check uses-dependency is available
                if (options.IsCheckUses) {
                    if (proposedModule.Uses != null) {
                        foreach (string uses in proposedModule.Uses) {
                            if (availableModuleNames.Contains(uses)) {
                                continue;
                            }

                            bool deployed = allDeployedModules.Contains(uses);
                            if (deployed) {
                                continue;
                            }

                            string message = "Module-dependency not found";
                            if (proposedModule.Name != null) {
                                message += " as declared by module '" + proposedModule.Name + "'";
                            }

                            message += " for uses-declaration '" + uses + "'";
                            throw new ModuleOrderException(message);
                        }
                    }
                }

                if ((proposedModule.Name == null) || (proposedModule.Uses == null)) {
                    continue;
                }

                ISet<string> usesSet = usesPerModuleName.Get(proposedModule.Name);
                if (usesSet == null) {
                    usesSet = new HashSet<string>();
                    usesPerModuleName.Put(proposedModule.Name, usesSet);
                }

                usesSet.AddAll(proposedModule.Uses);
            }

            IDictionary<string, SortedSet<int>> proposedModuleNames = new Dictionary<string, SortedSet<int>>()
                .WithNullKeySupport();

            int count = 0;
            foreach (Module proposedModule in proposedModules) {
                SortedSet<int> moduleNumbers = proposedModuleNames.Get(proposedModule.Name);
                if (moduleNumbers == null) {
                    moduleNumbers = new SortedSet<int>();
                    proposedModuleNames.Put(proposedModule.Name, moduleNumbers);
                }

                moduleNumbers.Add(count);
                count++;
            }

            DependencyGraph graph = new DependencyGraph(proposedModules.Count, false);
            int fromModule = 0;
            foreach (Module proposedModule in proposedModules) {
                if ((proposedModule.Uses == null) || (proposedModule.Uses.IsEmpty())) {
                    fromModule++;
                    continue;
                }

                SortedSet<int> dependentModuleNumbers = new SortedSet<int>();
                foreach (string use in proposedModule.Uses) {
                    SortedSet<int> moduleNumbers = proposedModuleNames.Get(use);
                    if (moduleNumbers == null) {
                        continue;
                    }

                    dependentModuleNumbers.AddAll(moduleNumbers);
                }

                dependentModuleNumbers.Remove(fromModule);
                graph.AddDependency(fromModule, dependentModuleNumbers);
                fromModule++;
            }

            if (options.IsCheckCircularDependency) {
                // Stack<int> 
                var circular = graph.FirstCircularDependency;
                if (circular != null) {
                    string message = "";
                    string delimiter = "";
                    foreach (int i in circular) {
                        message += delimiter;
                        message += "module '" + proposedModules[i].Name + "'";
                        delimiter = " uses (depends on) ";
                    }

                    throw new ModuleOrderException(
                        "Circular dependency detected in module uses-relationships: " + message);
                }
            }

            IList<Module> reverseDeployList = new List<Module>();
            ISet<int> ignoreList = new HashSet<int>();
            while (ignoreList.Count < proposedModules.Count) {
                // seconardy sort according to the order of listing
                ISet<int> rootNodes = new SortedSet<int>(
                    new ProxyComparer<int>() {
                        ProcCompare = (
                            o1,
                            o2) => {
                            return -1 * o1.CompareTo(o2);
                        },
                    });
                rootNodes.AddAll(graph.GetRootNodes(ignoreList));

                if (rootNodes.IsEmpty()) { // circular dependency could cause this
                    for (int i = 0; i < proposedModules.Count; i++) {
                        if (!ignoreList.Contains(i)) {
                            rootNodes.Add(i);
                            break;
                        }
                    }
                }

                foreach (int root in rootNodes) {
                    ignoreList.Add(root);
                    reverseDeployList.Add(proposedModules[root]);
                }
            }

            reverseDeployList.Reverse();
            return new ModuleOrder(reverseDeployList);
        }
Example #48
0
        public void StressTest15()
        {
            // Dependency graph
            DependencyGraph t = new DependencyGraph();

            // A bunch of strings to use
            const int SIZE = 800;

            string[] letters = new string[SIZE];
            for (int i = 0; i < SIZE; i++)
            {
                letters[i] = ("" + (char)('a' + i));
            }

            // The correct answers
            HashSet <string>[] dents = new HashSet <string> [SIZE];
            HashSet <string>[] dees  = new HashSet <string> [SIZE];
            for (int i = 0; i < SIZE; i++)
            {
                dents[i] = new HashSet <string>();
                dees[i]  = new HashSet <string>();
            }

            // Add a bunch of dependencies
            for (int i = 0; i < SIZE; i++)
            {
                for (int j = i + 1; j < SIZE; j++)
                {
                    t.AddDependency(letters[i], letters[j]);
                    dents[i].Add(letters[j]);
                    dees[j].Add(letters[i]);
                }
            }

            // Remove a bunch of dependencies
            for (int i = 0; i < SIZE; i++)
            {
                for (int j = i + 2; j < SIZE; j += 3)
                {
                    t.RemoveDependency(letters[i], letters[j]);
                    dents[i].Remove(letters[j]);
                    dees[j].Remove(letters[i]);
                }
            }

            // Replace a bunch of dependees
            for (int i = 0; i < SIZE; i += 2)
            {
                HashSet <string> newDees = new HashSet <String>();
                for (int j = 0; j < SIZE; j += 9)
                {
                    newDees.Add(letters[j]);
                }
                t.ReplaceDependees(letters[i], newDees);

                foreach (string s in dees[i])
                {
                    dents[s[0] - 'a'].Remove(letters[i]);
                }

                foreach (string s in newDees)
                {
                    dents[s[0] - 'a'].Add(letters[i]);
                }

                dees[i] = newDees;
            }

            // Make sure everything is right
            for (int i = 0; i < SIZE; i++)
            {
                Assert.IsTrue(dents[i].SetEquals(new HashSet <string>(t.GetDependents(letters[i]))));
                Assert.IsTrue(dees[i].SetEquals(new HashSet <string>(t.GetDependees(letters[i]))));
            }
        }
Example #49
0
        private List <IStatement> Schedule(DependencyGraph g, IReadOnlyList <IStatement> stmts, bool createFirstIterPostBlocks)
        {
            List <IStatement>     output       = new List <IStatement>();
            List <StatementBlock> blocks       = new List <StatementBlock>();
            List <NodeIndex>      currentBlock = null;
            DirectedGraphFilter <NodeIndex, EdgeIndex> graph2 = new DirectedGraphFilter <NodeIndex, EdgeIndex>(g.dependencyGraph, edge => !g.isDeleted[edge]);
            StrongComponents2 <NodeIndex> scc = new StrongComponents2 <NodeIndex>(graph2.SourcesOf, graph2);

            scc.AddNode        += delegate(NodeIndex node) { currentBlock.Add(node); };
            scc.BeginComponent += delegate() { currentBlock = new List <int>(); };
            scc.EndComponent   += delegate() {
                bool isCyclic = false;
                if (currentBlock.Count == 1)
                {
                    NodeIndex node = currentBlock[0];
                    foreach (NodeIndex source in graph2.SourcesOf(node))
                    {
                        if (source == node)
                        {
                            isCyclic = true;
                            break;
                        }
                    }
                }
                else
                {
                    isCyclic = true;
                }
                if (isCyclic)
                {
                    blocks.Add(new Loop()
                    {
                        indices = currentBlock
                    });
                }
                else
                {
                    blocks.Add(new StraightLine()
                    {
                        indices = currentBlock
                    });
                }
            };
            scc.SearchFrom(graph2.Nodes);
            //scc.SearchFrom(g.outputNodes);

            bool check = false;

            if (check)
            {
                // check that there are no edges from a later component to an earlier component
                Set <NodeIndex> earlierNodes = new Set <int>();
                foreach (StatementBlock block in blocks)
                {
                    earlierNodes.AddRange(block.indices);
                    foreach (NodeIndex node in block.indices)
                    {
                        foreach (NodeIndex source in graph2.SourcesOf(node))
                        {
                            if (!earlierNodes.Contains(source))
                            {
                                Console.WriteLine(g.NodeToString(node) + Environment.NewLine + "   depends on later node " + g.NodeToString(source));
                                Error("Internal error: Strong components are not ordered properly");
                            }
                        }
                    }
                }
            }

            Set <NodeIndex> nodesToMove = new Set <NodeIndex>();
            Dictionary <Loop, IBlockStatement> firstIterPostprocessing = null;

            if (createFirstIterPostBlocks)
            {
                firstIterPostprocessing = GetFirstIterPostprocessing(blocks, graph2, stmts, nodesToMove);
            }
            IVariableDeclaration iteration = Builder.VarDecl("iteration", typeof(int));

            IndexedProperty <NodeIndex, bool> isUniform = graph2.CreateNodeData <bool>(true);

            foreach (StatementBlock block in blocks)
            {
                if (block is Loop loop)
                {
                    foreach (NodeIndex i in block.indices)
                    {
                        isUniform[i] = false;
                    }
                    IWhileStatement    ws        = Builder.WhileStmt(Builder.LiteralExpr(true));
                    IList <IStatement> whileBody = ws.Body.Statements;

                    if (ContainsIterationStatement(stmts, block.indices))
                    {
                        List <IStatement> nodes = new List <IStatement>();
                        foreach (NodeIndex i in block.indices)
                        {
                            IStatement ist = stmts[i];
                            if (!context.InputAttributes.Has <IterationStatement>(ist))
                            {
                                nodes.Add(ist);
                            }
                        }
                        // build a new dependency graph with the dummy iteration statement removed
                        DependencyGraph   g2  = new DependencyGraph(context, nodes, ignoreMissingNodes: true, ignoreRequirements: true);
                        List <IStatement> sc3 = Schedule(g2, nodes, false);
                        if (sc3.Count == 1 && sc3[0] is IWhileStatement)
                        {
                            ws = (IWhileStatement)sc3[0];
                        }
                        else
                        {
                            // The statements in the outer loop are not strongly connected.
                            // Since we want the next transform to only process strong components,
                            // we mark the outer while loop as DoNotSchedule, leaving only the
                            // inner while loops to be scheduled.
                            // add all statements in sc3 to whileBody, but remove while loops around a single statement.
                            foreach (IStatement ist in sc3)
                            {
                                if (ist is IWhileStatement iws2)
                                {
                                    if (iws2.Body.Statements.Count == 1)
                                    {
                                        whileBody.AddRange(iws2.Body.Statements);
                                        continue;
                                    }
                                }
                                whileBody.Add(ist);
                            }
                            context.OutputAttributes.Set(ws, new DoNotSchedule());
                        }
                    }
                    else // !ContainsIterationStatement
                    {
                        foreach (NodeIndex i in block.indices)
                        {
                            IStatement st = stmts[i];
                            whileBody.Add(st);
                            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(st);
                            di.AddClones(clonesOfStatement);
                        }
                        RegisterUnchangedStatements(whileBody);
                    }
                    if (firstIterPostprocessing != null && firstIterPostprocessing.ContainsKey(loop))
                    {
                        var thenBlock         = firstIterPostprocessing[loop];
                        var iterIsZero        = Builder.BinaryExpr(BinaryOperator.ValueEquality, Builder.VarRefExpr(iteration), Builder.LiteralExpr(0));
                        var firstIterPostStmt = Builder.CondStmt(iterIsZero, thenBlock);
                        context.OutputAttributes.Set(firstIterPostStmt, new FirstIterationPostProcessingBlock());
                        whileBody.Add(firstIterPostStmt);
                    }
                    output.Add(ws);
                }
                else
                {
                    // not cyclic
                    foreach (NodeIndex i in block.indices)
                    {
                        IStatement st = stmts[i];
                        if (!nodesToMove.Contains(i))
                        {
                            output.Add(st);
                            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(st);
                            di.AddClones(clonesOfStatement);
                        }
                        isUniform[i] = g.IsUniform(i, source => !isUniform[source]);
                        if (isUniform[i] != g.isUniform[i])
                        {
                            Assert.IsTrue(isUniform[i]);
                            g.isUniform[i] = isUniform[i];
                            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(st);
                            di.IsUniform = isUniform[i];
                        }
                        // mark sources of output statements (for SchedulingTransform)
                        if (g.outputNodes.Contains(i))
                        {
                            foreach (NodeIndex source in graph2.SourcesOf(i))
                            {
                                IStatement sourceSt = stmts[source];
                                if (!context.InputAttributes.Has <OutputSource>(sourceSt))
                                {
                                    context.OutputAttributes.Set(sourceSt, new OutputSource());
                                }
                            }
                        }
                    }
                }
            }
            return(output);
        }
Example #50
0
        public void NullException1()
        {
            DependencyGraph G = new DependencyGraph();

            G.AddDependency("a", null);
        }
Example #51
0
        public void SimpleNullTest()
        {
            DependencyGraph t = new DependencyGraph();

            t.AddDependency(null, "hi");
        }
Example #52
0
        public void TestRemove()
        {
            DependencyGraph G = new DependencyGraph();

            G.RemoveDependency("a", "b");
        }
Example #53
0
        public void EmptyTest1()
        {
            DependencyGraph t = new DependencyGraph();

            Assert.AreEqual(0, t.Size);
        }
Example #54
0
        public void NullException3()
        {
            DependencyGraph G = new DependencyGraph();

            G.HasDependees(null);
        }
Example #55
0
        /// <summary>
        /// Build query plan using the filter.
        /// </summary>
        /// <param name="typesPerStream">event types for each stream</param>
        /// <param name="outerJoinDescList">list of outer join criteria, or null if there are no outer joins</param>
        /// <param name="queryGraph">relationships between streams based on filter expressions and outer-join on-criteria</param>
        /// <param name="streamNames">names of streams</param>
        /// <param name="historicalViewableDesc">The historical viewable desc.</param>
        /// <param name="dependencyGraph">dependencies between historical streams</param>
        /// <param name="historicalStreamIndexLists">index management, populated for the query plan</param>
        /// <param name="streamJoinAnalysisResult">The stream join analysis result.</param>
        /// <param name="isQueryPlanLogging">if set to <c>true</c> [is query plan logging].</param>
        /// <param name="annotations">The annotations.</param>
        /// <param name="exprEvaluatorContext">The expr evaluator context.</param>
        /// <returns>
        /// query plan
        /// </returns>
        /// <exception cref="System.ArgumentException">
        /// Number of join stream types is less then 2
        /// or
        /// Too many outer join descriptors found
        /// </exception>
        /// <throws>ExprValidationException if the query plan fails</throws>
        public static QueryPlan GetPlan(EventType[] typesPerStream,
                                        OuterJoinDesc[] outerJoinDescList,
                                        QueryGraph queryGraph,
                                        string[] streamNames,
                                        HistoricalViewableDesc historicalViewableDesc,
                                        DependencyGraph dependencyGraph,
                                        HistoricalStreamIndexList[] historicalStreamIndexLists,
                                        StreamJoinAnalysisResult streamJoinAnalysisResult,
                                        bool isQueryPlanLogging,
                                        Attribute[] annotations,
                                        ExprEvaluatorContext exprEvaluatorContext)

        {
            string methodName = ".getPlan ";

            int numStreams = typesPerStream.Length;

            if (numStreams < 2)
            {
                throw new ArgumentException("Number of join stream types is less then 2");
            }
            if (outerJoinDescList.Length >= numStreams)
            {
                throw new ArgumentException("Too many outer join descriptors found");
            }

            if (numStreams == 2)
            {
                OuterJoinType?outerJoinType = null;
                if (outerJoinDescList.Length > 0)
                {
                    outerJoinType = outerJoinDescList[0].OuterJoinType;
                }

                QueryPlan queryPlanX = TwoStreamQueryPlanBuilder.Build(typesPerStream, queryGraph, outerJoinType, streamJoinAnalysisResult.UniqueKeys, streamJoinAnalysisResult.TablesPerStream);
                RemoveUnidirectionalAndTable(queryPlanX, streamJoinAnalysisResult);

                if (log.IsDebugEnabled)
                {
                    log.Debug(methodName + "2-Stream queryPlan=" + queryPlanX);
                }
                return(queryPlanX);
            }

            bool hasPreferMergeJoin = HintEnum.PREFER_MERGE_JOIN.GetHint(annotations) != null;
            bool hasForceNestedIter = HintEnum.FORCE_NESTED_ITER.GetHint(annotations) != null;
            bool isAllInnerJoins    = outerJoinDescList.Length == 0 || OuterJoinDesc.ConsistsOfAllInnerJoins(outerJoinDescList);

            if (isAllInnerJoins && !hasPreferMergeJoin)
            {
                QueryPlan queryPlanX = NStreamQueryPlanBuilder.Build(queryGraph, typesPerStream,
                                                                     historicalViewableDesc, dependencyGraph, historicalStreamIndexLists,
                                                                     hasForceNestedIter, streamJoinAnalysisResult.UniqueKeys,
                                                                     streamJoinAnalysisResult.TablesPerStream);

                if (queryPlanX != null)
                {
                    RemoveUnidirectionalAndTable(queryPlanX, streamJoinAnalysisResult);

                    if (log.IsDebugEnabled)
                    {
                        log.Debug(methodName + "Count-Stream inner-join queryPlan=" + queryPlanX);
                    }
                    return(queryPlanX);
                }

                if (isQueryPlanLogging && queryPlanLog.IsInfoEnabled)
                {
                    log.Info("Switching to Outer-NStream algorithm for query plan");
                }
            }

            QueryPlan queryPlan = NStreamOuterQueryPlanBuilder.Build(queryGraph, outerJoinDescList, streamNames, typesPerStream,
                                                                     historicalViewableDesc, dependencyGraph, historicalStreamIndexLists, exprEvaluatorContext, streamJoinAnalysisResult.UniqueKeys,
                                                                     streamJoinAnalysisResult.TablesPerStream);

            RemoveUnidirectionalAndTable(queryPlan, streamJoinAnalysisResult);
            return(queryPlan);
        }
Example #56
0
        public void EmptyTest5()
        {
            DependencyGraph t = new DependencyGraph();

            t.RemoveDependency("x", "y");
        }
Example #57
0
        public void HasNoDependents()
        {
            DependencyGraph t = new DependencyGraph();

            Assert.IsFalse(t.HasDependents("a"));
        }
Example #58
0
        public void NullException5()
        {
            DependencyGraph G = new DependencyGraph();

            G.GetDependees(null);
        }
 void ProcessStatements(IList <IStatement> outputs, IList <IStatement> outputDecls, IList <IStatement> inputs, Dictionary <IStatement, IStatement> replacements)
 {
     for (int i = 0; i < inputs.Count; i++)
     {
         IStatement ist = inputs[i];
         if (ist is IWhileStatement)
         {
             IWhileStatement iws           = (IWhileStatement)ist;
             IWhileStatement ws            = Builder.WhileStmt(iws);
             bool            doNotSchedule = context.InputAttributes.Has <DoNotSchedule>(iws);
             if (doNotSchedule)
             {
                 // iws may contain nested while loops
                 // TODO: make sure the new decls go in the right place
                 ProcessStatements(ws.Body.Statements, outputDecls, iws.Body.Statements, replacements);
             }
             else
             {
                 IReadOnlyList <IStatement> inputStmts = (IReadOnlyList <IStatement>)iws.Body.Statements;
                 IStatement      firstIterPostBlock    = ForwardBackwardTransform.ExtractFirstIterationPostProcessingBlock(context, ref inputStmts);
                 DependencyGraph g = new DependencyGraph(context, inputStmts, ignoreMissingNodes: true, ignoreRequirements: true);
                 // look for cycles of initialized nodes and insert clones as needed
                 Set <NodeIndex> nodesToClone = GetNodesToClone(g, g.dependencyGraph.Nodes);
                 for (int node = 0; node < inputStmts.Count; node++)
                 {
                     IStatement st = inputStmts[node];
                     if (nodesToClone.Contains(node))
                     {
                         cloneDecls.Clear();
                         cloneUpdates.Clear();
                         containers.Clear();
                         IStatement newStmt   = ConvertStatement(st);
                         IStatement declStmt  = cloneDecls[0];
                         IStatement setToStmt = cloneUpdates[0];
                         outputDecls.AddRange(cloneDecls);
                         DependencyInformation diNew = (DependencyInformation)context.InputAttributes.Get <DependencyInformation>(newStmt).Clone();
                         context.OutputAttributes.Remove <DependencyInformation>(newStmt);
                         context.OutputAttributes.Set(newStmt, diNew);
                         DependencyInformation diSet = new DependencyInformation();
                         diSet.Add(DependencyType.Dependency | DependencyType.Requirement, newStmt);
                         context.OutputAttributes.Set(setToStmt, diSet);
                         DependencyInformation diDecl = new DependencyInformation();
                         context.OutputAttributes.Set(declStmt, diDecl);
                         foreach (IStatement writer in diNew.Overwrites)
                         {
                             diDecl.Add(DependencyType.Dependency, writer);
                             diSet.Add(DependencyType.Overwrite, writer);
                         }
                         diNew.Remove(DependencyType.Overwrite);
                         diNew.Add(DependencyType.Declaration | DependencyType.Dependency | DependencyType.Overwrite, declStmt);
                         if (loopMergingInfo != null)
                         {
                             // update loopMergingInfo with the new statement
                             int oldNode = loopMergingInfo.GetIndexOf(st);
                             int newNode = loopMergingInfo.AddNode(newStmt);
                             loopMergingInfo.InheritSourceConflicts(newNode, oldNode);
                             int setToNode = loopMergingInfo.AddNode(setToStmt);
                             loopMergingInfo.InheritTargetConflicts(setToNode, oldNode);
                             int declNode = loopMergingInfo.AddNode(declStmt);
                         }
                         replacements[st] = setToStmt;
                         context.InputAttributes.CopyObjectAttributesTo <InitialiseBackward>(st, context.OutputAttributes, setToStmt);
                         st = newStmt;
                         ws.Body.Statements.AddRange(cloneUpdates);
                     }
                     else
                     {
                         RegisterUnchangedStatement(st);
                     }
                     ws.Body.Statements.Add(st);
                 }
                 if (firstIterPostBlock != null)
                 {
                     ws.Body.Statements.Add(firstIterPostBlock);
                 }
             }
             context.InputAttributes.CopyObjectAttributesTo(iws, context.OutputAttributes, ws);
             ist = ws;
         }
         else
         {
             RegisterUnchangedStatement(ist);
         }
         outputs.Add(ist);
     }
 }
Example #60
0
        private static JoinSetComposerPrototype MakeComposerHistorical2Stream(OuterJoinDesc[] outerJoinDescList, ExprNode optionalFilterNode, EventType[] streamTypes, HistoricalViewableDesc historicalViewableDesc, bool queryPlanLogging, ExprEvaluatorContext exprEvaluatorContext, StatementContext statementContext, string[] streamNames, bool allowIndexInit)
        {
            var polledViewNum = 0;
            var streamViewNum = 1;

            if (historicalViewableDesc.Historical[1])
            {
                streamViewNum = 0;
                polledViewNum = 1;
            }

            // if all-historical join, check dependency
            var isAllHistoricalNoSubordinate = false;

            if ((historicalViewableDesc.Historical[0]) && historicalViewableDesc.Historical[1])
            {
                var graph = new DependencyGraph(2, false);
                graph.AddDependency(0, historicalViewableDesc.DependenciesPerHistorical[0]);
                graph.AddDependency(1, historicalViewableDesc.DependenciesPerHistorical[1]);
                if (graph.FirstCircularDependency != null)
                {
                    throw new ExprValidationException("Circular dependency detected between historical streams");
                }

                // if both streams are independent
                if (graph.RootNodes.Count == 2)
                {
                    isAllHistoricalNoSubordinate = true;     // No parameters used by either historical
                }
                else
                {
                    if ((graph.GetDependenciesForStream(0).Count == 0))
                    {
                        streamViewNum = 0;
                        polledViewNum = 1;
                    }
                    else
                    {
                        streamViewNum = 1;
                        polledViewNum = 0;
                    }
                }
            }

            // Build an outer join expression node
            var      isOuterJoin         = false;
            var      isInnerJoinOnly     = false;
            ExprNode outerJoinEqualsNode = null;

            if (outerJoinDescList.Length > 0)
            {
                var outerJoinDesc = outerJoinDescList[0];
                isInnerJoinOnly = outerJoinDesc.OuterJoinType == OuterJoinType.INNER;

                if (outerJoinDesc.OuterJoinType.Equals(OuterJoinType.FULL))
                {
                    isOuterJoin = true;
                }
                else if ((outerJoinDesc.OuterJoinType.Equals(OuterJoinType.LEFT)) &&
                         (streamViewNum == 0))
                {
                    isOuterJoin = true;
                }
                else if ((outerJoinDesc.OuterJoinType.Equals(OuterJoinType.RIGHT)) &&
                         (streamViewNum == 1))
                {
                    isOuterJoin = true;
                }

                outerJoinEqualsNode = outerJoinDesc.MakeExprNode(exprEvaluatorContext);
            }

            // Determine filter for indexing purposes
            ExprNode filterForIndexing = null;

            if ((outerJoinEqualsNode != null) && (optionalFilterNode != null) && isInnerJoinOnly)      // both filter and outer join, add
            {
                filterForIndexing = new ExprAndNodeImpl();
                filterForIndexing.AddChildNode(optionalFilterNode);
                filterForIndexing.AddChildNode(outerJoinEqualsNode);
            }
            else if ((outerJoinEqualsNode == null) && (optionalFilterNode != null))
            {
                filterForIndexing = optionalFilterNode;
            }
            else if (outerJoinEqualsNode != null)
            {
                filterForIndexing = outerJoinEqualsNode;
            }

            var indexStrategies =
                DetermineIndexing(filterForIndexing, streamTypes[polledViewNum], streamTypes[streamViewNum], polledViewNum, streamViewNum, statementContext, streamNames);

            var hook = QueryPlanIndexHookUtil.GetHook(statementContext.Annotations);

            if (queryPlanLogging && (QueryPlanLog.IsInfoEnabled || hook != null))
            {
                QueryPlanLog.Info("historical lookup strategy: " + indexStrategies.First.ToQueryPlan());
                QueryPlanLog.Info("historical index strategy: " + indexStrategies.Second.ToQueryPlan());
                if (hook != null)
                {
                    hook.Historical(new QueryPlanIndexDescHistorical(indexStrategies.First.GetType().Name, indexStrategies.Second.GetType().Name));
                }
            }

            return(new JoinSetComposerPrototypeHistorical2StreamImpl(
                       optionalFilterNode,
                       streamTypes,
                       exprEvaluatorContext,
                       polledViewNum,
                       streamViewNum,
                       isOuterJoin,
                       outerJoinEqualsNode,
                       indexStrategies,
                       isAllHistoricalNoSubordinate,
                       outerJoinDescList,
                       allowIndexInit));
        }