Make resource retrieval more efficient when specifing resource type
This resolves ONOS-4666
Change-Id: I9d09b60531ca48b36fc20f43498cda62f1badb8b
diff --git a/core/api/src/main/java/org/onosproject/net/resource/ResourceStore.java b/core/api/src/main/java/org/onosproject/net/resource/ResourceStore.java
index b531d04..8456106 100644
--- a/core/api/src/main/java/org/onosproject/net/resource/ResourceStore.java
+++ b/core/api/src/main/java/org/onosproject/net/resource/ResourceStore.java
@@ -111,6 +111,18 @@
Set<Resource> getChildResources(DiscreteResourceId parent);
/**
+ * Returns a set of the child resources of the specified parent and whose type is
+ * the specified class.
+ *
+ * @param parent ID of the parent of the resources to be returned
+ * @param cls class instance of the children
+ * @param <T> type of the resource
+ * @return a set of the child resources of the specified parent and whose type is
+ * the specified class
+ */
+ <T> Set<Resource> getChildResources(DiscreteResourceId parent, Class<T> cls);
+
+ /**
* Returns a collection of the resources which are children of the specified parent and
* whose type is the specified class.
*
diff --git a/core/net/src/main/java/org/onosproject/net/resource/impl/ResourceManager.java b/core/net/src/main/java/org/onosproject/net/resource/impl/ResourceManager.java
index 60a8516..52ea71d 100644
--- a/core/net/src/main/java/org/onosproject/net/resource/impl/ResourceManager.java
+++ b/core/net/src/main/java/org/onosproject/net/resource/impl/ResourceManager.java
@@ -165,9 +165,9 @@
checkNotNull(parent);
checkNotNull(cls);
- // naive implementation
- return getAvailableResources(parent).stream()
- .filter(resource -> resource.isTypeOf(cls))
+ return store.getChildResources(parent, cls).stream()
+ // We access store twice in this method, then the store may be updated by others
+ .filter(store::isAvailable)
.collect(Collectors.toSet());
}
@@ -177,9 +177,11 @@
checkNotNull(parent);
checkNotNull(cls);
- // naive implementation
- return getAvailableResources(parent).stream()
- .flatMap(resource -> Tools.stream(resource.valueAs(cls)))
+ return store.getChildResources(parent, cls).stream()
+ // We access store twice in this method, then the store may be updated by others
+ .filter(store::isAvailable)
+ .map(x -> x.valueAs(cls))
+ .flatMap(Tools::stream)
.collect(Collectors.toSet());
}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentContinuousResourceSubStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentContinuousResourceSubStore.java
index e9c9ad7..60eed40 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentContinuousResourceSubStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentContinuousResourceSubStore.java
@@ -32,6 +32,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.onosproject.store.resource.impl.ConsistentResourceStore.SERIALIZER;
@@ -79,6 +80,13 @@
return children.value();
}
+ <T> Set<ContinuousResource> getChildResources(DiscreteResourceId parent, Class<T> cls) {
+ // naive implementation
+ return getChildResources(parent).stream()
+ .filter(x -> x.isTypeOf(cls))
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ }
+
public boolean isAvailable(ContinuousResource resource) {
// check if it's registered or not.
Versioned<Set<ContinuousResource>> children = childMap.get(resource.parent().get().id());
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentDiscreteResourceSubStore.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentDiscreteResourceSubStore.java
index 5650585..d036c5f 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentDiscreteResourceSubStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/ConsistentDiscreteResourceSubStore.java
@@ -76,6 +76,16 @@
return children.value().values();
}
+ <T> Set<DiscreteResource> getChildResources(DiscreteResourceId parent, Class<T> cls) {
+ Versioned<DiscreteResources> children = childMap.get(parent);
+
+ if (children == null) {
+ return ImmutableSet.of();
+ }
+
+ return children.value().valuesOf(cls);
+ }
+
boolean isAvailable(DiscreteResource resource) {
return getResourceAllocations(resource.id()).isEmpty();
}
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 69645b1..0ecc108 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
@@ -296,6 +296,17 @@
.build();
}
+ @Override
+ public <T> Set<Resource> getChildResources(DiscreteResourceId parent, Class<T> cls) {
+ checkNotNull(parent);
+ checkNotNull(cls);
+
+ return ImmutableSet.<Resource>builder()
+ .addAll(discreteStore.getChildResources(parent, cls))
+ .addAll(continuousStore.getChildResources(parent, cls))
+ .build();
+ }
+
// computational complexity: O(n) where n is the number of the children of the parent
@Override
public <T> Collection<Resource> getAllocatedResources(DiscreteResourceId parent, Class<T> cls) {
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 b6acccc..3bb1f07 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
@@ -91,4 +91,13 @@
* @return all resources
*/
Set<DiscreteResource> values();
+
+ /**
+ * Returns all of resources this instance holds and filtered by the specified type.
+ *
+ * @param cls class instance of the resource value
+ * @param <T> type of the resource value
+ * @return all of resources this instance holds and filtered by the specified type
+ */
+ <T> Set<DiscreteResource> valuesOf(Class<T> cls);
}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EmptyDiscreteResources.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EmptyDiscreteResources.java
index d7c0f24..55a0e94 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EmptyDiscreteResources.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/EmptyDiscreteResources.java
@@ -68,4 +68,9 @@
.add("values", ImmutableSet.of())
.toString();
}
+
+ @Override
+ public <T> Set<DiscreteResource> valuesOf(Class<T> cls) {
+ return ImmutableSet.of();
+ }
}
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 25ec5a7..512b233 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
@@ -16,6 +16,7 @@
package org.onosproject.store.resource.impl;
import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.onosproject.net.resource.DiscreteResource;
import org.onosproject.net.resource.DiscreteResourceCodec;
@@ -114,6 +115,13 @@
.collect(Collectors.toCollection(LinkedHashSet::new));
}
+ @Override
+ public <T> Set<DiscreteResource> valuesOf(Class<T> cls) {
+ return Optional.ofNullable(values.get(cls))
+ .map(x -> x.values(parent.id()))
+ .orElse(ImmutableSet.of());
+ }
+
DiscreteResource parent() {
return parent;
}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/GenericDiscreteResources.java b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/GenericDiscreteResources.java
index 79eb13d..1aa8bb9 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/resource/impl/GenericDiscreteResources.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/resource/impl/GenericDiscreteResources.java
@@ -25,6 +25,7 @@
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
final class GenericDiscreteResources implements DiscreteResources {
private final Set<DiscreteResource> values;
@@ -87,6 +88,13 @@
}
@Override
+ public <T> Set<DiscreteResource> valuesOf(Class<T> cls) {
+ return values.stream()
+ .filter(x -> x.isTypeOf(cls))
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ }
+
+ @Override
public int hashCode() {
return Objects.hash(values);
}
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 0bd1fca..56e6b87 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
@@ -93,6 +93,11 @@
.collect(Collectors.toCollection(LinkedHashSet::new));
}
+ public <T> Set<DiscreteResource> valuesOf(Class<T> cls) {
+ return Stream.concat(encodables.valuesOf(cls).stream(), generics.valuesOf(cls).stream())
+ .collect(Collectors.toCollection(LinkedHashSet::new));
+ }
+
@Override
public int hashCode() {
return Objects.hash(generics, encodables);