static <K> TreeNode<K> rotateLeft(TreeNode<K> root, TreeNode<K> p) {
      TreeNode<K> r, pp, rl;
      if (p != null && (r = p.right) != null) {
        if ((rl = p.right = r.left) != null) {
          rl.parent = p;
        }
        if ((pp = r.parent = p.parent) == null) {
          (root = r).red = false;
        } else if (pp.left == p) {
          pp.left = r;
        } else {
          pp.right = r;
        }
        r.left = p;
        p.parent = r;
      }
      return root;
    }
Removes the given node, that must be present before this call. This is messier than typical
red-black deletion code because we cannot swap the contents of an interior node with a leaf
successor that is pinned by "next" pointers that are accessible independently of lock. So
instead we swap the tree linkages.

@return true if now too small, so should be untreeified
geode-core/src/main/java/org/apache/geode/internal/concurrent/CompactConcurrentHashSet2.java