private void LinkRemaining(ref SortedTreeNode <IdType, DataType> root) { foreach (SortedTreeNode <IdType, DataType> node in NodesToSort.Values) { if (!node.IsLinked) { if (root == null) { root = node; } else { root.SetNodeBefore(node); } } } }
private SortedTreeNode <IdType, DataType> LinkNodes() { List <IdType> orderedDependencies = KnownDependencies.ToSortedList(); List <IdType> orderedPreferences = KnownPreferences.ToSortedList(); SortedTreeNode <IdType, DataType> root = null; LinkDependencies(orderedDependencies, ref root); LinkBeforePreferences(orderedPreferences, ref root); LinkAfterPreferences(orderedPreferences, ref root); LinkRemaining(ref root); return(root); }
private void LinkDependencies(List <IdType> orderedDependencies, ref SortedTreeNode <IdType, DataType> root) { foreach (IdType depId in orderedDependencies) { if (NodesToSort.TryGetValue(depId, out SortedTreeNode <IdType, DataType> node)) { ICollection <SortedTreeNode <IdType, DataType> > dependOn = NodesToSort.FindNodes((n) => n.Dependencies.Contains(depId)); foreach (SortedTreeNode <IdType, DataType> item in dependOn) { if (!node.IsLinked) { node.SetNodeBefore(item); root = node; } } } } }
private void LinkBeforePreferences(List <IdType> orderedPreferences, ref SortedTreeNode <IdType, DataType> root) { foreach (IdType depId in orderedPreferences) { if (NodesToSort.TryGetValue(depId, out SortedTreeNode <IdType, DataType> node)) { ICollection <SortedTreeNode <IdType, DataType> > dependOn = NodesToSort.FindNodes((n) => n.LoadBefore.Contains(depId) || node.LoadAfter.Contains(n.Id)); foreach (SortedTreeNode <IdType, DataType> item in dependOn) { if (!node.IsLinked) { node.SetNodeAfter(item); root = node; } } } } }
private void CleanRedundant(GetCollection getCollection, CleanInternal cleanInternal) { Action cleanupActions = null; foreach (SortedTreeNode <IdType, DataType> node in NodesToSort.Values) { IList <IdType> collection = getCollection.Invoke(node); if (collection.Count < 2) { continue; } foreach (IdType d1 in collection) { SortedTreeNode <IdType, DataType> nodeD1 = NodesToSort[d1]; foreach (IdType d2 in collection) { if (d1.Equals(d2)) { continue; } SortedTreeNode <IdType, DataType> nodeD2 = NodesToSort[d2]; if (HasSortPreferenceWith(nodeD1, getCollection, nodeD2)) { // d2 can be removed from entries that already have d1 IdType d3 = d2; cleanupActions += () => CleanupRedundant(d1, getCollection, d3, cleanInternal); } else if (HasSortPreferenceWith(nodeD2, getCollection, nodeD1)) { // d1 can be removed from entries that already have d2 cleanupActions += () => CleanupRedundant(d2, getCollection, d1, cleanInternal); } } } } cleanupActions?.Invoke(); }
private void AddLinkedNodesToList(ref SortedTreeNode <IdType, DataType> node, List <DataType> list) { if (node == null) { return; } if (node.NodeBefore != null) { AddLinkedNodesToList(ref node.NodeBefore, list); } if (node.AllDependenciesPresent(NodesToSort.Keys) && !list.Contains(node.Data)) { list.Add(node.Data); } if (node.NodeAfter != null) { AddLinkedNodesToList(ref node.NodeAfter, list); } }
public List <DataType> GetSortedList() { CleanRedundantDependencies(); CleanRedundantLoadBefore(); CleanRedundantLoadAfter(); SortedTreeNode <IdType, DataType> root = LinkNodes(); if (root != null) { AddUnsortedNodes(ref root); } var sortedList = new List <DataType>(NodesToSort.Count); if (root != null) { AddLinkedNodesToList(ref root, sortedList); } return(sortedList); }
internal SortResults CompareLoadOrder(SortedTreeNode <IdType, DataType> a, SortedTreeNode <IdType, DataType> b) { throw new NotImplementedException(); }
private bool HasSortPreferenceWith(SortedTreeNode <IdType, DataType> a, GetCollection getCollection, SortedTreeNode <IdType, DataType> b) { var collection = getCollection.Invoke(a); if (collection.Count == 0) { return(false); } if (collection.Contains(b.Id)) { return(true); } foreach (IdType aDependency in collection) { var aDep = KnownNodes[aDependency]; if (HasSortPreferenceWith(aDep, getCollection, b)) { return(true); } } return(false); }
public void ClearLinks() { NodeBefore = null; NodeAfter = null; }
public SortResults Sort(SortedTreeNode <IdType, DataType> other, bool testing = false) { SortResults topLevelResult = Tree.CompareLoadOrder(this, other); SortResults midLevelResult = SortResults.NoSortPreference; switch (topLevelResult) { case SortResults.DuplicateId: case SortResults.CircularDependency: case SortResults.CircularLoadOrder: return(topLevelResult); case SortResults.NoSortPreference: if (LoadBefore != null && LoadAfter != null) { SortResults testAfterResult = SortAfter(other, true); SortResults testBeforeResult = SortBefore(other, true); if (testAfterResult > SortResults.NoSortPreference) { return(testAfterResult); } if (testBeforeResult > SortResults.NoSortPreference) { return(testBeforeResult); } midLevelResult = testAfterResult > testBeforeResult ? testAfterResult : testBeforeResult; } else if (LoadBefore == null && LoadAfter != null) { SortResults testAfterResult = SortAfter(other, true); if (testAfterResult > SortResults.NoSortPreference) { return(testAfterResult); } midLevelResult = testAfterResult; } else if (LoadAfter == null && LoadBefore != null) { SortResults testBeforeResult = SortBefore(other, true); if (testBeforeResult > SortResults.NoSortPreference) { return(testBeforeResult); } midLevelResult = testBeforeResult; } if (midLevelResult == SortResults.NoSortPreference) { midLevelResult = SortAfter(other, testing); } break; case SortResults.SortBefore: midLevelResult = SortBefore(other, testing); break; case SortResults.SortAfter: midLevelResult = SortAfter(other, testing); break; default: throw new ArgumentOutOfRangeException(); } if (!testing) { switch (midLevelResult) { case SortResults.SortBefore: NodesAddedBefore++; break; case SortResults.SortAfter: NodesAddedAfter++; break; } } return(midLevelResult); }
public void ClearLinks() { Parent = null; LoadBefore = null; LoadAfter = null; }