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 }; }
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; }
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()); }
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)); }
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))); }
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')); }
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(); }
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; }
public void EmptyIndexer() { DependencyGraph t = new DependencyGraph(); Assert.AreEqual(0, t["a"]); }
public NodeArg(string name, DependencyGraph graph) { _name = name; _graph = graph; }
public void IndexerWithUndefinedString() { DependencyGraph t = new DependencyGraph(); Assert.AreEqual(0, t["A"]); }
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(); }
public void Construct03() { DependencyGraph d1 = new DependencyGraph(null); }
public void Construct01() { DependencyGraph d1 = new DependencyGraph(); Assert.AreEqual(0, d1.Size); }
public void EmptyTest5() { DependencyGraph t = new DependencyGraph(); Assert.IsFalse(t.GetDependees("x").GetEnumerator().MoveNext()); }
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")); }
/// <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)); }
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); }
public void Null1() { DependencyGraph d = new DependencyGraph(); d.AddDependency("a", null); }
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])))); } }
/// <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); }
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])))); } }
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); }
public void NullException1() { DependencyGraph G = new DependencyGraph(); G.AddDependency("a", null); }
public void SimpleNullTest() { DependencyGraph t = new DependencyGraph(); t.AddDependency(null, "hi"); }
public void TestRemove() { DependencyGraph G = new DependencyGraph(); G.RemoveDependency("a", "b"); }
public void EmptyTest1() { DependencyGraph t = new DependencyGraph(); Assert.AreEqual(0, t.Size); }
public void NullException3() { DependencyGraph G = new DependencyGraph(); G.HasDependees(null); }
/// <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); }
public void EmptyTest5() { DependencyGraph t = new DependencyGraph(); t.RemoveDependency("x", "y"); }
public void HasNoDependents() { DependencyGraph t = new DependencyGraph(); Assert.IsFalse(t.HasDependents("a")); }
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); } }
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)); }