Skip to content

Commit a46565d

Browse files
java-team-github-botGoogle Java Core Libraries
authored and
Google Java Core Libraries
committed
Provide an optimized copyOf method for TreeRangeMap
RELNOTES=Provide an optimized copyOf method for TreeRangeMap PiperOrigin-RevId: 682878547
1 parent 81be061 commit a46565d

File tree

4 files changed

+138
-0
lines changed

4 files changed

+138
-0
lines changed

android/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java

+48
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.google.common.collect.testing.features.CollectionFeature;
2626
import com.google.common.collect.testing.features.CollectionSize;
2727
import com.google.common.collect.testing.features.MapFeature;
28+
import com.google.common.testing.EqualsTester;
2829
import java.util.List;
2930
import java.util.Map;
3031
import java.util.Map.Entry;
@@ -702,6 +703,53 @@ public void testSubRangeMapClear() {
702703
ImmutableMap.of(Range.open(3, 5), 1, Range.closed(12, 16), 3), rangeMap.asMapOfRanges());
703704
}
704705

706+
public void testCopyOfTreeRangeMap() {
707+
RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
708+
rangeMap.put(Range.open(3, 7), 1);
709+
rangeMap.put(Range.closed(9, 10), 2);
710+
rangeMap.put(Range.closed(12, 16), 3);
711+
712+
RangeMap<Integer, Integer> copy = TreeRangeMap.copyOf(rangeMap);
713+
714+
assertEquals(rangeMap.asMapOfRanges(), copy.asMapOfRanges());
715+
}
716+
717+
public void testCopyOfImmutableRangeMap() {
718+
ImmutableRangeMap<Integer, Integer> rangeMap =
719+
ImmutableRangeMap.<Integer, Integer>builder()
720+
.put(Range.open(3, 7), 1)
721+
.put(Range.closed(9, 10), 2)
722+
.put(Range.closed(12, 16), 3)
723+
.build();
724+
725+
RangeMap<Integer, Integer> copy = TreeRangeMap.copyOf(rangeMap);
726+
727+
assertEquals(rangeMap.asMapOfRanges(), copy.asMapOfRanges());
728+
}
729+
730+
// Overriding testEquals because it seems that we get spurious failures when it things empty
731+
// should be unequal to empty.
732+
public void testEquals() {
733+
TreeRangeMap<Integer, Integer> empty = TreeRangeMap.create();
734+
TreeRangeMap<Integer, Integer> nonEmpty = TreeRangeMap.create();
735+
nonEmpty.put(Range.all(), 1);
736+
TreeRangeMap<Integer, Integer> coalesced = TreeRangeMap.create();
737+
coalesced.put(Range.atLeast(1), 1);
738+
coalesced.putCoalescing(Range.atMost(1), 1);
739+
TreeRangeMap<Integer, Integer> differentValues = TreeRangeMap.create();
740+
differentValues.put(Range.closedOpen(1, 2), 2);
741+
differentValues.put(Range.closedOpen(3, 4), 2);
742+
TreeRangeMap<Double, Integer> differentTypes = TreeRangeMap.create();
743+
differentTypes.put(Range.closedOpen(1.0, 2.0), 2);
744+
differentTypes.put(Range.closedOpen(3.0, 4.0), 2);
745+
new EqualsTester()
746+
.addEqualityGroup(empty, TreeRangeMap.<Integer, Integer>create())
747+
.addEqualityGroup(nonEmpty, coalesced)
748+
.addEqualityGroup(differentValues)
749+
.addEqualityGroup(differentTypes)
750+
.testEquals();
751+
}
752+
705753
private void verify(Map<Integer, Integer> model, RangeMap<Integer, Integer> test) {
706754
for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
707755
assertEquals(model.get(i), test.get(i));

android/guava/src/com/google/common/collect/TreeRangeMap.java

+21
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,31 @@ public static <K extends Comparable, V> TreeRangeMap<K, V> create() {
5959
return new TreeRangeMap<>();
6060
}
6161

62+
@SuppressWarnings("unchecked")
63+
public static <K extends Comparable<?>, V> TreeRangeMap<K, V> copyOf(
64+
RangeMap<K, ? extends V> rangeMap) {
65+
if (rangeMap instanceof TreeRangeMap) {
66+
NavigableMap<Cut<K>, RangeMapEntry<K, V>> entriesByLowerBound = Maps.newTreeMap();
67+
entriesByLowerBound.putAll(((TreeRangeMap<K, V>) rangeMap).entriesByLowerBound);
68+
return new TreeRangeMap<>(entriesByLowerBound);
69+
} else {
70+
NavigableMap<Cut<K>, RangeMapEntry<K, V>> entriesByLowerBound = Maps.newTreeMap();
71+
for (Entry<Range<K>, ? extends V> entry : rangeMap.asMapOfRanges().entrySet()) {
72+
entriesByLowerBound.put(
73+
entry.getKey().lowerBound(), new RangeMapEntry<K, V>(entry.getKey(), entry.getValue()));
74+
}
75+
return new TreeRangeMap<>(entriesByLowerBound);
76+
}
77+
}
78+
6279
private TreeRangeMap() {
6380
this.entriesByLowerBound = Maps.newTreeMap();
6481
}
6582

83+
private TreeRangeMap(NavigableMap<Cut<K>, RangeMapEntry<K, V>> entriesByLowerBound) {
84+
this.entriesByLowerBound = entriesByLowerBound;
85+
}
86+
6687
private static final class RangeMapEntry<K extends Comparable, V>
6788
extends AbstractMapEntry<Range<K>, V> {
6889
private final Range<K> range;

guava-tests/test/com/google/common/collect/TreeRangeMapTest.java

+48
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.google.common.collect.testing.features.CollectionFeature;
2626
import com.google.common.collect.testing.features.CollectionSize;
2727
import com.google.common.collect.testing.features.MapFeature;
28+
import com.google.common.testing.EqualsTester;
2829
import java.util.List;
2930
import java.util.Map;
3031
import java.util.Map.Entry;
@@ -853,6 +854,53 @@ public void testSubRangeMapClear() {
853854
ImmutableMap.of(Range.open(3, 5), 1, Range.closed(12, 16), 3), rangeMap.asMapOfRanges());
854855
}
855856

857+
public void testCopyOfTreeRangeMap() {
858+
RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
859+
rangeMap.put(Range.open(3, 7), 1);
860+
rangeMap.put(Range.closed(9, 10), 2);
861+
rangeMap.put(Range.closed(12, 16), 3);
862+
863+
RangeMap<Integer, Integer> copy = TreeRangeMap.copyOf(rangeMap);
864+
865+
assertEquals(rangeMap.asMapOfRanges(), copy.asMapOfRanges());
866+
}
867+
868+
public void testCopyOfImmutableRangeMap() {
869+
ImmutableRangeMap<Integer, Integer> rangeMap =
870+
ImmutableRangeMap.<Integer, Integer>builder()
871+
.put(Range.open(3, 7), 1)
872+
.put(Range.closed(9, 10), 2)
873+
.put(Range.closed(12, 16), 3)
874+
.build();
875+
876+
RangeMap<Integer, Integer> copy = TreeRangeMap.copyOf(rangeMap);
877+
878+
assertEquals(rangeMap.asMapOfRanges(), copy.asMapOfRanges());
879+
}
880+
881+
// Overriding testEquals because it seems that we get spurious failures when it things empty
882+
// should be unequal to empty.
883+
public void testEquals() {
884+
TreeRangeMap<Integer, Integer> empty = TreeRangeMap.create();
885+
TreeRangeMap<Integer, Integer> nonEmpty = TreeRangeMap.create();
886+
nonEmpty.put(Range.all(), 1);
887+
TreeRangeMap<Integer, Integer> coalesced = TreeRangeMap.create();
888+
coalesced.put(Range.atLeast(1), 1);
889+
coalesced.putCoalescing(Range.atMost(1), 1);
890+
TreeRangeMap<Integer, Integer> differentValues = TreeRangeMap.create();
891+
differentValues.put(Range.closedOpen(1, 2), 2);
892+
differentValues.put(Range.closedOpen(3, 4), 2);
893+
TreeRangeMap<Double, Integer> differentTypes = TreeRangeMap.create();
894+
differentTypes.put(Range.closedOpen(1.0, 2.0), 2);
895+
differentTypes.put(Range.closedOpen(3.0, 4.0), 2);
896+
new EqualsTester()
897+
.addEqualityGroup(empty, TreeRangeMap.<Integer, Integer>create())
898+
.addEqualityGroup(nonEmpty, coalesced)
899+
.addEqualityGroup(differentValues)
900+
.addEqualityGroup(differentTypes)
901+
.testEquals();
902+
}
903+
856904
private void verify(Map<Integer, Integer> model, RangeMap<Integer, Integer> test) {
857905
for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
858906
assertEquals(model.get(i), test.get(i));

guava/src/com/google/common/collect/TreeRangeMap.java

+21
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,31 @@ public static <K extends Comparable, V> TreeRangeMap<K, V> create() {
6161
return new TreeRangeMap<>();
6262
}
6363

64+
@SuppressWarnings("unchecked")
65+
public static <K extends Comparable<?>, V> TreeRangeMap<K, V> copyOf(
66+
RangeMap<K, ? extends V> rangeMap) {
67+
if (rangeMap instanceof TreeRangeMap) {
68+
NavigableMap<Cut<K>, RangeMapEntry<K, V>> entriesByLowerBound = Maps.newTreeMap();
69+
entriesByLowerBound.putAll(((TreeRangeMap<K, V>) rangeMap).entriesByLowerBound);
70+
return new TreeRangeMap<>(entriesByLowerBound);
71+
} else {
72+
NavigableMap<Cut<K>, RangeMapEntry<K, V>> entriesByLowerBound = Maps.newTreeMap();
73+
for (Entry<Range<K>, ? extends V> entry : rangeMap.asMapOfRanges().entrySet()) {
74+
entriesByLowerBound.put(
75+
entry.getKey().lowerBound(), new RangeMapEntry<K, V>(entry.getKey(), entry.getValue()));
76+
}
77+
return new TreeRangeMap<>(entriesByLowerBound);
78+
}
79+
}
80+
6481
private TreeRangeMap() {
6582
this.entriesByLowerBound = Maps.newTreeMap();
6683
}
6784

85+
private TreeRangeMap(NavigableMap<Cut<K>, RangeMapEntry<K, V>> entriesByLowerBound) {
86+
this.entriesByLowerBound = entriesByLowerBound;
87+
}
88+
6889
private static final class RangeMapEntry<K extends Comparable, V>
6990
extends AbstractMapEntry<Range<K>, V> {
7091
private final Range<K> range;

0 commit comments

Comments
 (0)