blob: 1e161a2af2d1767cd8996f4b3bf002305e6effb3 [file] [log] [blame]
package net.onrc.onos.api.flowmanager;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.PortNumber;
import net.onrc.onos.core.util.SwitchPort;
/**
* A directed connected tree topology representation used by TreeFlow.
*/
public class Tree extends FlowLinks {
Map<Dpid, Set<PortNumber>> ports = new HashMap<Dpid, Set<PortNumber>>();
Map<SwitchPort, FlowLink> inLinks = new HashMap<SwitchPort, FlowLink>();
Map<SwitchPort, FlowLink> outLinks = new HashMap<SwitchPort, FlowLink>();
/**
* Creates new instance.
*/
public Tree() {
super();
}
/**
* Creates new instance from the specified Path object.
*
* @param path the Path object
* @throws IllegalArgumentException if the path object does not form a
* single connected directed path topology
*/
public Tree(Path path) {
super();
checkNotNull(path);
for (FlowLink link : path) {
if (!addLink(link)) {
throw new IllegalArgumentException();
}
}
}
/**
* Creates new instance using FlowLinks object.
*
* @param links the FlowLinks object
* @throws IllegalArgumentException if the links object does not form a
* single connected directed tree topology
*/
public Tree(FlowLinks links) {
super();
checkNotNull(links);
for (FlowLink link : links) {
if (!addLink(link)) {
throw new IllegalArgumentException();
}
}
}
private void addPort(SwitchPort port) {
checkNotNull(port);
if (!ports.containsKey(port.dpid())) {
ports.put(port.dpid(), new HashSet<PortNumber>());
}
ports.get(port.dpid()).add(port.port());
}
/**
* Adds FlowLink object to this tree.
* <p>
* This method checks specified FlowLink object to keep this Tree object a
* connected tree.
*
* @param link FlowLink object to be added.
* @return true if succeeded, false otherwise.
*/
public boolean addLink(FlowLink link) {
checkNotNull(link);
if (links.size() > 0) {
if (!hasDpid(link.getSrcDpid()) && !hasDpid(link.getDstDpid())) {
// no attaching point
return false;
}
if (hasDpid(link.getSrcDpid()) && hasDpid(link.getDstDpid())) {
// loop or duplicated paths
return false;
}
}
if (hasSwitchPort(link.getSrcSwitchPort())
|| hasSwitchPort(link.getDstSwitchPort())) {
// some port has already been occupied by another link
return false;
}
links.add(link);
addPort(link.getSrcSwitchPort());
addPort(link.getDstSwitchPort());
inLinks.put(link.getDstSwitchPort(), link);
outLinks.put(link.getSrcSwitchPort(), link);
return true;
}
/**
* Checks if specified dpid exists in this tree.
*
* @param dpid DPID to be checked.
* @return true if found, false otherwise.
*/
public boolean hasDpid(Dpid dpid) {
return ports.containsKey(dpid);
}
/**
* Checks if specified switch-port exists in this tree.
*
* @param port SwitchPort object to be checked.
* @return true if found, false otherwise.
*/
public boolean hasSwitchPort(SwitchPort port) {
return inLinks.containsKey(port) || outLinks.containsKey(port);
}
@Override
public int hashCode() {
// TODO think if this is correct.
return super.hashCode();
}
@Override
public boolean equals(Object o) {
// TODO think if this is correct.
// - has to check equality using a set, not a list?
return super.equals(o);
}
}