Exemple #1
0
  /**
   * 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);
  }