TreeList.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.collections4.list;

  18. import java.util.AbstractList;
  19. import java.util.ArrayDeque;
  20. import java.util.Collection;
  21. import java.util.ConcurrentModificationException;
  22. import java.util.Deque;
  23. import java.util.Iterator;
  24. import java.util.ListIterator;
  25. import java.util.NoSuchElementException;
  26. import java.util.Objects;

  27. import org.apache.commons.collections4.CollectionUtils;
  28. import org.apache.commons.collections4.OrderedIterator;

  29. /**
  30.  * A {@code List} implementation that is optimized for fast insertions and
  31.  * removals at any index in the list.
  32.  * <p>
  33.  * This list implementation utilises a tree structure internally to ensure that
  34.  * all insertions and removals are O(log n). This provides much faster performance
  35.  * than both an {@code ArrayList} and a {@code LinkedList} where elements
  36.  * are inserted and removed repeatedly from anywhere in the list.
  37.  * </p>
  38.  * <p>
  39.  * The following relative performance statistics are indicative of this class:
  40.  * </p>
  41.  * <pre>
  42.  *              get  add  insert  iterate  remove
  43.  * TreeList       3    5       1       2       1
  44.  * ArrayList      1    1      40       1      40
  45.  * LinkedList  5800    1     350       2     325
  46.  * </pre>
  47.  * <p>
  48.  * {@code ArrayList} is a good general purpose list implementation.
  49.  * It is faster than {@code TreeList} for most operations except inserting
  50.  * and removing in the middle of the list. {@code ArrayList} also uses less
  51.  * memory as {@code TreeList} uses one object per entry.
  52.  * </p>
  53.  * <p>
  54.  * {@code LinkedList} is rarely a good choice of implementation.
  55.  * {@code TreeList} is almost always a good replacement for it, although it
  56.  * does use slightly more memory.
  57.  * </p>
  58.  *
  59.  * @param <E> the type of the elements in the list.
  60.  * @since 3.1
  61.  */
  62. public class TreeList<E> extends AbstractList<E> {
  63. //    add; toArray; iterator; insert; get; indexOf; remove
  64. //    TreeList = 1260;7360;3080;  160;   170;3400;  170;
  65. //   ArrayList =  220;1480;1760; 6870;    50;1540; 7200;
  66. //  LinkedList =  270;7360;3350;55860;290720;2910;55200;

  67.     /**
  68.      * Implements an AVLNode which keeps the offset updated.
  69.      * <p>
  70.      * This node contains the real work.
  71.      * TreeList is just there to implement {@link java.util.List}.
  72.      * The nodes don't know the index of the object they are holding.  They
  73.      * do know however their position relative to their parent node.
  74.      * This allows to calculate the index of a node while traversing the tree.
  75.      * <p>
  76.      * The Faedelung calculation stores a flag for both the left and right child
  77.      * to indicate if they are a child (false) or a link as in linked list (true).
  78.      */
  79.     static class AVLNode<E> {
  80.         /** The left child node or the predecessor if {@link #leftIsPrevious}.*/
  81.         private AVLNode<E> left;
  82.         /** Flag indicating that left reference is not a subtree but the predecessor. */
  83.         private boolean leftIsPrevious;
  84.         /** The right child node or the successor if {@link #rightIsNext}. */
  85.         private AVLNode<E> right;
  86.         /** Flag indicating that right reference is not a subtree but the successor. */
  87.         private boolean rightIsNext;
  88.         /** How many levels of left/right are below this one. */
  89.         private int height;
  90.         /** The relative position, root holds absolute position. */
  91.         private int relativePosition;
  92.         /** The stored element. */
  93.         private E value;

  94.         /**
  95.          * Constructs a new AVL tree from a collection.
  96.          * <p>
  97.          * The collection must be nonempty.
  98.          *
  99.          * @param coll  a nonempty collection
  100.          */
  101.         private AVLNode(final Collection<? extends E> coll) {
  102.             this(coll.iterator(), 0, coll.size() - 1, 0, null, null);
  103.         }

  104.         /**
  105.          * Constructs a new node with a relative position.
  106.          *
  107.          * @param relativePosition  the relative position of the node
  108.          * @param obj  the value for the node
  109.          * @param rightFollower the node with the value following this one
  110.          * @param leftFollower the node with the value leading this one
  111.          */
  112.         private AVLNode(final int relativePosition, final E obj,
  113.                         final AVLNode<E> rightFollower, final AVLNode<E> leftFollower) {
  114.             this.relativePosition = relativePosition;
  115.             value = obj;
  116.             rightIsNext = true;
  117.             leftIsPrevious = true;
  118.             right = rightFollower;
  119.             left = leftFollower;
  120.         }

  121.         /**
  122.          * Constructs a new AVL tree from a collection.
  123.          * <p>
  124.          * This is a recursive helper for {@link #AVLNode(Collection)}. A call
  125.          * to this method will construct the subtree for elements {@code start}
  126.          * through {@code end} of the collection, assuming the iterator
  127.          * {@code e} already points at element {@code start}.
  128.          *
  129.          * @param iterator  an iterator over the collection, which should already point
  130.          *          to the element at index {@code start} within the collection
  131.          * @param start  the index of the first element in the collection that
  132.          *          should be in this subtree
  133.          * @param end  the index of the last element in the collection that
  134.          *          should be in this subtree
  135.          * @param absolutePositionOfParent  absolute position of this node's
  136.          *          parent, or 0 if this node is the root
  137.          * @param prev  the {@code AVLNode} corresponding to element (start - 1)
  138.          *          of the collection, or null if start is 0
  139.          * @param next  the {@code AVLNode} corresponding to element (end + 1)
  140.          *          of the collection, or null if end is the last element of the collection
  141.          */
  142.         private AVLNode(final Iterator<? extends E> iterator, final int start, final int end,
  143.                         final int absolutePositionOfParent, final AVLNode<E> prev, final AVLNode<E> next) {
  144.             final int mid = start + (end - start) / 2;
  145.             if (start < mid) {
  146.                 left = new AVLNode<>(iterator, start, mid - 1, mid, prev, this);
  147.             } else {
  148.                 leftIsPrevious = true;
  149.                 left = prev;
  150.             }
  151.             value = iterator.next();
  152.             relativePosition = mid - absolutePositionOfParent;
  153.             if (mid < end) {
  154.                 right = new AVLNode<>(iterator, mid + 1, end, mid, this, next);
  155.             } else {
  156.                 rightIsNext = true;
  157.                 right = next;
  158.             }
  159.             recalcHeight();
  160.         }

  161.         /**
  162.          * Appends the elements of another tree list to this tree list by efficiently
  163.          * merging the two AVL trees. This operation is destructive to both trees and
  164.          * runs in O(log(m + n)) time.
  165.          *
  166.          * @param otherTree
  167.          *            the root of the AVL tree to merge with this one
  168.          * @param currentSize
  169.          *            the number of elements in this AVL tree
  170.          * @return the root of the new, merged AVL tree
  171.          */
  172.         private AVLNode<E> addAll(AVLNode<E> otherTree, final int currentSize) {
  173.             final AVLNode<E> maxNode = max();
  174.             final AVLNode<E> otherTreeMin = otherTree.min();

  175.             // We need to efficiently merge the two AVL trees while keeping them
  176.             // balanced (or nearly balanced). To do this, we take the shorter
  177.             // tree and combine it with a similar-height subtree of the taller
  178.             // tree. There are two symmetric cases:
  179.             //   * this tree is taller, or
  180.             //   * otherTree is taller.
  181.             if (otherTree.height > height) {
  182.                 // CASE 1: The other tree is taller than this one. We will thus
  183.                 // merge this tree into otherTree.

  184.                 // STEP 1: Remove the maximum element from this tree.
  185.                 final AVLNode<E> leftSubTree = removeMax();

  186.                 // STEP 2: Navigate left from the root of otherTree until we
  187.                 // find a subtree, s, that is no taller than me. (While we are
  188.                 // navigating left, we store the nodes we encounter in a stack
  189.                 // so that we can re-balance them in step 4.)
  190.                 final Deque<AVLNode<E>> sAncestors = new ArrayDeque<>();
  191.                 AVLNode<E> s = otherTree;
  192.                 int sAbsolutePosition = s.relativePosition + currentSize;
  193.                 int sParentAbsolutePosition = 0;
  194.                 while (s != null && s.height > getHeight(leftSubTree)) {
  195.                     sParentAbsolutePosition = sAbsolutePosition;
  196.                     sAncestors.push(s);
  197.                     s = s.left;
  198.                     if (s != null) {
  199.                         sAbsolutePosition += s.relativePosition;
  200.                     }
  201.                 }

  202.                 // STEP 3: Replace s with a newly constructed subtree whose root
  203.                 // is maxNode, whose left subtree is leftSubTree, and whose right
  204.                 // subtree is s.
  205.                 maxNode.setLeft(leftSubTree, null);
  206.                 maxNode.setRight(s, otherTreeMin);
  207.                 if (leftSubTree != null) {
  208.                     leftSubTree.max().setRight(null, maxNode);
  209.                     leftSubTree.relativePosition -= currentSize - 1;
  210.                 }
  211.                 if (s != null) {
  212.                     s.min().setLeft(null, maxNode);
  213.                     s.relativePosition = sAbsolutePosition - currentSize + 1;
  214.                 }
  215.                 maxNode.relativePosition = currentSize - 1 - sParentAbsolutePosition;
  216.                 otherTree.relativePosition += currentSize;

  217.                 // STEP 4: Re-balance the tree and recalculate the heights of s's ancestors.
  218.                 s = maxNode;
  219.                 while (!sAncestors.isEmpty()) {
  220.                     final AVLNode<E> sAncestor = sAncestors.pop();
  221.                     sAncestor.setLeft(s, null);
  222.                     s = sAncestor.balance();
  223.                 }
  224.                 return s;
  225.             }
  226.             otherTree = otherTree.removeMin();

  227.             final Deque<AVLNode<E>> sAncestors = new ArrayDeque<>();
  228.             AVLNode<E> s = this;
  229.             int sAbsolutePosition = s.relativePosition;
  230.             int sParentAbsolutePosition = 0;
  231.             while (s != null && s.height > getHeight(otherTree)) {
  232.                 sParentAbsolutePosition = sAbsolutePosition;
  233.                 sAncestors.push(s);
  234.                 s = s.right;
  235.                 if (s != null) {
  236.                     sAbsolutePosition += s.relativePosition;
  237.                 }
  238.             }

  239.             otherTreeMin.setRight(otherTree, null);
  240.             otherTreeMin.setLeft(s, maxNode);
  241.             if (otherTree != null) {
  242.                 otherTree.min().setLeft(null, otherTreeMin);
  243.                 otherTree.relativePosition++;
  244.             }
  245.             if (s != null) {
  246.                 s.max().setRight(null, otherTreeMin);
  247.                 s.relativePosition = sAbsolutePosition - currentSize;
  248.             }
  249.             otherTreeMin.relativePosition = currentSize - sParentAbsolutePosition;

  250.             s = otherTreeMin;
  251.             while (!sAncestors.isEmpty()) {
  252.                 final AVLNode<E> sAncestor = sAncestors.pop();
  253.                 sAncestor.setRight(s, null);
  254.                 s = sAncestor.balance();
  255.             }
  256.             return s;
  257.         }

  258.         /**
  259.          * Balances according to the AVL algorithm.
  260.          */
  261.         private AVLNode<E> balance() {
  262.             switch (heightRightMinusLeft()) {
  263.             case 1:
  264.             case 0:
  265.             case -1:
  266.                 return this;
  267.             case -2:
  268.                 if (left.heightRightMinusLeft() > 0) {
  269.                     setLeft(left.rotateLeft(), null);
  270.                 }
  271.                 return rotateRight();
  272.             case 2:
  273.                 if (right.heightRightMinusLeft() < 0) {
  274.                     setRight(right.rotateRight(), null);
  275.                 }
  276.                 return rotateLeft();
  277.             default:
  278.                 throw new IllegalStateException("tree inconsistent!");
  279.             }
  280.         }

  281.         /**
  282.          * Gets the element with the given index relative to the
  283.          * offset of the parent of this node.
  284.          */
  285.         AVLNode<E> get(final int index) {
  286.             final int indexRelativeToMe = index - relativePosition;

  287.             if (indexRelativeToMe == 0) {
  288.                 return this;
  289.             }

  290.             final AVLNode<E> nextNode = indexRelativeToMe < 0 ? getLeftSubTree() : getRightSubTree();
  291.             if (nextNode == null) {
  292.                 return null;
  293.             }
  294.             return nextNode.get(indexRelativeToMe);
  295.         }

  296.         /**
  297.          * Gets the height of the node or -1 if the node is null.
  298.          */
  299.         private int getHeight(final AVLNode<E> node) {
  300.             return node == null ? -1 : node.height;
  301.         }

  302.         /**
  303.          * Gets the left node, returning null if it's a faedelung.
  304.          */
  305.         private AVLNode<E> getLeftSubTree() {
  306.             return leftIsPrevious ? null : left;
  307.         }

  308.         /**
  309.          * Gets the relative position.
  310.          */
  311.         private int getOffset(final AVLNode<E> node) {
  312.             if (node == null) {
  313.                 return 0;
  314.             }
  315.             return node.relativePosition;
  316.         }

  317.         /**
  318.          * Gets the right node, returning null if it's a faedelung.
  319.          */
  320.         private AVLNode<E> getRightSubTree() {
  321.             return rightIsNext ? null : right;
  322.         }

  323.         /**
  324.          * Gets the value.
  325.          *
  326.          * @return the value of this node
  327.          */
  328.         E getValue() {
  329.             return value;
  330.         }

  331.         /**
  332.          * Returns the height difference right - left
  333.          */
  334.         private int heightRightMinusLeft() {
  335.             return getHeight(getRightSubTree()) - getHeight(getLeftSubTree());
  336.         }

  337.         /**
  338.          * Finds the index that contains the specified object.
  339.          */
  340.         int indexOf(final Object object, final int index) {
  341.             if (getLeftSubTree() != null) {
  342.                 final int result = left.indexOf(object, index + left.relativePosition);
  343.                 if (result != -1) {
  344.                     return result;
  345.                 }
  346.             }
  347.             if (Objects.equals(value, object)) {
  348.                 return index;
  349.             }
  350.             if (getRightSubTree() != null) {
  351.                 return right.indexOf(object, index + right.relativePosition);
  352.             }
  353.             return -1;
  354.         }

  355.         /**
  356.          * Inserts a node at the position index.
  357.          *
  358.          * @param index is the index of the position relative to the position of
  359.          * the parent node.
  360.          * @param obj is the object to be stored in the position.
  361.          */
  362.         AVLNode<E> insert(final int index, final E obj) {
  363.             final int indexRelativeToMe = index - relativePosition;

  364.             if (indexRelativeToMe <= 0) {
  365.                 return insertOnLeft(indexRelativeToMe, obj);
  366.             }
  367.             return insertOnRight(indexRelativeToMe, obj);
  368.         }

  369.         private AVLNode<E> insertOnLeft(final int indexRelativeToMe, final E obj) {
  370.             if (getLeftSubTree() == null) {
  371.                 setLeft(new AVLNode<>(-1, obj, this, left), null);
  372.             } else {
  373.                 setLeft(left.insert(indexRelativeToMe, obj), null);
  374.             }

  375.             if (relativePosition >= 0) {
  376.                 relativePosition++;
  377.             }
  378.             final AVLNode<E> ret = balance();
  379.             recalcHeight();
  380.             return ret;
  381.         }

  382.         private AVLNode<E> insertOnRight(final int indexRelativeToMe, final E obj) {
  383.             if (getRightSubTree() == null) {
  384.                 setRight(new AVLNode<>(+1, obj, right, this), null);
  385.             } else {
  386.                 setRight(right.insert(indexRelativeToMe, obj), null);
  387.             }
  388.             if (relativePosition < 0) {
  389.                 relativePosition--;
  390.             }
  391.             final AVLNode<E> ret = balance();
  392.             recalcHeight();
  393.             return ret;
  394.         }

  395.         /**
  396.          * Gets the rightmost child of this node.
  397.          *
  398.          * @return the rightmost child (greatest index)
  399.          */
  400.         private AVLNode<E> max() {
  401.             return getRightSubTree() == null ? this : right.max();
  402.         }

  403.         /**
  404.          * Gets the leftmost child of this node.
  405.          *
  406.          * @return the leftmost child (smallest index)
  407.          */
  408.         private AVLNode<E> min() {
  409.             return getLeftSubTree() == null ? this : left.min();
  410.         }

  411.         /**
  412.          * Gets the next node in the list after this one.
  413.          *
  414.          * @return the next node
  415.          */
  416.         AVLNode<E> next() {
  417.             if (rightIsNext || right == null) {
  418.                 return right;
  419.             }
  420.             return right.min();
  421.         }

  422.         /**
  423.          * Gets the node in the list before this one.
  424.          *
  425.          * @return the previous node
  426.          */
  427.         AVLNode<E> previous() {
  428.             if (leftIsPrevious || left == null) {
  429.                 return left;
  430.             }
  431.             return left.max();
  432.         }

  433.         /**
  434.          * Sets the height by calculation.
  435.          */
  436.         private void recalcHeight() {
  437.             height = Math.max(
  438.                 getLeftSubTree() == null ? -1 : getLeftSubTree().height,
  439.                 getRightSubTree() == null ? -1 : getRightSubTree().height) + 1;
  440.         }

  441.         /**
  442.          * Removes the node at a given position.
  443.          *
  444.          * @param index is the index of the element to be removed relative to the position of
  445.          * the parent node of the current node.
  446.          */
  447.         AVLNode<E> remove(final int index) {
  448.             final int indexRelativeToMe = index - relativePosition;

  449.             if (indexRelativeToMe == 0) {
  450.                 return removeSelf();
  451.             }
  452.             if (indexRelativeToMe > 0) {
  453.                 setRight(right.remove(indexRelativeToMe), right.right);
  454.                 if (relativePosition < 0) {
  455.                     relativePosition++;
  456.                 }
  457.             } else {
  458.                 setLeft(left.remove(indexRelativeToMe), left.left);
  459.                 if (relativePosition > 0) {
  460.                     relativePosition--;
  461.                 }
  462.             }
  463.             recalcHeight();
  464.             return balance();
  465.         }

  466.         private AVLNode<E> removeMax() {
  467.             if (getRightSubTree() == null) {
  468.                 return removeSelf();
  469.             }
  470.             setRight(right.removeMax(), right.right);
  471.             if (relativePosition < 0) {
  472.                 relativePosition++;
  473.             }
  474.             recalcHeight();
  475.             return balance();
  476.         }

  477.         private AVLNode<E> removeMin() {
  478.             if (getLeftSubTree() == null) {
  479.                 return removeSelf();
  480.             }
  481.             setLeft(left.removeMin(), left.left);
  482.             if (relativePosition > 0) {
  483.                 relativePosition--;
  484.             }
  485.             recalcHeight();
  486.             return balance();
  487.         }

  488.         /**
  489.          * Removes this node from the tree.
  490.          *
  491.          * @return the node that replaces this one in the parent
  492.          */
  493.         private AVLNode<E> removeSelf() {
  494.             if (getRightSubTree() == null && getLeftSubTree() == null) {
  495.                 return null;
  496.             }
  497.             if (getRightSubTree() == null) {
  498.                 if (relativePosition > 0) {
  499.                     left.relativePosition += relativePosition;
  500.                 }
  501.                 left.max().setRight(null, right);
  502.                 return left;
  503.             }
  504.             if (getLeftSubTree() == null) {
  505.                 right.relativePosition += relativePosition - (relativePosition < 0 ? 0 : 1);
  506.                 right.min().setLeft(null, left);
  507.                 return right;
  508.             }

  509.             if (heightRightMinusLeft() > 0) {
  510.                 // more on the right, so delete from the right
  511.                 final AVLNode<E> rightMin = right.min();
  512.                 value = rightMin.value;
  513.                 if (leftIsPrevious) {
  514.                     left = rightMin.left;
  515.                 }
  516.                 right = right.removeMin();
  517.                 if (relativePosition < 0) {
  518.                     relativePosition++;
  519.                 }
  520.             } else {
  521.                 // more on the left or equal, so delete from the left
  522.                 final AVLNode<E> leftMax = left.max();
  523.                 value = leftMax.value;
  524.                 if (rightIsNext) {
  525.                     right = leftMax.right;
  526.                 }
  527.                 final AVLNode<E> leftPrevious = left.left;
  528.                 left = left.removeMax();
  529.                 if (left == null) {
  530.                     // special case where left that was deleted was a double link
  531.                     // only occurs when height difference is equal
  532.                     left = leftPrevious;
  533.                     leftIsPrevious = true;
  534.                 }
  535.                 if (relativePosition > 0) {
  536.                     relativePosition--;
  537.                 }
  538.             }
  539.             recalcHeight();
  540.             return this;
  541.         }

  542.         private AVLNode<E> rotateLeft() {
  543.             final AVLNode<E> newTop = right; // can't be faedelung!
  544.             final AVLNode<E> movedNode = getRightSubTree().getLeftSubTree();

  545.             final int newTopPosition = relativePosition + getOffset(newTop);
  546.             final int myNewPosition = -newTop.relativePosition;
  547.             final int movedPosition = getOffset(newTop) + getOffset(movedNode);

  548.             setRight(movedNode, newTop);
  549.             newTop.setLeft(this, null);

  550.             setOffset(newTop, newTopPosition);
  551.             setOffset(this, myNewPosition);
  552.             setOffset(movedNode, movedPosition);
  553.             return newTop;
  554.         }

  555.         private AVLNode<E> rotateRight() {
  556.             final AVLNode<E> newTop = left; // can't be faedelung
  557.             final AVLNode<E> movedNode = getLeftSubTree().getRightSubTree();

  558.             final int newTopPosition = relativePosition + getOffset(newTop);
  559.             final int myNewPosition = -newTop.relativePosition;
  560.             final int movedPosition = getOffset(newTop) + getOffset(movedNode);

  561.             setLeft(movedNode, newTop);
  562.             newTop.setRight(this, null);

  563.             setOffset(newTop, newTopPosition);
  564.             setOffset(this, myNewPosition);
  565.             setOffset(movedNode, movedPosition);
  566.             return newTop;
  567.         }

  568.         /**
  569.          * Sets the left field to the node, or the previous node if that is null
  570.          *
  571.          * @param node  the new left subtree node
  572.          * @param previous  the previous node in the linked list
  573.          */
  574.         private void setLeft(final AVLNode<E> node, final AVLNode<E> previous) {
  575.             leftIsPrevious = node == null;
  576.             left = leftIsPrevious ? previous : node;
  577.             recalcHeight();
  578.         }

  579.         /**
  580.          * Sets the relative position.
  581.          */
  582.         private int setOffset(final AVLNode<E> node, final int newOffset) {
  583.             if (node == null) {
  584.                 return 0;
  585.             }
  586.             final int oldOffset = getOffset(node);
  587.             node.relativePosition = newOffset;
  588.             return oldOffset;
  589.         }

  590.         /**
  591.          * Sets the right field to the node, or the next node if that is null
  592.          *
  593.          * @param node  the new left subtree node
  594.          * @param next  the next node in the linked list
  595.          */
  596.         private void setRight(final AVLNode<E> node, final AVLNode<E> next) {
  597.             rightIsNext = node == null;
  598.             right = rightIsNext ? next : node;
  599.             recalcHeight();
  600.         }

  601.         /**
  602.          * Sets the value.
  603.          *
  604.          * @param obj  the value to store
  605.          */
  606.         void setValue(final E obj) {
  607.             this.value = obj;
  608.         }

  609.         /**
  610.          * Stores the node and its children into the array specified.
  611.          *
  612.          * @param array the array to be filled
  613.          * @param index the index of this node
  614.          */
  615.         void toArray(final Object[] array, final int index) {
  616.             array[index] = value;
  617.             if (getLeftSubTree() != null) {
  618.                 left.toArray(array, index + left.relativePosition);
  619.             }
  620.             if (getRightSubTree() != null) {
  621.                 right.toArray(array, index + right.relativePosition);
  622.             }
  623.         }

  624. //      private void checkFaedelung() {
  625. //          AVLNode maxNode = left.max();
  626. //          if (!maxNode.rightIsFaedelung || maxNode.right != this) {
  627. //              throw new RuntimeException(maxNode + " should right-faedel to " + this);
  628. //          }
  629. //          AVLNode minNode = right.min();
  630. //          if (!minNode.leftIsFaedelung || minNode.left != this) {
  631. //              throw new RuntimeException(maxNode + " should left-faedel to " + this);
  632. //          }
  633. //      }
  634. //
  635. //        private int checkTreeDepth() {
  636. //            int hright = (getRightSubTree() == null ? -1 : getRightSubTree().checkTreeDepth());
  637. //            //          System.out.print("checkTreeDepth");
  638. //            //          System.out.print(this);
  639. //            //          System.out.print(" left: ");
  640. //            //          System.out.print(_left);
  641. //            //          System.out.print(" right: ");
  642. //            //          System.out.println(_right);
  643. //
  644. //            int hleft = (left == null ? -1 : left.checkTreeDepth());
  645. //            if (height != Math.max(hright, hleft) + 1) {
  646. //                throw new RuntimeException(
  647. //                    "height should be max" + hleft + "," + hright + " but is " + height);
  648. //            }
  649. //            return height;
  650. //        }
  651. //
  652. //        private int checkLeftSubNode() {
  653. //            if (getLeftSubTree() == null) {
  654. //                return 0;
  655. //            }
  656. //            int count = 1 + left.checkRightSubNode();
  657. //            if (left.relativePosition != -count) {
  658. //                throw new RuntimeException();
  659. //            }
  660. //            return count + left.checkLeftSubNode();
  661. //        }
  662. //
  663. //        private int checkRightSubNode() {
  664. //            AVLNode right = getRightSubTree();
  665. //            if (right == null) {
  666. //                return 0;
  667. //            }
  668. //            int count = 1;
  669. //            count += right.checkLeftSubNode();
  670. //            if (right.relativePosition != count) {
  671. //                throw new RuntimeException();
  672. //            }
  673. //            return count + right.checkRightSubNode();
  674. //        }

  675.         /**
  676.          * Used for debugging.
  677.          */
  678.         @Override
  679.         public String toString() {
  680.             return new StringBuilder()
  681.                 .append("AVLNode(")
  682.                 .append(relativePosition)
  683.                 .append(CollectionUtils.COMMA)
  684.                 .append(left != null)
  685.                 .append(CollectionUtils.COMMA)
  686.                 .append(value)
  687.                 .append(CollectionUtils.COMMA)
  688.                 .append(getRightSubTree() != null)
  689.                 .append(rightIsNext)
  690.                 .append(")")
  691.                 .toString();
  692.         }
  693.     }

  694.     /**
  695.      * A list iterator over the linked list.
  696.      */
  697.     static class TreeListIterator<E> implements ListIterator<E>, OrderedIterator<E> {
  698.         /** The parent list */
  699.         private final TreeList<E> parent;
  700.         /**
  701.          * Cache of the next node that will be returned by {@link #next()}.
  702.          */
  703.         private AVLNode<E> next;
  704.         /**
  705.          * The index of the next node to be returned.
  706.          */
  707.         private int nextIndex;
  708.         /**
  709.          * Cache of the last node that was returned by {@link #next()}
  710.          * or {@link #previous()}.
  711.          */
  712.         private AVLNode<E> current;
  713.         /**
  714.          * The index of the last node that was returned.
  715.          */
  716.         private int currentIndex;
  717.         /**
  718.          * The modification count that the list is expected to have. If the list
  719.          * doesn't have this count, then a
  720.          * {@link java.util.ConcurrentModificationException} may be thrown by
  721.          * the operations.
  722.          */
  723.         private int expectedModCount;

  724.         /**
  725.          * Create a ListIterator for a list.
  726.          *
  727.          * @param parent  the parent list
  728.          * @param fromIndex  the index to start at
  729.          */
  730.         protected TreeListIterator(final TreeList<E> parent, final int fromIndex) {
  731.             this.parent = parent;
  732.             this.expectedModCount = parent.modCount;
  733.             this.next = parent.root == null ? null : parent.root.get(fromIndex);
  734.             this.nextIndex = fromIndex;
  735.             this.currentIndex = -1;
  736.         }

  737.         @Override
  738.         public void add(final E obj) {
  739.             checkModCount();
  740.             parent.add(nextIndex, obj);
  741.             current = null;
  742.             currentIndex = -1;
  743.             nextIndex++;
  744.             expectedModCount++;
  745.         }

  746.         /**
  747.          * Checks the modification count of the list is the value that this
  748.          * object expects.
  749.          *
  750.          * @throws ConcurrentModificationException If the list's modification
  751.          * count isn't the value that was expected.
  752.          */
  753.         protected void checkModCount() {
  754.             if (parent.modCount != expectedModCount) {
  755.                 throw new ConcurrentModificationException();
  756.             }
  757.         }

  758.         @Override
  759.         public boolean hasNext() {
  760.             return nextIndex < parent.size();
  761.         }

  762.         @Override
  763.         public boolean hasPrevious() {
  764.             return nextIndex > 0;
  765.         }

  766.         @Override
  767.         public E next() {
  768.             checkModCount();
  769.             if (!hasNext()) {
  770.                 throw new NoSuchElementException("No element at index " + nextIndex + ".");
  771.             }
  772.             if (next == null) {
  773.                 next = parent.root.get(nextIndex);
  774.             }
  775.             final E value = next.getValue();
  776.             current = next;
  777.             currentIndex = nextIndex++;
  778.             next = next.next();
  779.             return value;
  780.         }

  781.         @Override
  782.         public int nextIndex() {
  783.             return nextIndex;
  784.         }

  785.         @Override
  786.         public E previous() {
  787.             checkModCount();
  788.             if (!hasPrevious()) {
  789.                 throw new NoSuchElementException("Already at start of list.");
  790.             }
  791.             if (next == null) {
  792.                 next = parent.root.get(nextIndex - 1);
  793.             } else {
  794.                 next = next.previous();
  795.             }
  796.             final E value = next.getValue();
  797.             current = next;
  798.             currentIndex = --nextIndex;
  799.             return value;
  800.         }

  801.         @Override
  802.         public int previousIndex() {
  803.             return nextIndex() - 1;
  804.         }

  805.         @Override
  806.         public void remove() {
  807.             checkModCount();
  808.             if (currentIndex == -1) {
  809.                 throw new IllegalStateException();
  810.             }
  811.             parent.remove(currentIndex);
  812.             if (nextIndex != currentIndex) {
  813.                 // remove() following next()
  814.                 nextIndex--;
  815.             }
  816.             // the AVL node referenced by next may have become stale after a remove
  817.             // reset it now: will be retrieved by next call to next()/previous() via nextIndex
  818.             next = null;
  819.             current = null;
  820.             currentIndex = -1;
  821.             expectedModCount++;
  822.         }

  823.         @Override
  824.         public void set(final E obj) {
  825.             checkModCount();
  826.             if (current == null) {
  827.                 throw new IllegalStateException();
  828.             }
  829.             current.setValue(obj);
  830.         }
  831.     }

  832.     /** The root node in the AVL tree */
  833.     private AVLNode<E> root;

  834.     /** The current size of the list */
  835.     private int size;

  836.     /**
  837.      * Constructs a new empty list.
  838.      */
  839.     public TreeList() {
  840.     }

  841.     /**
  842.      * Constructs a new empty list that copies the specified collection.
  843.      *
  844.      * @param coll  the collection to copy
  845.      * @throws NullPointerException if the collection is null
  846.      */
  847.     public TreeList(final Collection<? extends E> coll) {
  848.         if (!coll.isEmpty()) {
  849.             root = new AVLNode<>(coll);
  850.             size = coll.size();
  851.         }
  852.     }

  853.     /**
  854.      * Adds a new element to the list.
  855.      *
  856.      * @param index  the index to add before
  857.      * @param obj  the element to add
  858.      */
  859.     @Override
  860.     public void add(final int index, final E obj) {
  861.         modCount++;
  862.         checkInterval(index, 0, size());
  863.         if (root == null) {
  864.             root = new AVLNode<>(index, obj, null, null);
  865.         } else {
  866.             root = root.insert(index, obj);
  867.         }
  868.         size++;
  869.     }

  870.     /**
  871.      * Appends all the elements in the specified collection to the end of this list,
  872.      * in the order that they are returned by the specified collection's Iterator.
  873.      * <p>
  874.      * This method runs in O(n + log m) time, where m is
  875.      * the size of this list and n is the size of {@code c}.
  876.      *
  877.      * @param c  the collection to be added to this list
  878.      * @return {@code true} if this list changed as a result of the call
  879.      * @throws NullPointerException if the specified collection contains a
  880.      *         null element and this collection does not permit null elements,
  881.      *         or if the specified collection is null
  882.      */
  883.     @Override
  884.     public boolean addAll(final Collection<? extends E> c) {
  885.         if (c.isEmpty()) {
  886.             return false;
  887.         }
  888.         modCount += c.size();
  889.         final AVLNode<E> cTree = new AVLNode<>(c);
  890.         root = root == null ? cTree : root.addAll(cTree, size);
  891.         size += c.size();
  892.         return true;
  893.     }

  894.     /**
  895.      * Checks whether the index is valid.
  896.      *
  897.      * @param index  the index to check
  898.      * @param startIndex  the first allowed index
  899.      * @param endIndex  the last allowed index
  900.      * @throws IndexOutOfBoundsException if the index is invalid
  901.      */
  902.     private void checkInterval(final int index, final int startIndex, final int endIndex) {
  903.         if (index < startIndex || index > endIndex) {
  904.             throw new IndexOutOfBoundsException("Invalid index:" + index + ", size=" + size());
  905.         }
  906.     }

  907.     /**
  908.      * Clears the list, removing all entries.
  909.      */
  910.     @Override
  911.     public void clear() {
  912.         modCount++;
  913.         root = null;
  914.         size = 0;
  915.     }

  916.     /**
  917.      * Searches for the presence of an object in the list.
  918.      *
  919.      * @param object  the object to check
  920.      * @return true if the object is found
  921.      */
  922.     @Override
  923.     public boolean contains(final Object object) {
  924.         return indexOf(object) >= 0;
  925.     }

  926.     /**
  927.      * Gets the element at the specified index.
  928.      *
  929.      * @param index  the index to retrieve
  930.      * @return the element at the specified index
  931.      */
  932.     @Override
  933.     public E get(final int index) {
  934.         checkInterval(index, 0, size() - 1);
  935.         return root.get(index).getValue();
  936.     }

  937.     /**
  938.      * Searches for the index of an object in the list.
  939.      *
  940.      * @param object  the object to search
  941.      * @return the index of the object, -1 if not found
  942.      */
  943.     @Override
  944.     public int indexOf(final Object object) {
  945.         // override to go 75% faster
  946.         if (root == null) {
  947.             return -1;
  948.         }
  949.         return root.indexOf(object, root.relativePosition);
  950.     }

  951.     /**
  952.      * Gets an iterator over the list.
  953.      *
  954.      * @return an iterator over the list
  955.      */
  956.     @Override
  957.     public Iterator<E> iterator() {
  958.         // override to go 75% faster
  959.         return listIterator(0);
  960.     }

  961.     /**
  962.      * Gets a ListIterator over the list.
  963.      *
  964.      * @return the new iterator
  965.      */
  966.     @Override
  967.     public ListIterator<E> listIterator() {
  968.         // override to go 75% faster
  969.         return listIterator(0);
  970.     }

  971.     /**
  972.      * Gets a ListIterator over the list.
  973.      *
  974.      * @param fromIndex  the index to start from
  975.      * @return the new iterator
  976.      */
  977.     @Override
  978.     public ListIterator<E> listIterator(final int fromIndex) {
  979.         // override to go 75% faster
  980.         // cannot use EmptyIterator as iterator.add() must work
  981.         checkInterval(fromIndex, 0, size());
  982.         return new TreeListIterator<>(this, fromIndex);
  983.     }

  984.     /**
  985.      * Removes the element at the specified index.
  986.      *
  987.      * @param index  the index to remove
  988.      * @return the previous object at that index
  989.      */
  990.     @Override
  991.     public E remove(final int index) {
  992.         modCount++;
  993.         checkInterval(index, 0, size() - 1);
  994.         final E result = get(index);
  995.         root = root.remove(index);
  996.         size--;
  997.         return result;
  998.     }

  999.     /**
  1000.      * Sets the element at the specified index.
  1001.      *
  1002.      * @param index  the index to set
  1003.      * @param obj  the object to store at the specified index
  1004.      * @return the previous object at that index
  1005.      * @throws IndexOutOfBoundsException if the index is invalid
  1006.      */
  1007.     @Override
  1008.     public E set(final int index, final E obj) {
  1009.         checkInterval(index, 0, size() - 1);
  1010.         final AVLNode<E> node = root.get(index);
  1011.         final E result = node.value;
  1012.         node.setValue(obj);
  1013.         return result;
  1014.     }

  1015.     /**
  1016.      * Gets the current size of the list.
  1017.      *
  1018.      * @return the current size
  1019.      */
  1020.     @Override
  1021.     public int size() {
  1022.         return size;
  1023.     }

  1024.     /**
  1025.      * Converts the list into an array.
  1026.      *
  1027.      * @return the list as an array
  1028.      */
  1029.     @Override
  1030.     public Object[] toArray() {
  1031.         // override to go 20% faster
  1032.         final Object[] array = new Object[size()];
  1033.         if (root != null) {
  1034.             root.toArray(array, root.relativePosition);
  1035.         }
  1036.         return array;
  1037.     }

  1038. }