@Override public boolean intersects(Range<C> range) { checkNotNull(range); Entry<Cut<C>, Range<C>> ceilingEntry = rangesByLowerBound.ceilingEntry(range.lowerBound); if (ceilingEntry != null && ceilingEntry.getValue().isConnected(range) && !ceilingEntry.getValue().intersection(range).isEmpty()) { return true; } Entry<Cut<C>, Range<C>> priorEntry = rangesByLowerBound.lowerEntry(range.lowerBound); return priorEntry != null && priorEntry.getValue().isConnected(range) && !priorEntry.getValue().intersection(range).isEmpty(); }
/** * Returns an {@code ImmutableRangeMap} containing the associations previously added to this * builder. * * @throws IllegalArgumentException if any two ranges inserted into this builder overlap */ public ImmutableRangeMap<K, V> build() { Collections.sort(entries, Range.<K>rangeLexOrdering().onKeys()); ImmutableList.Builder<Range<K>> rangesBuilder = new ImmutableList.Builder<>(entries.size()); ImmutableList.Builder<V> valuesBuilder = new ImmutableList.Builder<V>(entries.size()); for (int i = 0; i < entries.size(); i++) { Range<K> range = entries.get(i).getKey(); if (i > 0) { Range<K> prevRange = entries.get(i - 1).getKey(); if (range.isConnected(prevRange) && !range.intersection(prevRange).isEmpty()) { throw new IllegalArgumentException( "Overlapping ranges: range " + prevRange + " overlaps with entry " + range); } } rangesBuilder.add(range); valuesBuilder.add(entries.get(i).getValue()); } return new ImmutableRangeMap<>(rangesBuilder.build(), valuesBuilder.build()); } }
/** Returns the range that spans the given range and entry, if the entry can be coalesced. */ private static <K extends Comparable, V> Range<K> coalesce( Range<K> range, V value, @Nullable Entry<Cut<K>, RangeMapEntry<K, V>> entry) { if (entry != null && entry.getValue().getKey().isConnected(range) && entry.getValue().getValue().equals(value)) { return range.span(entry.getValue().getKey()); } return range; }
@Override public boolean intersects(Range<C> otherRange) { int ceilingIndex = SortedLists.binarySearch( ranges, Range.<C>lowerBoundFn(), otherRange.lowerBound, Ordering.natural(), ANY_PRESENT, NEXT_HIGHER); if (ceilingIndex < ranges.size() && ranges.get(ceilingIndex).isConnected(otherRange) && !ranges.get(ceilingIndex).intersection(otherRange).isEmpty()) { return true; } return ceilingIndex > 0 && ranges.get(ceilingIndex - 1).isConnected(otherRange) && !ranges.get(ceilingIndex - 1).intersection(otherRange).isEmpty(); }
private NavigableMap<Cut<C>, Range<C>> subMap(Range<Cut<C>> subWindow) { if (!complementLowerBoundWindow.isConnected(subWindow)) { return ImmutableSortedMap.of(); } else { subWindow = subWindow.intersection(complementLowerBoundWindow); return new ComplementRangesByLowerBound<C>(positiveRangesByLowerBound, subWindow); } }
@Override public ImmutableRangeMap<K, V> subRangeMap(Range<K> subRange) { if (range.isConnected(subRange)) { return outer.subRangeMap(subRange.intersection(range)); } else { return ImmutableRangeMap.of(); } } };
private ContiguousSet<C> intersectionInCurrentDomain(Range<C> other) { return range.isConnected(other) ? ContiguousSet.create(range.intersection(other), domain) : new EmptyContiguousSet<C>(domain); }
private NavigableMap<Cut<C>, Range<C>> subMap(Range<Cut<C>> window) { if (window.isConnected(upperBoundWindow)) { return new RangesByUpperBound<C>(rangesByLowerBound, window.intersection(upperBoundWindow)); } else { return ImmutableSortedMap.of(); } }
private NavigableMap<Cut<C>, Range<C>> subMap(Range<Cut<C>> window) { if (!window.isConnected(lowerBoundWindow)) { return ImmutableSortedMap.of(); } else { return new SubRangeSetRangesByLowerBound<C>( lowerBoundWindow.intersection(window), restriction, rangesByLowerBound); } }
public void testIsConnected() { assertTrue(Range.closed(3, 5).isConnected(Range.open(5, 6))); assertTrue(Range.closed(3, 5).isConnected(Range.openClosed(5, 5))); assertTrue(Range.open(3, 5).isConnected(Range.closed(5, 6))); assertTrue(Range.closed(3, 7).isConnected(Range.open(6, 8))); assertTrue(Range.open(3, 7).isConnected(Range.closed(5, 6))); assertFalse(Range.closed(3, 5).isConnected(Range.closed(7, 8))); assertFalse(Range.closed(3, 5).isConnected(Range.closedOpen(7, 7))); }
/** Returns a view of the intersection of this range set with the given range. */ @Override public ImmutableRangeSet<C> subRangeSet(Range<C> range) { if (!isEmpty()) { Range<C> span = span(); if (range.encloses(span)) { return this; } else if (range.isConnected(span)) { return new ImmutableRangeSet<C>(intersectRanges(range)); } } return of(); }
private RangeSet<Integer> expectedSubRangeSet( RangeSet<Integer> rangeSet, Range<Integer> subRange) { RangeSet<Integer> expected = TreeRangeSet.create(); for (Range<Integer> range : rangeSet.asRanges()) { if (range.isConnected(subRange)) { expected.add(range.intersection(subRange)); } } return expected; }
public void testGetEntry() { for (Range<Integer> range1 : RANGES) { for (Range<Integer> range2 : RANGES) { if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) { ImmutableRangeMap<Integer, Integer> rangeMap = ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build(); for (int i = MIN_BOUND; i <= MAX_BOUND; i++) { Entry<Range<Integer>, Integer> expectedEntry = null; if (range1.contains(i)) { expectedEntry = Maps.immutableEntry(range1, 1); } else if (range2.contains(i)) { expectedEntry = Maps.immutableEntry(range2, 2); } assertEquals(expectedEntry, rangeMap.getEntry(i)); } } } } }
public void testSubRangeMap() { for (Range<Integer> range1 : RANGES) { for (Range<Integer> range2 : RANGES) { if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) { for (Range<Integer> subRange : RANGES) { ImmutableRangeMap<Integer, Integer> rangeMap = ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build(); ImmutableRangeMap.Builder<Integer, Integer> expectedBuilder = ImmutableRangeMap.builder(); for (Entry<Range<Integer>, Integer> entry : rangeMap.asMapOfRanges().entrySet()) { if (entry.getKey().isConnected(subRange) && !entry.getKey().intersection(subRange).isEmpty()) { expectedBuilder.put(entry.getKey().intersection(subRange), entry.getValue()); } } ImmutableRangeMap<Integer, Integer> expected = expectedBuilder.build(); assertEquals(expected, rangeMap.subRangeMap(subRange)); } } } } }
public void testIntersects(RangeSet<Integer> rangeSet) { for (Range<Integer> query : QUERY_RANGES) { boolean expectIntersect = false; for (Range<Integer> expectedRange : rangeSet.asRanges()) { if (expectedRange.isConnected(query) && !expectedRange.intersection(query).isEmpty()) { expectIntersect = true; break; } } assertEquals( rangeSet + " was incorrect on intersects(" + query + ")", expectIntersect, rangeSet.intersects(query)); } }
public void testGet() { for (Range<Integer> range1 : RANGES) { for (Range<Integer> range2 : RANGES) { if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) { ImmutableRangeMap<Integer, Integer> rangeMap = ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build(); for (int i = MIN_BOUND; i <= MAX_BOUND; i++) { Integer expectedValue = null; if (range1.contains(i)) { expectedValue = 1; } else if (range2.contains(i)) { expectedValue = 2; } assertEquals(expectedValue, rangeMap.get(i)); } } } } }
@AndroidIncompatible // slow public void testAsMapOfRanges() { for (Range<Integer> range1 : RANGES) { for (Range<Integer> range2 : RANGES) { if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) { ImmutableRangeMap<Integer, Integer> rangeMap = ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build(); ImmutableMap<Range<Integer>, Integer> expectedAsMap = ImmutableMap.of(range1, 1, range2, 2); ImmutableMap<Range<Integer>, Integer> asMap = rangeMap.asMapOfRanges(); ImmutableMap<Range<Integer>, Integer> descendingMap = rangeMap.asDescendingMapOfRanges(); assertEquals(expectedAsMap, asMap); assertEquals(expectedAsMap, descendingMap); SerializableTester.reserializeAndAssert(asMap); SerializableTester.reserializeAndAssert(descendingMap); assertEquals( ImmutableList.copyOf(asMap.entrySet()).reverse(), ImmutableList.copyOf(descendingMap.entrySet())); for (Range<Integer> query : RANGES) { assertEquals(expectedAsMap.get(query), asMap.get(query)); } } } } }
private static void doPairTest(Range<Integer> a, Range<Integer> b) { TreeRangeSet<Integer> rangeSet = TreeRangeSet.create(); rangeSet.add(a); rangeSet.add(b); if (a.isEmpty() && b.isEmpty()) { assertThat(rangeSet.asRanges()).isEmpty(); } else if (a.isEmpty()) { assertThat(rangeSet.asRanges()).contains(b); } else if (b.isEmpty()) { assertThat(rangeSet.asRanges()).contains(a); } else if (a.isConnected(b)) { assertThat(rangeSet.asRanges()).containsExactly(a.span(b)); } else { if (a.lowerEndpoint() < b.lowerEndpoint()) { assertThat(rangeSet.asRanges()).containsExactly(a, b).inOrder(); } else { assertThat(rangeSet.asRanges()).containsExactly(b, a).inOrder(); } } }
public void testSpanTwoRanges() { for (Range<Integer> range1 : RANGES) { for (Range<Integer> range2 : RANGES) { if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) { RangeMap<Integer, Integer> rangemap = ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build(); assertEquals(range1.span(range2), rangemap.span()); } } } }
public void testOverlapRejection() { for (Range<Integer> range1 : RANGES) { for (Range<Integer> range2 : RANGES) { boolean expectRejection = range1.isConnected(range2) && !range1.intersection(range2).isEmpty(); ImmutableRangeMap.Builder<Integer, Integer> builder = ImmutableRangeMap.builder(); builder.put(range1, 1).put(range2, 2); try { ImmutableRangeMap<Integer, Integer> unused = builder.build(); assertFalse(expectRejection); } catch (IllegalArgumentException e) { assertTrue(expectRejection); } } } }