public void ComplexBranching() { var g = new DependencyGraph <string>(); var a = new OrderedProcess <string>(g, "A"); var b1 = new OrderedProcess <string>(g, "B1"); var b2 = new OrderedProcess <string>(g, "B2"); var c1 = new OrderedProcess <string>(g, "C1"); var c2 = new OrderedProcess <string>(g, "C2"); var c3 = new OrderedProcess <string>(g, "C3"); var c4 = new OrderedProcess <string>(g, "C4"); var d = new OrderedProcess <string>(g, "D"); a.Before(b1, b2).Before(c1, c2, c3, c4).Before(d); IEnumerable <IEnumerable <OrderedProcess <string> > > s = g.CalculateSort(); Assert.Single(s.Skip(0).First()); Assert.Equal(a, s.Skip(0).First().First()); Assert.Equal(2, s.Skip(1).First().Count()); Assert.Contains(b1, s.Skip(1).First()); Assert.Contains(b2, s.Skip(1).First()); Assert.Equal(4, s.Skip(2).First().Count()); Assert.Contains(c1, s.Skip(2).First()); Assert.Contains(c2, s.Skip(2).First()); Assert.Contains(c3, s.Skip(2).First()); Assert.Contains(c4, s.Skip(2).First()); Assert.Single(s.Skip(3).First()); Assert.Equal(d, s.Skip(3).First().First()); }
public void ComplexBranching() { DependencyGraph g = new DependencyGraph(); OrderedProcess a = new OrderedProcess(g, "A"); OrderedProcess b1 = new OrderedProcess(g, "B1"); OrderedProcess b2 = new OrderedProcess(g, "B2"); OrderedProcess c1 = new OrderedProcess(g, "C1"); OrderedProcess c2 = new OrderedProcess(g, "C2"); OrderedProcess c3 = new OrderedProcess(g, "C3"); OrderedProcess c4 = new OrderedProcess(g, "C4"); OrderedProcess d = new OrderedProcess(g, "D"); a.Before(b1, b2).Before(c1, c2, c3, c4).Before(d); IEnumerable <IEnumerable <OrderedProcess> > s = g.CalculateSort(); Assert.AreEqual(1, s.Skip(0).First().Count()); Assert.AreEqual(a, s.Skip(0).First().First()); Assert.AreEqual(2, s.Skip(1).First().Count()); Assert.IsTrue(s.Skip(1).First().Contains(b1)); Assert.IsTrue(s.Skip(1).First().Contains(b2)); Assert.AreEqual(4, s.Skip(2).First().Count()); Assert.IsTrue(s.Skip(2).First().Contains(c1)); Assert.IsTrue(s.Skip(2).First().Contains(c2)); Assert.IsTrue(s.Skip(2).First().Contains(c3)); Assert.IsTrue(s.Skip(2).First().Contains(c4)); Assert.AreEqual(1, s.Skip(3).First().Count()); Assert.AreEqual(d, s.Skip(3).First().First()); }
public void BranchingResourceResolution() { var g = new DependencyGraph <string>(); var a = new OrderedProcess <string>(g, "A"); var b1 = new OrderedProcess <string>(g, "B1"); var b2 = new OrderedProcess <string>(g, "B2"); var c1 = new OrderedProcess <string>(g, "C1"); var c2 = new OrderedProcess <string>(g, "C2"); var c3 = new OrderedProcess <string>(g, "C3"); var c4 = new OrderedProcess <string>(g, "C4"); var d = new OrderedProcess <string>(g, "D"); a.Before(b1, b2).Before(c1, c2, c3, c4).Before(d); var resource = new Resource <string>(g, "Resource<string>"); resource.UsedBy(c1, c3); IEnumerable <IEnumerable <OrderedProcess <string> > > s = g.CalculateSort(); //check that A comes first Assert.Single(s.Skip(0).First()); Assert.Equal(a, s.Skip(0).First().First()); //check that D comes last Assert.Single(s.Skip(4).First()); Assert.Equal(d, s.Skip(4).First().First()); //check that no set contains both c1 and c3 Assert.Equal(0, s.Count(set => set.Contains(c1) && set.Contains(c3))); }
public void BranchingResourceResolution() { DependencyGraph g = new DependencyGraph(); OrderedProcess a = new OrderedProcess(g, "A"); OrderedProcess b1 = new OrderedProcess(g, "B1"); OrderedProcess b2 = new OrderedProcess(g, "B2"); OrderedProcess c1 = new OrderedProcess(g, "C1"); OrderedProcess c2 = new OrderedProcess(g, "C2"); OrderedProcess c3 = new OrderedProcess(g, "C3"); OrderedProcess c4 = new OrderedProcess(g, "C4"); OrderedProcess d = new OrderedProcess(g, "D"); a.Before(b1, b2).Before(c1, c2, c3, c4).Before(d); Resource resource = new Resource(g, "Resource"); resource.UsedBy(c1, c3); IEnumerable <IEnumerable <OrderedProcess> > s = g.CalculateSort(); //check that A comes first Assert.AreEqual(1, s.Skip(0).First().Count()); Assert.AreEqual(a, s.Skip(0).First().First()); //check that D comes last Assert.AreEqual(1, s.Skip(4).First().Count()); Assert.AreEqual(d, s.Skip(4).First().First()); //check that no set contains both c1 and c3 Assert.AreEqual(0, s.Where(set => set.Contains(c1) && set.Contains(c3)).Count()); }
public static string DeclareEmptySchema(Type[] schemaTypes) { var result = new StringBuilder(); var dependentTables = new HashSet <Type>(); var tables = schemaTypes.ToDictionary(k => k, v => GetQTableName(v)); var graph = new DependencyGraph <Type>(); var dependencyCache = new ObjectFactoryCache <Type, OrderedProcess <Type> >(t => new OrderedProcess <Type>(graph, t)); foreach (var tableType in tables.Keys) { var currentProcess = dependencyCache[tableType]; var properties = tableType.GetProperties(BindingFlags); foreach (var prop in properties) { var foreignKey = prop.GetCustomAttribute <ForeignKeyAttribute>(); if (foreignKey != null) { dependentTables.Add(tableType); var foreignProcess = dependencyCache[foreignKey.ForeignType]; currentProcess.After(foreignProcess); } } } // Output tables in dependency order var sortResult = graph.CalculateSort(); foreach (OrderedProcess <Type> process in sortResult) { result.AppendLine(DeclareEmptyTable(process.Value)); } return(result.ToString()); }
public void BasicResourceResolution() { DependencyGraph g = new DependencyGraph(); Resource res = new Resource(g, "resource"); OrderedProcess a = new OrderedProcess(g, "A"); OrderedProcess b = new OrderedProcess(g, "B"); OrderedProcess c = new OrderedProcess(g, "C"); a.Before(b); a.Before(c); b.Requires(res); c.Requires(res); IEnumerable <IEnumerable <OrderedProcess> > s = g.CalculateSort(); Assert.AreEqual(3, s.Count()); Assert.AreEqual(1, s.Skip(0).First().Count()); Assert.AreEqual(a, s.Skip(0).First().First()); Assert.AreEqual(1, s.Skip(1).First().Count()); Assert.IsTrue(s.Skip(1).First().First() == b || s.Skip(1).First().First() == c); Assert.AreEqual(1, s.Skip(0).First().Count()); Assert.IsTrue(s.Skip(2).First().First() == b || s.Skip(2).First().First() == c); Assert.AreNotEqual(s.Skip(1).First().First(), s.Skip(2).First().First()); }
public void BasicResourceResolution2() { DependencyGraph <int> g = new DependencyGraph <int>(); Resource <int> res = new Resource <int>(g, "Resource"); OrderedProcess <int> a = new OrderedProcess <int>(g, 1); OrderedProcess <int> b = new OrderedProcess <int>(g, 2); OrderedProcess <int> c = new OrderedProcess <int>(g, 3); a.Before(b); a.Before(c); b.Requires(res); c.Requires(res); IEnumerable <IEnumerable <OrderedProcess <int> > > s = g.CalculateSort(); Assert.AreEqual(3, s.Count()); Assert.AreEqual(1, s.Skip(0).First().Count()); Assert.AreEqual(a, s.Skip(0).First().First()); Assert.AreEqual(1, s.Skip(1).First().Count()); Assert.IsTrue(s.Skip(1).First().First() == b || s.Skip(1).First().First() == c); Assert.AreEqual(1, s.Skip(0).First().Count()); Assert.IsTrue(s.Skip(2).First().First() == b || s.Skip(2).First().First() == c); Assert.AreNotEqual(s.Skip(1).First().First(), s.Skip(2).First().First()); }
public void BasicResourceResolution() { var g = new DependencyGraph <string>(); var res = new Resource <string>(g, "Resource<string>"); var a = new OrderedProcess <string>(g, "A"); var b = new OrderedProcess <string>(g, "B"); var c = new OrderedProcess <string>(g, "C"); a.Before(b); a.Before(c); b.Requires(res); c.Requires(res); IEnumerable <IEnumerable <OrderedProcess <string> > > s = g.CalculateSort(); Assert.Equal(3, s.Count()); Assert.Single(s.Skip(0).First()); Assert.Equal(a, s.Skip(0).First().First()); Assert.Single(s.Skip(1).First()); Assert.True(s.Skip(1).First().First() == b || s.Skip(1).First().First() == c); Assert.Single(s.Skip(0).First()); Assert.True(s.Skip(2).First().First() == b || s.Skip(2).First().First() == c); Assert.NotEqual(s.Skip(1).First().First(), s.Skip(2).First().First()); }
public void Unorderable() { var g = new DependencyGraph <string>(); var a = new OrderedProcess <string>(g, "A"); var b = new OrderedProcess <string>(g, "B"); a.Before(b); b.Before(a); Assert.Throws <InvalidOperationException>(() => g.CalculateSort()); }
public void Unorderable() { DependencyGraph g = new DependencyGraph(); OrderedProcess a = new OrderedProcess(g, "A"); OrderedProcess b = new OrderedProcess(g, "B"); a.Before(b); b.Before(a); g.CalculateSort(); }
public void Unorderable() { DependencyGraph <string> g = new DependencyGraph <string>(); OrderedProcess <string> a = new OrderedProcess <string>(g, "A"); OrderedProcess <string> b = new OrderedProcess <string>(g, "B"); a.Before(b); b.Before(a); g.CalculateSort(); }
public void BranchingUnorderable() { DependencyGraph <string> g = new DependencyGraph <string>(); OrderedProcess <string> a = new OrderedProcess <string>(g, "A"); OrderedProcess <string> b1 = new OrderedProcess <string>(g, "B1"); OrderedProcess <string> b2 = new OrderedProcess <string>(g, "B2"); OrderedProcess <string> c1 = new OrderedProcess <string>(g, "C1"); OrderedProcess <string> c2 = new OrderedProcess <string>(g, "C2"); OrderedProcess <string> c3 = new OrderedProcess <string>(g, "C3"); OrderedProcess <string> c4 = new OrderedProcess <string>(g, "C4"); OrderedProcess <string> d = new OrderedProcess <string>(g, "D"); a.Before(b1, b2).Before(c1, c2, c3, c4).Before(d).Before(b1); g.CalculateSort(); }
public void BranchingUnorderable() { var g = new DependencyGraph <string>(); var a = new OrderedProcess <string>(g, "A"); var b1 = new OrderedProcess <string>(g, "B1"); var b2 = new OrderedProcess <string>(g, "B2"); var c1 = new OrderedProcess <string>(g, "C1"); var c2 = new OrderedProcess <string>(g, "C2"); var c3 = new OrderedProcess <string>(g, "C3"); var c4 = new OrderedProcess <string>(g, "C4"); var d = new OrderedProcess <string>(g, "D"); a.Before(b1, b2).Before(c1, c2, c3, c4).Before(d).Before(b1); Assert.Throws <InvalidOperationException>(() => g.CalculateSort()); }
public void BranchingUnorderable() { DependencyGraph g = new DependencyGraph(); OrderedProcess a = new OrderedProcess(g, "A"); OrderedProcess b1 = new OrderedProcess(g, "B1"); OrderedProcess b2 = new OrderedProcess(g, "B2"); OrderedProcess c1 = new OrderedProcess(g, "C1"); OrderedProcess c2 = new OrderedProcess(g, "C2"); OrderedProcess c3 = new OrderedProcess(g, "C3"); OrderedProcess c4 = new OrderedProcess(g, "C4"); OrderedProcess d = new OrderedProcess(g, "D"); a.Before(b1, b2).Before(c1, c2, c3, c4).Before(d).Before(b1); g.CalculateSort(); }
public void BasicOrderBefore() { var g = new DependencyGraph <string>(); var a = new OrderedProcess <string>(g, "A"); var b = new OrderedProcess <string>(g, "B"); var c = new OrderedProcess <string>(g, "C"); a.Before(b).Before(c); IEnumerable <IEnumerable <OrderedProcess <string> > > s = g.CalculateSort(); Assert.Single(s.Skip(0).First()); Assert.Equal(a, s.Skip(0).First().First()); Assert.Single(s.Skip(1).First()); Assert.Equal(b, s.Skip(1).First().First()); Assert.Single(s.Skip(2).First()); Assert.Equal(c, s.Skip(2).First().First()); }
public void BasicOrderBefore() { DependencyGraph g = new DependencyGraph(); OrderedProcess a = new OrderedProcess(g, "A"); OrderedProcess b = new OrderedProcess(g, "B"); OrderedProcess c = new OrderedProcess(g, "C"); a.Before(b).Before(c); IEnumerable <IEnumerable <OrderedProcess> > s = g.CalculateSort(); Assert.AreEqual(1, s.Skip(0).First().Count()); Assert.AreEqual(a, s.Skip(0).First().First()); Assert.AreEqual(1, s.Skip(1).First().Count()); Assert.AreEqual(b, s.Skip(1).First().First()); Assert.AreEqual(1, s.Skip(2).First().Count()); Assert.AreEqual(c, s.Skip(2).First().First()); }
public void BasicBranching() { DependencyGraph g = new DependencyGraph(); OrderedProcess a = new OrderedProcess(g, "A"); OrderedProcess b1 = new OrderedProcess(g, "B1"); OrderedProcess b2 = new OrderedProcess(g, "B2"); OrderedProcess c = new OrderedProcess(g, "C"); a.Before(b1, b2).Before(c); IEnumerable <IEnumerable <OrderedProcess> > s = g.CalculateSort(); Assert.AreEqual(1, s.Skip(0).First().Count()); Assert.AreEqual(a, s.Skip(0).First().First()); Assert.AreEqual(2, s.Skip(1).First().Count()); Assert.IsTrue(s.Skip(1).First().Contains(b1)); Assert.IsTrue(s.Skip(1).First().Contains(b2)); Assert.AreEqual(1, s.Skip(2).First().Count()); Assert.AreEqual(c, s.Skip(2).First().First()); }
public void BasicBranching() { var g = new DependencyGraph <string>(); var a = new OrderedProcess <string>(g, "A"); var b1 = new OrderedProcess <string>(g, "B1"); var b2 = new OrderedProcess <string>(g, "B2"); var c = new OrderedProcess <string>(g, "C"); a.Before(b1, b2).Before(c); IEnumerable <IEnumerable <OrderedProcess <string> > > s = g.CalculateSort(); Assert.Single(s.Skip(0).First()); Assert.Equal(a, s.Skip(0).First().First()); Assert.Equal(2, s.Skip(1).First().Count()); Assert.Contains(b1, s.Skip(1).First()); Assert.Contains(b2, s.Skip(1).First()); Assert.Single(s.Skip(2).First()); Assert.Equal(c, s.Skip(2).First().First()); }
public void BasicOrderAfter() { DependencyGraph <string> g = new DependencyGraph <string>(); OrderedProcess <string> a = new OrderedProcess <string>(g, "A"); OrderedProcess <string> b = new OrderedProcess <string>(g, "B"); OrderedProcess <string> c = new OrderedProcess <string>(g, "C"); a.Before(b).Before(c); c.After(b).After(a); IEnumerable <IEnumerable <OrderedProcess <string> > > s = g.CalculateSort(); Assert.AreEqual(1, s.Skip(0).First().Count()); Assert.AreEqual(a, s.Skip(0).First().First()); Assert.AreEqual(1, s.Skip(1).First().Count()); Assert.AreEqual(b, s.Skip(1).First().First()); Assert.AreEqual(1, s.Skip(2).First().Count()); Assert.AreEqual(c, s.Skip(2).First().First()); }
public virtual void TopologicalSort() { using (new Measure(Logger, "Topological Sorting", logLevel: LogLevel.Trace)) { var graph = new DependencyGraph(); Logger.ZLogTrace("\tTopological sorting first iteration..."); var hitCounters = new long[7]; foreach (var t in Types) { hitCounters[0]++; var parents = GetParents(t.Type); var reflectionName = GetReflectionName(t.Type); var tProcess = graph.Processes.FirstOrDefault(p => p.Name == reflectionName); if (tProcess == null) { hitCounters[1]++; tProcess = new OrderedProcess(graph, reflectionName); } for (int i = parents.Count - 1; i > -1; i--) { hitCounters[2]++; var x = parents[i]; reflectionName = GetReflectionName(x.Type); if (tProcess.Predecessors.All(p => p.Name != reflectionName)) { hitCounters[3]++; var dProcess = graph.Processes.FirstOrDefault(p => p.Name == reflectionName); if (dProcess == null) { hitCounters[4]++; dProcess = new OrderedProcess(graph, reflectionName); } if (tProcess != dProcess && dProcess.Predecessors.All(p => p.Name != tProcess.Name)) { hitCounters[4]++; tProcess.After(dProcess); } } } } for (int i = 0; i < hitCounters.Length; i++) { Logger.ZLogTrace("\t\tHitCounter{0} = {1}", i, hitCounters[i]); } Logger.ZLogTrace("\tTopological sorting first iteration done"); if (graph.ProcessCount > 0) { ITypeInfo tInfo = null; OrderedProcess handlingProcess = null; try { Logger.ZLogTrace("\tTopological sorting third iteration..."); System.Array.Clear(hitCounters, 0, hitCounters.Length); Logger.ZLogTrace("\t\tCalculate sorting..."); TopologicalSort sorted = graph.CalculateSort(); Logger.ZLogTrace("\t\tCalculate sorting done"); Logger.ZLogTrace("\t\tGetting Reflection names for {0} types...", Types.Count); var list = new List <ITypeInfo>(Types.Count); // 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>>"); while (sortedISetEnumerator.MoveNext()) { var processes = sortedISetEnumerator.Current; hitCounters[0]++; foreach (var process in processes) { handlingProcess = process; hitCounters[1]++; tInfo = Types.First(ti => GetReflectionName(ti.Type) == process.Name); var reflectionName = GetReflectionName(tInfo.Type); if (list.All(t => GetReflectionName(t.Type) != reflectionName)) { hitCounters[2]++; list.Add(tInfo); } } } Logger.ZLogTrace("\t\tGetting Reflection names done"); Types.Clear(); Types.AddRange(list); for (int i = 0; i < hitCounters.Length; i++) { Logger.ZLogTrace("\t\tHitCounter{0} = {1}", i, hitCounters[i]); } Logger.ZLogTrace("\tTopological sorting third iteration done"); } catch (System.Exception ex) { Logger.LogWarning($"Topological sort failed {(tInfo != null || handlingProcess != null ? "at type " + (tInfo != null ? tInfo.Type.ReflectionName : handlingProcess.Name) : string.Empty)} with error {ex}"); } } cacheParents = null; activeTypes = null; } }
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); } } }