Beispiel #1
0
  /**
   * Returns the intersection of the two ranges, or an empty range if their intersection is empty.
   */
  GeneralRange<T> intersect(GeneralRange<T> other) {
    checkNotNull(other);
    checkArgument(comparator.equals(other.comparator));

    boolean hasLowBound = this.hasLowerBound;
    @Nullable T lowEnd = getLowerEndpoint();
    BoundType lowType = getLowerBoundType();
    if (!hasLowerBound()) {
      hasLowBound = other.hasLowerBound;
      lowEnd = other.getLowerEndpoint();
      lowType = other.getLowerBoundType();
    } else if (other.hasLowerBound()) {
      int cmp = comparator.compare(getLowerEndpoint(), other.getLowerEndpoint());
      if (cmp < 0 || (cmp == 0 && other.getLowerBoundType() == OPEN)) {
        lowEnd = other.getLowerEndpoint();
        lowType = other.getLowerBoundType();
      }
    }

    boolean hasUpBound = this.hasUpperBound;
    @Nullable T upEnd = getUpperEndpoint();
    BoundType upType = getUpperBoundType();
    if (!hasUpperBound()) {
      hasUpBound = other.hasUpperBound;
      upEnd = other.getUpperEndpoint();
      upType = other.getUpperBoundType();
    } else if (other.hasUpperBound()) {
      int cmp = comparator.compare(getUpperEndpoint(), other.getUpperEndpoint());
      if (cmp > 0 || (cmp == 0 && other.getUpperBoundType() == OPEN)) {
        upEnd = other.getUpperEndpoint();
        upType = other.getUpperBoundType();
      }
    }

    if (hasLowBound && hasUpBound) {
      int cmp = comparator.compare(lowEnd, upEnd);
      if (cmp > 0 || (cmp == 0 && lowType == OPEN && upType == OPEN)) {
        // force allowed empty range
        lowEnd = upEnd;
        lowType = OPEN;
        upType = CLOSED;
      }
    }

    return new GeneralRange<T>(comparator, hasLowBound, lowEnd, lowType, hasUpBound, upEnd, upType);
  }
Beispiel #2
0
 @Override
 public boolean equals(@Nullable Object obj) {
   if (obj instanceof GeneralRange) {
     GeneralRange<?> r = (GeneralRange<?>) obj;
     return comparator.equals(r.comparator)
         && hasLowerBound == r.hasLowerBound
         && hasUpperBound == r.hasUpperBound
         && getLowerBoundType().equals(r.getLowerBoundType())
         && getUpperBoundType().equals(r.getUpperBoundType())
         && Objects.equal(getLowerEndpoint(), r.getLowerEndpoint())
         && Objects.equal(getUpperEndpoint(), r.getUpperEndpoint());
   }
   return false;
 }
Beispiel #3
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;
 }
Beispiel #4
0
 private long aggregateAboveRange(Aggregate aggr, @Nullable AvlNode<E> node) {
   if (node == null) {
     return 0;
   }
   int cmp = comparator().compare(range.getUpperEndpoint(), node.elem);
   if (cmp > 0) {
     return aggregateAboveRange(aggr, node.right);
   } else if (cmp == 0) {
     switch (range.getUpperBoundType()) {
       case OPEN:
         return aggr.nodeAggregate(node) + aggr.treeAggregate(node.right);
       case CLOSED:
         return aggr.treeAggregate(node.right);
       default:
         throw new AssertionError();
     }
   } else {
     return aggr.treeAggregate(node.right)
         + aggr.nodeAggregate(node)
         + aggregateAboveRange(aggr, node.left);
   }
 }