Example #1
0
 @CanIgnoreReturnValue
 @Override
 public int remove(@Nullable Object element, int occurrences) {
   checkNonnegative(occurrences, "occurrences");
   if (occurrences == 0) {
     return count(element);
   }
   AvlNode<E> root = rootReference.get();
   int[] result = new int[1]; // used as a mutable int reference to hold result
   AvlNode<E> newRoot;
   try {
     @SuppressWarnings("unchecked")
     E e = (E) element;
     if (!range.contains(e) || root == null) {
       return 0;
     }
     newRoot = root.remove(comparator(), e, occurrences, result);
   } catch (ClassCastException e) {
     return 0;
   } catch (NullPointerException e) {
     return 0;
   }
   rootReference.checkAndSet(root, newRoot);
   return result[0];
 }
Example #2
0
 /**
  * Rotate binary tree node with right child. For AVL trees, this is a single rotation for case 4.
  * Update heights, then return new root.
  */
 private static AvlNode rotateWithRightChild(AvlNode k1) {
   AvlNode k2 = k1.right;
   k1.right = k2.left;
   k2.left = k1;
   k1.height = max(height(k1.left), height(k1.right)) + 1;
   k2.height = max(height(k2.right), k1.height) + 1;
   return k2;
 }
Example #3
0
 private AvlNode<T> rotateWithRightChild(AvlNode<T> k2) {
   AvlNode<T> k1 = k2.right;
   k2.right = k1.left;
   k1.left = k2;
   k2.height = Math.max(height(k2.left), height(k2.right)) + 1;
   k1.height = Math.max(k2.height, height(k1.right)) + 1;
   return k1;
 }
Example #4
0
 public int count(Comparator<? super E> comparator, E e) {
   int cmp = comparator.compare(e, elem);
   if (cmp < 0) {
     return (left == null) ? 0 : left.count(comparator, e);
   } else if (cmp > 0) {
     return (right == null) ? 0 : right.count(comparator, e);
   } else {
     return elemCount;
   }
 }
Example #5
0
 private AvlNode<E> rotateRight() {
   checkState(left != null);
   AvlNode<E> newTop = left;
   this.left = newTop.right;
   newTop.right = this;
   newTop.totalCount = this.totalCount;
   newTop.distinctElements = this.distinctElements;
   this.recompute();
   newTop.recomputeHeight();
   return newTop;
 }
Example #6
0
 @Nullable
 private AvlNode<E> floor(Comparator<? super E> comparator, E e) {
   int cmp = comparator.compare(e, elem);
   if (cmp > 0) {
     return (right == null) ? this : MoreObjects.firstNonNull(right.floor(comparator, e), this);
   } else if (cmp == 0) {
     return this;
   } else {
     return (left == null) ? null : left.floor(comparator, e);
   }
 }
Example #7
0
    AvlNode<E> remove(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
      int cmp = comparator.compare(e, elem);
      if (cmp < 0) {
        AvlNode<E> initLeft = left;
        if (initLeft == null) {
          result[0] = 0;
          return this;
        }

        left = initLeft.remove(comparator, e, count, result);

        if (result[0] > 0) {
          if (count >= result[0]) {
            this.distinctElements--;
            this.totalCount -= result[0];
          } else {
            this.totalCount -= count;
          }
        }
        return (result[0] == 0) ? this : rebalance();
      } else if (cmp > 0) {
        AvlNode<E> initRight = right;
        if (initRight == null) {
          result[0] = 0;
          return this;
        }

        right = initRight.remove(comparator, e, count, result);

        if (result[0] > 0) {
          if (count >= result[0]) {
            this.distinctElements--;
            this.totalCount -= result[0];
          } else {
            this.totalCount -= count;
          }
        }
        return rebalance();
      }

      // removing count from me!
      result[0] = elemCount;
      if (count >= elemCount) {
        return deleteMe();
      } else {
        this.elemCount -= count;
        this.totalCount -= count;
        return this;
      }
    }
Example #8
0
 @Override
 public int count(@Nullable Object element) {
   try {
     @SuppressWarnings("unchecked")
     E e = (E) element;
     AvlNode<E> root = rootReference.get();
     if (!range.contains(e) || root == null) {
       return 0;
     }
     return root.count(comparator(), e);
   } catch (ClassCastException e) {
     return 0;
   } catch (NullPointerException e) {
     return 0;
   }
 }
Example #9
0
 /**
  * Internal method to insert into a subtree.
  *
  * @param x the item to insert.
  * @param t the node that roots the tree.
  * @return the new root.
  */
 private AvlNode insert(Comparable x, AvlNode t) {
   if (t == null) t = new AvlNode(x, null, null);
   else if (x.compareTo(t.element) < 0) {
     t.left = insert(x, t.left);
     if (height(t.left) - height(t.right) == 2)
       if (x.compareTo(t.left.element) < 0) t = rotateWithLeftChild(t);
       else t = doubleWithLeftChild(t);
   } else if (x.compareTo(t.element) > 0) {
     t.right = insert(x, t.right);
     if (height(t.right) - height(t.left) == 2)
       if (x.compareTo(t.right.element) > 0) t = rotateWithRightChild(t);
       else t = doubleWithRightChild(t);
   } else ; // Duplicate; do nothing
   t.height = max(height(t.left), height(t.right)) + 1;
   return t;
 }
Example #10
0
    AvlNode<E> setCount(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
      int cmp = comparator.compare(e, elem);
      if (cmp < 0) {
        AvlNode<E> initLeft = left;
        if (initLeft == null) {
          result[0] = 0;
          return (count > 0) ? addLeftChild(e, count) : this;
        }

        left = initLeft.setCount(comparator, e, count, result);

        if (count == 0 && result[0] != 0) {
          this.distinctElements--;
        } else if (count > 0 && result[0] == 0) {
          this.distinctElements++;
        }

        this.totalCount += count - result[0];
        return rebalance();
      } else if (cmp > 0) {
        AvlNode<E> initRight = right;
        if (initRight == null) {
          result[0] = 0;
          return (count > 0) ? addRightChild(e, count) : this;
        }

        right = initRight.setCount(comparator, e, count, result);

        if (count == 0 && result[0] != 0) {
          this.distinctElements--;
        } else if (count > 0 && result[0] == 0) {
          this.distinctElements++;
        }

        this.totalCount += count - result[0];
        return rebalance();
      }

      // setting my count
      result[0] = elemCount;
      if (count == 0) {
        return deleteMe();
      }
      this.totalCount += count - elemCount;
      this.elemCount = count;
      return this;
    }
Example #11
0
 public AvlNode<T> insert(T x, AvlNode<T> t) {
   if (t == null) return new AvlNode<>(x, null, null);
   int compareResult = compare(x, t.element);
   if (compareResult < 0) {
     t.left = insert(x, t.left);
     if (height(t.left) - height(t.right) == 2)
       if (compare(x, t.left.element) < 0) t = rotateWithLeftChild(t);
       else t = doubleWithLeftChild(t);
   } else if (compareResult > 0) {
     t.right = insert(x, t.right);
     if (height(t.right) - height(t.left) == 2)
       if (compare(x, t.right.element) > 0) t = rotateWithRightChild(t);
       else t = doubleWithRightChild(t);
   } else ;
   t.height = Math.max(height(t.left), height(t.right)) + 1;
   return t;
 }
Example #12
0
 private AvlNode<E> rebalance() {
   switch (balanceFactor()) {
     case -2:
       if (right.balanceFactor() > 0) {
         right = right.rotateRight();
       }
       return rotateLeft();
     case 2:
       if (left.balanceFactor() < 0) {
         left = left.rotateLeft();
       }
       return rotateRight();
     default:
       recomputeHeight();
       return this;
   }
 }
Example #13
0
    AvlNode<E> add(Comparator<? super E> comparator, @Nullable E e, int count, int[] result) {
      /*
       * It speeds things up considerably to unconditionally add count to totalCount here,
       * but that destroys failure atomicity in the case of count overflow. =(
       */
      int cmp = comparator.compare(e, elem);
      if (cmp < 0) {
        AvlNode<E> initLeft = left;
        if (initLeft == null) {
          result[0] = 0;
          return addLeftChild(e, count);
        }
        int initHeight = initLeft.height;

        left = initLeft.add(comparator, e, count, result);
        if (result[0] == 0) {
          distinctElements++;
        }
        this.totalCount += count;
        return (left.height == initHeight) ? this : rebalance();
      } else if (cmp > 0) {
        AvlNode<E> initRight = right;
        if (initRight == null) {
          result[0] = 0;
          return addRightChild(e, count);
        }
        int initHeight = initRight.height;

        right = initRight.add(comparator, e, count, result);
        if (result[0] == 0) {
          distinctElements++;
        }
        this.totalCount += count;
        return (right.height == initHeight) ? this : rebalance();
      }

      // adding count to me!  No rebalance possible.
      result[0] = elemCount;
      long resultCount = (long) elemCount + count;
      checkArgument(resultCount <= Integer.MAX_VALUE);
      this.elemCount += count;
      this.totalCount += count;
      return this;
    }
Example #14
0
 // Removes the minimum node from this subtree to be reused elsewhere
 private AvlNode<E> removeMin(AvlNode<E> node) {
   if (left == null) {
     return right;
   } else {
     left = left.removeMin(node);
     distinctElements--;
     totalCount -= node.elemCount;
     return rebalance();
   }
 }
Example #15
0
 // Removes the maximum node from this subtree to be reused elsewhere
 private AvlNode<E> removeMax(AvlNode<E> node) {
   if (right == null) {
     return left;
   } else {
     right = right.removeMax(node);
     distinctElements--;
     totalCount -= node.elemCount;
     return rebalance();
   }
 }
Example #16
0
 @CanIgnoreReturnValue
 @Override
 public int add(@Nullable E element, int occurrences) {
   checkNonnegative(occurrences, "occurrences");
   if (occurrences == 0) {
     return count(element);
   }
   checkArgument(range.contains(element));
   AvlNode<E> root = rootReference.get();
   if (root == null) {
     comparator().compare(element, element);
     AvlNode<E> newRoot = new AvlNode<E>(element, occurrences);
     successor(header, newRoot, header);
     rootReference.checkAndSet(root, newRoot);
     return 0;
   }
   int[] result = new int[1]; // used as a mutable int reference to hold result
   AvlNode<E> newRoot = root.add(comparator(), element, occurrences, result);
   rootReference.checkAndSet(root, newRoot);
   return result[0];
 }
Example #17
0
  @CanIgnoreReturnValue
  @Override
  public int setCount(@Nullable E element, int count) {
    checkNonnegative(count, "count");
    if (!range.contains(element)) {
      checkArgument(count == 0);
      return 0;
    }

    AvlNode<E> root = rootReference.get();
    if (root == null) {
      if (count > 0) {
        add(element, count);
      }
      return 0;
    }
    int[] result = new int[1]; // used as a mutable int reference to hold result
    AvlNode<E> newRoot = root.setCount(comparator(), element, count, result);
    rootReference.checkAndSet(root, newRoot);
    return result[0];
  }
Example #18
0
 @Nullable
 private AvlNode<E> lastNode() {
   AvlNode<E> root = rootReference.get();
   if (root == null) {
     return null;
   }
   AvlNode<E> node;
   if (range.hasUpperBound()) {
     E endpoint = range.getUpperEndpoint();
     node = rootReference.get().floor(comparator(), endpoint);
     if (node == null) {
       return null;
     }
     if (range.getUpperBoundType() == BoundType.OPEN
         && comparator().compare(endpoint, node.getElement()) == 0) {
       node = node.pred;
     }
   } else {
     node = header.pred;
   }
   return (node == header || !range.contains(node.getElement())) ? null : node;
 }
Example #19
0
  @CanIgnoreReturnValue
  @Override
  public boolean setCount(@Nullable E element, int oldCount, int newCount) {
    checkNonnegative(newCount, "newCount");
    checkNonnegative(oldCount, "oldCount");
    checkArgument(range.contains(element));

    AvlNode<E> root = rootReference.get();
    if (root == null) {
      if (oldCount == 0) {
        if (newCount > 0) {
          add(element, newCount);
        }
        return true;
      } else {
        return false;
      }
    }
    int[] result = new int[1]; // used as a mutable int reference to hold result
    AvlNode<E> newRoot = root.setCount(comparator(), element, oldCount, newCount, result);
    rootReference.checkAndSet(root, newRoot);
    return result[0] == oldCount;
  }
Example #20
0
 private static <T> void successor(AvlNode<T> a, AvlNode<T> b) {
   a.succ = b;
   b.pred = a;
 }
Example #21
0
 /**
  * Double rotate binary tree node: first left child with its right child; then node k3 with new
  * left child. For AVL trees, this is a double rotation for case 2. Update heights, then return
  * new root.
  */
 private static AvlNode doubleWithLeftChild(AvlNode k3) {
   k3.left = rotateWithRightChild(k3.left);
   return rotateWithLeftChild(k3);
 }
Example #22
0
 /**
  * Double rotate binary tree node: first right child with its left child; then node k1 with new
  * right child. For AVL trees, this is a double rotation for case 3. Update heights, then return
  * new root.
  */
 private static AvlNode doubleWithRightChild(AvlNode k1) {
   k1.right = rotateWithLeftChild(k1.right);
   return rotateWithRightChild(k1);
 }
Example #23
0
 private AvlNode<T> doubleWithRightChild(AvlNode<T> k3) {
   k3.right = rotateWithLeftChild(k3.right);
   return rotateWithRightChild(k3);
 }
Example #24
0
 private AvlNode<E> deleteMe() {
   int oldElemCount = this.elemCount;
   this.elemCount = 0;
   successor(pred, succ);
   if (left == null) {
     return right;
   } else if (right == null) {
     return left;
   } else if (left.height >= right.height) {
     AvlNode<E> newTop = pred;
     // newTop is the maximum node in my left subtree
     newTop.left = left.removeMax(newTop);
     newTop.right = right;
     newTop.distinctElements = distinctElements - 1;
     newTop.totalCount = totalCount - oldElemCount;
     return newTop.rebalance();
   } else {
     AvlNode<E> newTop = succ;
     newTop.right = right.removeMin(newTop);
     newTop.left = left;
     newTop.distinctElements = distinctElements - 1;
     newTop.totalCount = totalCount - oldElemCount;
     return newTop.rebalance();
   }
 }