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);
        }
示例#8
0
 internal SortResults CompareLoadOrder(SortedTreeNode <IdType, DataType> a, SortedTreeNode <IdType, DataType> b)
 {
     throw new NotImplementedException();
 }
示例#9
0
        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);
        }
示例#10
0
 public void ClearLinks()
 {
     NodeBefore = null;
     NodeAfter  = null;
 }
示例#11
0
        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);
        }
示例#12
0
 public void ClearLinks()
 {
     Parent     = null;
     LoadBefore = null;
     LoadAfter  = null;
 }