Skip to content

Commit

Permalink
Improve SortedSet DeepCopy performance (#56561)
Browse files Browse the repository at this point in the history
* SortedSet recursive deep copy

* Make DeepCopy iterative

* Undo accidental delete
  • Loading branch information
johnthcall authored Oct 12, 2021
1 parent 784687f commit d4e4d33
Showing 1 changed file with 14 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1681,41 +1681,27 @@ public Node DeepClone(int count)
#if DEBUG
Debug.Assert(count == GetCount());
#endif

// Breadth-first traversal to recreate nodes, preorder traversal to replicate nodes.

var originalNodes = new Stack<Node>(2 * Log2(count) + 2);
var newNodes = new Stack<Node>(2 * Log2(count) + 2);
Node newRoot = ShallowClone();

Node? originalCurrent = this;
Node newCurrent = newRoot;
var pendingNodes = new Stack<(Node source, Node target)>(2 * Log2(count) + 2);
pendingNodes.Push((this, newRoot));

while (originalCurrent != null)
while (pendingNodes.TryPop(out var next))
{
originalNodes.Push(originalCurrent);
newNodes.Push(newCurrent);
newCurrent.Left = originalCurrent.Left?.ShallowClone();
originalCurrent = originalCurrent.Left;
newCurrent = newCurrent.Left!;
}
Node clonedNode;

while (originalNodes.Count != 0)
{
originalCurrent = originalNodes.Pop();
newCurrent = newNodes.Pop();

Node? originalRight = originalCurrent.Right;
Node? newRight = originalRight?.ShallowClone();
newCurrent.Right = newRight;
if (next.source.Left is Node left)
{
clonedNode = left.ShallowClone();
next.target.Left = clonedNode;
pendingNodes.Push((left, clonedNode));
}

while (originalRight != null)
if (next.source.Right is Node right)
{
originalNodes.Push(originalRight);
newNodes.Push(newRight!);
newRight!.Left = originalRight.Left?.ShallowClone();
originalRight = originalRight.Left;
newRight = newRight.Left;
clonedNode = right.ShallowClone();
next.target.Right = clonedNode;
pendingNodes.Push((right, clonedNode));
}
}

Expand Down

0 comments on commit d4e4d33

Please sign in to comment.