Exemple #1
0
  /**
   * Remove an element from the left digit.
   *
   * @param pos position inside the left digit
   * @return resulting tree
   */
  private FingerTree<N, E> removeLeft(final long pos) {
    if (left.length > 1) {
      // left digit cannot underflow, just delete the element
      return new DeepTree<>(remove(left, pos), leftSize - 1, middle, right, size - 1);
    }

    // singleton digit might underflow
    final Node<N, E> node = left[0];

    if (!middle.isEmpty()) {
      // next node for balancing is in middle tree
      final InnerNode<N, E> head = (InnerNode<N, E>) middle.head();
      final Node<N, E> first = head.getSub(0);
      final NodeLike<N, E>[] rem = node.remove(null, first, pos);
      final Node<N, E> newNode = (Node<N, E>) rem[1], newFirst = (Node<N, E>) rem[2];

      if (newNode == null) {
        // nodes were merged
        final Node<N, E>[] newLeft = head.children.clone();
        newLeft[0] = newFirst;
        return get(newLeft, middle.tail(), right, size - 1);
      }

      @SuppressWarnings("unchecked")
      final Node<N, E>[] newLeft = new Node[] {newNode};

      if (newFirst != first) {
        // nodes were balanced
        final FingerTree<Node<N, E>, E> newMid = middle.replaceHead(head.replaceFirst(newFirst));
        return new DeepTree<>(newLeft, newNode.size(), newMid, right, size - 1);
      }

      // no changes to this tree's structure
      return new DeepTree<>(newLeft, newNode.size(), middle, right, size - 1);
    }

    // potentially balance with right digit
    final NodeLike<N, E>[] rem = node.remove(null, right[0], pos);
    final Node<N, E> newNode = (Node<N, E>) rem[1], newFirstRight = (Node<N, E>) rem[2];

    if (newNode == null) {
      // nodes were merged
      if (right.length == 1) return new SingletonTree<>(newFirstRight);
      final int mid = right.length / 2;
      final Node<N, E>[] newLeft = slice(right, 0, mid);
      newLeft[0] = newFirstRight;
      return get(newLeft, middle, slice(right, mid, right.length), size - 1);
    }

    // structure does not change
    @SuppressWarnings("unchecked")
    final Node<N, E>[] newLeft = new Node[] {newNode};

    if (newFirstRight == right[0]) {
      // right digit stays the same
      return new DeepTree<>(newLeft, newLeft[0].size(), middle, right, size - 1);
    }

    // adapt the right digit
    final Node<N, E>[] newRight = right.clone();
    newRight[0] = newFirstRight;
    return new DeepTree<>(newLeft, newNode.size(), middle, newRight, size - 1);
  }