using System; namespace Ryujinx.Common.Collections { /// /// Tree that provides the ability for O(logN) lookups for keys that exist in the tree, and O(logN) lookups for keys immediately greater than or less than a specified key. /// /// Derived node type public class IntrusiveRedBlackTree : IntrusiveRedBlackTreeImpl where T : IntrusiveRedBlackTreeNode, IComparable { #region Public Methods /// /// Adds a new node into the tree. /// /// Node to be added /// Node to be added under /// is null public void Add(T node, T parent = null) { ArgumentNullException.ThrowIfNull(node); Insert(node, parent); } /// /// Removes a node from the tree. /// /// Note to be removed /// is null public void Remove(T node) { ArgumentNullException.ThrowIfNull(node); if (Delete(node) != null) { Count--; } } /// /// Retrieve the node that is considered equal to the specified node by the comparator. /// /// Node to compare with /// Node that is equal to /// is null public T GetNode(T searchNode) { ArgumentNullException.ThrowIfNull(searchNode); T node = Root; while (node != null) { int cmp = searchNode.CompareTo(node); if (cmp < 0) { node = node.Left; } else if (cmp > 0) { node = node.Right; } else { return node; } } return null; } #endregion #region Private Methods (BST) /// /// Inserts a new node into the tree. /// /// Node to be inserted /// Node to be inserted under private void Insert(T node, T parent = null) { T newNode = parent != null ? InsertWithParent(node, parent) : BSTInsert(node); RestoreBalanceAfterInsertion(newNode); } /// /// Insertion Mechanism for a Binary Search Tree (BST). ///

/// Iterates the tree starting from the root and inserts a new node /// where all children in the left subtree are less than , /// and all children in the right subtree are greater than . ///
/// Node to be inserted /// The inserted Node private T BSTInsert(T newNode) { T parent = null; T node = Root; while (node != null) { parent = node; int cmp = newNode.CompareTo(node); if (cmp < 0) { node = node.Left; } else if (cmp > 0) { node = node.Right; } else { return node; } } newNode.Parent = parent; if (parent == null) { Root = newNode; } else if (newNode.CompareTo(parent) < 0) { parent.Left = newNode; newNode.Successor = parent; if (parent.Predecessor != null) { newNode.Predecessor = parent.Predecessor; parent.Predecessor = newNode; newNode.Predecessor.Successor = newNode; } parent.Predecessor = newNode; } else { parent.Right = newNode; newNode.Predecessor = parent; if (parent.Successor != null) { newNode.Successor = parent.Successor; newNode.Successor.Predecessor = newNode; } parent.Successor = newNode; } Count++; return newNode; } /// /// Insertion Mechanism for a Binary Search Tree (BST). ///

/// Inserts a new node directly under a parent node /// where all children in the left subtree are less than , /// and all children in the right subtree are greater than . ///
/// Node to be inserted /// Node to be inserted under /// The inserted Node private T InsertWithParent(T newNode, T parent) { newNode.Parent = parent; if (newNode.CompareTo(parent) < 0) { parent.Left = newNode; newNode.Successor = parent; if (parent.Predecessor != null) { newNode.Predecessor = parent.Predecessor; parent.Predecessor = newNode; newNode.Predecessor.Successor = newNode; } parent.Predecessor = newNode; } else { parent.Right = newNode; newNode.Predecessor = parent; if (parent.Successor != null) { newNode.Successor = parent.Successor; newNode.Successor.Predecessor = newNode; } parent.Successor = newNode; } Count++; return newNode; } /// /// Removes from the tree, if it exists. /// /// Node to be removed /// The deleted Node private T Delete(T nodeToDelete) { if (nodeToDelete == null) { return null; } T old = nodeToDelete; T child; T parent; bool color; if (LeftOf(nodeToDelete) == null) { child = RightOf(nodeToDelete); } else if (RightOf(nodeToDelete) == null) { child = LeftOf(nodeToDelete); } else { T element = nodeToDelete.Successor; child = RightOf(element); parent = ParentOf(element); color = ColorOf(element); if (child != null) { child.Parent = parent; } if (parent == null) { Root = child; } else if (element == LeftOf(parent)) { parent.Left = child; } else { parent.Right = child; } element.Color = old.Color; element.Left = old.Left; element.Right = old.Right; element.Parent = old.Parent; element.Predecessor = old.Predecessor; if (element.Predecessor != null) element.Predecessor.Successor = element; if (ParentOf(old) == null) { Root = element; } else if (old == LeftOf(ParentOf(old))) { ParentOf(old).Left = element; } else { ParentOf(old).Right = element; } LeftOf(old).Parent = element; if (RightOf(old) != null) { RightOf(old).Parent = element; } if (child != null && color == Black) { RestoreBalanceAfterRemoval(child); } return old; } parent = ParentOf(nodeToDelete); color = ColorOf(nodeToDelete); if (child != null) { child.Parent = parent; } if (parent == null) { Root = child; } else if (nodeToDelete == LeftOf(parent)) { parent.Left = child; } else { parent.Right = child; } if (child != null && color == Black) { RestoreBalanceAfterRemoval(child); } if (old.Successor != null) old.Successor.Predecessor = old.Predecessor; if (old.Predecessor != null) old.Predecessor.Successor = old.Successor; return old; } #endregion } public static class IntrusiveRedBlackTreeExtensions { /// /// Retrieve the node that is considered equal to the key by the comparator. /// /// Tree to search at /// Key of the node to be found /// Node that is equal to public static TNode GetNodeByKey(this IntrusiveRedBlackTree tree, TKey key) where TNode : IntrusiveRedBlackTreeNode, IComparable, IComparable where TKey : struct { TNode node = tree.RootNode; while (node != null) { int cmp = node.CompareTo(key); if (cmp < 0) { node = node.Right; } else if (cmp > 0) { node = node.Left; } else { return node; } } return null; } } }