@Override protected Entry<Cut<C>, Range<C>> computeNext() { if (complementLowerBoundWindow.upperBound.isLessThan(nextComplementRangeLowerBound) || nextComplementRangeLowerBound == Cut.<C>aboveAll()) { return endOfData(); } Range<C> negativeRange; if (positiveItr.hasNext()) { Range<C> positiveRange = positiveItr.next(); negativeRange = Range.create(nextComplementRangeLowerBound, positiveRange.lowerBound); nextComplementRangeLowerBound = positiveRange.upperBound; } else { negativeRange = Range.create(nextComplementRangeLowerBound, Cut.<C>aboveAll()); nextComplementRangeLowerBound = Cut.aboveAll(); } return Maps.immutableEntry(negativeRange.lowerBound, negativeRange); } };
/** * Returns a range that contains all values greater than or equal to {@code lower} and less than * or equal to {@code upper}. * * @throws IllegalArgumentException if {@code lower} is greater than {@code upper} * @throws ClassCastException if {@code lower} and {@code upper} are not mutually comparable * @since 14.0 */ public static <C extends Comparable<?>> Range<C> closed(C lower, C upper) { return create(Cut.belowValue(lower), Cut.aboveValue(upper)); }
@Override protected Entry<Cut<C>, Range<C>> computeNext() { if (nextComplementRangeUpperBound == Cut.<C>belowAll()) { return endOfData(); } else if (positiveItr.hasNext()) { Range<C> positiveRange = positiveItr.next(); Range<C> negativeRange = Range.create(positiveRange.upperBound, nextComplementRangeUpperBound); nextComplementRangeUpperBound = positiveRange.lowerBound; if (complementLowerBoundWindow.lowerBound.isLessThan(negativeRange.lowerBound)) { return Maps.immutableEntry(negativeRange.lowerBound, negativeRange); } } else if (complementLowerBoundWindow.lowerBound.isLessThan(Cut.<C>belowAll())) { Range<C> negativeRange = Range.create(Cut.<C>belowAll(), nextComplementRangeUpperBound); nextComplementRangeUpperBound = Cut.belowAll(); return Maps.immutableEntry(Cut.<C>belowAll(), negativeRange); } return endOfData(); } };
/** * Returns a range that contains all values less than or equal to {@code endpoint}. * * @since 14.0 */ public static <C extends Comparable<?>> Range<C> atMost(C endpoint) { return create(Cut.<C>belowAll(), Cut.aboveValue(endpoint)); }
/** * Returns a range that contains all values greater than or equal to {@code endpoint}. * * @since 14.0 */ public static <C extends Comparable<?>> Range<C> atLeast(C endpoint) { return create(Cut.belowValue(endpoint), Cut.<C>aboveAll()); }
@Override @Nullable public Range<C> rangeContaining(C value) { checkNotNull(value); Entry<Cut<C>, Range<C>> floorEntry = rangesByLowerBound.floorEntry(Cut.belowValue(value)); if (floorEntry != null && floorEntry.getValue().contains(value)) { return floorEntry.getValue(); } else { // TODO(kevinb): revisit this design choice return null; } }
@Override public @Nullable Entry<Range<K>, V> getEntry(K key) { int index = SortedLists.binarySearch( ranges, Range.<K>lowerBoundFn(), Cut.belowValue(key), KeyPresentBehavior.ANY_PRESENT, KeyAbsentBehavior.NEXT_LOWER); if (index == -1) { return null; } else { Range<K> range = ranges.get(index); return range.contains(key) ? Maps.immutableEntry(range, values.get(index)) : null; } }
@Override @Nullable public Entry<Range<K>, V> getEntry(K key) { Map.Entry<Cut<K>, RangeMapEntry<K, V>> mapEntry = entriesByLowerBound.floorEntry(Cut.belowValue(key)); if (mapEntry != null && mapEntry.getValue().contains(key)) { return mapEntry.getValue(); } else { return null; } }
complementLowerBoundWindow.hasUpperBound() ? complementLowerBoundWindow.upperEndpoint() : Cut.<C>aboveAll(); boolean inclusive = complementLowerBoundWindow.hasUpperBound() && complementLowerBoundWindow.upperBoundType() == BoundType.CLOSED; final PeekingIterator<Range<C>> positiveItr = Iterators.peekingIterator( positiveRangesByUpperBound .headMap(startingPoint, inclusive) .descendingMap() .values() .iterator()); Cut<C> cut; if (positiveItr.hasNext()) { cut = (positiveItr.peek().upperBound == Cut.<C>aboveAll()) ? positiveItr.next().lowerBound : positiveRangesByLowerBound.higherKey(positiveItr.peek().upperBound); } else if (!complementLowerBoundWindow.contains(Cut.<C>belowAll()) || positiveRangesByLowerBound.containsKey(Cut.belowAll())) { return Iterators.emptyIterator(); } else { cut = positiveRangesByLowerBound.higherKey(Cut.<C>belowAll()); MoreObjects.firstNonNull(cut, Cut.<C>aboveAll()); return new AbstractIterator<Entry<Cut<C>, Range<C>>>() { Cut<C> nextComplementRangeUpperBound = firstComplementRangeUpperBound;
if (complementLowerBoundWindow.hasLowerBound()) { positiveRanges = positiveRangesByUpperBound .tailMap( complementLowerBoundWindow.lowerEndpoint(), complementLowerBoundWindow.lowerBoundType() == BoundType.CLOSED) .values(); } else { positiveRanges = positiveRangesByUpperBound.values(); Iterators.peekingIterator(positiveRanges.iterator()); final Cut<C> firstComplementRangeLowerBound; if (complementLowerBoundWindow.contains(Cut.<C>belowAll()) && (!positiveItr.hasNext() || positiveItr.peek().lowerBound != Cut.<C>belowAll())) { firstComplementRangeLowerBound = Cut.belowAll(); } else if (positiveItr.hasNext()) { firstComplementRangeLowerBound = positiveItr.next().upperBound; } else { return Iterators.emptyIterator();
@Override Iterator<Entry<Cut<C>, Range<C>>> descendingEntryIterator() { if (restriction.isEmpty()) { return Iterators.emptyIterator(); .min(lowerBoundWindow.upperBound, Cut.belowValue(restriction.upperBound)); final Iterator<Range<C>> completeRangeItr = rangesByLowerBound .headMap( upperBoundOnLowerBounds.endpoint(), upperBoundOnLowerBounds.typeAsUpperBound() == BoundType.CLOSED) .descendingMap() .values() .iterator(); return new AbstractIterator<Entry<Cut<C>, Range<C>>>() {
@Override Iterator<Entry<Cut<C>, Range<C>>> entryIterator() { if (restriction.isEmpty()) { return Iterators.emptyIterator(); if (lowerBoundWindow.upperBound.isLessThan(restriction.lowerBound)) { return Iterators.emptyIterator(); } else if (lowerBoundWindow.lowerBound.isLessThan(restriction.lowerBound)) { rangesByUpperBound.tailMap(restriction.lowerBound, false).values().iterator(); } else { .tailMap( lowerBoundWindow.lowerBound.endpoint(), lowerBoundWindow.lowerBoundType() == BoundType.CLOSED) .values() .iterator(); .min(lowerBoundWindow.upperBound, Cut.belowValue(restriction.upperBound)); return new AbstractIterator<Entry<Cut<C>, Range<C>>>() { @Override
@Override public @Nullable Range<C> get(@Nullable Object key) { if (key instanceof Cut) { try { @SuppressWarnings("unchecked") // we catch CCE's Cut<C> cut = (Cut<C>) key; if (!lowerBoundWindow.contains(cut) || cut.compareTo(restriction.lowerBound) < 0 || cut.compareTo(restriction.upperBound) >= 0) { return null; } else if (cut.equals(restriction.lowerBound)) { // it might be present, truncated on the left Range<C> candidate = Maps.valueOrNull(rangesByLowerBound.floorEntry(cut)); if (candidate != null && candidate.upperBound.compareTo(restriction.lowerBound) > 0) { return candidate.intersection(restriction); } } else { Range<C> result = rangesByLowerBound.get(cut); if (result != null) { return result.intersection(restriction); } } } catch (ClassCastException e) { return null; } } return null; }
checkNotNull(rangeToAdd); if (rangeToAdd.isEmpty()) { return; Cut<C> ubToAdd = rangeToAdd.upperBound; Entry<Cut<C>, Range<C>> entryBelowLB = rangesByLowerBound.lowerEntry(lbToAdd); if (entryBelowLB != null) { if (rangeBelowLB.upperBound.compareTo(lbToAdd) >= 0) { if (rangeBelowLB.upperBound.compareTo(ubToAdd) >= 0) { Entry<Cut<C>, Range<C>> entryBelowUB = rangesByLowerBound.floorEntry(ubToAdd); if (entryBelowUB != null) { if (rangeBelowUB.upperBound.compareTo(ubToAdd) >= 0) { rangesByLowerBound.subMap(lbToAdd, ubToAdd).clear(); replaceRangeWithSameLowerBound(Range.create(lbToAdd, ubToAdd));
@Override protected Entry<Cut<C>, Range<C>> computeNext() { if (!completeRangeItr.hasNext()) { return endOfData(); } Range<C> nextRange = completeRangeItr.next(); if (restriction.lowerBound.compareTo(nextRange.upperBound) >= 0) { return endOfData(); } nextRange = nextRange.intersection(restriction); if (lowerBoundWindow.contains(nextRange.lowerBound)) { return Maps.immutableEntry(nextRange.lowerBound, nextRange); } else { return endOfData(); } } };
@Override public @Nullable Range<C> rangeContaining(C value) { checkNotNull(value); Entry<Cut<C>, Range<C>> floorEntry = rangesByLowerBound.floorEntry(Cut.belowValue(value)); if (floorEntry != null && floorEntry.getValue().contains(value)) { return floorEntry.getValue(); } else { // TODO(kevinb): revisit this design choice return null; } }
@Override public Range<C> get(@Nullable Object key) { if (key instanceof Cut) { try { @SuppressWarnings("unchecked") // we catch CCEs Cut<C> cut = (Cut<C>) key; if (!upperBoundWindow.contains(cut)) { return null; } Entry<Cut<C>, Range<C>> candidate = rangesByLowerBound.lowerEntry(cut); if (candidate != null && candidate.getValue().upperBound.equals(cut)) { return candidate.getValue(); } } catch (ClassCastException e) { return null; } } return null; }
@Override public @Nullable Entry<Range<K>, V> getEntry(K key) { Entry<Cut<K>, RangeMapEntry<K, V>> mapEntry = entriesByLowerBound.floorEntry(Cut.belowValue(key)); if (mapEntry != null && mapEntry.getValue().contains(key)) { return mapEntry.getValue(); } else { return null; } }
@Override public @Nullable Range<C> get(Object key) { if (key instanceof Cut) { try { @SuppressWarnings("unchecked") Cut<C> cut = (Cut<C>) key; // tailMap respects the current window Entry<Cut<C>, Range<C>> firstEntry = tailMap(cut, true).firstEntry(); if (firstEntry != null && firstEntry.getKey().equals(cut)) { return firstEntry.getValue(); } } catch (ClassCastException e) { return null; } } return null; }
public static Range<?> instantiate(SerializationStreamReader reader) throws SerializationException { Cut lowerBound; boolean hasLowerBound = reader.readBoolean(); if (hasLowerBound) { boolean lowerIsClosed = reader.readBoolean(); Comparable lower = (Comparable) reader.readObject(); lowerBound = lowerIsClosed ? Cut.belowValue(lower) : Cut.aboveValue(lower); } else { lowerBound = Cut.belowAll(); } Cut upperBound; boolean hasUpperBound = reader.readBoolean(); if (hasUpperBound) { boolean upperIsClosed = reader.readBoolean(); Comparable upper = (Comparable) reader.readObject(); upperBound = upperIsClosed ? Cut.aboveValue(upper) : Cut.belowValue(upper); } else { upperBound = Cut.aboveAll(); } return Range.create(lowerBound, upperBound); }