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

Merge remote-tracking branch 'origin/m_stein/master-A1' into

br/a1-master-merge

Conflicts:
	pom.xml
	src/de/tudarmstadt/maki/simonstrator/api/component/sis/type/SiSTypes.java
parents f6e37288 71cab85f
......@@ -54,6 +54,7 @@ org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
......@@ -99,6 +100,7 @@ org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
......@@ -146,6 +148,7 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=inser
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
......@@ -223,6 +226,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do n
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
......@@ -277,7 +281,7 @@ org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.lineSplit=80
org.eclipse.jdt.core.formatter.lineSplit=120
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
......@@ -290,3 +294,4 @@ org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
......@@ -70,15 +70,18 @@ sp_cleanup.always_use_blocks=true
sp_cleanup.always_use_parentheses_in_expressions=false
sp_cleanup.always_use_this_for_non_static_field_access=false
sp_cleanup.always_use_this_for_non_static_method_access=false
sp_cleanup.convert_functional_interfaces=false
sp_cleanup.convert_to_enhanced_for_loop=false
sp_cleanup.correct_indentation=false
sp_cleanup.format_source_code=true
sp_cleanup.format_source_code_changes_only=true
sp_cleanup.insert_inferred_type_arguments=false
sp_cleanup.make_local_variable_final=false
sp_cleanup.make_parameters_final=false
sp_cleanup.make_private_fields_final=true
sp_cleanup.make_type_abstract_if_missing_method=false
sp_cleanup.make_variable_declarations_final=true
sp_cleanup.moflon.createinjections=false
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
sp_cleanup.on_save_use_additional_actions=false
......@@ -89,6 +92,7 @@ sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
sp_cleanup.remove_redundant_type_arguments=false
sp_cleanup.remove_trailing_whitespaces=false
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
......@@ -102,10 +106,13 @@ sp_cleanup.remove_unused_private_methods=true
sp_cleanup.remove_unused_private_types=true
sp_cleanup.sort_members=false
sp_cleanup.sort_members_all=false
sp_cleanup.use_anonymous_class_creation=false
sp_cleanup.use_blocks=false
sp_cleanup.use_blocks_only_for_return_and_throw=false
sp_cleanup.use_lambda=false
sp_cleanup.use_parentheses_in_expressions=false
sp_cleanup.use_this_for_non_static_field_access=false
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
sp_cleanup.use_this_for_non_static_method_access=false
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
sp_cleanup.use_type_arguments=false
......@@ -88,5 +88,12 @@
<url>https://dev.kom.e-technik.tu-darmstadt.de/mvn/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -19,22 +19,22 @@
*/
package de.tudarmstadt.maki.simonstrator.api;
package de.tudarmstadt.maki.simonstrator.api;
/**
*
* The event handler is notified upon incoming events.
*
* @author Bjoern Richerzhagen
*
*/
public interface EventHandler {
*/
public interface EventHandler {
/**
* This method passes an occurred Event to its appropriate EventHandler
*
* @param content
*/
public void eventOccurred(Object content, int type);
}
*/
public void eventOccurred(Object content, int type);
}
......@@ -89,8 +89,8 @@ public final class Graphs {
public static Graph createGraph(Iterable<? extends INode> nodes,
Iterable<? extends IEdge> edges) {
Graph graph = getGraphComponent().createGraph();
graph.addElements(nodes);
graph.addElements(edges);
graph.addNodes(nodes);
graph.addEdges(edges);
return graph;
}
......@@ -125,6 +125,10 @@ public final class Graphs {
return new DirectedEdge(sourceId, targetId);
}
public static IEdge createDirectedEdge(EdgeID edgeId, INodeID sourceId, INodeID targetId) {
return new DirectedEdge(sourceId, targetId, edgeId);
}
public static Node createNode(long id) {
return new Node(INodeID.get(id));
}
......@@ -133,4 +137,8 @@ public final class Graphs {
return new Node(INodeID.get(id));
}
public static INode createNode(INodeID id) {
return new Node(id);
}
}
......@@ -19,35 +19,35 @@
*/
package de.tudarmstadt.maki.simonstrator.api;
package de.tudarmstadt.maki.simonstrator.api;
import java.io.Serializable;
/**
* General message interface for all messages exchanged between inside of the
* same layer in the simulator. Each layer and component will have their own
* sub-interface or implementation of this class.
*
* @author Konstantin Pussep
* @author Sebastian Kaune
* @version 3.0, 03.12.2007
*
*/
public interface Message extends Serializable {
/**
* Returns the message size in bytes
*
* @return message size in bytes
*/
public long getSize();
/**
* Returns the payload of a message
*
* @return payload of message
*/
public Message getPayload();
}
/**
* General message interface for all messages exchanged between inside of the
* same layer in the simulator. Each layer and component will have their own
* sub-interface or implementation of this class.
*
* @author Konstantin Pussep
* @author Sebastian Kaune
* @version 3.0, 03.12.2007
*
*/
public interface Message extends Serializable {
/**
* Returns the message size in bytes
*
* @return message size in bytes
*/
public long getSize();
/**
* Returns the payload of a message
*
* @return payload of message
*/
public Message getPayload();
}
......@@ -165,7 +165,7 @@ public final class Time {
return Math.round(Math.floor(getSimSeconds(time) / 60d));
}
private static long getHours(long time) {
public static long getHours(long time) {
return Math.round(Math.floor(getSimMinutes(time) / 60d));
}
......
......@@ -38,18 +38,10 @@ package de.tudarmstadt.maki.simonstrator.api.common;
*/
public interface UniqueID extends Transmitable, Comparable<UniqueID> {
// TODO BR: The documentation is outdated (rkluge)
/**
* Representation as a BigInteger, from which you might derive
* representations as double, etc. Usually, there should be no need to
* actually use this method. All you need to to with IDs in the overlay
* should be sorting (as provided by the IDSpace) and comparison/equality
* checks.
*
* <b>For performance reasons, a reference to the internal BigInteger-Object
* is returned. DO NOT modify the value of this reference!</b>
*
* @return
* Representation as a long. Usually, there should be no need to actually
* use this method. All you need to to with IDs in the overlay should be
* sorting (as provided by the IDSpace) and comparison/equality checks.
*/
public long value();
......
......@@ -22,6 +22,7 @@ package de.tudarmstadt.maki.simonstrator.api.common.graph;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
......@@ -58,6 +59,12 @@ public class BasicGraph implements Graph {
// Assigns to each node the set of incoming edges of this node
private final Map<INodeID, Set<IEdge>> incomingAdjacencyList = new HashMap<>();
// Assigns to each node the set of successors of this node
private final Map<INodeID, HashSet<INodeID>> successorNodes = new HashMap<>();
// Assigns to each node the set of predecessors of this node
private final Map<INodeID, HashSet<INodeID>> predecessorNodes = new HashMap<>();
/**
* Creates an empty graph. Components should create new graphs by using the
* {@link Graphs} class in the API
......@@ -98,8 +105,8 @@ public class BasicGraph implements Graph {
public BasicGraph(Iterable<? extends IEdge> edges) {
this();
for (final IEdge edge : edges) {
this.addNode(this.createNode(edge.fromId()));
this.addNode(this.createNode(edge.toId()));
this.createAndAddNode(edge.fromId());
this.createAndAddNode(edge.toId());
}
this.addElements(edges);
}
......@@ -152,9 +159,7 @@ public class BasicGraph implements Graph {
if (this.containsNode(id)) {
return this.getNode(id);
} else {
Node newNode = new Node(id);
this.addNode(newNode);
return newNode;
return new Node(id);
}
}
......@@ -183,6 +188,8 @@ public class BasicGraph implements Graph {
this.edgesById.put(edge.getId(), edge);
this.outgoingAdjacencyList.get(edge.fromId()).add(edge);
this.incomingAdjacencyList.get(edge.toId()).add(edge);
this.successorNodes.get(edge.fromId()).add(edge.toId());
this.predecessorNodes.get(edge.toId()).add(edge.fromId());
return true;
} else {
return false;
......@@ -196,6 +203,8 @@ public class BasicGraph implements Graph {
this.nodesById.put(node.getId(), node);
this.incomingAdjacencyList.put(node.getId(), new HashSet<IEdge>());
this.outgoingAdjacencyList.put(node.getId(), new HashSet<IEdge>());
this.successorNodes.put(node.getId(), new HashSet<INodeID>());
this.predecessorNodes.put(node.getId(), new HashSet<INodeID>());
return true;
} else {
return false;
......@@ -258,6 +267,8 @@ public class BasicGraph implements Graph {
this.incomingAdjacencyList.get(edge.toId()).remove(edge);
this.outgoingAdjacencyList.get(edge.fromId()).remove(edge);
this.successorNodes.get(edge.fromId()).remove(edge.toId());
this.predecessorNodes.get(edge.toId()).remove(edge.fromId());
this.edges.remove(edge);
this.edgesById.remove(edge.getId());
return true;
......@@ -273,6 +284,10 @@ public class BasicGraph implements Graph {
return this.nodesById.keySet();
}
public Set<INodeID> getNodeIdsSet() {
return this.nodesById.keySet();
}
@Override
public Set<EdgeID> getEdgeIds() {
return this.edgesById.keySet();
......@@ -321,14 +336,43 @@ public class BasicGraph implements Graph {
@Override
public IEdge getEdge(INodeID from, INodeID to) {
for (IEdge edge : edges) {
if (edge.toId().equals(to) && edge.fromId().equals(from)) {
return edge;
if (!this.containsNode(from))
return null;
if (!this.containsNode(to))
return null;
final Set<IEdge> outgoingEdgesOfFrom = this.outgoingAdjacencyList.get(from);
for (final IEdge outgoingEdgeOfFrom : outgoingEdgesOfFrom) {
if (outgoingEdgeOfFrom.toId().equals(to)) {
return outgoingEdgeOfFrom;
}
}
return null;
}
@Override
public Collection<IEdge> getEdges(INodeID from, INodeID to) {
final List<IEdge> resultSet = new ArrayList<>();
if (!this.containsNode(from))
return resultSet;
if (!this.containsNode(to))
return resultSet;
final Set<IEdge> outgoingEdgesOfFrom = this.outgoingAdjacencyList.get(from);
for (final IEdge outgoingEdgeOfFrom : outgoingEdgesOfFrom) {
if (outgoingEdgeOfFrom.toId().equals(to)) {
resultSet.add(outgoingEdgeOfFrom);
}
}
return resultSet;
}
@Override
public IEdge getEdge(EdgeID edgeID) {
return this.edgesById.get(edgeID);
......@@ -387,6 +431,8 @@ public class BasicGraph implements Graph {
this.edges.clear();
this.incomingAdjacencyList.clear();
this.outgoingAdjacencyList.clear();
this.predecessorNodes.clear();
this.successorNodes.clear();
}
/**
......@@ -399,8 +445,11 @@ public class BasicGraph implements Graph {
@Override
public Set<INodeID> getNeighbors(INodeID center, int k,
boolean directedNeighborhood) {
return getNeighbors(center, k, directedNeighborhood,
new LinkedHashSet<INodeID>());
// assert (getNeighbors(center, k, directedNeighborhood, new
// LinkedHashSet<INodeID>())
// .equals(getNeighborsIter(center, k, directedNeighborhood)));
return getNeighborsIter(center, k, directedNeighborhood);
}
/**
......@@ -419,22 +468,55 @@ public class BasicGraph implements Graph {
}
// helper method
private Set<INodeID> getNeighborsIter(INodeID node, int k,
boolean directedNeighborhood) {
HashSet<INodeID> visited = new HashSet<INodeID>();
// visited.add(node);
if (k < 0)
throw new IllegalArgumentException("k must be >=0, but was " + k);
if (k == 0) {
return visited;
}
HashSet<INodeID> neighbors = new HashSet<INodeID>();
HashSet<INodeID> newNeighbors = new HashSet<INodeID>();
neighbors.add(node);
for (int i = k; i > 0; i--) {
for (INodeID neighbor : neighbors) {
if (visited.add(neighbor))
newNeighbors.addAll(getNeighbors(neighbor, directedNeighborhood));
}
neighbors = new HashSet<INodeID>(newNeighbors);
newNeighbors.clear();
}
visited.addAll(neighbors);
return visited;
}
// helper method, replaced by getNeighborsIter which is thought to be more
// efficient
@SuppressWarnings("unused")
private Set<INodeID> getNeighbors(INodeID node, int k,
boolean directedNeighborhood, LinkedHashSet<INodeID> visited) {
boolean directedNeighborhood, HashSet<INodeID> visited) {
if (k < 0)
throw new IllegalArgumentException("k must be >=0, but was " + k);
if (k == 0) {
visited.add(node);
LinkedHashSet<INodeID> oneNodeNeighborSet = new LinkedHashSet<INodeID>();
HashSet<INodeID> oneNodeNeighborSet = new HashSet<INodeID>();
oneNodeNeighborSet.add(node);
return oneNodeNeighborSet;
}
visited.add(node);
LinkedHashSet<INodeID> neighbors = new LinkedHashSet<INodeID>();
HashSet<INodeID> neighbors = new HashSet<INodeID>();
neighbors.add(node);
for (INodeID neighbor : getNeighbors(node, directedNeighborhood)) {
......@@ -463,17 +545,13 @@ public class BasicGraph implements Graph {
@Override
public Set<INodeID> getNeighbors(INodeID node,
boolean directedNeighborhood) {
Set<INodeID> neighbors = new LinkedHashSet<INodeID>();
for (final IEdge edge : this.getOutgoingEdges(node))
neighbors.add(edge.toId());
// Also add start nodes of incoming links
if (!directedNeighborhood)
for (final IEdge edge : this.getIncomingEdges(node))
neighbors.add(edge.fromId());
return Collections.unmodifiableSet(neighbors);
}
if (directedNeighborhood)
return Collections.unmodifiableSet(successorNodes.get(node));
@SuppressWarnings("unchecked")
Set<INodeID> neighbors = (Set<INodeID>) successorNodes.get(node).clone();
neighbors.addAll(predecessorNodes.get(node));
return neighbors;
}
@Override
public Set<INodeID> getNeighbors(INodeID node) {
......@@ -491,16 +569,46 @@ public class BasicGraph implements Graph {
"Node " + node + " is not contained in the graph");
}
@SuppressWarnings("unused")
private BasicGraph(Set<INode> nodes, Map<INodeID, INode> nodesById, Set<IEdge> edges, Map<EdgeID, IEdge> edgesById,
Map<INodeID, Set<IEdge>> outgoingAdjacencyList, Map<INodeID, Set<IEdge>> incomingAdjacencyList,
Map<INodeID, HashSet<INodeID>> successorNodes, Map<INodeID, HashSet<INodeID>> predecessorNodes) {
this.nodes.addAll(nodes);
this.edges.addAll(edges);
this.nodesById.putAll(nodesById);
this.edgesById.putAll(edgesById);
this.outgoingAdjacencyList.putAll(outgoingAdjacencyList);
this.incomingAdjacencyList.putAll(incomingAdjacencyList);
this.successorNodes.putAll(successorNodes);
this.predecessorNodes.putAll(predecessorNodes);
}
@Override
public BasicGraph clone() {
/*
* more efficient, but less clean than inserting each node and edge
*
* Map<INodeID, Set<IEdge>> outs = new HashMap<INodeID, Set<IEdge>>();
* Map<INodeID, Set<IEdge>> ins = new HashMap<INodeID, Set<IEdge>>();
* Map<INodeID, Set<INodeID>> pres = new HashMap<INodeID,
* Set<INodeID>>(); Map<INodeID, Set<INodeID>> succ = new
* HashMap<INodeID, Set<INodeID>>(); for (INodeID n : getNodeIds()) {
* outs.put(n, new HashSet<>(outgoingAdjacencyList.get(n))); ins.put(n,
* new HashSet<>(incomingAdjacencyList.get(n))); pres.put(n, new
* HashSet<>(predecessorNodes.get(n))); succ.put(n, new
* HashSet<>(successorNodes.get(n))); } return new
* BasicGraph(this.nodes, this.nodesById, this.edges, this.edgesById,
* outs, ins, succ, pres);
*
* As per the API contract, the inner objects are NOT cloned. This
* cloned graph is just a new view.
*/
BasicGraph g = new BasicGraph();
g.addNodes(this.nodes);
g.addEdges(this.edges);
return g;
}
@Override
......@@ -586,6 +694,11 @@ public class BasicGraph implements Graph {
return this.getIncomingEdges(node).size();
}
@Override
public int getDegree(INodeID nodeID) {
return this.getIndegree(nodeID) + this.getOutdegree(nodeID);
}
@Override
public Set<INodeID> getNeighbors(INode node, int k,
boolean directedNeighborhood) {
......@@ -679,4 +792,40 @@ public class BasicGraph implements Graph {
public boolean remove(IElement element) {
return this.removeElement(element);
}
/**
* get all nodes that precede n, i.e., for each returned node m, there is an
* edge m -> n
*
* @param n
* @return all nodes with an edge to n
*/
public Set<INodeID> getPredecessorNodes(INodeID n) {
return Collections.unmodifiableSet(predecessorNodes.get(n));
}
/**
* get all edges between nodes of the input set this provides all edges for
* the node-induced subgraph
*
* @param nodes
* @return all edges m -> n where m,n in nodes
*/
public Collection<IEdge> getEdges(Collection<INodeID> nodes) {
final List<IEdge> resultList = new ArrayList<>();
final Set<INodeID> nodesSet = new HashSet<INodeID>(nodes);
final Set<IEdge> newEdges = new LinkedHashSet<IEdge>();
for (INodeID id : nodesSet) {
if (this.getNode(id) == null)
return new ArrayList<>();
newEdges.addAll(this.outgoingAdjacencyList.get(id));
}
for (final IEdge e : newEdges) {
if (nodesSet.contains(e.toId())) {
resultList.add(e);
}
}
return resultList;
}
}
......@@ -23,6 +23,7 @@ package de.tudarmstadt.maki.simonstrator.api.common.graph;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import de.tudarmstadt.maki.simonstrator.api.Graphs;
import de.tudarmstadt.maki.simonstrator.api.component.sis.type.SiSType;
......@@ -185,10 +186,29 @@ public class DirectedEdge implements IEdge {
public String toString() {
return "DirectedEdge [" + (startNode != null ? startNode + " -> " : "")
+ (endNode != null ? endNode : "")
+ (properties != null ? ", properties=" + properties : "")
+ (properties != null && !properties.isEmpty() ? ", properties=" + formatProperties() : "")
+ "]";
}
public String formatProperties() {
final StringBuilder builder = new StringBuilder();
builder.append("[");
for (final Entry<SiSType<?>, Object> entry : this.properties.entrySet()) {
/*
* Special treatment to avoid infinite loops if the property is of
* type IEdge (e.g. if it represents the reverse edge of this edge).
*/
if (IEdge.class.isInstance(entry.getValue()))
{
builder.append(String.format("%s, %s", entry.getKey().toString(), ((IEdge) entry.getValue()).getId()));
} else {
builder.append(String.format("%s, %s", entry.getKey().toString(), entry.getValue().toString()));
}
}
builder.append("]");
return builder.toString();
}
@Override
public int hashCode() {
final int prime = 31;
......
......@@ -23,15 +23,10 @@ package de.tudarmstadt.maki.simonstrator.api.common.graph;
import java.util.LinkedHashMap;
import java.util.Map;
import de.tudarmstadt.maki.simonstrator.api.common.UniqueID;
public class EdgeID implements UniqueID {
public class EdgeID extends GraphElementID {
private static final long serialVersionUID = 1L;
private final long id;
private String stringId;
private final transient static Map<Long, EdgeID> ids = new LinkedHashMap<>();
private final transient static Map<String, EdgeID> stringIds = new LinkedHashMap<>();
......@@ -47,77 +42,44 @@ public class EdgeID implements UniqueID {
public static EdgeID get(String str) {
EdgeID id = stringIds.get(str);
if (id == null) {
id = new EdgeID(str);
final int hashCode = determineHashCode(str);
id = new EdgeID(str, hashCode);
stringIds.put(str, id);
}
return id;
}
public static EdgeID get(INodeID startNode, INodeID endNode) {
return get(startNode.valueAsString() + "->" + endNode.valueAsString());
}
/**
* Private constructor
* This method calculates the hash code for the given edge ID.
*
* @param id
* If the ID has the specific format for directed edges (e.g., 12->541),
* then the hash code is calculated in a way that avoids hash collisions (at
* least for node counts up to 1e5).
*
* @param edgeId
* @return the hash code to be used
*/
protected EdgeID(long id) {
this.id = id;
this.stringId = Long.toString(this.id);
}
public EdgeID(String stringId) {
this.id = stringId.hashCode();
this.stringId = stringId;
}
@Override
public long value() {
return id;
}
@Override
public String valueAsString() {
return this.stringId;
}
@Override
public int getTransmissionSize() {
// a long ID
return 8;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
private static int determineHashCode(String edgeId) {
if (edgeId.matches("\\d+->\\d+")) {
final String[] segments = edgeId.split("->");
final int sourceId = Integer.parseInt(segments[0]);
final int targetId = Integer.parseInt(segments[1]);
return sourceId * 100000 + targetId;
} else {
return edgeId.hashCode();
}
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EdgeID other = (EdgeID) obj;
if (id != other.id)
return false;
return true;
public static EdgeID get(INodeID startNode, INodeID endNode) {
return get(startNode.valueAsString() + "->" + endNode.valueAsString());
}
@Override
public String toString() {
return this.stringId;
protected EdgeID(long id) {
super(id);
}
@Override
public int compareTo(UniqueID o) {
return Long.compare(id, o.value());
protected EdgeID(String stringId, int hashCode) {
super(stringId, hashCode);
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of Simonstrator.KOM.
*
* Simonstrator.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tudarmstadt.maki.simonstrator.api.common.graph;
/**
* Property that only applies to {@link IEdge}s.
*/
public class EdgeProperty<T> extends GraphElementProperty<T> {
public EdgeProperty(String name, Class<T> valueType) {
super(name, valueType);
}
}
......@@ -28,6 +28,15 @@ public interface GenericGraphElementProperties {
/**
* Edge weight
*/
public static final GraphElementProperty<Double> WEIGHT = new GraphElementProperty<>(
"WEIGHT", Double.class);
public static final GraphElementProperty<Double> WEIGHT = new GraphElementProperty<>("WEIGHT", Double.class);
/**
* Hop count
*/
public static final GraphElementProperty<Double> HOP_COUNT = new GraphElementProperty<>("hopCount", Double.class);
/**
* This property points to the reverse edge of an edge
*/
GraphElementProperty<IEdge> REVERSE_EDGE = new GraphElementProperty<IEdge>("reverseEdge", IEdge.class);
}
......@@ -231,7 +231,7 @@ public interface Graph extends Cloneable {
public INode getNode(INodeID nodeId);
/**
* Returns the edge (if present) between from and to, null otherwise
* Returns some edge (if present) between from and to, null otherwise
*
* @param from
* @param to
......@@ -239,6 +239,15 @@ public interface Graph extends Cloneable {
*/
public IEdge getEdge(INodeID from, INodeID to);
/**
* Returns all edges (if present) between from and to, null otherwise
*
* @param from
* @param to
* @return edge or null
*/
Collection<IEdge> getEdges(INodeID from, INodeID to);
/**
* Returns the edge with the given ID.
*
......@@ -440,6 +449,14 @@ public interface Graph extends Cloneable {
*/
public Set<EdgeID> getEdgeIds();
/**
* Returns the degree of a node, which is equal to the sum of its indegree
* and outdegree
*
* @see #getIndegree(INodeID)
* @see #getOutdegree(INodeID)
*/
public int getDegree(INodeID nodeID);
}
......@@ -25,6 +25,8 @@ import de.tudarmstadt.maki.simonstrator.api.Graphs;
public class GraphBuilder {
private Graph graph;
private INode mostRecentNode;
private IEdge mostRecentEdge;
private GraphBuilder() {
......@@ -39,14 +41,21 @@ public class GraphBuilder {
return this.graph;
}
public GraphBuilder addEdge(String sourceId, String targetId) {
this.graph.addEdge(
new DirectedEdge(INodeID.get(sourceId), INodeID.get(targetId)));
public GraphBuilder n(final String nodeId) {
final Node node = Graphs.createNode(nodeId);
this.graph.addNode(node);
this.mostRecentNode = node;
return this;
}
public GraphBuilder addEdge(String sourceId, String targetId,
String edgeId) {
public GraphBuilder e(String sourceId, String targetId) {
final DirectedEdge edge = new DirectedEdge(INodeID.get(sourceId), INodeID.get(targetId));
this.graph.addEdge(edge);
this.mostRecentEdge = edge;
return this;
}
public GraphBuilder e(String sourceId, String targetId, String edgeId) {
INodeID sourceNodeId = INodeID.get(sourceId);
INodeID targetNodeId = INodeID.get(targetId);
if (!this.graph.containsNode(sourceNodeId)) {
......@@ -55,13 +64,13 @@ public class GraphBuilder {
if (!this.graph.containsNode(targetNodeId)) {
this.graph.createAndAddNode(targetNodeId);
}
this.graph.addEdge(new DirectedEdge(sourceNodeId, targetNodeId,
EdgeID.get(targetId)));
final DirectedEdge edge = new DirectedEdge(sourceNodeId, targetNodeId, EdgeID.get(targetId));
this.graph.addEdge(edge);
this.mostRecentEdge = edge;
return this;
}
public GraphBuilder addEdge(String sourceId, String targetId, String edgeId,
double weight) {
public GraphBuilder e(String sourceId, String targetId, String edgeId, double weight) {
INodeID sourceNodeId = INodeID.get(sourceId);
INodeID targetNodeId = INodeID.get(targetId);
if (!this.graph.containsNode(sourceNodeId)) {
......@@ -70,8 +79,33 @@ public class GraphBuilder {
if (!this.graph.containsNode(targetNodeId)) {
this.graph.createAndAddNode(targetNodeId);
}
this.graph.addEdge(Graphs.createDirectedWeightedEdge(
INodeID.get(sourceId), INodeID.get(targetId), weight));
final IEdge edge = Graphs.createDirectedWeightedEdge(INodeID.get(sourceId), INodeID.get(targetId), weight);
this.graph.addEdge(edge);
this.mostRecentEdge = edge;
return this;
}
public <T> GraphBuilder pn(final GraphElementProperty<T> property, final T value) {
if (null == this.mostRecentNode)
throw new IllegalStateException("Cannot set property: No node added, yet");
this.mostRecentNode.setProperty(property, value);
return this;
}
public <T> GraphBuilder pe(final GraphElementProperty<T> property, final T value) {
if (null == this.mostRecentEdge)
throw new IllegalStateException("Cannot set property: No edge added, yet");
this.mostRecentEdge.setProperty(property, value);
return this;
}
public IEdge getMostRecentEdge() {
return mostRecentEdge;
}
public INode getMostRecentNode() {
return mostRecentNode;
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of Simonstrator.KOM.
*
* Simonstrator.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tudarmstadt.maki.simonstrator.api.common.graph;
import de.tudarmstadt.maki.simonstrator.api.common.UniqueID;
public abstract class GraphElementID implements UniqueID {
private static final long serialVersionUID = 1L;
private final long id;
private final String stringId;
private final int hashCode;
protected GraphElementID(final long id) {
this.id = id;
this.stringId = Long.toString(this.id);
this.hashCode = (int) (id ^ (id >>> 32));
}
/**
* Initializes the ID using a String
*
* @param stringId
*/
protected GraphElementID(String stringId) {
this(stringId, stringId.hashCode());
}
/**
* This constructor allows to set the hash code of this ID explicitly
*/
protected GraphElementID(String stringId, final int hashCode) {
this.id = stringId.hashCode();
this.stringId = stringId;
this.hashCode = hashCode;
}
@Override
public long value() {
return id;
}
@Override
public String valueAsString() {
return this.stringId;
}
@Override
public int getTransmissionSize() {
// a long ID
return 8;
}
@Override
public int hashCode() {
return this.hashCode;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
GraphElementID other = (GraphElementID) obj;
if (id != other.id)
return false;
return true;
}
@Override
public String toString() {
return this.stringId;
}
@Override
public int compareTo(UniqueID o) {
return Long.compare(id, o.value());
}
}
/*
* Copyright (c) 2005-2010 KOM Multimedia Communications Lab
*
* This file is part of Simonstrator.KOM.
*
* Simonstrator.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tudarmstadt.maki.simonstrator.api.common.graph;
import java.util.Comparator;
//TODO@rkluge: Test me
public class GraphElementPropertyBasedComparator implements Comparator<IElement> {
private final GraphElementProperty<? extends Number> graphElementProperty;
public GraphElementPropertyBasedComparator(
final GraphElementProperty<? extends Number> graphElementProperty) {
this.graphElementProperty = graphElementProperty;
}
@Override
public int compare(IElement o1, IElement o2) {
Number p1 = o1.getProperty(graphElementProperty);
Number p2 = o2.getProperty(graphElementProperty);
if (p1 == null)
throw new IllegalArgumentException(
String.format("Element %s does not have required property %s", o1, graphElementProperty));
if (p2 == null)
throw new IllegalArgumentException(
String.format("Element %s does not have required property %s", o2, graphElementProperty));
return p1.doubleValue() == p2.doubleValue() ? 0 : p1.doubleValue() < p2.doubleValue() ? -1 : 0;
}
}
......@@ -25,8 +25,6 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import de.tudarmstadt.maki.simonstrator.api.common.UniqueID;
/**
* As the SiS and Monitoring deal with multiple topologies collected in the
* underlay, any overlay and the applications, we need a common identifier for
......@@ -36,13 +34,10 @@ import de.tudarmstadt.maki.simonstrator.api.common.UniqueID;
* @author Bjoern Richerzhagen
*
*/
public class INodeID implements UniqueID {
public class INodeID extends GraphElementID {
private static final long serialVersionUID = 1L;
private final long id;
private String stringId;
protected final transient static Map<Long, INodeID> ids = new LinkedHashMap<>();
protected final transient static Map<String, INodeID> stringIds = new LinkedHashMap<>();
......@@ -82,61 +77,10 @@ public class INodeID implements UniqueID {
* @param id
*/
protected INodeID(long id) {
this.id = id;
this.stringId = Long.toString(this.id);
}
public INodeID(String stringId) {
this.id = stringId.hashCode();
this.stringId = stringId;
}
@Override
public long value() {
return id;
}
@Override
public String valueAsString() {
return this.stringId;
super(id);
}
@Override
public int getTransmissionSize() {
// a long ID
return 8;
protected INodeID(String stringId) {
super(stringId);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
INodeID other = (INodeID) obj;
if (id != other.id)
return false;
return true;
}
@Override
public String toString() {
return this.stringId;
}
@Override
public int compareTo(UniqueID o) {
return Long.compare(id, o.value());
}
}
/*
* Copyright (c) 2005-2010 KOM – Multimedia Communications Lab
*
* This file is part of Simonstrator.KOM.
*
* Simonstrator.KOM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* PeerfactSim.KOM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.tudarmstadt.maki.simonstrator.api.common.graph;
/**
* This exception may be used to indicate that a necessary property of an
* {@link INode} or {@link IEdge} is not set.
*/
public class MissingGraphElementPropertyException extends RuntimeException {
public MissingGraphElementPropertyException(IEdge edge, GraphElementProperty<?> property) {
super(String.format("Edge %s is missing required property %s", edge, property));
}
public MissingGraphElementPropertyException(INode node, GraphElementProperty<?> property) {
super(String.format("Node %s is missing required property %s", node, property));
}
private static final long serialVersionUID = 8622616464282511495L;
}
......@@ -63,15 +63,6 @@ public class Node implements INode {
this(INodeID.get(id));
}
/**
* @deprecated Only during the reconciliation
* @param str
*/
// TODO MS
public Node(String str) {
this(INodeID.get(str.hashCode())); // TODO@rkluge FIXME
}
@Override
public INodeID getId() {
return id;
......@@ -110,8 +101,8 @@ public class Node implements INode {
@Override
public String toString() {
return "Node [" + (id != null ? "id=" + id + ", " : "")
+ (properties != null ? "properties=" + properties : "") + "]";
return "Node [" + (id != null ? "id=" + id : "")
+ (properties != null && !properties.isEmpty() ? ", properties=" + properties : "") + "]";
}
@Override
......
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