Compaction of discrete resources with range based representation
This resolves ONOS-4281
Change-Id: I0739ba94cc0b3ce617e2db44307fef396dcfb942
(cherry picked from commit 34e2c1c223ec62c85c2613c0d899a0cc06b63f33)
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceStore.java
index 549675b..dd78e50 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentResourceStore.java
@@ -23,6 +23,7 @@
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.util.Tools;
+import org.onlab.util.KryoNamespace;
import org.onosproject.net.resource.ContinuousResource;
import org.onosproject.net.resource.ContinuousResourceId;
import org.onosproject.net.resource.DiscreteResource;
@@ -45,7 +46,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
@@ -70,11 +70,14 @@
implements ResourceStore {
private static final Logger log = LoggerFactory.getLogger(ConsistentResourceStore.class);
- static final Serializer SERIALIZER = Serializer.using(
- Arrays.asList(KryoNamespaces.API),
- UnifiedDiscreteResources.class,
- NonEncodableDiscreteResources.class,
- ContinuousResourceAllocation.class);
+ static final Serializer SERIALIZER = Serializer.using(KryoNamespace.newBuilder()
+ .register(KryoNamespaces.API)
+ .register(UnifiedDiscreteResources.class)
+ .register(new EncodableDiscreteResourcesSerializer(), EncodableDiscreteResources.class)
+ .register(NonEncodableDiscreteResources.class)
+ .register(EmptyDiscreteResources.class)
+ .register(ContinuousResourceAllocation.class)
+ .build());
// TODO: We should provide centralized values for this
static final int MAX_RETRIES = 5;
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/DiscreteResources.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/DiscreteResources.java
index 6b7da8e..3b39120 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/DiscreteResources.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/DiscreteResources.java
@@ -32,7 +32,7 @@
* @return a empty set.
*/
static DiscreteResources empty() {
- return UnifiedDiscreteResources.empty();
+ return EmptyDiscreteResources.INSTANCE;
}
/**
@@ -41,7 +41,7 @@
* @param resources resources
* @return instance
*/
- static DiscreteResources of(List<DiscreteResource> resources) {
+ static DiscreteResources of(Set<DiscreteResource> resources) {
return UnifiedDiscreteResources.of(resources);
}
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 891f35f..a20ca52 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
@@ -43,6 +43,10 @@
}
static DiscreteResources of(Set<DiscreteResource> resources) {
+ if (resources.isEmpty()) {
+ return DiscreteResources.empty();
+ }
+
DiscreteResource parent = resources.iterator().next().parent().get();
return of(parent, resources);
}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/NonEncodableDiscreteResources.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/NonEncodableDiscreteResources.java
index 7b991b4..333a40b 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/NonEncodableDiscreteResources.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/NonEncodableDiscreteResources.java
@@ -30,26 +30,23 @@
final class NonEncodableDiscreteResources implements DiscreteResources {
private final Set<DiscreteResource> values;
- static NonEncodableDiscreteResources empty() {
- return new NonEncodableDiscreteResources();
- }
+ static DiscreteResources of(Set<DiscreteResource> resources) {
+ if (resources.isEmpty()) {
+ return DiscreteResources.empty();
+ }
- static NonEncodableDiscreteResources of(List<DiscreteResource> resources) {
return new NonEncodableDiscreteResources(resources);
}
- private NonEncodableDiscreteResources() {
- this.values = new LinkedHashSet<>();
- }
-
- private NonEncodableDiscreteResources(List<DiscreteResource> values) {
- this.values = new LinkedHashSet<>(values);
- }
-
private NonEncodableDiscreteResources(Set<DiscreteResource> values) {
this.values = values;
}
+ // for serializer
+ private NonEncodableDiscreteResources() {
+ this.values = null;
+ }
+
@Override
public Optional<DiscreteResource> lookup(DiscreteResourceId id) {
DiscreteResource resource = Resources.discrete(id).resource();
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalDiscreteResourceSubStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalDiscreteResourceSubStore.java
index d4306a7..e98cb20 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalDiscreteResourceSubStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/TransactionalDiscreteResourceSubStore.java
@@ -24,6 +24,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
@@ -59,7 +60,7 @@
return true;
}
- DiscreteResources requested = DiscreteResources.of(values);
+ DiscreteResources requested = DiscreteResources.of(new LinkedHashSet<>(values));
DiscreteResources oldValues = childMap.putIfAbsent(key, requested);
if (oldValues == null) {
return true;
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/UnifiedDiscreteResources.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/UnifiedDiscreteResources.java
index ec121cd..1b4ded4 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/UnifiedDiscreteResources.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/UnifiedDiscreteResources.java
@@ -15,12 +15,18 @@
*/
package org.onosproject.store.resource.impl;
+import com.google.common.collect.Sets;
import org.onosproject.net.resource.DiscreteResource;
import org.onosproject.net.resource.DiscreteResourceId;
+import org.onosproject.net.resource.Resources;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* Represents a set of resources containing resources that can be encoded as integer
@@ -28,55 +34,66 @@
*/
final class UnifiedDiscreteResources implements DiscreteResources {
private final DiscreteResources nonEncodables;
+ private final DiscreteResources encodables;
+ private static final Codecs CODECS = Codecs.getInstance();
- static DiscreteResources empty() {
- return new UnifiedDiscreteResources();
+ static DiscreteResources of(Set<DiscreteResource> resources) {
+ if (resources.isEmpty()) {
+ return DiscreteResources.empty();
+ }
+
+ Map<Boolean, Set<DiscreteResource>> partitioned = resources.stream()
+ .collect(Collectors.partitioningBy(CODECS::isEncodable, Collectors.toCollection(LinkedHashSet::new)));
+ return new UnifiedDiscreteResources(
+ NonEncodableDiscreteResources.of(partitioned.get(false)),
+ EncodableDiscreteResources.of(partitioned.get(true))
+ );
}
- static DiscreteResources of(List<DiscreteResource> resources) {
- return new UnifiedDiscreteResources(resources);
- }
-
- private UnifiedDiscreteResources() {
- this.nonEncodables = NonEncodableDiscreteResources.empty();
- }
-
- private UnifiedDiscreteResources(List<DiscreteResource> resources) {
- this.nonEncodables = NonEncodableDiscreteResources.of(resources);
+ private UnifiedDiscreteResources(DiscreteResources nonEncodables, DiscreteResources encodables) {
+ this.nonEncodables = nonEncodables;
+ this.encodables = encodables;
}
@Override
public Optional<DiscreteResource> lookup(DiscreteResourceId id) {
+ if (CODECS.isEncodable(Resources.discrete(id).resource())) {
+ return encodables.lookup(id);
+ }
+
return nonEncodables.lookup(id);
}
@Override
public DiscreteResources difference(DiscreteResources other) {
- return nonEncodables.difference(other);
+ return of(Sets.difference(values(), other.values()));
}
@Override
public boolean isEmpty() {
- return nonEncodables.isEmpty();
+ return nonEncodables.isEmpty() && encodables.isEmpty();
}
@Override
public boolean containsAny(List<DiscreteResource> other) {
- return nonEncodables.containsAny(other);
+ Map<Boolean, List<DiscreteResource>> partitioned = other.stream()
+ .collect(Collectors.partitioningBy(CODECS::isEncodable));
+ return nonEncodables.containsAny(partitioned.get(false)) || encodables.containsAny(partitioned.get(true));
}
@Override
public DiscreteResources add(DiscreteResources other) {
- return nonEncodables.add(other);
+ return of(Sets.union(this.values(), other.values()));
}
@Override
public DiscreteResources remove(List<DiscreteResource> removed) {
- return nonEncodables.remove(removed);
+ return of(Sets.difference(values(), new LinkedHashSet<>(removed)));
}
@Override
public Set<DiscreteResource> values() {
- return nonEncodables.values();
+ return Stream.concat(encodables.values().stream(), nonEncodables.values().stream())
+ .collect(Collectors.toCollection(LinkedHashSet::new));
}
}