Sho SHIMIZU
Committed by Gerrit Code Review

Make resource retrieval more efficient when specifing resource type

This resolves ONOS-4666

Change-Id: I9d09b60531ca48b36fc20f43498cda62f1badb8b
......@@ -111,6 +111,18 @@ public interface ResourceStore extends Store<ResourceEvent, ResourceStoreDelegat
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.
*
......
......@@ -165,9 +165,9 @@ public final class ResourceManager extends AbstractListenerManager<ResourceEvent
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 @@ public final class ResourceManager extends AbstractListenerManager<ResourceEvent
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());
}
......
......@@ -32,6 +32,7 @@ import org.onosproject.store.service.Versioned;
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 @@ class ConsistentContinuousResourceSubStore {
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());
......
......@@ -76,6 +76,16 @@ class ConsistentDiscreteResourceSubStore {
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();
}
......
......@@ -296,6 +296,17 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour
.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) {
......
......@@ -91,4 +91,13 @@ interface DiscreteResources {
* @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);
}
......
......@@ -68,4 +68,9 @@ final class EmptyDiscreteResources implements DiscreteResources {
.add("values", ImmutableSet.of())
.toString();
}
@Override
public <T> Set<DiscreteResource> valuesOf(Class<T> cls) {
return ImmutableSet.of();
}
}
......
......@@ -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 @@ final class EncodableDiscreteResources implements DiscreteResources {
.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;
}
......
......@@ -25,6 +25,7 @@ import java.util.LinkedHashSet;
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 @@ final class GenericDiscreteResources implements DiscreteResources {
}
@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);
}
......
......@@ -93,6 +93,11 @@ final class UnifiedDiscreteResources implements DiscreteResources {
.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);
......