Avoid extracting resoure set from backing range set
This is one of fixes for ONOS-4684
Change-Id: I93cd95317b985f98fd6e72a4f96c7f7d6857f279
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EncodableDiscreteResources.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EncodableDiscreteResources.java
index fdfaf7c..f1b8f89 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EncodableDiscreteResources.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EncodableDiscreteResources.java
@@ -30,6 +30,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* A set of discrete resources that can be encoded as integers.
@@ -88,7 +89,16 @@
@Override
public DiscreteResources difference(DiscreteResources other) {
if (other instanceof EncodableDiscreteResources) {
- return of(parent, Sets.difference(this.values(), other.values()));
+ EncodableDiscreteResources cast = (EncodableDiscreteResources) other;
+ Map<Class<?>, EncodedDiscreteResources> newMap =
+ Stream.concat(this.map.entrySet().stream(), cast.map.entrySet().stream())
+ .filter(entry -> this.map.containsKey(entry.getKey()))
+ .collect(Collectors.toMap(
+ Map.Entry::getKey,
+ Map.Entry::getValue,
+ EncodedDiscreteResources::difference,
+ LinkedHashMap::new));
+ return new EncodableDiscreteResources(parent, newMap);
} else if (other instanceof EmptyDiscreteResources) {
return this;
}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EncodedDiscreteResources.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EncodedDiscreteResources.java
index 6e3f613..5ccb6d2 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EncodedDiscreteResources.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EncodedDiscreteResources.java
@@ -32,6 +32,8 @@
import java.util.stream.Collectors;
import java.util.stream.IntStream;
+import static com.google.common.base.Preconditions.checkArgument;
+
/**
* Represents discrete resources encoded by a codec.
*/
@@ -82,6 +84,15 @@
.orElse(false);
}
+ EncodedDiscreteResources difference(EncodedDiscreteResources other) {
+ checkArgument(this.codec.getClass() == other.codec.getClass());
+
+ RangeSet<Integer> newRangeSet = TreeRangeSet.create(this.rangeSet);
+ newRangeSet.removeAll(other.rangeSet);
+
+ return new EncodedDiscreteResources(newRangeSet, this.codec);
+ }
+
boolean isEmpty() {
return rangeSet.isEmpty();
}
diff --git a/core/store/dist/src/test/java/org/onosproject/store/resource/impl/EncodedDiscreteResourcesTest.java b/core/store/dist/src/test/java/org/onosproject/store/resource/impl/EncodedDiscreteResourcesTest.java
index e7483cd..fe1e781 100644
--- a/core/store/dist/src/test/java/org/onosproject/store/resource/impl/EncodedDiscreteResourcesTest.java
+++ b/core/store/dist/src/test/java/org/onosproject/store/resource/impl/EncodedDiscreteResourcesTest.java
@@ -50,4 +50,16 @@
assertThat(sut.contains(res3), is(false));
}
+ @Test
+ public void testDifference() {
+ DiscreteResource res1 = Resources.discrete(DID, PN, VID1).resource();
+ DiscreteResource res2 = Resources.discrete(DID, PN, VID2).resource();
+ DiscreteResource res3 = Resources.discrete(DID, PN, VID3).resource();
+
+ EncodedDiscreteResources sut = EncodedDiscreteResources.of(ImmutableSet.of(res1, res2), new VlanIdCodec());
+ EncodedDiscreteResources other = EncodedDiscreteResources.of(ImmutableSet.of(res1, res3), new VlanIdCodec());
+
+ assertThat(sut.difference(other), is(EncodedDiscreteResources.of(ImmutableSet.of(res2), new VlanIdCodec())));
+ }
+
}