Commit adddcbed authored by Björn Richerzhagen's avatar Björn Richerzhagen
Browse files

Graph-API updates

parent 320cc86f
......@@ -23,7 +23,9 @@ package de.tudarmstadt.maki.simonstrator.api.common.graph;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import de.tudarmstadt.maki.simonstrator.api.Graphs;
......@@ -38,7 +40,9 @@ public class BasicGraph implements Graph {
private Set<DirectedEdge> edges;
private Set<Node> nodes;
private Map<INodeID, Node> nodes;
private Set<Node> nodeSet;
/**
* Creates an empty graph. Components should create new graphs by using the
......@@ -46,7 +50,8 @@ public class BasicGraph implements Graph {
*/
public BasicGraph() {
edges = new LinkedHashSet<>();
nodes = new LinkedHashSet<>();
nodes = new LinkedHashMap<>();
nodeSet = new LinkedHashSet<>();
}
/**
......@@ -59,8 +64,11 @@ public class BasicGraph implements Graph {
*/
public BasicGraph(Set<Node> nodes, Set<DirectedEdge> edges) {
this.edges = edges;
this.nodes = nodes;
this.nodeSet = nodes;
this.nodes = new LinkedHashMap<>();
for (Node node : nodes) {
this.nodes.put(node.getId(), node);
}
assert checkGraphConsistency();
}
......@@ -100,13 +108,13 @@ public class BasicGraph implements Graph {
}
@Override
public DirectedEdge createEdge(Node from, Node to) {
return new DirectedEdge(from, to);
public DirectedEdge createEdge(INodeID from, INodeID to) {
return new DirectedEdge(getNode(from), getNode(to));
}
@Override
public DirectedEdge createEdge(Node from, Node to, double weight) {
return new DirectedEdge(from, to, weight);
public DirectedEdge createEdge(INodeID from, INodeID to, double weight) {
return new DirectedEdge(getNode(from), getNode(to), weight);
}
@Override
......@@ -116,7 +124,12 @@ public class BasicGraph implements Graph {
@Override
public Set<Node> getNodes() {
return this.nodes;
return nodeSet;
}
@Override
public Node getNode(INodeID nodeId) {
return nodes.get(nodeId);
}
@Override
......@@ -155,8 +168,12 @@ public class BasicGraph implements Graph {
}
// modify g accordingly
g.nodeSet.clear();
g.nodeSet.addAll(kHopNodes);
g.nodes.clear();
g.nodes.addAll(kHopNodes);
for (Node cnode : g.nodeSet) {
g.nodes.put(cnode.getId(), cnode);
}
g.edges.clear();
g.edges.addAll(kHopEdges);
......@@ -184,8 +201,8 @@ public class BasicGraph implements Graph {
*/
private boolean checkGraphConsistency() {
for (DirectedEdge directedEdge : edges) {
if (!nodes.contains(directedEdge.getStartNode())
|| !nodes.contains(directedEdge.getEndNode())) {
if (!nodeSet.contains(directedEdge.getStartNode())
|| !nodeSet.contains(directedEdge.getEndNode())) {
return false;
}
}
......@@ -242,7 +259,7 @@ public class BasicGraph implements Graph {
*/
@Override
public Set<DirectedEdge> getOutgoingEdges(Node node) {
assert this.nodes.contains(node);
assert this.nodeSet.contains(node);
Set<DirectedEdge> outgoingEdges = new LinkedHashSet<DirectedEdge>();
for (DirectedEdge directedEdge : this.edges) {
......@@ -262,7 +279,7 @@ public class BasicGraph implements Graph {
*/
@Override
public Set<DirectedEdge> getIncomingEdges(Node node) {
assert this.nodes.contains(node);
assert this.nodeSet.contains(node);
Set<DirectedEdge> incomingEdges = new LinkedHashSet<DirectedEdge>();
for (DirectedEdge directedEdge : this.edges) {
......@@ -312,7 +329,9 @@ public class BasicGraph implements Graph {
}
public boolean remove(Node node) {
return this.nodes.remove(node);
boolean removed = this.nodeSet.remove(node);
this.nodes.remove(node.getId());
return removed;
}
public boolean remove(DirectedEdge edge) {
......@@ -333,7 +352,8 @@ public class BasicGraph implements Graph {
@Override
public Graph add(GraphElement element) {
if (element instanceof Node) {
nodes.add((Node) element);
nodeSet.add((Node) element);
nodes.put(((Node) element).getId(), (Node) element);
} else if (element instanceof DirectedEdge) {
edges.add((DirectedEdge) element);
} else {
......@@ -346,7 +366,8 @@ public class BasicGraph implements Graph {
@Override
public boolean remove(GraphElement element) {
if (element instanceof Node) {
return nodes.remove((Node) element);
nodes.remove(((Node) element).getId());
return nodeSet.remove(((Node) element).getId());
} else if (element instanceof DirectedEdge) {
return edges.remove((DirectedEdge) element);
} else {
......@@ -358,7 +379,7 @@ public class BasicGraph implements Graph {
public BasicGraph clone() {
// clone nodes
Set<Node> newNodes = new LinkedHashSet<Node>();
for (Node node : this.nodes) {
for (Node node : this.nodeSet) {
Node newNode = node.clone();
newNodes.add(newNode);
}
......@@ -377,7 +398,7 @@ public class BasicGraph implements Graph {
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Nodes: ");
sb.append(this.nodes);
sb.append(this.nodeSet);
sb.append(" Edges: ");
sb.append(this.edges);
return sb.toString();
......@@ -388,7 +409,7 @@ public class BasicGraph implements Graph {
final int prime = 31;
int result = 1;
result = prime * result + ((edges == null) ? 0 : edges.hashCode());
result = prime * result + ((nodes == null) ? 0 : nodes.hashCode());
result = prime * result + ((nodeSet == null) ? 0 : nodeSet.hashCode());
return result;
}
......@@ -406,10 +427,10 @@ public class BasicGraph implements Graph {
return false;
} else if (!edges.equals(other.edges))
return false;
if (nodes == null) {
if (other.nodes != null)
if (nodeSet == null) {
if (other.nodeSet != null)
return false;
} else if (!nodes.equals(other.nodes))
} else if (!nodeSet.equals(other.nodeSet))
return false;
return true;
}
......@@ -425,10 +446,10 @@ public class BasicGraph implements Graph {
otherGraph.getEdges())
&& isContainedInBasedOnEqualAttributes(otherGraph.getEdges(),
this.edges)
&& isContainedInBasedOnEqualAttributes(this.nodes,
&& isContainedInBasedOnEqualAttributes(this.nodeSet,
otherGraph.getNodes())
&& isContainedInBasedOnEqualAttributes(otherGraph.getNodes(),
this.nodes);
this.nodeSet);
}
......@@ -481,12 +502,12 @@ public class BasicGraph implements Graph {
}
@Override
public Graph createAndAddEdge(Node from, Node to) {
public Graph createAndAddEdge(INodeID from, INodeID to) {
return add(createEdge(from, to));
}
@Override
public Graph createAndAddEdge(Node from, Node to, double weight) {
public Graph createAndAddEdge(INodeID from, INodeID to, double weight) {
return add(createEdge(from, to, weight));
}
......
......@@ -53,7 +53,7 @@ public interface Graph extends Cloneable {
* @param to
* @return
*/
public DirectedEdge createEdge(Node from, Node to);
public DirectedEdge createEdge(INodeID from, INodeID to);
/**
* Create and return a weighted edge. The edge is <strong>not</strong> yet
......@@ -66,7 +66,7 @@ public interface Graph extends Cloneable {
* weight of the edge
* @return
*/
public DirectedEdge createEdge(Node from, Node to, double weight);
public DirectedEdge createEdge(INodeID from, INodeID to, double weight);
/*
* Graph Interface and convenience methods
......@@ -74,6 +74,15 @@ public interface Graph extends Cloneable {
public Set<Node> getNodes();
/**
* Returns the node with the given ID if existent in the graph. null
* otherwise
*
* @param node
* @return
*/
public Node getNode(INodeID nodeId);
public Set<DirectedEdge> getEdges();
/**
......@@ -155,9 +164,9 @@ public interface Graph extends Cloneable {
*/
public Graph createAndAddNode(INodeID id);
public Graph createAndAddEdge(Node from, Node to);
public Graph createAndAddEdge(INodeID from, INodeID to);
public Graph createAndAddEdge(Node from, Node to, double weight);
public Graph createAndAddEdge(INodeID from, INodeID to, double weight);
/**
* TODO define the method's contract w.r.t. duplicates etc.
......
......@@ -21,12 +21,35 @@
package de.tudarmstadt.maki.simonstrator.api.common.graph;
/**
* Minimal Edge Interface as used in the SiS. Edges can be annotated with
* {@link IEdgeProperty}s.
*
* @author Bjoern Richerzhagen
*
*/
public interface IEdge {
/**
* {@link INodeID} of the source node
*
* @return
*/
public INodeID fromId();
/**
* {@link INodeID} of the destination node
*
* @return
*/
public INodeID toId();
/**
* Get the {@link IEdgeProperty} object that can be used to annotate the
* given edge with additional properties.
*
* @return
*/
public IEdgeProperty getEdgeProperties();
}
......@@ -20,8 +20,19 @@
package de.tudarmstadt.maki.simonstrator.api.common.graph;
/**
* An object defining additional properties for an edge in a graph.
*
* @author Bjoern Richerzhagen
*
*/
public interface IEdgeProperty {
// marker
/**
* For now: basic weights.
*
* @return
*/
public double getWeight();
}
......@@ -20,11 +20,26 @@
package de.tudarmstadt.maki.simonstrator.api.common.graph;
/**
* Basic node interface, as used by the SiS.
*
* @author Bjoern Richerzhagen
*
*/
public interface INode {
/**
* {@link INodeID} of the node.
*
* @return
*/
public INodeID getId();
/**
* Additional Properties attached to this node object.
*
* @return
*/
public INodeProperty getProperties();
}
......@@ -25,13 +25,31 @@ import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.component.network.NetID;
/**
* As the SiS and Monitoring deal with multiple topologies collected in the
* underlay, any overlay and the applications, we need a common identifier for
* nodes. Seems that the NetID is suited for most practical scenarios. This
* class provides static methods to retrieve the ID.
*
* In cases, where a NetID is not known or not needed (e.g., in graph utils),
* there is also a get-method that is based on strings. This, however, should
* not be used in production overlay code.
*
* @author Bjoern Richerzhagen
*
*/
public class INodeID {
public final NetID netId;
private final static Map<NetID, INodeID> ids = new LinkedHashMap<>();
/**
* Retrieve the {@link INodeID} for the given {@link NetID}.
*
* @param netId
* @return
*/
public static INodeID get(NetID netId) {
INodeID id = ids.get(netId);
if (id == null) {
......@@ -41,6 +59,18 @@ public class INodeID {
return id;
}
/**
*
* @param identifier
* @return
* @deprecated This should not be used in production code.
*/
@Deprecated
public static INodeID get(String identifier) {
NetID netId = new DummyNetID(identifier);
return get(netId);
}
private INodeID(NetID netId) {
this.netId = netId;
}
......@@ -70,4 +100,61 @@ public class INodeID {
return true;
}
@Override
public String toString() {
return netId.toString();
}
/**
* A dummy NetID used internally, if the String-based identifiers are used
* instead of the {@link NetID}-based IDs.
*
* @author Bjoern Richerzhagen
*
*/
private static class DummyNetID implements NetID {
private final String id;
public DummyNetID(String id) {
this.id = id;
}
@Override
public int getTransmissionSize() {
return 4;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DummyNetID other = (DummyNetID) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
@Override
public String toString() {
return id;
}
}
}
......@@ -20,6 +20,14 @@
package de.tudarmstadt.maki.simonstrator.api.common.graph;
/**
* Object supporting node annotations in a graph.
*
* TODO define later
*
* @author Bjoern Richerzhagen
*
*/
public interface INodeProperty {
// marker
......
......@@ -35,9 +35,11 @@ import de.tudarmstadt.maki.simonstrator.api.component.HostComponent;
*/
public class SiSInfoProperties {
public static final SiSInfoProperties NONE = new SiSInfoProperties();
private SiSScope scope = null;
private Class<? extends HostComponent> sourceComponent;
private Class<? extends HostComponent> sourceComponent = null;
/*
* Here, we should collect some ideas for common description properties.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment