/// <summary> /// Indicates that this resource is used by the given process /// </summary> /// <param name="process">The process.</param> /// <returns></returns> public void UsedBy(OrderedProcess process) { DependencyGraph.CheckGraph(this, process); if (users.Add(process)) process.Requires(this); }
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 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()); }
internal static void CheckGraph(Resource a, OrderedProcess b) { if (a.Graph != b.Graph) { throw new ArgumentException(string.Format("Resource {0} is not associated with the same graph as process {1}", a, b)); } }
/// <summary> /// Indicates that this resource is used by the given process /// </summary> /// <param name="process">The process.</param> /// <returns></returns> public void UsedBy(OrderedProcess process) { DependencyGraph.CheckGraph(this, process); if (users.Add(process)) { process.Requires(this); } }
/// <summary> /// Indicates that this process should execute before another /// </summary> /// <param name="follower">The ancestor.</param> /// <returns>returns this process</returns> public OrderedProcess Before(OrderedProcess follower) { DependencyGraph.CheckGraph(this, follower); if (_followers.Add(follower)) { follower.After(this); } return(follower); }
/// <summary> /// Indicates that this process should execute after another /// </summary> /// <param name="predecessor">The predecessor.</param> /// <returns>returns this process</returns> public OrderedProcess After(OrderedProcess predecessor) { DependencyGraph.CheckGraph(this, predecessor); if (_predecessors.Add(predecessor)) { predecessor.Before(this); } return(predecessor); }
public bool Equals(OrderedProcess <T> x, OrderedProcess <T> y) { if (x == null && y == null) { return(true); } if (x == null || y == null) { return(false); } return(Comparer.Equals(x.Value, y.Value)); }
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 virtual void TopologicalSort() { this.Log.Trace("Topological sorting..."); var graph = new TopologicalSorting.DependencyGraph(); this.Log.Trace("\tTopological sorting first iteration..."); var hitCounters = new long[7]; foreach (var t in this.Types) { hitCounters[0]++; var parents = this.GetParents(t.Type); var tProcess = graph.Processes.FirstOrDefault(p => p.Name == t.Type.ReflectionName); if (tProcess == null) { hitCounters[1]++; tProcess = new TopologicalSorting.OrderedProcess(graph, t.Type.ReflectionName); } for (int i = parents.Count - 1; i > -1; i--) { hitCounters[2]++; var x = parents[i]; if (tProcess.Predecessors.All(p => p.Name != x.Type.ReflectionName)) { hitCounters[3]++; var dProcess = graph.Processes.FirstOrDefault(p => p.Name == x.Type.ReflectionName); if (dProcess == null) { hitCounters[4]++; dProcess = new TopologicalSorting.OrderedProcess(graph, x.Type.ReflectionName); } //var dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.FullName); if (dProcess.Predecessors.All(p => p.Name != tProcess.Name)) { hitCounters[4]++; tProcess.After(dProcess); } } } } for (int i = 0; i < hitCounters.Length; i++) { this.Log.Trace("\t\tHitCounter" + i + " = " + hitCounters[i]); } this.Log.Trace("\tTopological sorting first iteration done"); /*this.Log.Trace("\tTopological sorting second iteration..."); System.Array.Clear(hitCounters, 0, hitCounters.Length); foreach (var t in this.Types) { hitCounters[0]++; var finder = new DependencyFinderVisitor(this, t); t.TypeDeclaration.AcceptVisitor(finder); var tProcess = graph.Processes.FirstOrDefault(p => p.Name == t.Type.ReflectionName); if (tProcess == null) { hitCounters[1]++; tProcess = new TopologicalSorting.OrderedProcess(graph, t.Type.ReflectionName); } if (finder.Dependencies.Count > 0) { hitCounters[2]++; foreach (var dependency in finder.Dependencies) { hitCounters[3]++; if (tProcess.Predecessors.All(p => p.Name != dependency.Type.ReflectionName)) { hitCounters[4]++; var dProcess = graph.Processes.FirstOrDefault(p => p.Name == dependency.Type.ReflectionName); if (dProcess == null) { hitCounters[5]++; dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.ReflectionName); } //var dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.FullName); if (dProcess.Predecessors.All(p => p.Name != tProcess.Name)) { hitCounters[6]++; tProcess.After(dProcess); } } } } } for (int i = 0; i < hitCounters.Length; i++) { this.Log.Trace("\t\tHitCounter" + i + " = " + hitCounters[i]); } this.Log.Trace("\t\tgraph.ProcessCount = " + graph.ProcessCount); this.Log.Trace("\tTopological sorting second iteration done");*/ if (graph.ProcessCount > 0) { ITypeInfo tInfo = null; try { this.Log.Trace("\tTopological sorting third iteration..."); System.Array.Clear(hitCounters, 0, hitCounters.Length); this.Log.Trace("\t\tCalculate sorting..."); IEnumerable<IEnumerable<OrderedProcess>> sorted = graph.CalculateSort(); this.Log.Trace("\t\tCalculate sorting done"); var list = new List<ITypeInfo>(this.Types.Count); foreach (var processes in sorted) { hitCounters[0]++; foreach (var process in processes) { hitCounters[1]++; tInfo = this.Types.First(ti => ti.Type.ReflectionName == process.Name); if (list.All(t => t.Type.ReflectionName != tInfo.Type.ReflectionName)) { hitCounters[2]++; list.Add(tInfo); } } } this.Types.Clear(); this.Types.AddRange(list); for (int i = 0; i < hitCounters.Length; i++) { this.Log.Trace("\t\tHitCounter" + i + " = " + hitCounters[i]); } this.Log.Trace("\tTopological sorting third iteration done"); } catch (System.Exception ex) { this.LogWarning(string.Format("Topological sort failed {0} with error {1}", tInfo != null ? "at type " + tInfo.Type.ReflectionName : string.Empty, ex)); } } this.Log.Trace("Topological sorting done"); }
public virtual void TopologicalSort() { var graph = new TopologicalSorting.DependencyGraph(); foreach (var t in this.Types) { var finder = new DependencyFinderVisitor(this, t); t.TypeDeclaration.AcceptVisitor(finder); var tProcess = graph.Processes.FirstOrDefault(p => p.Name == t.Type.ReflectionName); if (tProcess == null) { tProcess = new TopologicalSorting.OrderedProcess(graph, t.Type.ReflectionName); } if (finder.Dependencies.Count > 0) { foreach (var dependency in finder.Dependencies) { if (tProcess.Predecessors.All(p => p.Name != dependency.Type.ReflectionName)) { var dProcess = graph.Processes.FirstOrDefault(p => p.Name == dependency.Type.ReflectionName); if (dProcess == null) { dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.ReflectionName); } //var dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.FullName); if (dProcess.Predecessors.All(p => p.Name != tProcess.Name)) { tProcess.After(dProcess); } } } } } if (graph.ProcessCount > 0) { ITypeInfo tInfo = null; try { IEnumerable <IEnumerable <OrderedProcess> > sorted = graph.CalculateSort(); var list = new List <ITypeInfo>(this.Types.Count); foreach (var processes in sorted) { foreach (var process in processes) { tInfo = this.Types.First(ti => ti.Type.ReflectionName == process.Name); if (list.All(t => t.Type.ReflectionName != tInfo.Type.ReflectionName)) { list.Add(tInfo); } } } this.Types.Clear(); this.Types.AddRange(list); } catch (System.Exception ex) { this.LogWarning(string.Format("Topological sort failed {0} with error {1}", tInfo != null ? "at type " + tInfo.Type.ReflectionName : string.Empty, ex)); } } }
public virtual void TopologicalSort() { this.Log.Trace("Topological sorting..."); var graph = new TopologicalSorting.DependencyGraph(); this.Log.Trace("\tTopological sorting first iteration..."); var hitCounters = new long[7]; foreach (var t in this.Types) { hitCounters[0]++; var parents = this.GetParents(t.Type); var tProcess = graph.Processes.FirstOrDefault(p => p.Name == t.Type.ReflectionName); if (tProcess == null) { hitCounters[1]++; tProcess = new TopologicalSorting.OrderedProcess(graph, t.Type.ReflectionName); } for (int i = parents.Count - 1; i > -1; i--) { hitCounters[2]++; var x = parents[i]; if (tProcess.Predecessors.All(p => p.Name != x.Type.ReflectionName)) { hitCounters[3]++; var dProcess = graph.Processes.FirstOrDefault(p => p.Name == x.Type.ReflectionName); if (dProcess == null) { hitCounters[4]++; dProcess = new TopologicalSorting.OrderedProcess(graph, x.Type.ReflectionName); } //var dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.FullName); if (dProcess.Predecessors.All(p => p.Name != tProcess.Name)) { hitCounters[4]++; tProcess.After(dProcess); } } } } for (int i = 0; i < hitCounters.Length; i++) { this.Log.Trace("\t\tHitCounter" + i + " = " + hitCounters[i]); } this.Log.Trace("\tTopological sorting first iteration done"); /*this.Log.Trace("\tTopological sorting second iteration..."); * * System.Array.Clear(hitCounters, 0, hitCounters.Length); * * foreach (var t in this.Types) * { * hitCounters[0]++; * * var finder = new DependencyFinderVisitor(this, t); * t.TypeDeclaration.AcceptVisitor(finder); * * var tProcess = graph.Processes.FirstOrDefault(p => p.Name == t.Type.ReflectionName); * if (tProcess == null) * { * hitCounters[1]++; * tProcess = new TopologicalSorting.OrderedProcess(graph, t.Type.ReflectionName); * } * * if (finder.Dependencies.Count > 0) * { * hitCounters[2]++; * * foreach (var dependency in finder.Dependencies) * { * hitCounters[3]++; * * if (tProcess.Predecessors.All(p => p.Name != dependency.Type.ReflectionName)) * { * hitCounters[4]++; * * var dProcess = graph.Processes.FirstOrDefault(p => p.Name == dependency.Type.ReflectionName); * if (dProcess == null) * { * hitCounters[5]++; * dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.ReflectionName); * } * //var dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.FullName); * * if (dProcess.Predecessors.All(p => p.Name != tProcess.Name)) * { * hitCounters[6]++; * tProcess.After(dProcess); * } * } * } * } * } * * for (int i = 0; i < hitCounters.Length; i++) * { * this.Log.Trace("\t\tHitCounter" + i + " = " + hitCounters[i]); * } * * this.Log.Trace("\t\tgraph.ProcessCount = " + graph.ProcessCount); * * this.Log.Trace("\tTopological sorting second iteration done");*/ if (graph.ProcessCount > 0) { ITypeInfo tInfo = null; try { this.Log.Trace("\tTopological sorting third iteration..."); System.Array.Clear(hitCounters, 0, hitCounters.Length); this.Log.Trace("\t\tCalculate sorting..."); IEnumerable <IEnumerable <OrderedProcess> > sorted = graph.CalculateSort(); this.Log.Trace("\t\tCalculate sorting done"); var list = new List <ITypeInfo>(this.Types.Count); foreach (var processes in sorted) { hitCounters[0]++; foreach (var process in processes) { hitCounters[1]++; tInfo = this.Types.First(ti => ti.Type.ReflectionName == process.Name); if (list.All(t => t.Type.ReflectionName != tInfo.Type.ReflectionName)) { hitCounters[2]++; list.Add(tInfo); } } } this.Types.Clear(); this.Types.AddRange(list); for (int i = 0; i < hitCounters.Length; i++) { this.Log.Trace("\t\tHitCounter" + i + " = " + hitCounters[i]); } this.Log.Trace("\tTopological sorting third iteration done"); } catch (System.Exception ex) { this.LogWarning(string.Format("Topological sort failed {0} with error {1}", tInfo != null ? "at type " + tInfo.Type.ReflectionName : string.Empty, ex)); } } this.Log.Trace("Topological sorting done"); }
protected virtual void SortReferences() { var graph = new TopologicalSorting.DependencyGraph(); foreach (var t in this.References) { var parents = this.GetParentAssemblies(t); var tProcess = graph.Processes.FirstOrDefault(p => p.Name == t.FullName); if (tProcess == null) { tProcess = new TopologicalSorting.OrderedProcess(graph, t.FullName); } for (int i = parents.Count - 1; i > -1; i--) { var x = parents[i]; if (tProcess.Predecessors.All(p => p.Name != x.FullName)) { var dProcess = graph.Processes.FirstOrDefault(p => p.Name == x.FullName); if (dProcess == null) { dProcess = new TopologicalSorting.OrderedProcess(graph, x.FullName); } if (tProcess != dProcess && dProcess.Predecessors.All(p => p.Name != tProcess.Name)) { tProcess.After(dProcess); } } } } if (graph.ProcessCount > 0) { AssemblyDefinition asmDef = null; try { IEnumerable <IEnumerable <OrderedProcess> > sorted = graph.CalculateSort(); var list = new List <AssemblyDefinition>(this.References.Count()); this.Log.Trace("Sorting references..."); foreach (var processes in sorted) { foreach (var process in processes) { this.Log.Trace("\tHandling " + process.Name); asmDef = this.References.First(r => r.FullName == process.Name); if (list.All(r => r.FullName != asmDef.FullName)) { list.Add(asmDef); } } } this.References = list; this.Log.Trace("Sorting references done:"); for (int i = 0; i < list.Count; i++) { this.Log.Trace("\t" + list[i].Name); } } catch (System.Exception ex) { this.Log.Warn(string.Format("Topological sort failed {0} with error {1}", asmDef != null ? "at reference " + asmDef.FullName : string.Empty, ex)); } } activeAssemblies = null; }
internal bool Add(OrderedProcess orderedProcess) { return _processes.Add(orderedProcess); }
public virtual void TopologicalSort() { this.Log.Trace("Topological sorting..."); var graph = new TopologicalSorting.DependencyGraph(); this.Log.Trace("\tTopological sorting first iteration..."); var hitCounters = new long[7]; foreach (var t in this.Types) { hitCounters[0]++; var parents = this.GetParents(t.Type); var reflectionName = GetReflectionName(t.Type); var tProcess = graph.Processes.FirstOrDefault(p => p.Name == reflectionName); if (tProcess == null) { hitCounters[1]++; tProcess = new TopologicalSorting.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 TopologicalSorting.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++) { this.Log.Trace("\t\tHitCounter" + i + " = " + hitCounters[i]); } this.Log.Trace("\tTopological sorting first iteration done"); if (graph.ProcessCount > 0) { ITypeInfo tInfo = null; OrderedProcess handlingProcess = null; try { this.Log.Trace("\tTopological sorting third iteration..."); System.Array.Clear(hitCounters, 0, hitCounters.Length); this.Log.Trace("\t\tCalculate sorting..."); TopologicalSort sorted = graph.CalculateSort(); this.Log.Trace("\t\tCalculate sorting done"); this.Log.Trace("\t\tGetting Reflection names for " + this.Types.Count + " types..."); var list = new List <ITypeInfo>(this.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> >; this.Log.Trace("\t\tGot Enumerable<ISet<OrderedProcess>>"); var sortedISetEnumerator = sortedISetEnumerable.GetEnumerator(); this.Log.Trace("\t\tGot Enumerator<ISet<OrderedProcess>>"); while (sortedISetEnumerator.MoveNext()) { var processes = sortedISetEnumerator.Current; hitCounters[0]++; foreach (var process in processes) { handlingProcess = process; hitCounters[1]++; tInfo = this.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); } } } this.Log.Trace("\t\tGetting Reflection names done"); this.Types.Clear(); this.Types.AddRange(list); for (int i = 0; i < hitCounters.Length; i++) { this.Log.Trace("\t\tHitCounter" + i + " = " + hitCounters[i]); } this.Log.Trace("\tTopological sorting third iteration done"); } catch (System.Exception ex) { this.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; this.Log.Trace("Topological sorting done"); }
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 int GetHashCode(OrderedProcess <T> obj) { return(obj.Value.GetHashCode()); }
/// <summary> /// Indicates that all members of the enumerable must happen before the single follower /// </summary> /// <param name="predecessors">The predecessors.</param> /// <param name="follower">The follower.</param> /// <returns>the followers</returns> public static OrderedProcess <T> Before <T>(this IEnumerable <OrderedProcess <T> > predecessors, OrderedProcess <T> follower) { follower.After(predecessors); return(follower); }
/// <summary> /// Indicates that all the members of the enumerable must happen after the single predecessor /// </summary> /// <param name="followers">The followers.</param> /// <param name="predecessor">The predecessor.</param> /// <returns>the predecessor</returns> public static OrderedProcess <T> After <T>(this IEnumerable <OrderedProcess <T> > followers, OrderedProcess <T> predecessor) { predecessor.Before(followers); return(predecessor); }
/// <summary> /// Indicates that this process should execute after another /// </summary> /// <param name="predecessor">The predecessor.</param> /// <returns>returns this process</returns> public OrderedProcess After(OrderedProcess predecessor) { DependencyGraph.CheckGraph(this, predecessor); if (predecessors.Add(predecessor)) predecessor.Before(this); return predecessor; }
/// <summary> /// Indicates that this process should execute before another /// </summary> /// <param name="follower">The ancestor.</param> /// <returns>returns this process</returns> public OrderedProcess Before(OrderedProcess follower) { DependencyGraph.CheckGraph(this, follower); if (followers.Add(follower)) follower.After(this); return follower; }
public virtual void TopologicalSort() { var graph = new TopologicalSorting.DependencyGraph(); foreach (var t in this.Types) { var finder = new DependencyFinderVisitor(this, t); t.TypeDeclaration.AcceptVisitor(finder); var tProcess = graph.Processes.FirstOrDefault(p => p.Name == t.Type.ReflectionName); if (tProcess == null) { tProcess = new TopologicalSorting.OrderedProcess(graph, t.Type.ReflectionName); } if (finder.Dependencies.Count > 0) { foreach (var dependency in finder.Dependencies) { if (tProcess.Predecessors.All(p => p.Name != dependency.Type.ReflectionName)) { var dProcess = graph.Processes.FirstOrDefault(p => p.Name == dependency.Type.ReflectionName); if (dProcess == null) { dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.ReflectionName); } //var dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.FullName); if (dProcess.Predecessors.All(p => p.Name != tProcess.Name)) { tProcess.After(dProcess); } } } } } foreach (var t in this.Types) { for (int i = this.Types.Count - 1; i > -1; i--) { var x = this.Types[i]; var tProcess = graph.Processes.FirstOrDefault(p => p.Name == t.Type.ReflectionName); if (tProcess == null) { tProcess = new TopologicalSorting.OrderedProcess(graph, t.Type.ReflectionName); } if (this.IsInheritedFrom(t, x)) { if (tProcess.Predecessors.All(p => p.Name != x.Type.ReflectionName)) { var dProcess = graph.Processes.FirstOrDefault(p => p.Name == x.Type.ReflectionName); if (dProcess == null) { dProcess = new TopologicalSorting.OrderedProcess(graph, x.Type.ReflectionName); } //var dProcess = new TopologicalSorting.OrderedProcess(graph, dependency.Type.FullName); if (dProcess.Predecessors.All(p => p.Name != tProcess.Name)) { tProcess.After(dProcess); } } } } } if (graph.ProcessCount > 0) { ITypeInfo tInfo = null; try { IEnumerable<IEnumerable<OrderedProcess>> sorted = graph.CalculateSort(); var list = new List<ITypeInfo>(this.Types.Count); foreach (var processes in sorted) { foreach (var process in processes) { tInfo = this.Types.First(ti => ti.Type.ReflectionName == process.Name); if (list.All(t => t.Type.ReflectionName != tInfo.Type.ReflectionName)) { list.Add(tInfo); } } } this.Types.Clear(); this.Types.AddRange(list); } catch (System.Exception ex) { this.LogWarning(string.Format("Topological sort failed {0} with error {1}", tInfo != null ? "at type " + tInfo.Type.ReflectionName : string.Empty, ex)); } } }
internal bool Add(OrderedProcess orderedProcess) { return(_processes.Add(orderedProcess)); }
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 virtual void TopologicalSort() { this.Log.Trace("Topological sorting..."); var graph = new TopologicalSorting.DependencyGraph(); this.Log.Trace("\tTopological sorting first iteration..."); var hitCounters = new long[7]; foreach (var t in this.Types) { hitCounters[0]++; var parents = this.GetParents(t.Type); var reflectionName = GetReflectionName(t.Type); var tProcess = graph.Processes.FirstOrDefault(p => p.Name == reflectionName); if (tProcess == null) { hitCounters[1]++; tProcess = new TopologicalSorting.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 TopologicalSorting.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++) { this.Log.Trace("\t\tHitCounter" + i + " = " + hitCounters[i]); } this.Log.Trace("\tTopological sorting first iteration done"); if (graph.ProcessCount > 0) { ITypeInfo tInfo = null; try { this.Log.Trace("\tTopological sorting third iteration..."); System.Array.Clear(hitCounters, 0, hitCounters.Length); this.Log.Trace("\t\tCalculate sorting..."); IEnumerable <IEnumerable <OrderedProcess> > sorted = graph.CalculateSort(); this.Log.Trace("\t\tCalculate sorting done"); var list = new List <ITypeInfo>(this.Types.Count); foreach (var processes in sorted) { hitCounters[0]++; foreach (var process in processes) { hitCounters[1]++; tInfo = this.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); } } } this.Types.Clear(); this.Types.AddRange(list); for (int i = 0; i < hitCounters.Length; i++) { this.Log.Trace("\t\tHitCounter" + i + " = " + hitCounters[i]); } this.Log.Trace("\tTopological sorting third iteration done"); } catch (System.Exception ex) { this.LogWarning(string.Format("Topological sort failed {0} with error {1}", tInfo != null ? "at type " + tInfo.Type.ReflectionName : string.Empty, ex)); } } cacheParents = null; activeTypes = null; this.Log.Trace("Topological sorting done"); }
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(); }
internal static void CheckGraph(OrderedProcess a, OrderedProcess b) { if (a.Graph != b.Graph) throw new ArgumentException(string.Format("process {0} is not associated with the same graph as process {1}", a, b)); }
protected virtual void SortReferences() { var graph = new TopologicalSorting.DependencyGraph(); foreach (var t in this.References) { var parents = this.GetParentAssemblies(t); var tProcess = graph.Processes.FirstOrDefault(p => p.Name == t.FullName); if (tProcess == null) { tProcess = new TopologicalSorting.OrderedProcess(graph, t.FullName); } for (int i = parents.Count - 1; i > -1; i--) { var x = parents[i]; if (tProcess.Predecessors.All(p => p.Name != x.FullName)) { var dProcess = graph.Processes.FirstOrDefault(p => p.Name == x.FullName); if (dProcess == null) { dProcess = new TopologicalSorting.OrderedProcess(graph, x.FullName); } if (tProcess != dProcess && dProcess.Predecessors.All(p => p.Name != tProcess.Name)) { tProcess.After(dProcess); } } } } if (graph.ProcessCount > 0) { AssemblyDefinition asmDef = null; try { var list = new List <AssemblyDefinition>(this.References.Count()); this.Log.Trace("Sorting references..."); this.Log.Trace("\t\tCalculate sorting references..."); //IEnumerable<IEnumerable<OrderedProcess>> sorted = graph.CalculateSort(); TopologicalSort sorted = graph.CalculateSort(); this.Log.Trace("\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> >; this.Log.Trace("\t\tGot Enumerable<ISet<OrderedProcess>>"); var sortedISetEnumerator = sortedISetEnumerable.GetEnumerator(); this.Log.Trace("\t\tGot Enumerator<ISet<OrderedProcess>>"); //foreach (var processes in sorted) while (sortedISetEnumerator.MoveNext()) { var processes = sortedISetEnumerator.Current; foreach (var process in processes) { this.Log.Trace("\tHandling " + process.Name); asmDef = this.References.First(r => r.FullName == process.Name); if (list.All(r => r.FullName != asmDef.FullName)) { list.Add(asmDef); } } } this.References = list; this.Log.Trace("Sorting references done:"); for (int i = 0; i < list.Count; i++) { this.Log.Trace("\t" + list[i].Name); } } catch (System.Exception ex) { this.Log.Warn(string.Format("Topological sort failed {0} with error {1}", asmDef != null ? "at reference " + asmDef.FullName : string.Empty, ex)); } } activeAssemblies = null; }