private SplayedEntry Splay()

in src/Proton/Utilities/SplayedDictionary.cs [860:985]


      private SplayedEntry Splay(SplayedEntry root, K key)
      {
         if (root == null || EqualityComparer<K>.Default.Equals(root.Key, key))
         {
            return root;
         }

         SplayedEntry lessThanKeyRoot = null;
         SplayedEntry lessThanKeyNode = null;
         SplayedEntry greaterThanKeyRoot = null;
         SplayedEntry greaterThanKeyNode = null;

         while (true)
         {
            if (Compare(key, root.Key) < 0)
            {
               // Entry must be to the left of the current node so we bring that up
               // and then work from there to see if we can find the key
               if (root.left != null && Compare(key, root.left.Key) < 0)
               {
                  root = RightRotate(root);
               }

               // Is there nowhere else to go, if so we are done.
               if (root.left == null)
               {
                  break;
               }

               // Haven't found it yet but we now know the current element is greater
               // than the element we are looking for so it goes to the right tree.
               if (greaterThanKeyRoot == null)
               {
                  greaterThanKeyRoot = greaterThanKeyNode = root;
               }
               else
               {
                  greaterThanKeyNode.left = root;
                  greaterThanKeyNode.left.parent = greaterThanKeyNode;
                  greaterThanKeyNode = root;
               }

               root = root.left;
               root.parent = null;
            }
            else if (Compare(key, root.Key) > 0)
            {
               // Entry must be to the right of the current node so we bring that up
               // and then work from there to see if we can find the key
               if (root.right != null && Compare(key, root.right.Key) > 0)
               {
                  root = LeftRotate(root);
               }

               // Is there nowhere else to go, if so we are done.
               if (root.right == null)
               {
                  break;
               }

               // Haven't found it yet but we now know the current element is less
               // than the element we are looking for so it goes to the left tree.
               if (lessThanKeyRoot == null)
               {
                  lessThanKeyRoot = lessThanKeyNode = root;
               }
               else
               {
                  lessThanKeyNode.right = root;
                  lessThanKeyNode.right.parent = lessThanKeyNode;
                  lessThanKeyNode = root;
               }

               root = root.right;
               root.parent = null;
            }
            else
            {
               break; // Found it
            }
         }

         // Reassemble the tree from the left, right and middle the assembled nodes in the
         // left and right should have their last element either nulled out or linked to the
         // remaining items middle tree
         if (lessThanKeyRoot == null)
         {
            lessThanKeyRoot = root.left;
         }
         else
         {
            lessThanKeyNode.right = root.left;
            if (lessThanKeyNode.right != null)
            {
               lessThanKeyNode.right.parent = lessThanKeyNode;
            }
         }

         if (greaterThanKeyRoot == null)
         {
            greaterThanKeyRoot = root.right;
         }
         else
         {
            greaterThanKeyNode.left = root.right;
            if (greaterThanKeyNode.left != null)
            {
               greaterThanKeyNode.left.parent = greaterThanKeyNode;
            }
         }

         // The found or last accessed element is now rooted to the splayed
         // left and right trees and returned as the new tree.
         root.left = lessThanKeyRoot;
         if (root.left != null)
         {
            root.left.parent = root;
         }
         root.right = greaterThanKeyRoot;
         if (root.right != null)
         {
            root.right.parent = root;
         }

         return root;
      }