/** * Remove an element from the right digit. * * @param pos position inside the right digit * @return resulting tree */ private FingerTree<N, E> removeRight(final long pos) { if (right.length > 1) { // right digit cannot underflow, just delete the element return new DeepTree<>(left, leftSize, middle, remove(right, pos), size - 1); } // singleton digit might underflow final Node<N, E> node = right[0]; if (!middle.isEmpty()) { // potentially balance with middle tree final InnerNode<N, E> last = (InnerNode<N, E>) middle.last(); final Node<N, E> lastSub = last.getSub(last.arity() - 1); final NodeLike<N, E>[] rem = node.remove(lastSub, null, pos); final Node<N, E> newLastSub = (Node<N, E>) rem[0], newNode = (Node<N, E>) rem[1]; if (newNode == null) { // nodes were merged final Node<N, E>[] newRight = last.children.clone(); newRight[newRight.length - 1] = newLastSub; return new DeepTree<>(left, leftSize, middle.init(), newRight, size - 1); } @SuppressWarnings("unchecked") final Node<N, E>[] newRight = new Node[] {newNode}; // replace last node in middle tree final Node<Node<N, E>, E> newLast = last.replaceLast(newLastSub); return new DeepTree<>(left, leftSize, middle.replaceLast(newLast), newRight, size - 1); } // balance with left digit final Node<N, E> lastLeft = left[left.length - 1]; final NodeLike<N, E>[] rem = node.remove(lastLeft, null, pos); final Node<N, E> newLastLeft = (Node<N, E>) rem[0], newNode = (Node<N, E>) rem[1]; if (newNode == null) { // nodes were merged if (left.length == 1) { // only one node left return new SingletonTree<>(newLastLeft); } @SuppressWarnings("unchecked") final Node<N, E>[] newRight = new Node[] {newLastLeft}; return get(slice(left, 0, left.length - 1), newRight, size - 1); } @SuppressWarnings("unchecked") final Node<N, E>[] newRight = new Node[] {newNode}; if (newLastLeft == lastLeft) { // deletion could be absorbed return get(left, leftSize, newRight, size - 1); } // adapt the left digit final Node<N, E>[] newLeft = left.clone(); newLeft[newLeft.length - 1] = newLastLeft; return get(newLeft, newRight, size - 1); }