Sho SHIMIZU
Committed by Gerrit Code Review

Refactor ResourcePath internal implementation

Change-Id: Idb3aa467b4d0e8181adf0d1766812a038b5408ac
......@@ -20,6 +20,7 @@ import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
......@@ -39,18 +40,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
@Beta
public final class ResourcePath {
private final List<Object> resources;
private final ResourcePath parent;
private final Object last;
public static final ResourcePath ROOT = new ResourcePath(ImmutableList.of());
public static ResourcePath child(ResourcePath parent, Object child) {
ImmutableList<Object> components = ImmutableList.builder()
.addAll(parent.components())
.add(child)
.build();
return new ResourcePath(components);
}
/**
* Creates an resource path from the specified components.
*
......@@ -67,13 +61,32 @@ public final class ResourcePath {
*/
public ResourcePath(List<Object> components) {
checkNotNull(components);
if (components.isEmpty()) {
this.parent = null;
this.last = null;
return;
}
LinkedList<Object> children = new LinkedList<>(components);
this.last = children.pollLast();
this.parent = new ResourcePath(children);
}
this.resources = ImmutableList.copyOf(components);
/**
* Creates an resource path from the specified parent and child.
*
* @param parent the parent of this resource
* @param last a child of the parent
*/
public ResourcePath(ResourcePath parent, Object last) {
this.parent = checkNotNull(parent);
this.last = checkNotNull(last);
}
// for serialization
private ResourcePath() {
this.resources = null;
this.parent = null;
this.last = null;
}
/**
......@@ -82,7 +95,15 @@ public final class ResourcePath {
* @return the components of this resource path
*/
public List<Object> components() {
return resources;
LinkedList<Object> components = new LinkedList<>();
ResourcePath parentPath = parent;
while (parentPath != null) {
components.addFirst(last);
parentPath = parent.parent;
}
return components;
}
/**
......@@ -93,20 +114,11 @@ public final class ResourcePath {
* If there is no parent, empty instance will be returned.
*/
public Optional<ResourcePath> parent() {
if (!isRoot()) {
return Optional.of(new ResourcePath(resources.subList(0, resources.size() - 1)));
}
return Optional.empty();
return Optional.ofNullable(parent);
}
/**
* Returns true if the path represents root.
*
* @return true if the path represents root, false otherwise.
*/
public boolean isRoot() {
return resources.size() == 0;
public ResourcePath child(Object child) {
return new ResourcePath(this, child);
}
/**
......@@ -115,14 +127,13 @@ public final class ResourcePath {
* @return the last component of this instance.
* The return value is equal to the last object of {@code components()}.
*/
public Object lastComponent() {
int last = resources.size() - 1;
return resources.get(last);
public Object last() {
return last;
}
@Override
public int hashCode() {
return resources.hashCode();
return Objects.hash(this.parent, this.last);
}
@Override
......@@ -134,13 +145,15 @@ public final class ResourcePath {
return false;
}
final ResourcePath that = (ResourcePath) obj;
return Objects.equals(this.resources, that.resources);
return Objects.equals(this.parent, that.parent)
&& Objects.equals(this.last, that.last);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("resources", resources)
.add("parent", parent)
.add("last", last)
.toString();
}
}
......
......@@ -76,7 +76,7 @@ public class ResourcePathTest {
LinkKey linkKey = LinkKey.linkKey(CP1_1, CP2_1);
ResourcePath path = new ResourcePath(linkKey);
LinkKey child = (LinkKey) path.lastComponent();
LinkKey child = (LinkKey) path.last();
assertThat(child, is(linkKey));
}
}
......
......@@ -146,8 +146,8 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> {
private Optional<MplsLabel> findMplsLabel(LinkKey link) {
return resourceService.getAvailableResources(new ResourcePath(link)).stream()
.filter(x -> x.lastComponent() instanceof MplsLabel)
.map(x -> (MplsLabel) x.lastComponent())
.filter(x -> x.last() instanceof MplsLabel)
.map(x -> (MplsLabel) x.last())
.findFirst();
}
......
......@@ -183,7 +183,7 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
IndexedLambda minLambda = findFirstLambda(lambdas);
List<ResourcePath> lambdaResources = path.links().stream()
.map(x -> new ResourcePath(linkKey(x.src(), x.dst())))
.map(x -> ResourcePath.child(x, minLambda))
.map(x -> x.child(minLambda))
.collect(Collectors.toList());
List<ResourceAllocation> allocations = resourceService.allocate(intent.id(), lambdaResources);
......@@ -198,8 +198,8 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical
return links.stream()
.map(x -> new ResourcePath(linkKey(x.src(), x.dst())))
.map(resourceService::getAvailableResources)
.map(x -> Iterables.filter(x, r -> r.lastComponent() instanceof IndexedLambda))
.map(x -> Iterables.transform(x, r -> (IndexedLambda) r.lastComponent()))
.map(x -> Iterables.filter(x, r -> r.last() instanceof IndexedLambda))
.map(x -> Iterables.transform(x, r -> (IndexedLambda) r.last()))
.map(x -> (Set<IndexedLambda>) ImmutableSet.copyOf(x))
.reduce(Sets::intersection)
.orElse(Collections.emptySet());
......
......@@ -169,7 +169,7 @@ public final class ResourceManager extends AbstractListenerManager<ResourceEvent
checkNotNull(children);
checkArgument(!children.isEmpty());
List<ResourcePath> resources = Lists.transform(children, x -> ResourcePath.child(parent, x));
List<ResourcePath> resources = Lists.transform(children, parent::child);
return store.register(resources);
}
......@@ -179,7 +179,7 @@ public final class ResourceManager extends AbstractListenerManager<ResourceEvent
checkNotNull(children);
checkArgument(!children.isEmpty());
List<ResourcePath> resources = Lists.transform(children, x -> ResourcePath.child(parent, x));
List<ResourcePath> resources = Lists.transform(children, parent::child);
return store.unregister(resources);
}
......
......@@ -90,7 +90,7 @@ class MockResourceService implements ResourceService {
@Override
public Collection<ResourcePath> getAvailableResources(ResourcePath parent) {
ResourcePath resource = ResourcePath.child(parent, MplsLabel.mplsLabel(10));
ResourcePath resource = parent.child(MplsLabel.mplsLabel(10));
return ImmutableList.of(resource);
}
......
......@@ -264,7 +264,7 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour
}
return children.value().stream()
.filter(x -> x.lastComponent().getClass().equals(cls))
.filter(x -> x.last().getClass().equals(cls))
.filter(consumerMap::containsKey)
.collect(Collectors.toList());
}
......@@ -344,7 +344,7 @@ public class ConsistentResourceStore extends AbstractStore<ResourceEvent, Resour
*/
private boolean isRegistered(TransactionalMap<ResourcePath, List<ResourcePath>> map, ResourcePath resource) {
// root is always regarded to be registered
if (resource.isRoot()) {
if (!resource.parent().isPresent()) {
return true;
}
......