src/Shared/EntityFramework/Core/Common/Utils/Helpers.cs
// <summary>
// Builds a balanced binary tree with the specified nodes as leaves.
// Note that the current elements of <paramref name="nodes" /> MAY be overwritten
// as the leaves are combined to produce the tree.
// </summary>
// <typeparam name="TNode"> The type of each node in the tree </typeparam>
// <param name="nodes"> The leaf nodes to combine into an balanced binary tree </param>
// <param name="combinator"> A function that produces a new node that is the combination of the two specified argument nodes </param>
// <returns> The single node that is the root of the balanced binary tree </returns>
Builds a balanced binary tree with the specified nodes as leaves.
Note that the current elements of  MAY be overwritten
as the leaves are combined to produce the tree.
Builds a balanced binary tree with the specified nodes as leaves . Note that the current elements of MAY be overwritten as the leaves are combined to produce the tree .
internal static TNode BuildBalancedTreeInPlace<TNode>(IList<TNode> nodes, Func<TNode, TNode, TNode> combinator)
        {
            DebugCheck.NotNull(nodes);
            DebugCheck.NotNull(combinator);
            Debug.Assert(nodes.Count > 0, "At least one node is required");
            if (nodes.Count == 1)
            {
                return nodes[0];
            }
            if (nodes.Count == 2)
            {
                return combinator(nodes[0], nodes[1]);
            }
             Build the balanced tree in a bottom-up fashion.
             On each iteration, an even number of nodes are paired off using the
             combinator function, reducing the total number of available leaf nodes
             by half each time. If the number of nodes in an iteration is not even,
             the 'last' node in the set is omitted, then combined with the last pair
             that is produced.
             Nodes are collected from left to right with newly combined nodes overwriting
             nodes from the previous iteration that have already been consumed (as can
             be seen by 'writePos' lagging 'readPos' in the main statement of the loop below).
             When a single available leaf node remains, this node is the root of the
             balanced binary tree and can be returned to the caller.
            var nodesToPair = nodes.Count;
            while (nodesToPair != 1)
            {
                var combineModulo = ((nodesToPair & 0x1) == 1);
                if (combineModulo)
                {
                    nodesToPair--;
                }
                var writePos = 0;
                for (var readPos = 0; readPos < nodesToPair; readPos += 2)
                {
                    nodes[writePos++] = combinator(nodes[readPos], nodes[readPos + 1]);
                }
                if (combineModulo)
                {
                    var updatePos = writePos - 1;
                    nodes[updatePos] = combinator(nodes[updatePos], nodes[nodesToPair]);
                }
                nodesToPair /= 2;
            }
            return nodes[0];
        }
internal static TNode BuildBalancedTreeInPlace < TNode > ( IList < TNode > nodes , Func < TNode , TNode , TNode > combinator ) { DebugCheck . NotNull ( nodes ) ; DebugCheck . NotNull ( combinator ) ; Debug . Assert ( nodes . Count > 0 , " " ) ; if ( nodes . Count == 1 ) { return nodes [ 0 ] ; } if ( nodes . Count == 2 ) { return combinator ( nodes [ 0 ] , nodes [ 1 ] ) ; } var nodesToPair = nodes . Count ; while ( nodesToPair != 1 ) { var combineModulo = ( ( nodesToPair & 0x1 ) == 1 ) ; if ( combineModulo ) { nodesToPair -- ; } var writePos = 0 ; for ( var readPos = 0 ; readPos < nodesToPair ; readPos += 2 ) { nodes [ writePos ++ ] = combinator ( nodes [ readPos ] , nodes [ readPos + 1 ] ) ; } if ( combineModulo ) { var updatePos = writePos - 1 ; nodes [ updatePos ] = combinator ( nodes [ updatePos ] , nodes [ nodesToPair ] ) ; } nodesToPair /= 2 ; } return nodes [ 0 ] ; }
Builds a balanced binary tree with the specified nodes as leaves.
Builds a balanced binary tree with the specified nodes as leaves .
// If only one node is present, return the single node. // For the two-node case, simply combine the two nodes and return the result. // // Build the balanced tree in a bottom-up fashion. // On each iteration, an even number of nodes are paired off using the // combinator function, reducing the total number of available leaf nodes // by half each time. If the number of nodes in an iteration is not even, // the 'last' node in the set is omitted, then combined with the last pair // that is produced. // Nodes are collected from left to right with newly combined nodes overwriting // nodes from the previous iteration that have already been consumed (as can // be seen by 'writePos' lagging 'readPos' in the main statement of the loop below). // When a single available leaf node remains, this node is the root of the // balanced binary tree and can be returned to the caller. //
The single node that is the root of the balanced binary tree
The single node that is the root of the balanced binary tree
nodes
IList<TNode>
The leaf nodes to combine into an balanced binary tree
The leaf nodes to combine into an balanced binary tree
combinator
Func<TNode, TNode, TNode>
A function that produces a new node that is the combination of the two specified argument nodes
A function that produces a new node that is the combination of the two specified argument nodes
typeparam
The type of each node in the tree
The type of each node in the tree