AvalonStudio.TextEditor.Document.TextAnchorTree.FixTreeOnInsert C# (CSharp) Method

FixTreeOnInsert() private method

private FixTreeOnInsert ( TextAnchorNode node ) : void
node TextAnchorNode
return void
		private void FixTreeOnInsert(TextAnchorNode node)
		{
			Debug.Assert(node != null);
			Debug.Assert(node.color == RED);
			Debug.Assert(node.left == null || node.left.color == BLACK);
			Debug.Assert(node.right == null || node.right.color == BLACK);

			var parentNode = node.parent;
			if (parentNode == null)
			{
				// we inserted in the root -> the node must be black
				// since this is a root node, making the node black increments the number of black nodes
				// on all paths by one, so it is still the same for all paths.
				node.color = BLACK;
				return;
			}
			if (parentNode.color == BLACK)
			{
				// if the parent node where we inserted was black, our red node is placed correctly.
				// since we inserted a red node, the number of black nodes on each path is unchanged
				// -> the tree is still balanced
				return;
			}
			// parentNode is red, so there is a conflict here!

			// because the root is black, parentNode is not the root -> there is a grandparent node
			var grandparentNode = parentNode.parent;
			var uncleNode = Sibling(parentNode);
			if (uncleNode != null && uncleNode.color == RED)
			{
				parentNode.color = BLACK;
				uncleNode.color = BLACK;
				grandparentNode.color = RED;
				FixTreeOnInsert(grandparentNode);
				return;
			}
			// now we know: parent is red but uncle is black
			// First rotation:
			if (node == parentNode.right && parentNode == grandparentNode.left)
			{
				RotateLeft(parentNode);
				node = node.left;
			}
			else if (node == parentNode.left && parentNode == grandparentNode.right)
			{
				RotateRight(parentNode);
				node = node.right;
			}
			// because node might have changed, reassign variables:
			parentNode = node.parent;
			grandparentNode = parentNode.parent;

			// Now recolor a bit:
			parentNode.color = BLACK;
			grandparentNode.color = RED;
			// Second rotation:
			if (node == parentNode.left && parentNode == grandparentNode.left)
			{
				RotateRight(grandparentNode);
			}
			else
			{
				// because of the first rotation, this is guaranteed:
				Debug.Assert(node == parentNode.right && parentNode == grandparentNode.right);
				RotateLeft(grandparentNode);
			}
		}