src/Shared/EntityFramework/Core/Mapping/Update/Internal/Graph.cs
// <summary>
// DESTRUCTIVE OPERATION: performing a sort modifies the graph
// Performs topological sort on graph. Nodes with no remaining incoming edges are removed
// in sort order (assumes elements implement IComparable(Of TVertex))
// </summary>
// <returns> true if the sort succeeds; false if it fails and there is a remainder </returns>
DESTRUCTIVE OPERATION: performing a sort modifies the graph
Performs topological sort on graph. Nodes with no remaining incoming edges are removed
in sort order (assumes elements implement IComparable(Of TVertex))
DESTRUCTIVE OPERATION : performing a sort modifies the graph Performs topological sort on graph . Nodes with no remaining incoming edges are removed in sort order ( assumes elements implement IComparable ( Of TVertex ))
internal bool TryTopologicalSort(out IEnumerable<TVertex> orderedVertices, out IEnumerable<TVertex> remainder)
        {
            var rootsPriorityQueue = new SortedSet<TVertex>(Comparer<TVertex>.Default);
            foreach (var vertex in m_vertices)
            {
                int predecessorCount;
                if (!m_predecessorCounts.TryGetValue(vertex, out predecessorCount)
                    || 0 == predecessorCount)
                {
                    rootsPriorityQueue.Add(vertex);
                }
            }
            var result = new TVertex[m_vertices.Count];
            var resultCount = 0;
            while (0 < rootsPriorityQueue.Count)
            {
                var from = rootsPriorityQueue.Min;
                rootsPriorityQueue.Remove(from);
                HashSet<TVertex> toSet;
                if (m_successorMap.TryGetValue(from, out toSet))
                {
                    foreach (var to in toSet)
                    {
                        var predecessorCount = m_predecessorCounts[to] - 1;
                        m_predecessorCounts[to] = predecessorCount;
                        if (predecessorCount == 0)
                        {
                            rootsPriorityQueue.Add(to);
                        }
                    }
                    m_successorMap.Remove(from);
                }
                result[resultCount++] = from;
                m_vertices.Remove(from);
            }
            if (m_vertices.Count == 0)
            {
                orderedVertices = result;
                remainder = Enumerable.Empty<TVertex>();
                return true;
            }
            else
            {
                orderedVertices = result.Take(resultCount);
                remainder = m_vertices;
                return false;
            }
        }
internal bool TryTopologicalSort ( out IEnumerable < TVertex > orderedVertices , out IEnumerable < TVertex > remainder ) { var rootsPriorityQueue = new SortedSet < TVertex > ( Comparer < TVertex > . Default ) ; foreach ( var vertex in m_vertices ) { int predecessorCount ; if ( ! m_predecessorCounts . TryGetValue ( vertex , out predecessorCount ) || 0 == predecessorCount ) { rootsPriorityQueue . Add ( vertex ) ; } } var result = new TVertex [ m_vertices . Count ] ; var resultCount = 0 ; while ( 0 < rootsPriorityQueue . Count ) { var from = rootsPriorityQueue . Min ; rootsPriorityQueue . Remove ( from ) ; HashSet < TVertex > toSet ; if ( m_successorMap . TryGetValue ( from , out toSet ) ) { foreach ( var to in toSet ) { var predecessorCount = m_predecessorCounts [ to ] - 1 ; m_predecessorCounts [ to ] = predecessorCount ; if ( predecessorCount == 0 ) { rootsPriorityQueue . Add ( to ) ; } } m_successorMap . Remove ( from ) ; } result [ resultCount ++ ] = from ; m_vertices . Remove ( from ) ; } if ( m_vertices . Count == 0 ) { orderedVertices = result ; remainder = Enumerable . Empty < TVertex > ( ) ; return true ; } else { orderedVertices = result . Take ( resultCount ) ; remainder = m_vertices ; return false ; } }
DESTRUCTIVE OPERATION: performing a sort modifies the graph
Performs topological sort on graph.
DESTRUCTIVE OPERATION : performing a sort modifies the graph Performs topological sort on graph .
// populate all predecessor-less nodes to root queue // perform sort // get the vertex that is next in line in the secondary ordering // remove all outgoing edges (free all vertices that depend on 'from') // 'to' contains no incoming edges, so it is now a root // remove the entire successor set since it has been emptied // add the freed vertex to the result and remove it from the graph // check that all elements were yielded // all vertices were ordered
true if the sort succeeds; false if it fails and there is a remainder
true if the sort succeeds ; false if it fails and there is a remainder
IEnumerable<TVertex>
out