From 0cafe5c7efdf92cdc1f28bf2caae762764caabba Mon Sep 17 00:00:00 2001 From: archangel777 Date: Wed, 7 Feb 2018 16:18:01 -0300 Subject: [PATCH 01/16] Added card functionality with SpatialCard included --- .../insightlab/graphast/cards/EdgeCard.java | 5 +++ .../insightlab/graphast/cards/GraphCard.java | 5 +++ .../insightlab/graphast/cards/NodeCard.java | 5 +++ .../cards/spatial_cards/Geometry.java | 27 ++++++++++++++ .../graphast/cards/spatial_cards/Point.java | 29 +++++++++++++++ .../spatial_cards/SpatialCardController.java | 35 +++++++++++++++++++ .../cards/spatial_cards/SpatialEdgeCard.java | 17 +++++++++ .../cards/spatial_cards/SpatialGraphCard.java | 9 +++++ .../cards/spatial_cards/SpatialNodeCard.java | 29 +++++++++++++++ .../org/insightlab/graphast/model/Edge.java | 19 ++++++++++ .../org/insightlab/graphast/model/Graph.java | 11 ++++++ .../org/insightlab/graphast/model/Node.java | 19 ++++++++++ .../structure/DefaultGraphStructure.java | 18 ++++++++++ .../graphast/structure/GraphStructure.java | 7 ++++ .../structure/MMapGraphStructure.java | 13 +++++++ 15 files changed, 248 insertions(+) create mode 100644 core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java create mode 100644 core/src/main/java/org/insightlab/graphast/cards/GraphCard.java create mode 100644 core/src/main/java/org/insightlab/graphast/cards/NodeCard.java create mode 100644 core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Geometry.java create mode 100644 core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Point.java create mode 100644 core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java create mode 100644 core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java create mode 100644 core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java create mode 100644 core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java diff --git a/core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java b/core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java new file mode 100644 index 0000000..8f17f6c --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java @@ -0,0 +1,5 @@ +package org.insightlab.graphast.cards; + +public interface EdgeCard { + +} diff --git a/core/src/main/java/org/insightlab/graphast/cards/GraphCard.java b/core/src/main/java/org/insightlab/graphast/cards/GraphCard.java new file mode 100644 index 0000000..da378c1 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/cards/GraphCard.java @@ -0,0 +1,5 @@ +package org.insightlab.graphast.cards; + +public interface GraphCard { + +} diff --git a/core/src/main/java/org/insightlab/graphast/cards/NodeCard.java b/core/src/main/java/org/insightlab/graphast/cards/NodeCard.java new file mode 100644 index 0000000..e03133e --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/cards/NodeCard.java @@ -0,0 +1,5 @@ +package org.insightlab.graphast.cards; + +public interface NodeCard { + +} diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Geometry.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Geometry.java new file mode 100644 index 0000000..2b21af4 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Geometry.java @@ -0,0 +1,27 @@ +package org.insightlab.graphast.cards.spatial_cards; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class Geometry { + + private List geometry; + + public Geometry() { + geometry = new ArrayList<>(); + } + + public Geometry(Point ...points) { + geometry.addAll(Arrays.asList(points)); + } + + public void addPoint(Point p) { + geometry.add(p); + } + + public List getGeometry() { + return geometry; + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Point.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Point.java new file mode 100644 index 0000000..d84cbff --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Point.java @@ -0,0 +1,29 @@ +package org.insightlab.graphast.cards.spatial_cards; + +public class Point { + + private int lat; + private int lng; + + public Point(int lat, int lng) { + this.lat = lat; + this.lng = lng; + } + + public int getLat() { + return lat; + } + + public int getLng() { + return lng; + } + + public void setLat(int lat) { + this.lat = lat; + } + + public void setLng(int lng) { + this.lng = lng; + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java new file mode 100644 index 0000000..561e51f --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java @@ -0,0 +1,35 @@ +package org.insightlab.graphast.cards.spatial_cards; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.Node; + +public class SpatialCardController { + + private static String cardName = "SpatialCard"; + + public static SpatialGraphCard getCard(Graph g) { + return (SpatialGraphCard) g.getCard(cardName); + } + + public static SpatialNodeCard getCard(Node n) { + return (SpatialNodeCard) n.getCard(cardName); + } + + public static SpatialEdgeCard getCard(Edge e) { + return (SpatialEdgeCard) e.getCard(cardName); + } + + public static void setCard(Graph g) { + g.setCard(cardName, new SpatialGraphCard()); + } + + public static void setCard(Node n, int lat, int lng) { + n.setCard(cardName, new SpatialNodeCard(new Point(lat, lng))); + } + + public static void setCard(Edge e, Geometry geometry) { + e.setCard(cardName, new SpatialEdgeCard(geometry)); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java new file mode 100644 index 0000000..a79f35b --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java @@ -0,0 +1,17 @@ +package org.insightlab.graphast.cards.spatial_cards; + +import org.insightlab.graphast.cards.EdgeCard; + +public class SpatialEdgeCard implements EdgeCard { + + private Geometry geometry; + + public SpatialEdgeCard(Geometry geometry) { + this.geometry = geometry; + } + + public Geometry getGeometry() { + return geometry; + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java new file mode 100644 index 0000000..eb10f57 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java @@ -0,0 +1,9 @@ +package org.insightlab.graphast.cards.spatial_cards; + +import org.insightlab.graphast.cards.GraphCard; + +public class SpatialGraphCard implements GraphCard { + + public SpatialGraphCard() {} + +} diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java new file mode 100644 index 0000000..cb56483 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java @@ -0,0 +1,29 @@ +package org.insightlab.graphast.cards.spatial_cards; + +import org.insightlab.graphast.cards.NodeCard; + +public class SpatialNodeCard implements NodeCard { + + private Point point; + + public SpatialNodeCard(Point p) { + this.point = p; + } + + public int getLat() { + return point.getLat(); + } + + public int getLng() { + return point.getLng(); + } + + public void setLat(int lat) { + point.setLat(lat); + } + + public void setLng(int lng) { + point.setLng(lng); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/model/Edge.java b/core/src/main/java/org/insightlab/graphast/model/Edge.java index a9a97d2..3887053 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Edge.java +++ b/core/src/main/java/org/insightlab/graphast/model/Edge.java @@ -24,12 +24,19 @@ package org.insightlab.graphast.model; +import java.util.HashMap; +import java.util.Map; + +import org.insightlab.graphast.cards.EdgeCard; + /** * The Edge class. It represents the model of a graph edge. * It extends the GraphObject abstract class. */ public class Edge extends GraphObject { + private Map edgeCards = null; + private long fromNode; private long toNode; private double cost; @@ -159,6 +166,18 @@ public long getAdjacent(long id) { return id == toNode ? fromNode : toNode; } + public void setCard(String cardName, EdgeCard card) { + if (edgeCards == null) + edgeCards = new HashMap<>(); + edgeCards.put(cardName, card); + } + + public EdgeCard getCard(String cardName) { + if (edgeCards == null || !edgeCards.containsKey(cardName)) + return null; + return edgeCards.get(cardName); + } + /** * Equals method. It receives an object and checks if it is an Edge object * and if it has the same incoming node id, the same outcoming node id and diff --git a/core/src/main/java/org/insightlab/graphast/model/Graph.java b/core/src/main/java/org/insightlab/graphast/model/Graph.java index fe555e0..b819914 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Graph.java +++ b/core/src/main/java/org/insightlab/graphast/model/Graph.java @@ -26,6 +26,7 @@ import java.util.Iterator; +import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.structure.DefaultGraphStructure; import org.insightlab.graphast.structure.GraphStructure; @@ -186,6 +187,16 @@ public Iterator getInEdges(long id) { return structure.getInEdges(id); } + + public GraphCard getCard(String cardName) { + return structure.getCard(cardName); + } + + public void setCard(String cardName, GraphCard card) { + structure.setCard(cardName, card); + } + + /** * Gets the neighborhood from a node represented by a given id. If the graph * has any Node object with the given id, this function returns an Iterator diff --git a/core/src/main/java/org/insightlab/graphast/model/Node.java b/core/src/main/java/org/insightlab/graphast/model/Node.java index 6245064..a47583a 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Node.java +++ b/core/src/main/java/org/insightlab/graphast/model/Node.java @@ -24,12 +24,19 @@ package org.insightlab.graphast.model; +import java.util.HashMap; +import java.util.Map; + +import org.insightlab.graphast.cards.NodeCard; + /** * The Node class. It represents the model of a graph node. * It extends the GraphObject abstract class. */ public class Node extends GraphObject { + private Map nodeCards = null; + private long id; /** @@ -50,6 +57,18 @@ public long getId() { return id; } + public void setCard(String cardName, NodeCard card) { + if (nodeCards == null) + nodeCards = new HashMap<>(); + nodeCards.put(cardName, card); + } + + public NodeCard getCard(String cardName) { + if (nodeCards == null || !nodeCards.containsKey(cardName)) + return null; + return nodeCards.get(cardName); + } + /** * Equals method. It receives an object and checks if it is a Node * and if it has the same id than the Node object calling this function. diff --git a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java index 02e3d39..ac6b1a0 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java @@ -27,7 +27,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.Map; +import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.exceptions.DuplicatedNodeException; import org.insightlab.graphast.exceptions.NodeNotFoundException; import org.insightlab.graphast.model.Edge; @@ -39,6 +41,8 @@ */ public class DefaultGraphStructure implements GraphStructure { + private Map graphCards = null; + private Integer nextId = 0; private HashMap idMapping = new HashMap<>(); @@ -173,4 +177,18 @@ public Iterator getInEdges(final long id) { return inEdges.get(idMapping.get(id)).iterator(); } + @Override + public void setCard(String cardName, GraphCard card) { + if (graphCards == null) + graphCards = new HashMap<>(); + graphCards.put(cardName, card); + } + + @Override + public GraphCard getCard(String cardName) { + if (graphCards == null || !graphCards.containsKey(cardName)) + return null; + return graphCards.get(cardName); + } + } diff --git a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java index ffa5da3..5d5c83b 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java @@ -26,6 +26,7 @@ import java.util.Iterator; +import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Node; @@ -85,4 +86,10 @@ public interface GraphStructure { */ Iterator getInEdges(final long id); + + GraphCard getCard(String cardName); + + + void setCard(String cardName, GraphCard card); + } diff --git a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java index 2d53593..9d5cf4c 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.util.Iterator; +import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Node; import org.insightlab.hugedataaccess.DataAccess; @@ -354,4 +355,16 @@ public void remove() { } + @Override + public GraphCard getCard(String cardName) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void setCard(String cardName, GraphCard card) { + // TODO Auto-generated method stub + + } + } From 0ce26f8c7329dc0ed7a8607fc20610e114e5e0bf Mon Sep 17 00:00:00 2001 From: archangel777 Date: Wed, 7 Feb 2018 20:47:42 -0300 Subject: [PATCH 02/16] A card may now access it's holder, and a simple test added --- .../insightlab/graphast/cards/EdgeCard.java | 14 ++++++- .../insightlab/graphast/cards/GraphCard.java | 14 ++++++- .../insightlab/graphast/cards/NodeCard.java | 14 ++++++- .../spatial_cards/SpatialCardController.java | 14 ++++--- .../cards/spatial_cards/SpatialEdgeCard.java | 10 ++++- .../cards/spatial_cards/SpatialGraphCard.java | 7 +++- .../cards/spatial_cards/SpatialNodeCard.java | 6 ++- .../exceptions/MissingCardException.java | 18 ++++++++ .../org/insightlab/graphast/model/Edge.java | 5 +++ .../org/insightlab/graphast/model/Graph.java | 6 ++- .../org/insightlab/graphast/model/Node.java | 5 +++ .../structure/DefaultGraphStructure.java | 8 ++++ .../graphast/structure/GraphStructure.java | 4 ++ .../structure/MMapGraphStructure.java | 8 +++- .../graphast/cards/SpatialCardTest.java | 42 +++++++++++++++++++ 15 files changed, 159 insertions(+), 16 deletions(-) create mode 100644 core/src/main/java/org/insightlab/graphast/exceptions/MissingCardException.java create mode 100644 core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java diff --git a/core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java b/core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java index 8f17f6c..87b6bc8 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java +++ b/core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java @@ -1,5 +1,17 @@ package org.insightlab.graphast.cards; -public interface EdgeCard { +import org.insightlab.graphast.model.Edge; + +public abstract class EdgeCard { + + private Edge edge = null; + + public void setEdge(Edge edge) { + this.edge = edge; + } + + public Edge getEdge() { + return edge; + } } diff --git a/core/src/main/java/org/insightlab/graphast/cards/GraphCard.java b/core/src/main/java/org/insightlab/graphast/cards/GraphCard.java index da378c1..bdda1a6 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/GraphCard.java +++ b/core/src/main/java/org/insightlab/graphast/cards/GraphCard.java @@ -1,5 +1,17 @@ package org.insightlab.graphast.cards; -public interface GraphCard { +import org.insightlab.graphast.model.Graph; +public abstract class GraphCard { + + private Graph graph = null; + + public void setGraph(Graph graph) { + this.graph = graph; + } + + public Graph getGraph() { + return graph; + } + } diff --git a/core/src/main/java/org/insightlab/graphast/cards/NodeCard.java b/core/src/main/java/org/insightlab/graphast/cards/NodeCard.java index e03133e..e0a70f3 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/NodeCard.java +++ b/core/src/main/java/org/insightlab/graphast/cards/NodeCard.java @@ -1,5 +1,17 @@ package org.insightlab.graphast.cards; -public interface NodeCard { +import org.insightlab.graphast.model.Node; +public abstract class NodeCard { + + private Node node = null; + + public void setNode(Node node) { + this.node = node; + } + + public Node getNode() { + return node; + } + } diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java index 561e51f..650a65f 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java +++ b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java @@ -6,7 +6,11 @@ public class SpatialCardController { - private static String cardName = "SpatialCard"; + private static final String cardName = "SpatialCard"; + + public static String getCardName() { + return cardName; + } public static SpatialGraphCard getCard(Graph g) { return (SpatialGraphCard) g.getCard(cardName); @@ -21,15 +25,15 @@ public static SpatialEdgeCard getCard(Edge e) { } public static void setCard(Graph g) { - g.setCard(cardName, new SpatialGraphCard()); + g.setCard(cardName, new SpatialGraphCard(g)); } - public static void setCard(Node n, int lat, int lng) { - n.setCard(cardName, new SpatialNodeCard(new Point(lat, lng))); + public static void setCard(Node n, Point p) { + n.setCard(cardName, new SpatialNodeCard(n, p)); } public static void setCard(Edge e, Geometry geometry) { - e.setCard(cardName, new SpatialEdgeCard(geometry)); + e.setCard(cardName, new SpatialEdgeCard(e, geometry)); } } diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java index a79f35b..33de4a3 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java +++ b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java @@ -1,12 +1,18 @@ package org.insightlab.graphast.cards.spatial_cards; import org.insightlab.graphast.cards.EdgeCard; +import org.insightlab.graphast.model.Edge; -public class SpatialEdgeCard implements EdgeCard { +public class SpatialEdgeCard extends EdgeCard { private Geometry geometry; - public SpatialEdgeCard(Geometry geometry) { + public SpatialEdgeCard(Edge e) { + this(e, new Geometry()); + } + + public SpatialEdgeCard(Edge e, Geometry geometry) { + this.setEdge(e); this.geometry = geometry; } diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java index eb10f57..95e60e6 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java +++ b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java @@ -1,9 +1,12 @@ package org.insightlab.graphast.cards.spatial_cards; import org.insightlab.graphast.cards.GraphCard; +import org.insightlab.graphast.model.Graph; -public class SpatialGraphCard implements GraphCard { +public class SpatialGraphCard extends GraphCard { - public SpatialGraphCard() {} + public SpatialGraphCard(Graph g) { + this.setGraph(g); + } } diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java index cb56483..6edb880 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java +++ b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java @@ -1,12 +1,14 @@ package org.insightlab.graphast.cards.spatial_cards; import org.insightlab.graphast.cards.NodeCard; +import org.insightlab.graphast.model.Node; -public class SpatialNodeCard implements NodeCard { +public class SpatialNodeCard extends NodeCard { private Point point; - public SpatialNodeCard(Point p) { + public SpatialNodeCard(Node n, Point p) { + this.setNode(n); this.point = p; } diff --git a/core/src/main/java/org/insightlab/graphast/exceptions/MissingCardException.java b/core/src/main/java/org/insightlab/graphast/exceptions/MissingCardException.java new file mode 100644 index 0000000..1530d23 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/exceptions/MissingCardException.java @@ -0,0 +1,18 @@ +package org.insightlab.graphast.exceptions; + +public class MissingCardException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = -915981947597562490L; + + public MissingCardException() { + super(); + } + + public MissingCardException(String cardName) { + super("'" + cardName + "' not found!"); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/model/Edge.java b/core/src/main/java/org/insightlab/graphast/model/Edge.java index 3887053..14f3a20 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Edge.java +++ b/core/src/main/java/org/insightlab/graphast/model/Edge.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.insightlab.graphast.cards.EdgeCard; @@ -178,6 +179,10 @@ public EdgeCard getCard(String cardName) { return edgeCards.get(cardName); } + public Set getAllCardNames() { + return edgeCards.keySet(); + } + /** * Equals method. It receives an object and checks if it is an Edge object * and if it has the same incoming node id, the same outcoming node id and diff --git a/core/src/main/java/org/insightlab/graphast/model/Graph.java b/core/src/main/java/org/insightlab/graphast/model/Graph.java index b819914..9ac5f00 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Graph.java +++ b/core/src/main/java/org/insightlab/graphast/model/Graph.java @@ -25,6 +25,7 @@ package org.insightlab.graphast.model; import java.util.Iterator; +import java.util.Set; import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.structure.DefaultGraphStructure; @@ -86,7 +87,6 @@ public void addNode(Node n) { * @param nodes the Node objects to be added to the graph. */ public void addNodes(Node ...nodes) { - for (Node n : nodes) this.addNode(n); } @@ -196,6 +196,10 @@ public void setCard(String cardName, GraphCard card) { structure.setCard(cardName, card); } + public Set getAllCardNames() { + return structure.getAllCardNames(); + } + /** * Gets the neighborhood from a node represented by a given id. If the graph diff --git a/core/src/main/java/org/insightlab/graphast/model/Node.java b/core/src/main/java/org/insightlab/graphast/model/Node.java index a47583a..cacadc7 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Node.java +++ b/core/src/main/java/org/insightlab/graphast/model/Node.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.insightlab.graphast.cards.NodeCard; @@ -69,6 +70,10 @@ public NodeCard getCard(String cardName) { return nodeCards.get(cardName); } + public Set getAllCardNames() { + return nodeCards.keySet(); + } + /** * Equals method. It receives an object and checks if it is a Node * and if it has the same id than the Node object calling this function. diff --git a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java index ac6b1a0..db56b15 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.Set; import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.exceptions.DuplicatedNodeException; @@ -191,4 +192,11 @@ public GraphCard getCard(String cardName) { return graphCards.get(cardName); } + @Override + public Set getAllCardNames() { + if (graphCards == null) + return null; + return graphCards.keySet(); + } + } diff --git a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java index 5d5c83b..62c08ca 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java @@ -25,6 +25,7 @@ package org.insightlab.graphast.structure; import java.util.Iterator; +import java.util.Set; import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.model.Edge; @@ -87,6 +88,9 @@ public interface GraphStructure { Iterator getInEdges(final long id); + Set getAllCardNames(); + + GraphCard getCard(String cardName); diff --git a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java index 9d5cf4c..2834f1a 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java @@ -27,6 +27,7 @@ import java.io.File; import java.io.IOException; import java.util.Iterator; +import java.util.Set; import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.model.Edge; @@ -364,7 +365,12 @@ public GraphCard getCard(String cardName) { @Override public void setCard(String cardName, GraphCard card) { // TODO Auto-generated method stub - + } + + @Override + public Set getAllCardNames() { + // TODO Auto-generated method stub + return null; } } diff --git a/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java b/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java new file mode 100644 index 0000000..f944507 --- /dev/null +++ b/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java @@ -0,0 +1,42 @@ +package org.insightlab.graphast.cards; + +import static org.junit.Assert.*; + +import org.insightlab.graphast.cards.spatial_cards.Point; +import org.insightlab.graphast.cards.spatial_cards.SpatialCardController; +//import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.Node; +import org.junit.Before; +import org.junit.Test; + +public class SpatialCardTest { + + Graph g; + private Node n0, n1, n2, n3; +// private Edge e0, e1, e2, e3; + + @Before + public void setUp() throws Exception { + g = new Graph(); + n0 = new Node(0); + SpatialCardController.setCard(n0, new Point(12, 4)); + n1 = new Node(1); + SpatialCardController.setCard(n1, new Point(13, 3)); + n2 = new Node(2); + SpatialCardController.setCard(n2, new Point(14, 2)); + n3 = new Node(3); + SpatialCardController.setCard(n3, new Point(15, 1)); +// e0 = new Edge(1, 2, true); +// e1 = new Edge(2, 3); +// e2 = new Edge(0, 1); +// e3 = new Edge(3, 0, true); + } + + @Test + public void test() { + assertEquals("N1 lat test", 13, SpatialCardController.getCard(n1).getLat()); + assertEquals("N3 lng test", 1, SpatialCardController.getCard(n3).getLng()); + } + +} From ac6aa8194b6ec11a9b0d65152fe5da00489087bb Mon Sep 17 00:00:00 2001 From: archangel777 Date: Fri, 9 Feb 2018 11:36:18 -0300 Subject: [PATCH 03/16] Name refactoring: 'Card' -> 'Component'; Component controller refactoring: 'Static' -> 'Singleton' --- .../spatial_cards/SpatialCardController.java | 39 --------------- .../cards/spatial_cards/SpatialEdgeCard.java | 23 --------- .../cards/spatial_cards/SpatialGraphCard.java | 12 ----- .../org/insightlab/graphast/model/Edge.java | 8 ++-- .../org/insightlab/graphast/model/Graph.java | 6 +-- .../org/insightlab/graphast/model/Node.java | 8 ++-- .../cards/EdgeComponent.java} | 4 +- .../cards/GraphComponent.java} | 4 +- .../cards/NodeComponent.java} | 4 +- .../cards/spatial_cards/Geometry.java | 2 +- .../cards/spatial_cards/Point.java | 2 +- .../SpatialComponentController.java | 48 +++++++++++++++++++ .../spatial_cards/SpatialEdgeComponent.java | 23 +++++++++ .../spatial_cards/SpatialGraphComponent.java | 12 +++++ .../spatial_cards/SpatialNodeComponent.java} | 8 ++-- .../structure/DefaultGraphStructure.java | 8 ++-- .../graphast/structure/GraphStructure.java | 6 +-- .../structure/MMapGraphStructure.java | 6 +-- .../graphast/cards/SpatialCardTest.java | 18 +++---- 19 files changed, 126 insertions(+), 115 deletions(-) delete mode 100644 core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java delete mode 100644 core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java delete mode 100644 core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java rename core/src/main/java/org/insightlab/graphast/{cards/EdgeCard.java => model/cards/EdgeComponent.java} (64%) rename core/src/main/java/org/insightlab/graphast/{cards/GraphCard.java => model/cards/GraphComponent.java} (65%) rename core/src/main/java/org/insightlab/graphast/{cards/NodeCard.java => model/cards/NodeComponent.java} (64%) rename core/src/main/java/org/insightlab/graphast/{ => model}/cards/spatial_cards/Geometry.java (82%) rename core/src/main/java/org/insightlab/graphast/{ => model}/cards/spatial_cards/Point.java (78%) create mode 100644 core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialComponentController.java create mode 100644 core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialEdgeComponent.java create mode 100644 core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialGraphComponent.java rename core/src/main/java/org/insightlab/graphast/{cards/spatial_cards/SpatialNodeCard.java => model/cards/spatial_cards/SpatialNodeComponent.java} (56%) diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java deleted file mode 100644 index 650a65f..0000000 --- a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialCardController.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.insightlab.graphast.cards.spatial_cards; - -import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.Graph; -import org.insightlab.graphast.model.Node; - -public class SpatialCardController { - - private static final String cardName = "SpatialCard"; - - public static String getCardName() { - return cardName; - } - - public static SpatialGraphCard getCard(Graph g) { - return (SpatialGraphCard) g.getCard(cardName); - } - - public static SpatialNodeCard getCard(Node n) { - return (SpatialNodeCard) n.getCard(cardName); - } - - public static SpatialEdgeCard getCard(Edge e) { - return (SpatialEdgeCard) e.getCard(cardName); - } - - public static void setCard(Graph g) { - g.setCard(cardName, new SpatialGraphCard(g)); - } - - public static void setCard(Node n, Point p) { - n.setCard(cardName, new SpatialNodeCard(n, p)); - } - - public static void setCard(Edge e, Geometry geometry) { - e.setCard(cardName, new SpatialEdgeCard(e, geometry)); - } - -} diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java deleted file mode 100644 index 33de4a3..0000000 --- a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialEdgeCard.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.insightlab.graphast.cards.spatial_cards; - -import org.insightlab.graphast.cards.EdgeCard; -import org.insightlab.graphast.model.Edge; - -public class SpatialEdgeCard extends EdgeCard { - - private Geometry geometry; - - public SpatialEdgeCard(Edge e) { - this(e, new Geometry()); - } - - public SpatialEdgeCard(Edge e, Geometry geometry) { - this.setEdge(e); - this.geometry = geometry; - } - - public Geometry getGeometry() { - return geometry; - } - -} diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java b/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java deleted file mode 100644 index 95e60e6..0000000 --- a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialGraphCard.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.insightlab.graphast.cards.spatial_cards; - -import org.insightlab.graphast.cards.GraphCard; -import org.insightlab.graphast.model.Graph; - -public class SpatialGraphCard extends GraphCard { - - public SpatialGraphCard(Graph g) { - this.setGraph(g); - } - -} diff --git a/core/src/main/java/org/insightlab/graphast/model/Edge.java b/core/src/main/java/org/insightlab/graphast/model/Edge.java index 14f3a20..5946fda 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Edge.java +++ b/core/src/main/java/org/insightlab/graphast/model/Edge.java @@ -28,7 +28,7 @@ import java.util.Map; import java.util.Set; -import org.insightlab.graphast.cards.EdgeCard; +import org.insightlab.graphast.model.cards.EdgeComponent; /** * The Edge class. It represents the model of a graph edge. @@ -36,7 +36,7 @@ */ public class Edge extends GraphObject { - private Map edgeCards = null; + private Map edgeCards = null; private long fromNode; private long toNode; @@ -167,13 +167,13 @@ public long getAdjacent(long id) { return id == toNode ? fromNode : toNode; } - public void setCard(String cardName, EdgeCard card) { + public void setCard(String cardName, EdgeComponent card) { if (edgeCards == null) edgeCards = new HashMap<>(); edgeCards.put(cardName, card); } - public EdgeCard getCard(String cardName) { + public EdgeComponent getCard(String cardName) { if (edgeCards == null || !edgeCards.containsKey(cardName)) return null; return edgeCards.get(cardName); diff --git a/core/src/main/java/org/insightlab/graphast/model/Graph.java b/core/src/main/java/org/insightlab/graphast/model/Graph.java index 9ac5f00..fc3ca4f 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Graph.java +++ b/core/src/main/java/org/insightlab/graphast/model/Graph.java @@ -27,7 +27,7 @@ import java.util.Iterator; import java.util.Set; -import org.insightlab.graphast.cards.GraphCard; +import org.insightlab.graphast.model.cards.GraphComponent; import org.insightlab.graphast.structure.DefaultGraphStructure; import org.insightlab.graphast.structure.GraphStructure; @@ -188,11 +188,11 @@ public Iterator getInEdges(long id) { } - public GraphCard getCard(String cardName) { + public GraphComponent getCard(String cardName) { return structure.getCard(cardName); } - public void setCard(String cardName, GraphCard card) { + public void setCard(String cardName, GraphComponent card) { structure.setCard(cardName, card); } diff --git a/core/src/main/java/org/insightlab/graphast/model/Node.java b/core/src/main/java/org/insightlab/graphast/model/Node.java index cacadc7..ce48dd5 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Node.java +++ b/core/src/main/java/org/insightlab/graphast/model/Node.java @@ -28,7 +28,7 @@ import java.util.Map; import java.util.Set; -import org.insightlab.graphast.cards.NodeCard; +import org.insightlab.graphast.model.cards.NodeComponent; /** * The Node class. It represents the model of a graph node. @@ -36,7 +36,7 @@ */ public class Node extends GraphObject { - private Map nodeCards = null; + private Map nodeCards = null; private long id; @@ -58,13 +58,13 @@ public long getId() { return id; } - public void setCard(String cardName, NodeCard card) { + public void setCard(String cardName, NodeComponent card) { if (nodeCards == null) nodeCards = new HashMap<>(); nodeCards.put(cardName, card); } - public NodeCard getCard(String cardName) { + public NodeComponent getCard(String cardName) { if (nodeCards == null || !nodeCards.containsKey(cardName)) return null; return nodeCards.get(cardName); diff --git a/core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java b/core/src/main/java/org/insightlab/graphast/model/cards/EdgeComponent.java similarity index 64% rename from core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java rename to core/src/main/java/org/insightlab/graphast/model/cards/EdgeComponent.java index 87b6bc8..4ace495 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/EdgeCard.java +++ b/core/src/main/java/org/insightlab/graphast/model/cards/EdgeComponent.java @@ -1,8 +1,8 @@ -package org.insightlab.graphast.cards; +package org.insightlab.graphast.model.cards; import org.insightlab.graphast.model.Edge; -public abstract class EdgeCard { +public abstract class EdgeComponent { private Edge edge = null; diff --git a/core/src/main/java/org/insightlab/graphast/cards/GraphCard.java b/core/src/main/java/org/insightlab/graphast/model/cards/GraphComponent.java similarity index 65% rename from core/src/main/java/org/insightlab/graphast/cards/GraphCard.java rename to core/src/main/java/org/insightlab/graphast/model/cards/GraphComponent.java index bdda1a6..f278eef 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/GraphCard.java +++ b/core/src/main/java/org/insightlab/graphast/model/cards/GraphComponent.java @@ -1,8 +1,8 @@ -package org.insightlab.graphast.cards; +package org.insightlab.graphast.model.cards; import org.insightlab.graphast.model.Graph; -public abstract class GraphCard { +public abstract class GraphComponent { private Graph graph = null; diff --git a/core/src/main/java/org/insightlab/graphast/cards/NodeCard.java b/core/src/main/java/org/insightlab/graphast/model/cards/NodeComponent.java similarity index 64% rename from core/src/main/java/org/insightlab/graphast/cards/NodeCard.java rename to core/src/main/java/org/insightlab/graphast/model/cards/NodeComponent.java index e0a70f3..1d8145c 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/NodeCard.java +++ b/core/src/main/java/org/insightlab/graphast/model/cards/NodeComponent.java @@ -1,8 +1,8 @@ -package org.insightlab.graphast.cards; +package org.insightlab.graphast.model.cards; import org.insightlab.graphast.model.Node; -public abstract class NodeCard { +public abstract class NodeComponent { private Node node = null; diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Geometry.java b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Geometry.java similarity index 82% rename from core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Geometry.java rename to core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Geometry.java index 2b21af4..cdd537a 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Geometry.java +++ b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Geometry.java @@ -1,4 +1,4 @@ -package org.insightlab.graphast.cards.spatial_cards; +package org.insightlab.graphast.model.cards.spatial_cards; import java.util.ArrayList; import java.util.Arrays; diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Point.java b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Point.java similarity index 78% rename from core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Point.java rename to core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Point.java index d84cbff..2536f5a 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/Point.java +++ b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Point.java @@ -1,4 +1,4 @@ -package org.insightlab.graphast.cards.spatial_cards; +package org.insightlab.graphast.model.cards.spatial_cards; public class Point { diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialComponentController.java b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialComponentController.java new file mode 100644 index 0000000..75f8ee2 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialComponentController.java @@ -0,0 +1,48 @@ +package org.insightlab.graphast.model.cards.spatial_cards; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.Node; + +public class SpatialComponentController { + + private static SpatialComponentController instance = null; + private static final String cardName = "SpatialCard"; + + private SpatialComponentController() {} + + public static SpatialComponentController getInstance() { + if (instance == null) + instance = new SpatialComponentController(); + return instance; + } + + public String getCardName() { + return cardName; + } + + public SpatialGraphComponent getCard(Graph g) { + return (SpatialGraphComponent) g.getCard(cardName); + } + + public SpatialNodeComponent getCard(Node n) { + return (SpatialNodeComponent) n.getCard(cardName); + } + + public SpatialEdgeComponent getCard(Edge e) { + return (SpatialEdgeComponent) e.getCard(cardName); + } + + public void setCard(Graph g) { + g.setCard(cardName, new SpatialGraphComponent(g)); + } + + public void setCard(Node n, Point p) { + n.setCard(cardName, new SpatialNodeComponent(n, p)); + } + + public void setCard(Edge e, Geometry geometry) { + e.setCard(cardName, new SpatialEdgeComponent(e, geometry)); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialEdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialEdgeComponent.java new file mode 100644 index 0000000..c923156 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialEdgeComponent.java @@ -0,0 +1,23 @@ +package org.insightlab.graphast.model.cards.spatial_cards; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.cards.EdgeComponent; + +public class SpatialEdgeComponent extends EdgeComponent { + + private Geometry geometry; + + public SpatialEdgeComponent(Edge e) { + this(e, new Geometry()); + } + + public SpatialEdgeComponent(Edge e, Geometry geometry) { + this.setEdge(e); + this.geometry = geometry; + } + + public Geometry getGeometry() { + return geometry; + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialGraphComponent.java b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialGraphComponent.java new file mode 100644 index 0000000..be54ccb --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialGraphComponent.java @@ -0,0 +1,12 @@ +package org.insightlab.graphast.model.cards.spatial_cards; + +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.cards.GraphComponent; + +public class SpatialGraphComponent extends GraphComponent { + + public SpatialGraphComponent(Graph g) { + this.setGraph(g); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialNodeComponent.java similarity index 56% rename from core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java rename to core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialNodeComponent.java index 6edb880..2ad4b2a 100644 --- a/core/src/main/java/org/insightlab/graphast/cards/spatial_cards/SpatialNodeCard.java +++ b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialNodeComponent.java @@ -1,13 +1,13 @@ -package org.insightlab.graphast.cards.spatial_cards; +package org.insightlab.graphast.model.cards.spatial_cards; -import org.insightlab.graphast.cards.NodeCard; import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.cards.NodeComponent; -public class SpatialNodeCard extends NodeCard { +public class SpatialNodeComponent extends NodeComponent { private Point point; - public SpatialNodeCard(Node n, Point p) { + public SpatialNodeComponent(Node n, Point p) { this.setNode(n); this.point = p; } diff --git a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java index db56b15..2faf98a 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java @@ -30,11 +30,11 @@ import java.util.Map; import java.util.Set; -import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.exceptions.DuplicatedNodeException; import org.insightlab.graphast.exceptions.NodeNotFoundException; import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.cards.GraphComponent; /** * This class implements a default graph structure using the interface GraphStructure. @@ -42,7 +42,7 @@ */ public class DefaultGraphStructure implements GraphStructure { - private Map graphCards = null; + private Map graphCards = null; private Integer nextId = 0; @@ -179,14 +179,14 @@ public Iterator getInEdges(final long id) { } @Override - public void setCard(String cardName, GraphCard card) { + public void setCard(String cardName, GraphComponent card) { if (graphCards == null) graphCards = new HashMap<>(); graphCards.put(cardName, card); } @Override - public GraphCard getCard(String cardName) { + public GraphComponent getCard(String cardName) { if (graphCards == null || !graphCards.containsKey(cardName)) return null; return graphCards.get(cardName); diff --git a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java index 62c08ca..7cfc699 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java @@ -27,9 +27,9 @@ import java.util.Iterator; import java.util.Set; -import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.cards.GraphComponent; /** * The GraphStructure interface. This interface contains declarations of general methods @@ -91,9 +91,9 @@ public interface GraphStructure { Set getAllCardNames(); - GraphCard getCard(String cardName); + GraphComponent getCard(String cardName); - void setCard(String cardName, GraphCard card); + void setCard(String cardName, GraphComponent card); } diff --git a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java index 2834f1a..d47ee47 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java @@ -29,9 +29,9 @@ import java.util.Iterator; import java.util.Set; -import org.insightlab.graphast.cards.GraphCard; import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.cards.GraphComponent; import org.insightlab.hugedataaccess.DataAccess; import org.insightlab.hugedataaccess.MMapDataAccess; import org.insightlab.hugedataaccess.structures.MMapMap; @@ -357,13 +357,13 @@ public void remove() { } @Override - public GraphCard getCard(String cardName) { + public GraphComponent getCard(String cardName) { // TODO Auto-generated method stub return null; } @Override - public void setCard(String cardName, GraphCard card) { + public void setCard(String cardName, GraphComponent card) { // TODO Auto-generated method stub } diff --git a/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java b/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java index f944507..ed6b7d1 100644 --- a/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java +++ b/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java @@ -2,11 +2,11 @@ import static org.junit.Assert.*; -import org.insightlab.graphast.cards.spatial_cards.Point; -import org.insightlab.graphast.cards.spatial_cards.SpatialCardController; //import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Graph; import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.cards.spatial_cards.Point; +import org.insightlab.graphast.model.cards.spatial_cards.SpatialComponentController; import org.junit.Before; import org.junit.Test; @@ -14,19 +14,21 @@ public class SpatialCardTest { Graph g; private Node n0, n1, n2, n3; + SpatialComponentController controller; // private Edge e0, e1, e2, e3; @Before public void setUp() throws Exception { + controller = SpatialComponentController.getInstance(); g = new Graph(); n0 = new Node(0); - SpatialCardController.setCard(n0, new Point(12, 4)); + controller.setCard(n0, new Point(12, 4)); n1 = new Node(1); - SpatialCardController.setCard(n1, new Point(13, 3)); + controller.setCard(n1, new Point(13, 3)); n2 = new Node(2); - SpatialCardController.setCard(n2, new Point(14, 2)); + controller.setCard(n2, new Point(14, 2)); n3 = new Node(3); - SpatialCardController.setCard(n3, new Point(15, 1)); + controller.setCard(n3, new Point(15, 1)); // e0 = new Edge(1, 2, true); // e1 = new Edge(2, 3); // e2 = new Edge(0, 1); @@ -35,8 +37,8 @@ public void setUp() throws Exception { @Test public void test() { - assertEquals("N1 lat test", 13, SpatialCardController.getCard(n1).getLat()); - assertEquals("N3 lng test", 1, SpatialCardController.getCard(n3).getLng()); + assertEquals("N1 lat test", 13, controller.getCard(n1).getLat()); + assertEquals("N3 lng test", 1, controller.getCard(n3).getLng()); } } From 9a84da44e9ba0e30bded09d299f180b9b5213a19 Mon Sep 17 00:00:00 2001 From: archangel777 Date: Fri, 9 Feb 2018 19:33:17 -0300 Subject: [PATCH 04/16] Further name refactoring and component names have been replaced by the components class types --- .../insightlab/graphast/MainClassDiagram.png | Bin 0 -> 113157 bytes .../insightlab/graphast/MainClassDiagram.ucls | 287 ++++++++++++++++++ .../org/insightlab/graphast/model/Edge.java | 48 +-- .../org/insightlab/graphast/model/Graph.java | 14 +- .../org/insightlab/graphast/model/Node.java | 22 +- .../SpatialComponentController.java | 48 --- .../{cards => components}/EdgeComponent.java | 2 +- .../{cards => components}/GraphComponent.java | 2 +- .../{cards => components}/NodeComponent.java | 2 +- .../spatial_components}/Geometry.java | 12 +- .../spatial_components}/Point.java | 2 +- .../SpatialComponentController.java | 43 +++ .../SpatialEdgeComponent.java | 4 +- .../SpatialGraphComponent.java | 4 +- .../SpatialNodeComponent.java | 4 +- .../structure/DefaultGraphStructure.java | 24 +- .../graphast/structure/GraphStructure.java | 8 +- .../structure/MMapGraphStructure.java | 14 +- .../graphast/cards/SpatialCardTest.java | 10 +- 19 files changed, 418 insertions(+), 132 deletions(-) create mode 100644 core/src/main/java/org/insightlab/graphast/MainClassDiagram.png create mode 100644 core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls delete mode 100644 core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialComponentController.java rename core/src/main/java/org/insightlab/graphast/model/{cards => components}/EdgeComponent.java (76%) rename core/src/main/java/org/insightlab/graphast/model/{cards => components}/GraphComponent.java (77%) rename core/src/main/java/org/insightlab/graphast/model/{cards => components}/NodeComponent.java (76%) rename core/src/main/java/org/insightlab/graphast/model/{cards/spatial_cards => components/spatial_components}/Geometry.java (50%) rename core/src/main/java/org/insightlab/graphast/model/{cards/spatial_cards => components/spatial_components}/Point.java (77%) create mode 100644 core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialComponentController.java rename core/src/main/java/org/insightlab/graphast/model/{cards/spatial_cards => components/spatial_components}/SpatialEdgeComponent.java (70%) rename core/src/main/java/org/insightlab/graphast/model/{cards/spatial_cards => components/spatial_components}/SpatialGraphComponent.java (54%) rename core/src/main/java/org/insightlab/graphast/model/{cards/spatial_cards => components/spatial_components}/SpatialNodeComponent.java (72%) diff --git a/core/src/main/java/org/insightlab/graphast/MainClassDiagram.png b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..56641958f3dc3009fefa4202c1a12455f24b7342 GIT binary patch literal 113157 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 pyIhn?!wskg_l)7eva1B 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

DL>$9%o_{Y! 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 literal 0 HcmV?d00001 diff --git a/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls new file mode 100644 index 0000000..8d996d1 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls @@ -0,0 +1,287 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/src/main/java/org/insightlab/graphast/model/Edge.java b/core/src/main/java/org/insightlab/graphast/model/Edge.java index 5946fda..75b8a2b 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Edge.java +++ b/core/src/main/java/org/insightlab/graphast/model/Edge.java @@ -28,7 +28,7 @@ import java.util.Map; import java.util.Set; -import org.insightlab.graphast.model.cards.EdgeComponent; +import org.insightlab.graphast.model.components.EdgeComponent; /** * The Edge class. It represents the model of a graph edge. @@ -36,10 +36,10 @@ */ public class Edge extends GraphObject { - private Map edgeCards = null; + private Map, EdgeComponent> edgeComponent = null; - private long fromNode; - private long toNode; + private long fromNodeId; + private long toNodeId; private double cost; private boolean bidirectional; @@ -61,8 +61,8 @@ public Edge(long from, long to) { * @param cost the cost value of the edge. */ public Edge(long from, long to, double cost) { - this.fromNode = from; - this.toNode = to; + this.fromNodeId = from; + this.toNodeId = to; this.cost = cost; } @@ -96,7 +96,7 @@ public Edge(long from, long to, double cost, boolean bidirectional) { * @return the id from the outing node of the edge. */ public long getFromNodeId() { - return fromNode; + return fromNodeId; } /** @@ -105,7 +105,7 @@ public long getFromNodeId() { * @return the id from the incoming node of the edge. */ public long getToNodeId() { - return toNode; + return toNodeId; } /** @@ -123,7 +123,7 @@ public double getCost() { * @param fromNode the new id from the outing node of the edge. */ public void setFromNodeId(long fromNode) { - this.fromNode = fromNode; + this.fromNodeId = fromNode; } /** @@ -132,7 +132,7 @@ public void setFromNodeId(long fromNode) { * @param toNode the new id from the incoming node of the edge. */ public void setToNodeId(long toNode) { - this.toNode = toNode; + this.toNodeId = toNode; } /** @@ -164,23 +164,23 @@ public boolean isBidirectional() { * @return the id from the adjacent node, based on the given id. */ public long getAdjacent(long id) { - return id == toNode ? fromNode : toNode; + return id == toNodeId ? fromNodeId : toNodeId; } - public void setCard(String cardName, EdgeComponent card) { - if (edgeCards == null) - edgeCards = new HashMap<>(); - edgeCards.put(cardName, card); + public void setComponent(EdgeComponent component) { + if (edgeComponent == null) + edgeComponent = new HashMap<>(); + edgeComponent.put(component.getClass(), component); } - public EdgeComponent getCard(String cardName) { - if (edgeCards == null || !edgeCards.containsKey(cardName)) + public EdgeComponent getComponent(Class componentClass) { + if (edgeComponent == null || !edgeComponent.containsKey(componentClass)) return null; - return edgeCards.get(cardName); + return edgeComponent.get(componentClass); } - public Set getAllCardNames() { - return edgeCards.keySet(); + public Set> getAllComponentClasses() { + return edgeComponent.keySet(); } /** @@ -202,8 +202,8 @@ public boolean equals(Object obj) { Edge other = (Edge) obj; - boolean okFromNode = this.fromNode == other.fromNode; - boolean okToNode = this.toNode == other.toNode; + boolean okFromNode = this.fromNodeId == other.fromNodeId; + boolean okToNode = this.toNodeId == other.toNodeId; boolean okCost = this.cost == other.cost; return okFromNode && okToNode && okCost; @@ -221,7 +221,7 @@ public boolean equals(Object obj) { */ @Override public int hashCode() { - return (fromNode + "|" + toNode + "|" + cost).hashCode(); + return (fromNodeId + "|" + toNodeId + "|" + cost).hashCode(); } /** @@ -231,7 +231,7 @@ public int hashCode() { */ @Override public String toString() { - return fromNode + "|" + toNode + "|" + cost; + return fromNodeId + "|" + toNodeId + "|" + cost; } } diff --git a/core/src/main/java/org/insightlab/graphast/model/Graph.java b/core/src/main/java/org/insightlab/graphast/model/Graph.java index fc3ca4f..96e786e 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Graph.java +++ b/core/src/main/java/org/insightlab/graphast/model/Graph.java @@ -27,7 +27,7 @@ import java.util.Iterator; import java.util.Set; -import org.insightlab.graphast.model.cards.GraphComponent; +import org.insightlab.graphast.model.components.GraphComponent; import org.insightlab.graphast.structure.DefaultGraphStructure; import org.insightlab.graphast.structure.GraphStructure; @@ -188,16 +188,16 @@ public Iterator getInEdges(long id) { } - public GraphComponent getCard(String cardName) { - return structure.getCard(cardName); + public GraphComponent getComponent(Class componentClass) { + return structure.getComponent(componentClass); } - public void setCard(String cardName, GraphComponent card) { - structure.setCard(cardName, card); + public void setComponent(GraphComponent component) { + structure.setComponent(component); } - public Set getAllCardNames() { - return structure.getAllCardNames(); + public Set> getAllCardNames() { + return structure.getAllComponentClasses(); } diff --git a/core/src/main/java/org/insightlab/graphast/model/Node.java b/core/src/main/java/org/insightlab/graphast/model/Node.java index ce48dd5..8dd74a3 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Node.java +++ b/core/src/main/java/org/insightlab/graphast/model/Node.java @@ -28,7 +28,7 @@ import java.util.Map; import java.util.Set; -import org.insightlab.graphast.model.cards.NodeComponent; +import org.insightlab.graphast.model.components.NodeComponent; /** * The Node class. It represents the model of a graph node. @@ -36,7 +36,7 @@ */ public class Node extends GraphObject { - private Map nodeCards = null; + private Map, NodeComponent> nodeComponents = null; private long id; @@ -58,20 +58,20 @@ public long getId() { return id; } - public void setCard(String cardName, NodeComponent card) { - if (nodeCards == null) - nodeCards = new HashMap<>(); - nodeCards.put(cardName, card); + public void setComponent(NodeComponent component) { + if (nodeComponents == null) + nodeComponents = new HashMap<>(); + nodeComponents.put(component.getClass(), component); } - public NodeComponent getCard(String cardName) { - if (nodeCards == null || !nodeCards.containsKey(cardName)) + public NodeComponent getComponent(Class componentClass) { + if (nodeComponents == null || !nodeComponents.containsKey(componentClass)) return null; - return nodeCards.get(cardName); + return nodeComponents.get(componentClass); } - public Set getAllCardNames() { - return nodeCards.keySet(); + public Set> getAllComponentClasses() { + return nodeComponents.keySet(); } /** diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialComponentController.java b/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialComponentController.java deleted file mode 100644 index 75f8ee2..0000000 --- a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialComponentController.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.insightlab.graphast.model.cards.spatial_cards; - -import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.Graph; -import org.insightlab.graphast.model.Node; - -public class SpatialComponentController { - - private static SpatialComponentController instance = null; - private static final String cardName = "SpatialCard"; - - private SpatialComponentController() {} - - public static SpatialComponentController getInstance() { - if (instance == null) - instance = new SpatialComponentController(); - return instance; - } - - public String getCardName() { - return cardName; - } - - public SpatialGraphComponent getCard(Graph g) { - return (SpatialGraphComponent) g.getCard(cardName); - } - - public SpatialNodeComponent getCard(Node n) { - return (SpatialNodeComponent) n.getCard(cardName); - } - - public SpatialEdgeComponent getCard(Edge e) { - return (SpatialEdgeComponent) e.getCard(cardName); - } - - public void setCard(Graph g) { - g.setCard(cardName, new SpatialGraphComponent(g)); - } - - public void setCard(Node n, Point p) { - n.setCard(cardName, new SpatialNodeComponent(n, p)); - } - - public void setCard(Edge e, Geometry geometry) { - e.setCard(cardName, new SpatialEdgeComponent(e, geometry)); - } - -} diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/EdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java similarity index 76% rename from core/src/main/java/org/insightlab/graphast/model/cards/EdgeComponent.java rename to core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java index 4ace495..e3acaaa 100644 --- a/core/src/main/java/org/insightlab/graphast/model/cards/EdgeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java @@ -1,4 +1,4 @@ -package org.insightlab.graphast.model.cards; +package org.insightlab.graphast.model.components; import org.insightlab.graphast.model.Edge; diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/GraphComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java similarity index 77% rename from core/src/main/java/org/insightlab/graphast/model/cards/GraphComponent.java rename to core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java index f278eef..14917bd 100644 --- a/core/src/main/java/org/insightlab/graphast/model/cards/GraphComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java @@ -1,4 +1,4 @@ -package org.insightlab.graphast.model.cards; +package org.insightlab.graphast.model.components; import org.insightlab.graphast.model.Graph; diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/NodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java similarity index 76% rename from core/src/main/java/org/insightlab/graphast/model/cards/NodeComponent.java rename to core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java index 1d8145c..2b65b70 100644 --- a/core/src/main/java/org/insightlab/graphast/model/cards/NodeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java @@ -1,4 +1,4 @@ -package org.insightlab.graphast.model.cards; +package org.insightlab.graphast.model.components; import org.insightlab.graphast.model.Node; diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Geometry.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java similarity index 50% rename from core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Geometry.java rename to core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java index cdd537a..005bbbf 100644 --- a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Geometry.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java @@ -1,4 +1,4 @@ -package org.insightlab.graphast.model.cards.spatial_cards; +package org.insightlab.graphast.model.components.spatial_components; import java.util.ArrayList; import java.util.Arrays; @@ -6,22 +6,22 @@ public class Geometry { - private List geometry; + private List points; public Geometry() { - geometry = new ArrayList<>(); + this.points = new ArrayList<>(); } public Geometry(Point ...points) { - geometry.addAll(Arrays.asList(points)); + this.points.addAll(Arrays.asList(points)); } public void addPoint(Point p) { - geometry.add(p); + this.points.add(p); } public List getGeometry() { - return geometry; + return this.points; } } diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Point.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java similarity index 77% rename from core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Point.java rename to core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java index 2536f5a..0ed8105 100644 --- a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/Point.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java @@ -1,4 +1,4 @@ -package org.insightlab.graphast.model.cards.spatial_cards; +package org.insightlab.graphast.model.components.spatial_components; public class Point { diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialComponentController.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialComponentController.java new file mode 100644 index 0000000..bb84456 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialComponentController.java @@ -0,0 +1,43 @@ +package org.insightlab.graphast.model.components.spatial_components; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.Node; + +public class SpatialComponentController { + + private static SpatialComponentController instance = null; + + private SpatialComponentController() {} + + public static SpatialComponentController getInstance() { + if (instance == null) + instance = new SpatialComponentController(); + return instance; + } + + public SpatialGraphComponent getComponent(Graph g) { + return (SpatialGraphComponent) g.getComponent(SpatialGraphComponent.class); + } + + public SpatialNodeComponent getComponent(Node n) { + return (SpatialNodeComponent) n.getComponent(SpatialNodeComponent.class); + } + + public SpatialEdgeComponent getComponent(Edge e) { + return (SpatialEdgeComponent) e.getComponent(SpatialEdgeComponent.class); + } + + public void setCard(Graph g) { + g.setComponent(new SpatialGraphComponent(g)); + } + + public void setCard(Node n, Point p) { + n.setComponent(new SpatialNodeComponent(n, p)); + } + + public void setCard(Edge e, Geometry geometry) { + e.setComponent(new SpatialEdgeComponent(e, geometry)); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialEdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java similarity index 70% rename from core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialEdgeComponent.java rename to core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java index c923156..b00647c 100644 --- a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialEdgeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java @@ -1,7 +1,7 @@ -package org.insightlab.graphast.model.cards.spatial_cards; +package org.insightlab.graphast.model.components.spatial_components; import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.cards.EdgeComponent; +import org.insightlab.graphast.model.components.EdgeComponent; public class SpatialEdgeComponent extends EdgeComponent { diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialGraphComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java similarity index 54% rename from core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialGraphComponent.java rename to core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java index be54ccb..68d8cda 100644 --- a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialGraphComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java @@ -1,7 +1,7 @@ -package org.insightlab.graphast.model.cards.spatial_cards; +package org.insightlab.graphast.model.components.spatial_components; import org.insightlab.graphast.model.Graph; -import org.insightlab.graphast.model.cards.GraphComponent; +import org.insightlab.graphast.model.components.GraphComponent; public class SpatialGraphComponent extends GraphComponent { diff --git a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialNodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java similarity index 72% rename from core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialNodeComponent.java rename to core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java index 2ad4b2a..99177ea 100644 --- a/core/src/main/java/org/insightlab/graphast/model/cards/spatial_cards/SpatialNodeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java @@ -1,7 +1,7 @@ -package org.insightlab.graphast.model.cards.spatial_cards; +package org.insightlab.graphast.model.components.spatial_components; import org.insightlab.graphast.model.Node; -import org.insightlab.graphast.model.cards.NodeComponent; +import org.insightlab.graphast.model.components.NodeComponent; public class SpatialNodeComponent extends NodeComponent { diff --git a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java index 2faf98a..18f2580 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java @@ -34,7 +34,7 @@ import org.insightlab.graphast.exceptions.NodeNotFoundException; import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Node; -import org.insightlab.graphast.model.cards.GraphComponent; +import org.insightlab.graphast.model.components.GraphComponent; /** * This class implements a default graph structure using the interface GraphStructure. @@ -42,7 +42,7 @@ */ public class DefaultGraphStructure implements GraphStructure { - private Map graphCards = null; + private Map, GraphComponent> graphComponents = null; private Integer nextId = 0; @@ -179,24 +179,24 @@ public Iterator getInEdges(final long id) { } @Override - public void setCard(String cardName, GraphComponent card) { - if (graphCards == null) - graphCards = new HashMap<>(); - graphCards.put(cardName, card); + public void setComponent(GraphComponent component) { + if (graphComponents == null) + graphComponents = new HashMap<>(); + graphComponents.put(component.getClass(), component); } @Override - public GraphComponent getCard(String cardName) { - if (graphCards == null || !graphCards.containsKey(cardName)) + public GraphComponent getComponent(Class componentClass) { + if (graphComponents == null || !graphComponents.containsKey(componentClass)) return null; - return graphCards.get(cardName); + return graphComponents.get(componentClass); } @Override - public Set getAllCardNames() { - if (graphCards == null) + public Set> getAllComponentClasses() { + if (graphComponents == null) return null; - return graphCards.keySet(); + return graphComponents.keySet(); } } diff --git a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java index 7cfc699..f7781f1 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java @@ -29,7 +29,7 @@ import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Node; -import org.insightlab.graphast.model.cards.GraphComponent; +import org.insightlab.graphast.model.components.GraphComponent; /** * The GraphStructure interface. This interface contains declarations of general methods @@ -88,12 +88,12 @@ public interface GraphStructure { Iterator getInEdges(final long id); - Set getAllCardNames(); + Set> getAllComponentClasses(); - GraphComponent getCard(String cardName); + GraphComponent getComponent(Class componentClass); - void setCard(String cardName, GraphComponent card); + void setComponent(GraphComponent component); } diff --git a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java index d47ee47..06c8b55 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java @@ -31,7 +31,7 @@ import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Node; -import org.insightlab.graphast.model.cards.GraphComponent; +import org.insightlab.graphast.model.components.GraphComponent; import org.insightlab.hugedataaccess.DataAccess; import org.insightlab.hugedataaccess.MMapDataAccess; import org.insightlab.hugedataaccess.structures.MMapMap; @@ -357,20 +357,22 @@ public void remove() { } @Override - public GraphComponent getCard(String cardName) { + public Set> getAllComponentClasses() { // TODO Auto-generated method stub return null; } @Override - public void setCard(String cardName, GraphComponent card) { + public GraphComponent getComponent(Class componentClass) { // TODO Auto-generated method stub + return null; } - + @Override - public Set getAllCardNames() { + public void setComponent(GraphComponent component) { // TODO Auto-generated method stub - return null; + } + } diff --git a/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java b/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java index ed6b7d1..8508820 100644 --- a/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java +++ b/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java @@ -5,8 +5,8 @@ //import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Graph; import org.insightlab.graphast.model.Node; -import org.insightlab.graphast.model.cards.spatial_cards.Point; -import org.insightlab.graphast.model.cards.spatial_cards.SpatialComponentController; +import org.insightlab.graphast.model.components.spatial_components.Point; +import org.insightlab.graphast.model.components.spatial_components.SpatialComponentController; import org.junit.Before; import org.junit.Test; @@ -29,6 +29,7 @@ public void setUp() throws Exception { controller.setCard(n2, new Point(14, 2)); n3 = new Node(3); controller.setCard(n3, new Point(15, 1)); + // e0 = new Edge(1, 2, true); // e1 = new Edge(2, 3); // e2 = new Edge(0, 1); @@ -37,8 +38,9 @@ public void setUp() throws Exception { @Test public void test() { - assertEquals("N1 lat test", 13, controller.getCard(n1).getLat()); - assertEquals("N3 lng test", 1, controller.getCard(n3).getLng()); + assertEquals("N1 lat test", 13, controller.getComponent(n1).getLat()); + assertEquals("N3 lng test", 1, controller.getComponent(n3).getLng()); + } } From 75e82b65d84d6d101f1148245a93aebe49ace32f Mon Sep 17 00:00:00 2001 From: archangel777 Date: Sun, 11 Feb 2018 14:23:15 -0300 Subject: [PATCH 05/16] Removed the need for a component controller, without having to make casts --- .../insightlab/graphast/MainClassDiagram.ucls | 128 +++++++++--------- .../org/insightlab/graphast/model/Edge.java | 5 +- .../org/insightlab/graphast/model/Graph.java | 5 +- .../org/insightlab/graphast/model/Node.java | 5 +- .../spatial_components/Geometry.java | 3 +- .../components/spatial_components/Point.java | 8 ++ .../SpatialComponentController.java | 43 ------ .../SpatialEdgeComponent.java | 9 +- .../SpatialGraphComponent.java | 4 +- .../SpatialNodeComponent.java | 4 +- .../graphast/cards/SpatialCardTest.java | 46 ------- .../components/SpatialComponentTest.java | 54 ++++++++ 12 files changed, 140 insertions(+), 174 deletions(-) delete mode 100644 core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialComponentController.java delete mode 100644 core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java create mode 100644 core/src/test/java/org/insightlab/graphast/components/SpatialComponentTest.java diff --git a/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls index 8d996d1..41aaff9 100644 --- a/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls +++ b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls @@ -154,128 +154,128 @@ - - - - - - - - - - - - - - - - - + - + - + - - - - + + + + + + + + - + - + - - - - + + + + + + + + - - + + - + - - - - - + + + + + - + - + - + - + + + + + + + + + + + + + - + - + - - - - + + + + - - + + - + - - - - + + + + - - + + - + - - - - - - + + - + (); edgeComponent.put(component.getClass(), component); + component.setEdge(this); } - public EdgeComponent getComponent(Class componentClass) { + public C getComponent(Class componentClass) { if (edgeComponent == null || !edgeComponent.containsKey(componentClass)) return null; - return edgeComponent.get(componentClass); + return componentClass.cast(edgeComponent.get(componentClass)); } public Set> getAllComponentClasses() { diff --git a/core/src/main/java/org/insightlab/graphast/model/Graph.java b/core/src/main/java/org/insightlab/graphast/model/Graph.java index 96e786e..686a201 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Graph.java +++ b/core/src/main/java/org/insightlab/graphast/model/Graph.java @@ -188,12 +188,13 @@ public Iterator getInEdges(long id) { } - public GraphComponent getComponent(Class componentClass) { - return structure.getComponent(componentClass); + public C getComponent(Class componentClass) { + return componentClass.cast(structure.getComponent(componentClass)); } public void setComponent(GraphComponent component) { structure.setComponent(component); + component.setGraph(this); } public Set> getAllCardNames() { diff --git a/core/src/main/java/org/insightlab/graphast/model/Node.java b/core/src/main/java/org/insightlab/graphast/model/Node.java index 8dd74a3..eee7cc4 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Node.java +++ b/core/src/main/java/org/insightlab/graphast/model/Node.java @@ -62,12 +62,13 @@ public void setComponent(NodeComponent component) { if (nodeComponents == null) nodeComponents = new HashMap<>(); nodeComponents.put(component.getClass(), component); + component.setNode(this); } - public NodeComponent getComponent(Class componentClass) { + public C getComponent(Class componentClass) { if (nodeComponents == null || !nodeComponents.containsKey(componentClass)) return null; - return nodeComponents.get(componentClass); + return componentClass.cast(nodeComponents.get(componentClass)); } public Set> getAllComponentClasses() { diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java index 005bbbf..8c68287 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java @@ -13,6 +13,7 @@ public Geometry() { } public Geometry(Point ...points) { + this(); this.points.addAll(Arrays.asList(points)); } @@ -20,7 +21,7 @@ public void addPoint(Point p) { this.points.add(p); } - public List getGeometry() { + public List getPoints() { return this.points; } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java index 0ed8105..706c927 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java @@ -25,5 +25,13 @@ public void setLat(int lat) { public void setLng(int lng) { this.lng = lng; } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Point)) + return false; + Point other = (Point) obj; + return lat == other.getLat() && lng == other.getLng(); + } } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialComponentController.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialComponentController.java deleted file mode 100644 index bb84456..0000000 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialComponentController.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.insightlab.graphast.model.components.spatial_components; - -import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.Graph; -import org.insightlab.graphast.model.Node; - -public class SpatialComponentController { - - private static SpatialComponentController instance = null; - - private SpatialComponentController() {} - - public static SpatialComponentController getInstance() { - if (instance == null) - instance = new SpatialComponentController(); - return instance; - } - - public SpatialGraphComponent getComponent(Graph g) { - return (SpatialGraphComponent) g.getComponent(SpatialGraphComponent.class); - } - - public SpatialNodeComponent getComponent(Node n) { - return (SpatialNodeComponent) n.getComponent(SpatialNodeComponent.class); - } - - public SpatialEdgeComponent getComponent(Edge e) { - return (SpatialEdgeComponent) e.getComponent(SpatialEdgeComponent.class); - } - - public void setCard(Graph g) { - g.setComponent(new SpatialGraphComponent(g)); - } - - public void setCard(Node n, Point p) { - n.setComponent(new SpatialNodeComponent(n, p)); - } - - public void setCard(Edge e, Geometry geometry) { - e.setComponent(new SpatialEdgeComponent(e, geometry)); - } - -} diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java index b00647c..511cf70 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java @@ -1,18 +1,11 @@ package org.insightlab.graphast.model.components.spatial_components; -import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.components.EdgeComponent; public class SpatialEdgeComponent extends EdgeComponent { private Geometry geometry; - - public SpatialEdgeComponent(Edge e) { - this(e, new Geometry()); - } - - public SpatialEdgeComponent(Edge e, Geometry geometry) { - this.setEdge(e); + public SpatialEdgeComponent(Geometry geometry) { this.geometry = geometry; } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java index 68d8cda..8a8dea9 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java @@ -1,12 +1,10 @@ package org.insightlab.graphast.model.components.spatial_components; -import org.insightlab.graphast.model.Graph; import org.insightlab.graphast.model.components.GraphComponent; public class SpatialGraphComponent extends GraphComponent { - public SpatialGraphComponent(Graph g) { - this.setGraph(g); + public SpatialGraphComponent() { } } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java index 99177ea..32f3ee5 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java @@ -1,14 +1,12 @@ package org.insightlab.graphast.model.components.spatial_components; -import org.insightlab.graphast.model.Node; import org.insightlab.graphast.model.components.NodeComponent; public class SpatialNodeComponent extends NodeComponent { private Point point; - public SpatialNodeComponent(Node n, Point p) { - this.setNode(n); + public SpatialNodeComponent(Point p) { this.point = p; } diff --git a/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java b/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java deleted file mode 100644 index 8508820..0000000 --- a/core/src/test/java/org/insightlab/graphast/cards/SpatialCardTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.insightlab.graphast.cards; - -import static org.junit.Assert.*; - -//import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.Graph; -import org.insightlab.graphast.model.Node; -import org.insightlab.graphast.model.components.spatial_components.Point; -import org.insightlab.graphast.model.components.spatial_components.SpatialComponentController; -import org.junit.Before; -import org.junit.Test; - -public class SpatialCardTest { - - Graph g; - private Node n0, n1, n2, n3; - SpatialComponentController controller; -// private Edge e0, e1, e2, e3; - - @Before - public void setUp() throws Exception { - controller = SpatialComponentController.getInstance(); - g = new Graph(); - n0 = new Node(0); - controller.setCard(n0, new Point(12, 4)); - n1 = new Node(1); - controller.setCard(n1, new Point(13, 3)); - n2 = new Node(2); - controller.setCard(n2, new Point(14, 2)); - n3 = new Node(3); - controller.setCard(n3, new Point(15, 1)); - -// e0 = new Edge(1, 2, true); -// e1 = new Edge(2, 3); -// e2 = new Edge(0, 1); -// e3 = new Edge(3, 0, true); - } - - @Test - public void test() { - assertEquals("N1 lat test", 13, controller.getComponent(n1).getLat()); - assertEquals("N3 lng test", 1, controller.getComponent(n3).getLng()); - - } - -} diff --git a/core/src/test/java/org/insightlab/graphast/components/SpatialComponentTest.java b/core/src/test/java/org/insightlab/graphast/components/SpatialComponentTest.java new file mode 100644 index 0000000..ef83ca4 --- /dev/null +++ b/core/src/test/java/org/insightlab/graphast/components/SpatialComponentTest.java @@ -0,0 +1,54 @@ +package org.insightlab.graphast.components; + +import static org.junit.Assert.*; + +import org.insightlab.graphast.model.Edge; +//import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.components.spatial_components.Geometry; +import org.insightlab.graphast.model.components.spatial_components.Point; +import org.insightlab.graphast.model.components.spatial_components.SpatialEdgeComponent; +import org.insightlab.graphast.model.components.spatial_components.SpatialGraphComponent; +import org.insightlab.graphast.model.components.spatial_components.SpatialNodeComponent; +import org.junit.Before; +import org.junit.Test; + +public class SpatialComponentTest { + + Graph g; + private Node n0, n1, n2, n3; + private Edge e0, e1, e2, e3; + + @Before + public void setUp() throws Exception { + g = new Graph(); + g.setComponent(new SpatialGraphComponent()); + n0 = new Node(0); + n0.setComponent(new SpatialNodeComponent(new Point(12, 4))); + n1 = new Node(1); + n1.setComponent(new SpatialNodeComponent(new Point(13, 3))); + n2 = new Node(2); + n2.setComponent(new SpatialNodeComponent(new Point(14, 2))); + n3 = new Node(3); + n3.setComponent(new SpatialNodeComponent(new Point(15, 1))); + + e0 = new Edge(1, 2, true); + e0.setComponent(new SpatialEdgeComponent(new Geometry(new Point(1, 2)))); + e1 = new Edge(2, 3); + e1.setComponent(new SpatialEdgeComponent(new Geometry(new Point(2, 3), new Point(4, 5)))); + e2 = new Edge(0, 1); + e2.setComponent(new SpatialEdgeComponent(new Geometry(new Point(1, 3)))); + e3 = new Edge(3, 0, true); + e3.setComponent(new SpatialEdgeComponent(new Geometry())); + } + + @Test + public void test() { + assertEquals("N1 lat test", 13, n1.getComponent(SpatialNodeComponent.class).getLat()); + assertEquals("N3 lng test", 1, n3.getComponent(SpatialNodeComponent.class).getLng()); + System.out.println(e2.getComponent(SpatialEdgeComponent.class).getGeometry().getPoints().toArray()); + assertArrayEquals("E2 Geometry test", new Point[] {new Point(1, 3)}, e2.getComponent(SpatialEdgeComponent.class).getGeometry().getPoints().toArray()); + } + +} From fcb67fa7e07492b0390b2d6785403cf51734b4e2 Mon Sep 17 00:00:00 2001 From: archangel777 Date: Tue, 13 Feb 2018 16:01:23 -0300 Subject: [PATCH 06/16] Added temporal Edge component and changed "setComponent" to "addComponent" --- .../insightlab/graphast/MainClassDiagram.ucls | 165 ++++++++---------- .../org/insightlab/graphast/model/Edge.java | 2 +- .../org/insightlab/graphast/model/Graph.java | 4 +- .../org/insightlab/graphast/model/Node.java | 2 +- .../TemporalEdgeComponent.java | 24 +++ .../structure/DefaultGraphStructure.java | 2 +- .../graphast/structure/GraphStructure.java | 2 +- .../structure/MMapGraphStructure.java | 2 +- .../graphast/components/ComponentTest.java | 70 ++++++++ .../components/SpatialComponentTest.java | 54 ------ 10 files changed, 178 insertions(+), 149 deletions(-) create mode 100644 core/src/main/java/org/insightlab/graphast/model/components/temporal_components/TemporalEdgeComponent.java create mode 100644 core/src/test/java/org/insightlab/graphast/components/ComponentTest.java delete mode 100644 core/src/test/java/org/insightlab/graphast/components/SpatialComponentTest.java diff --git a/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls index 41aaff9..b827476 100644 --- a/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls +++ b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls @@ -111,18 +111,7 @@ - - - - - - - - @@ -132,7 +121,7 @@ - @@ -142,142 +131,142 @@ - - - + + + - + - + - - - + + + - + - + - - - - - - - - + + + + - + - + - - - - - - - - + + + + - - + + - + - - - - - - - + + + - + - + - - - - - - - - + + + + - - + + - + - - - + + + - + - + - - - + + + - + - + - - - - + + + + + + + + + + + + - - + + - + - - - - + + + + + + + + - - + + - + + + + + diff --git a/core/src/main/java/org/insightlab/graphast/model/Edge.java b/core/src/main/java/org/insightlab/graphast/model/Edge.java index 2a6f180..64da00b 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Edge.java +++ b/core/src/main/java/org/insightlab/graphast/model/Edge.java @@ -167,7 +167,7 @@ public long getAdjacent(long id) { return id == toNodeId ? fromNodeId : toNodeId; } - public void setComponent(EdgeComponent component) { + public void addComponent(EdgeComponent component) { if (edgeComponent == null) edgeComponent = new HashMap<>(); edgeComponent.put(component.getClass(), component); diff --git a/core/src/main/java/org/insightlab/graphast/model/Graph.java b/core/src/main/java/org/insightlab/graphast/model/Graph.java index 686a201..5bbb641 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Graph.java +++ b/core/src/main/java/org/insightlab/graphast/model/Graph.java @@ -192,8 +192,8 @@ public C getComponent(Class componentClass) { return componentClass.cast(structure.getComponent(componentClass)); } - public void setComponent(GraphComponent component) { - structure.setComponent(component); + public void addComponent(GraphComponent component) { + structure.addComponent(component); component.setGraph(this); } diff --git a/core/src/main/java/org/insightlab/graphast/model/Node.java b/core/src/main/java/org/insightlab/graphast/model/Node.java index eee7cc4..87cce89 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Node.java +++ b/core/src/main/java/org/insightlab/graphast/model/Node.java @@ -58,7 +58,7 @@ public long getId() { return id; } - public void setComponent(NodeComponent component) { + public void addComponent(NodeComponent component) { if (nodeComponents == null) nodeComponents = new HashMap<>(); nodeComponents.put(component.getClass(), component); diff --git a/core/src/main/java/org/insightlab/graphast/model/components/temporal_components/TemporalEdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/temporal_components/TemporalEdgeComponent.java new file mode 100644 index 0000000..dac5b3d --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/model/components/temporal_components/TemporalEdgeComponent.java @@ -0,0 +1,24 @@ +package org.insightlab.graphast.model.components.temporal_components; + +import java.util.Arrays; +import java.util.List; + +import org.insightlab.graphast.model.components.EdgeComponent; + +public class TemporalEdgeComponent extends EdgeComponent { + + private List costList; + + public TemporalEdgeComponent(Double ...costs) { + costList = Arrays.asList(costs); + } + + public double getSpecificCost(int index) { + return costList.get(index); + } + + public double getMeanCost() { + return costList.stream().reduce(0., (x1, x2) -> x1 + x2) / costList.size(); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java index 18f2580..0c74d9e 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java @@ -179,7 +179,7 @@ public Iterator getInEdges(final long id) { } @Override - public void setComponent(GraphComponent component) { + public void addComponent(GraphComponent component) { if (graphComponents == null) graphComponents = new HashMap<>(); graphComponents.put(component.getClass(), component); diff --git a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java index f7781f1..9172b49 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java @@ -94,6 +94,6 @@ public interface GraphStructure { GraphComponent getComponent(Class componentClass); - void setComponent(GraphComponent component); + void addComponent(GraphComponent component); } diff --git a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java index 06c8b55..f53d67c 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java @@ -369,7 +369,7 @@ public GraphComponent getComponent(Class componentClas } @Override - public void setComponent(GraphComponent component) { + public void addComponent(GraphComponent component) { // TODO Auto-generated method stub } diff --git a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java new file mode 100644 index 0000000..96dc070 --- /dev/null +++ b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java @@ -0,0 +1,70 @@ +package org.insightlab.graphast.components; + +import static org.junit.Assert.*; + +import org.insightlab.graphast.model.Edge; +//import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.components.spatial_components.Geometry; +import org.insightlab.graphast.model.components.spatial_components.Point; +import org.insightlab.graphast.model.components.spatial_components.SpatialEdgeComponent; +import org.insightlab.graphast.model.components.spatial_components.SpatialGraphComponent; +import org.insightlab.graphast.model.components.spatial_components.SpatialNodeComponent; +import org.insightlab.graphast.model.components.temporal_components.TemporalEdgeComponent; +import org.junit.Before; +import org.junit.Test; + +public class ComponentTest { + + Graph g; + private Node n0, n1, n2, n3; + private Edge e0, e1, e2, e3; + + @Before + public void setUp() throws Exception { + g = new Graph(); + g.addComponent(new SpatialGraphComponent()); + n0 = new Node(0); + n0.addComponent(new SpatialNodeComponent(new Point(12, 4))); + n1 = new Node(1); + n1.addComponent(new SpatialNodeComponent(new Point(13, 3))); + n2 = new Node(2); + n2.addComponent(new SpatialNodeComponent(new Point(14, 2))); + n3 = new Node(3); + n3.addComponent(new SpatialNodeComponent(new Point(15, 1))); + + e0 = new Edge(1, 2, true); + e0.addComponent(new SpatialEdgeComponent(new Geometry(new Point(1, 2)))); + e0.addComponent(new TemporalEdgeComponent(2., 3., 1., 5., 6., 3., 1.)); + + e1 = new Edge(2, 3); + e1.addComponent(new SpatialEdgeComponent(new Geometry(new Point(2, 3), new Point(4, 5)))); + e1.addComponent(new TemporalEdgeComponent(1., 2., 1., 4., 7., 1., 2.)); + + e2 = new Edge(0, 1); + e2.addComponent(new SpatialEdgeComponent(new Geometry(new Point(1, 3)))); + e2.addComponent(new TemporalEdgeComponent(3., 4., 2., 6., 6., 4., 3.)); + + e3 = new Edge(3, 0, true); + e3.addComponent(new SpatialEdgeComponent(new Geometry())); + e3.addComponent(new TemporalEdgeComponent(2., 1., 2., 4., 8., 4., 2.)); + } + + @Test + public void spatialTest() { + assertEquals("N1 lat test", 13, n1.getComponent(SpatialNodeComponent.class).getLat()); + assertEquals("N3 lng test", 1, n3.getComponent(SpatialNodeComponent.class).getLng()); + System.out.println(e2.getComponent(SpatialEdgeComponent.class).getGeometry().getPoints().toArray()); + assertArrayEquals("E2 Geometry test", new Point[] {new Point(1, 3)}, e2.getComponent(SpatialEdgeComponent.class).getGeometry().getPoints().toArray()); + } + + @Test + public void temporalTest() { + assertEquals("E0 specific cost test", 5., e0.getComponent(TemporalEdgeComponent.class).getSpecificCost(3), 0.); + assertEquals("E2 specific cost test", 4., e2.getComponent(TemporalEdgeComponent.class).getSpecificCost(5), 0.); + assertEquals("E1 mean cost test", 2.571, e1.getComponent(TemporalEdgeComponent.class).getMeanCost(), 0.001); + assertEquals("E3 mean cost test", 3.286, e3.getComponent(TemporalEdgeComponent.class).getMeanCost(), 0.001); + } + +} diff --git a/core/src/test/java/org/insightlab/graphast/components/SpatialComponentTest.java b/core/src/test/java/org/insightlab/graphast/components/SpatialComponentTest.java deleted file mode 100644 index ef83ca4..0000000 --- a/core/src/test/java/org/insightlab/graphast/components/SpatialComponentTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.insightlab.graphast.components; - -import static org.junit.Assert.*; - -import org.insightlab.graphast.model.Edge; -//import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.Graph; -import org.insightlab.graphast.model.Node; -import org.insightlab.graphast.model.components.spatial_components.Geometry; -import org.insightlab.graphast.model.components.spatial_components.Point; -import org.insightlab.graphast.model.components.spatial_components.SpatialEdgeComponent; -import org.insightlab.graphast.model.components.spatial_components.SpatialGraphComponent; -import org.insightlab.graphast.model.components.spatial_components.SpatialNodeComponent; -import org.junit.Before; -import org.junit.Test; - -public class SpatialComponentTest { - - Graph g; - private Node n0, n1, n2, n3; - private Edge e0, e1, e2, e3; - - @Before - public void setUp() throws Exception { - g = new Graph(); - g.setComponent(new SpatialGraphComponent()); - n0 = new Node(0); - n0.setComponent(new SpatialNodeComponent(new Point(12, 4))); - n1 = new Node(1); - n1.setComponent(new SpatialNodeComponent(new Point(13, 3))); - n2 = new Node(2); - n2.setComponent(new SpatialNodeComponent(new Point(14, 2))); - n3 = new Node(3); - n3.setComponent(new SpatialNodeComponent(new Point(15, 1))); - - e0 = new Edge(1, 2, true); - e0.setComponent(new SpatialEdgeComponent(new Geometry(new Point(1, 2)))); - e1 = new Edge(2, 3); - e1.setComponent(new SpatialEdgeComponent(new Geometry(new Point(2, 3), new Point(4, 5)))); - e2 = new Edge(0, 1); - e2.setComponent(new SpatialEdgeComponent(new Geometry(new Point(1, 3)))); - e3 = new Edge(3, 0, true); - e3.setComponent(new SpatialEdgeComponent(new Geometry())); - } - - @Test - public void test() { - assertEquals("N1 lat test", 13, n1.getComponent(SpatialNodeComponent.class).getLat()); - assertEquals("N3 lng test", 1, n3.getComponent(SpatialNodeComponent.class).getLng()); - System.out.println(e2.getComponent(SpatialEdgeComponent.class).getGeometry().getPoints().toArray()); - assertArrayEquals("E2 Geometry test", new Point[] {new Point(1, 3)}, e2.getComponent(SpatialEdgeComponent.class).getGeometry().getPoints().toArray()); - } - -} From 89cfa674dbb5263e9926f2e67a0ec3dfa9b990de Mon Sep 17 00:00:00 2001 From: ericklt Date: Tue, 13 Feb 2018 22:46:46 -0300 Subject: [PATCH 07/16] Now you can create an arbitrary cost function to use in an algorithm --- .../query/cost_functions/CostFunction.java | 9 ++++++++ .../cost_functions/DefaultCostFunction.java | 12 ++++++++++ .../TemporalMeanCostFunction.java | 16 ++++++++++++++ .../TemporalSpecificCostFunction.java | 22 +++++++++++++++++++ .../query/shortestpath/DijkstraStrategy.java | 17 +++++++++++++- .../shortestpath/ShortestPathStrategy.java | 5 ++++- .../graphast/components/ComponentTest.java | 20 +++++++++++++++++ 7 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunction.java create mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/DefaultCostFunction.java create mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java create mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunction.java new file mode 100644 index 0000000..62ffc98 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunction.java @@ -0,0 +1,9 @@ +package org.insightlab.graphast.query.cost_functions; + +import org.insightlab.graphast.model.Edge; + +public interface CostFunction { + + double getCost(Edge e) throws Exception; //TODO Create specific exception + +} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/DefaultCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/DefaultCostFunction.java new file mode 100644 index 0000000..c94e22d --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/DefaultCostFunction.java @@ -0,0 +1,12 @@ +package org.insightlab.graphast.query.cost_functions; + +import org.insightlab.graphast.model.Edge; + +public class DefaultCostFunction implements CostFunction { + + @Override + public double getCost(Edge e) { + return e.getCost(); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java new file mode 100644 index 0000000..e6caa88 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java @@ -0,0 +1,16 @@ +package org.insightlab.graphast.query.cost_functions; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.components.temporal_components.TemporalEdgeComponent; + +public class TemporalMeanCostFunction implements CostFunction { + + @Override + public double getCost(Edge e) throws Exception { + TemporalEdgeComponent component = e.getComponent(TemporalEdgeComponent.class); + if (component == null) + throw new Exception("Temporal component not found"); + return component.getMeanCost(); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java new file mode 100644 index 0000000..0debff7 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java @@ -0,0 +1,22 @@ +package org.insightlab.graphast.query.cost_functions; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.components.temporal_components.TemporalEdgeComponent; + +public class TemporalSpecificCostFunction implements CostFunction { + + private int timeframe; + + public TemporalSpecificCostFunction(int timeframe) { + this.timeframe = timeframe; + } + + @Override + public double getCost(Edge e) throws Exception { + TemporalEdgeComponent component = e.getComponent(TemporalEdgeComponent.class); + if (component == null) + throw new Exception("Temporal component not found"); + return component.getSpecificCost(timeframe); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java b/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java index 087387a..f76f160 100644 --- a/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java +++ b/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java @@ -31,6 +31,8 @@ import org.insightlab.graphast.exceptions.NodeNotFoundException; import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.query.cost_functions.CostFunction; +import org.insightlab.graphast.query.cost_functions.DefaultCostFunction; import org.insightlab.graphast.query.utils.DistanceElement; import org.insightlab.graphast.query.utils.DistanceVector; @@ -44,6 +46,7 @@ public class DijkstraStrategy implements ShortestPathStrategy { private Graph g; + private CostFunction costFunction; /** * Instantiates a new DijkstraStrategy class, given a Graph object. @@ -52,6 +55,11 @@ public class DijkstraStrategy implements ShortestPathStrategy { */ public DijkstraStrategy(Graph g) { this.g = g; + costFunction = new DefaultCostFunction(); + } + + public void setCostFunction(CostFunction costFunction) { + this.costFunction = costFunction; } /** @@ -159,7 +167,13 @@ private void visitNode(DistanceElement node, DistanceVector vector, Queue toVisit) { - double newDistance = node.getDistance() + e.getCost(); + double newDistance; + try { + newDistance = node.getDistance() + costFunction.getCost(e); + } catch (Exception e1) { + System.err.println(e1.getMessage() + ", using edge default cost intead."); + newDistance = e.getCost(); + } if (neighbor.getDistance() > newDistance && !neighbor.isVisited()) { @@ -168,6 +182,7 @@ private void relaxPath(Edge e, DistanceElement node, DistanceElement neighbor, Q toVisit.add(neighbor); } + } } diff --git a/core/src/main/java/org/insightlab/graphast/query/shortestpath/ShortestPathStrategy.java b/core/src/main/java/org/insightlab/graphast/query/shortestpath/ShortestPathStrategy.java index 6ab4913..1c9407e 100644 --- a/core/src/main/java/org/insightlab/graphast/query/shortestpath/ShortestPathStrategy.java +++ b/core/src/main/java/org/insightlab/graphast/query/shortestpath/ShortestPathStrategy.java @@ -25,6 +25,7 @@ package org.insightlab.graphast.query.shortestpath; import org.insightlab.graphast.exceptions.NodeNotFoundException; +import org.insightlab.graphast.query.cost_functions.CostFunction; import org.insightlab.graphast.query.utils.DistanceVector; /** @@ -33,6 +34,8 @@ */ public interface ShortestPathStrategy { + void setCostFunction(CostFunction costFunction); + /** * Run method. This method serves as a declaration to a general shortest path strategy calculation. * A DistanceVector object containing the shortest path between a source node and all the other nodes @@ -60,6 +63,6 @@ public interface ShortestPathStrategy { * of nodes (DistanceElement objects) and their respective parameters, e.g. the distance value for each node. * @throws NodeNotFoundException exception thrown if a node id given in the function call is not found in the graph. */ - DistanceVector run(long sourceId, long targetId) throws NodeNotFoundException;; + DistanceVector run(long sourceId, long targetId) throws NodeNotFoundException; } diff --git a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java index 96dc070..99adefe 100644 --- a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java +++ b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java @@ -12,6 +12,10 @@ import org.insightlab.graphast.model.components.spatial_components.SpatialGraphComponent; import org.insightlab.graphast.model.components.spatial_components.SpatialNodeComponent; import org.insightlab.graphast.model.components.temporal_components.TemporalEdgeComponent; +import org.insightlab.graphast.query.cost_functions.TemporalSpecificCostFunction; +import org.insightlab.graphast.query.shortestpath.DijkstraStrategy; +import org.insightlab.graphast.query.shortestpath.ShortestPathStrategy; +import org.insightlab.graphast.query.utils.DistanceVector; import org.junit.Before; import org.junit.Test; @@ -49,6 +53,9 @@ public void setUp() throws Exception { e3 = new Edge(3, 0, true); e3.addComponent(new SpatialEdgeComponent(new Geometry())); e3.addComponent(new TemporalEdgeComponent(2., 1., 2., 4., 8., 4., 2.)); + + g.addNodes(n0, n1, n2, n3); + g.addEdges(e0, e1, e2, e3); } @Test @@ -66,5 +73,18 @@ public void temporalTest() { assertEquals("E1 mean cost test", 2.571, e1.getComponent(TemporalEdgeComponent.class).getMeanCost(), 0.001); assertEquals("E3 mean cost test", 3.286, e3.getComponent(TemporalEdgeComponent.class).getMeanCost(), 0.001); } + + @Test + public void temporalDijkstraTest() { + ShortestPathStrategy dijkstra = new DijkstraStrategy(g); + + dijkstra.setCostFunction(new TemporalSpecificCostFunction(2)); + DistanceVector result = dijkstra.run(2); + result.print(); + + dijkstra.setCostFunction(new TemporalSpecificCostFunction(3)); + result = dijkstra.run(2); + result.print(); + } } From 8de46f055b3ee36203fcef7ec51720d3236931a0 Mon Sep 17 00:00:00 2001 From: ericklt Date: Sat, 17 Feb 2018 13:50:15 -0300 Subject: [PATCH 08/16] Some name changes and the cost function usage is more intuitive --- .../insightlab/graphast/MainClassDiagram.ucls | 122 +++++----- .../org/insightlab/graphast/model/Edge.java | 22 +- .../org/insightlab/graphast/model/Graph.java | 22 +- .../CostListEdgeComponent.java} | 10 +- .../CostListNodeComponent.java | 28 +++ .../components/spatial_components/Point.java | 14 +- .../SpatialNodeComponent.java | 16 +- .../cost_functions/DefaultCostFunction.java | 2 +- .../TemporalLinearCostFunction.java | 48 ++++ .../TemporalMeanCostFunction.java | 4 +- .../TemporalSpecificCostFunction.java | 12 +- .../query/shortestpath/DijkstraStrategy.java | 2 +- .../structure/MMapGraphStructure.java | 4 +- .../graphast/components/ComponentTest.java | 75 +++++-- .../graphast/generators/CostsGenerator.java | 36 +++ .../graphast/generators/GraphGenerator.java | 210 ++++++++++++++++++ .../graphast/model/DefaultGraphTest.java | 12 +- .../insightlab/graphast/model/EdgeTest.java | 14 +- .../graphast/model/MMapGraphTest.java | 18 +- 19 files changed, 522 insertions(+), 149 deletions(-) rename core/src/main/java/org/insightlab/graphast/model/components/{temporal_components/TemporalEdgeComponent.java => cost_list_components/CostListEdgeComponent.java} (58%) create mode 100644 core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java create mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalLinearCostFunction.java create mode 100644 core/src/test/java/org/insightlab/graphast/generators/CostsGenerator.java create mode 100644 core/src/test/java/org/insightlab/graphast/generators/GraphGenerator.java diff --git a/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls index b827476..eff7554 100644 --- a/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls +++ b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls @@ -143,130 +143,118 @@ - - - + + + + + + + - + - + - + + + + + - + - + - - - + + + + + + + - + - + - - - - + + + + + + + + - - + + - + - - - - + + + + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - + + - + - - - - diff --git a/core/src/main/java/org/insightlab/graphast/model/Edge.java b/core/src/main/java/org/insightlab/graphast/model/Edge.java index 64da00b..4d8bf89 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Edge.java +++ b/core/src/main/java/org/insightlab/graphast/model/Edge.java @@ -40,7 +40,7 @@ public class Edge extends GraphObject { private long fromNodeId; private long toNodeId; - private double cost; + private double weight; private boolean bidirectional; /** @@ -63,7 +63,7 @@ public Edge(long from, long to) { public Edge(long from, long to, double cost) { this.fromNodeId = from; this.toNodeId = to; - this.cost = cost; + this.weight = cost; } /** @@ -113,8 +113,8 @@ public long getToNodeId() { * * @return the cost of the edge (double). */ - public double getCost() { - return cost; + public double getWeight() { + return weight; } /** @@ -136,12 +136,12 @@ public void setToNodeId(long toNode) { } /** - * Sets the cost value of the edge. + * Sets the weight value of the edge. * - * @param cost the new cost of the edge. + * @param weight the new weight of the edge. */ - public void setCost(double cost) { - this.cost = cost; + public void setWeight(double weight) { + this.weight = weight; } /** @@ -205,7 +205,7 @@ public boolean equals(Object obj) { boolean okFromNode = this.fromNodeId == other.fromNodeId; boolean okToNode = this.toNodeId == other.toNodeId; - boolean okCost = this.cost == other.cost; + boolean okCost = this.weight == other.weight; return okFromNode && okToNode && okCost; @@ -222,7 +222,7 @@ public boolean equals(Object obj) { */ @Override public int hashCode() { - return (fromNodeId + "|" + toNodeId + "|" + cost).hashCode(); + return (fromNodeId + "|" + toNodeId + "|" + weight).hashCode(); } /** @@ -232,7 +232,7 @@ public int hashCode() { */ @Override public String toString() { - return fromNodeId + "|" + toNodeId + "|" + cost; + return fromNodeId + "|" + toNodeId + "|" + weight; } } diff --git a/core/src/main/java/org/insightlab/graphast/model/Graph.java b/core/src/main/java/org/insightlab/graphast/model/Graph.java index 5bbb641..2bcb916 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Graph.java +++ b/core/src/main/java/org/insightlab/graphast/model/Graph.java @@ -132,19 +132,37 @@ public boolean containsNode(long id) { * * @return the iterator of the list of nodes contained in this graph. */ - public Iterator nodeIterator() { + public Iterator getNodeIterator() { return structure.nodeIterator(); } + public Iterable getNodes() { + return new Iterable() { + @Override + public Iterator iterator() { + return getNodeIterator(); + } + }; + } + /** * It returns an Iterator object of the Edge elements contained in this graph. * * @return the iterator of the list of edges contained in this graph. */ - public Iterator edgeIterator() { + public Iterator getEdgeIterator() { return structure.edgeIterator(); } + public Iterable getEdges() { + return new Iterable() { + @Override + public Iterator iterator() { + return getEdgeIterator(); + } + }; + } + /** * Gets the number of nodes of the graph. * diff --git a/core/src/main/java/org/insightlab/graphast/model/components/temporal_components/TemporalEdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java similarity index 58% rename from core/src/main/java/org/insightlab/graphast/model/components/temporal_components/TemporalEdgeComponent.java rename to core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java index dac5b3d..a973834 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/temporal_components/TemporalEdgeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java @@ -1,18 +1,22 @@ -package org.insightlab.graphast.model.components.temporal_components; +package org.insightlab.graphast.model.components.cost_list_components; import java.util.Arrays; import java.util.List; import org.insightlab.graphast.model.components.EdgeComponent; -public class TemporalEdgeComponent extends EdgeComponent { +public class CostListEdgeComponent extends EdgeComponent { private List costList; - public TemporalEdgeComponent(Double ...costs) { + public CostListEdgeComponent(Double ...costs) { costList = Arrays.asList(costs); } + public List getCostList() { + return costList; + } + public double getSpecificCost(int index) { return costList.get(index); } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java new file mode 100644 index 0000000..890176e --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java @@ -0,0 +1,28 @@ +package org.insightlab.graphast.model.components.cost_list_components; + +import java.util.Arrays; +import java.util.List; + +import org.insightlab.graphast.model.components.NodeComponent; + +public class CostListNodeComponent extends NodeComponent { + + private List costList; + + public CostListNodeComponent(Double ...costs) { + costList = Arrays.asList(costs); + } + + public List getCostList() { + return costList; + } + + public double getSpecificCost(int index) { + return costList.get(index); + } + + public double getMeanCost() { + return costList.stream().reduce(0., (x1, x2) -> x1 + x2) / costList.size(); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java index 706c927..94f1d6c 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java @@ -2,27 +2,27 @@ public class Point { - private int lat; - private int lng; + private double lat; + private double lng; - public Point(int lat, int lng) { + public Point(double lat, double lng) { this.lat = lat; this.lng = lng; } - public int getLat() { + public double getLat() { return lat; } - public int getLng() { + public double getLng() { return lng; } - public void setLat(int lat) { + public void setLat(double lat) { this.lat = lat; } - public void setLng(int lng) { + public void setLng(double lng) { this.lng = lng; } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java index 32f3ee5..1ba0643 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java @@ -6,23 +6,27 @@ public class SpatialNodeComponent extends NodeComponent { private Point point; - public SpatialNodeComponent(Point p) { - this.point = p; + public SpatialNodeComponent(double lat, double lng) { + this(new Point(lat, lng)); } - public int getLat() { + public SpatialNodeComponent(Point point) { + this.point = point; + } + + public double getLat() { return point.getLat(); } - public int getLng() { + public double getLng() { return point.getLng(); } - public void setLat(int lat) { + public void setLat(double lat) { point.setLat(lat); } - public void setLng(int lng) { + public void setLng(double lng) { point.setLng(lng); } diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/DefaultCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/DefaultCostFunction.java index c94e22d..7982b38 100644 --- a/core/src/main/java/org/insightlab/graphast/query/cost_functions/DefaultCostFunction.java +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/DefaultCostFunction.java @@ -6,7 +6,7 @@ public class DefaultCostFunction implements CostFunction { @Override public double getCost(Edge e) { - return e.getCost(); + return e.getWeight(); } } diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalLinearCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalLinearCostFunction.java new file mode 100644 index 0000000..6c42f42 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalLinearCostFunction.java @@ -0,0 +1,48 @@ +package org.insightlab.graphast.query.cost_functions; + +import java.util.List; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; + +public class TemporalLinearCostFunction implements CostFunction { + + private int hour, min; + + public TemporalLinearCostFunction(int hour, int min) { + this.setTime(hour, min); + } + + public void setTime(int hour, int min) { + this.hour = hour; + this.min = min; + } + + private double getLinearInterpolation(double n1, double n2, double x) { + return n1 + x * (n2 - n1); + } + + public double getLinearCostByTime(List costList) { + if (hour >= 0 && hour < 24 && min >= 0 && min < 60) { + int totalMins = hour*60 + min; + double proportion = totalMins * costList.size() / (24*60.); + int index = (int) Math.floor(proportion); + + double x = proportion - index; + double n1 = costList.get(index); + double n2 = (index + 1 < costList.size()) ? costList.get(index + 1) : costList.get(0); + return getLinearInterpolation(n1, n2, x); + } + return -1; + } + + @Override + public double getCost(Edge e) throws Exception { + CostListEdgeComponent component = e.getComponent(CostListEdgeComponent.class); + if (component == null) + throw new Exception("Temporal component not found"); + return getLinearCostByTime(component.getCostList()); + } + + +} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java index e6caa88..b561aea 100644 --- a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java @@ -1,13 +1,13 @@ package org.insightlab.graphast.query.cost_functions; import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.components.temporal_components.TemporalEdgeComponent; +import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; public class TemporalMeanCostFunction implements CostFunction { @Override public double getCost(Edge e) throws Exception { - TemporalEdgeComponent component = e.getComponent(TemporalEdgeComponent.class); + CostListEdgeComponent component = e.getComponent(CostListEdgeComponent.class); if (component == null) throw new Exception("Temporal component not found"); return component.getMeanCost(); diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java index 0debff7..4e539fa 100644 --- a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java @@ -1,22 +1,22 @@ package org.insightlab.graphast.query.cost_functions; import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.components.temporal_components.TemporalEdgeComponent; +import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; public class TemporalSpecificCostFunction implements CostFunction { - private int timeframe; + private int index; - public TemporalSpecificCostFunction(int timeframe) { - this.timeframe = timeframe; + public TemporalSpecificCostFunction(int index) { + this.index = index; } @Override public double getCost(Edge e) throws Exception { - TemporalEdgeComponent component = e.getComponent(TemporalEdgeComponent.class); + CostListEdgeComponent component = e.getComponent(CostListEdgeComponent.class); if (component == null) throw new Exception("Temporal component not found"); - return component.getSpecificCost(timeframe); + return component.getSpecificCost(index); } } diff --git a/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java b/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java index f76f160..7fe54d6 100644 --- a/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java +++ b/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java @@ -172,7 +172,7 @@ private void relaxPath(Edge e, DistanceElement node, DistanceElement neighbor, Q newDistance = node.getDistance() + costFunction.getCost(e); } catch (Exception e1) { System.err.println(e1.getMessage() + ", using edge default cost intead."); - newDistance = e.getCost(); + newDistance = e.getWeight(); } if (neighbor.getDistance() > newDistance && !neighbor.isVisited()) { diff --git a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java index f53d67c..4ebabb4 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java @@ -143,7 +143,7 @@ private void addDirectionalEdge(Edge e) { edgeAccess.setLong ( edgeIndex , fromId ); edgeAccess.setLong ( edgeIndex + 8 , toId ); - edgeAccess.setDouble ( edgeIndex + 16 , e.getCost() ); + edgeAccess.setDouble ( edgeIndex + 16 , e.getWeight() ); edgeAccess.setLong ( edgeIndex + 24 , nodeAccess.getLong(fromIndex + 8) ); edgeAccess.setLong ( edgeIndex + 32 , nodeAccess.getLong(toIndex + 16) ); @@ -184,7 +184,7 @@ public void addEdge(Edge e) { addDirectionalEdge(e); if (e.isBidirectional()) - addDirectionalEdge(new Edge(e.getToNodeId(), e.getFromNodeId(), e.getCost())); + addDirectionalEdge(new Edge(e.getToNodeId(), e.getFromNodeId(), e.getWeight())); } /** diff --git a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java index 99adefe..f84e641 100644 --- a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java +++ b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java @@ -2,16 +2,18 @@ import static org.junit.Assert.*; +import org.insightlab.graphast.generators.GraphGenerator; import org.insightlab.graphast.model.Edge; //import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Graph; import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; import org.insightlab.graphast.model.components.spatial_components.Geometry; import org.insightlab.graphast.model.components.spatial_components.Point; import org.insightlab.graphast.model.components.spatial_components.SpatialEdgeComponent; import org.insightlab.graphast.model.components.spatial_components.SpatialGraphComponent; import org.insightlab.graphast.model.components.spatial_components.SpatialNodeComponent; -import org.insightlab.graphast.model.components.temporal_components.TemporalEdgeComponent; +import org.insightlab.graphast.query.cost_functions.TemporalLinearCostFunction; import org.insightlab.graphast.query.cost_functions.TemporalSpecificCostFunction; import org.insightlab.graphast.query.shortestpath.DijkstraStrategy; import org.insightlab.graphast.query.shortestpath.ShortestPathStrategy; @@ -22,6 +24,7 @@ public class ComponentTest { Graph g; + Graph graphExample4; private Node n0, n1, n2, n3; private Edge e0, e1, e2, e3; @@ -30,61 +33,95 @@ public void setUp() throws Exception { g = new Graph(); g.addComponent(new SpatialGraphComponent()); n0 = new Node(0); - n0.addComponent(new SpatialNodeComponent(new Point(12, 4))); + n0.addComponent(new SpatialNodeComponent(12, 4)); n1 = new Node(1); - n1.addComponent(new SpatialNodeComponent(new Point(13, 3))); + n1.addComponent(new SpatialNodeComponent(13, 3)); n2 = new Node(2); - n2.addComponent(new SpatialNodeComponent(new Point(14, 2))); + n2.addComponent(new SpatialNodeComponent(14, 2)); n3 = new Node(3); - n3.addComponent(new SpatialNodeComponent(new Point(15, 1))); + n3.addComponent(new SpatialNodeComponent(15, 1)); e0 = new Edge(1, 2, true); e0.addComponent(new SpatialEdgeComponent(new Geometry(new Point(1, 2)))); - e0.addComponent(new TemporalEdgeComponent(2., 3., 1., 5., 6., 3., 1.)); + e0.addComponent(new CostListEdgeComponent(2., 3., 1., 5., 6., 3., 1.)); e1 = new Edge(2, 3); e1.addComponent(new SpatialEdgeComponent(new Geometry(new Point(2, 3), new Point(4, 5)))); - e1.addComponent(new TemporalEdgeComponent(1., 2., 1., 4., 7., 1., 2.)); + e1.addComponent(new CostListEdgeComponent(1., 2., 1., 4., 7., 1., 2.)); e2 = new Edge(0, 1); e2.addComponent(new SpatialEdgeComponent(new Geometry(new Point(1, 3)))); - e2.addComponent(new TemporalEdgeComponent(3., 4., 2., 6., 6., 4., 3.)); + e2.addComponent(new CostListEdgeComponent(3., 4., 2., 6., 6., 4., 3.)); e3 = new Edge(3, 0, true); e3.addComponent(new SpatialEdgeComponent(new Geometry())); - e3.addComponent(new TemporalEdgeComponent(2., 1., 2., 4., 8., 4., 2.)); + e3.addComponent(new CostListEdgeComponent(2., 1., 2., 4., 8., 4., 2.)); g.addNodes(n0, n1, n2, n3); g.addEdges(e0, e1, e2, e3); + + graphExample4 = GraphGenerator.getInstance().generateExample4(); } @Test public void spatialTest() { - assertEquals("N1 lat test", 13, n1.getComponent(SpatialNodeComponent.class).getLat()); - assertEquals("N3 lng test", 1, n3.getComponent(SpatialNodeComponent.class).getLng()); - System.out.println(e2.getComponent(SpatialEdgeComponent.class).getGeometry().getPoints().toArray()); + assertEquals("N1 lat test", 13, n1.getComponent(SpatialNodeComponent.class).getLat(), 0); + assertEquals("N3 lng test", 1, n3.getComponent(SpatialNodeComponent.class).getLng(), 0); + + e3.getComponent(SpatialEdgeComponent.class).getGeometry(); + e3.getComponent(CostListEdgeComponent.class).getMeanCost(); + assertArrayEquals("E2 Geometry test", new Point[] {new Point(1, 3)}, e2.getComponent(SpatialEdgeComponent.class).getGeometry().getPoints().toArray()); } @Test public void temporalTest() { - assertEquals("E0 specific cost test", 5., e0.getComponent(TemporalEdgeComponent.class).getSpecificCost(3), 0.); - assertEquals("E2 specific cost test", 4., e2.getComponent(TemporalEdgeComponent.class).getSpecificCost(5), 0.); - assertEquals("E1 mean cost test", 2.571, e1.getComponent(TemporalEdgeComponent.class).getMeanCost(), 0.001); - assertEquals("E3 mean cost test", 3.286, e3.getComponent(TemporalEdgeComponent.class).getMeanCost(), 0.001); + assertEquals("E0 specific cost test", 5., e0.getComponent(CostListEdgeComponent.class).getSpecificCost(3), 0.); + assertEquals("E2 specific cost test", 4., e2.getComponent(CostListEdgeComponent.class).getSpecificCost(5), 0.); + assertEquals("E1 mean cost test", 2.571, e1.getComponent(CostListEdgeComponent.class).getMeanCost(), 0.001); + assertEquals("E3 mean cost test", 3.286, e3.getComponent(CostListEdgeComponent.class).getMeanCost(), 0.001); } @Test public void temporalDijkstraTest() { ShortestPathStrategy dijkstra = new DijkstraStrategy(g); + DistanceVector result; dijkstra.setCostFunction(new TemporalSpecificCostFunction(2)); - DistanceVector result = dijkstra.run(2); - result.print(); + result = dijkstra.run(2); + assertEquals("Temporal dijkstra test index 2", 3, result.getDistance(0), 0); dijkstra.setCostFunction(new TemporalSpecificCostFunction(3)); result = dijkstra.run(2); - result.print(); + assertEquals("Temporal dijkstra test index 3", 8, result.getDistance(0), 0); + } + + @Test + public void temporalDijkstraTestExample4() { + ShortestPathStrategy dijkstra = new DijkstraStrategy(graphExample4); + TemporalLinearCostFunction costFunction = new TemporalLinearCostFunction(6, 0); + dijkstra.setCostFunction(costFunction); + DistanceVector result; + + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 6:00", 14, result.getDistance(6), 0); + result.print(0, 6); + + costFunction.setTime(12, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 12:00", 12, result.getDistance(6), 0); + result.print(0, 6); + + costFunction.setTime(15, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 15:00", 13, result.getDistance(6), 0); + result.print(0, 6); + + costFunction.setTime(20, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 20:00", 14, result.getDistance(6), 0); + result.print(0, 6); + } } diff --git a/core/src/test/java/org/insightlab/graphast/generators/CostsGenerator.java b/core/src/test/java/org/insightlab/graphast/generators/CostsGenerator.java new file mode 100644 index 0000000..783c4d5 --- /dev/null +++ b/core/src/test/java/org/insightlab/graphast/generators/CostsGenerator.java @@ -0,0 +1,36 @@ +package org.insightlab.graphast.generators; + +import java.util.Random; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; + +public class CostsGenerator { + + private static CostsGenerator instance = null; + private Random r; + + public static CostsGenerator getInstance() { + if (instance == null) + instance = new CostsGenerator(); + return instance; + } + + private CostsGenerator() { + r = new Random(); + } + + public Double[] generateCosts(int quantity) { + Double[] costs = new Double[quantity]; + for (int i = 0; i < quantity; i++) + costs[i] = r.nextDouble()*9 + 1; + return costs; + } + + public void generateTemporalCosts(Graph g) { + for (Edge e : g.getEdges()) + e.addComponent(new CostListEdgeComponent(generateCosts(r.nextInt(23) + 1))); + } + +} diff --git a/core/src/test/java/org/insightlab/graphast/generators/GraphGenerator.java b/core/src/test/java/org/insightlab/graphast/generators/GraphGenerator.java new file mode 100644 index 0000000..023d7ba --- /dev/null +++ b/core/src/test/java/org/insightlab/graphast/generators/GraphGenerator.java @@ -0,0 +1,210 @@ +package org.insightlab.graphast.generators; + +import java.io.FileNotFoundException; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; +import org.insightlab.graphast.model.components.cost_list_components.CostListNodeComponent; +import org.insightlab.graphast.model.components.spatial_components.Geometry; +import org.insightlab.graphast.model.components.spatial_components.Point; +import org.insightlab.graphast.model.components.spatial_components.SpatialEdgeComponent; +import org.insightlab.graphast.model.components.spatial_components.SpatialNodeComponent; +import org.insightlab.graphast.storage.GraphStorage; +import org.insightlab.graphast.storage.GraphStorageFactory; +import org.insightlab.graphast.storage.OSMGraphStorageTest; +import org.insightlab.graphast.structure.DefaultGraphStructure; + +public class GraphGenerator { + + private static GraphGenerator instance = null; + + public static GraphGenerator getInstance() { + if (instance == null) + instance = new GraphGenerator(); + return instance; + } + + private GraphGenerator() {} + + public Graph generateExample1() { + + Graph graph = new Graph(); + + Node n1 = new Node(0l); + n1.addComponent(new SpatialNodeComponent(10., 10.)); + + Node n2 = new Node(1l); + n2.addComponent(new SpatialNodeComponent(43.7294668047756, 7.413772473047058)); + + Node n3 = new Node(2l); + n3.addComponent(new SpatialNodeComponent(10., 30.)); + n3.addComponent(new CostListNodeComponent(1., 2., 3., 4.)); + + Node n4 = new Node(3l); + n4.addComponent(new SpatialNodeComponent(10., 40.)); + + Node n5 = new Node(4l); + n5.addComponent(new SpatialNodeComponent(11., 32.)); + + graph.addNodes(n1, n2, n3, n4, n5); + + + CostsGenerator costsGenerator = CostsGenerator.getInstance(); + + Edge e1 = new Edge(0l, 1l, 10); + e1.addComponent(new SpatialEdgeComponent(new Geometry(new Point(10.,10.), new Point(10.,20.)))); + e1.addComponent(new CostListEdgeComponent(costsGenerator.generateCosts(10))); + + Edge e2 = new Edge(1l, 0l, 20); + e2.addComponent(new SpatialEdgeComponent(new Geometry(new Point(10.,20.), new Point(10.,15.), new Point(10., 10.)))); + e2.addComponent(new CostListEdgeComponent(costsGenerator.generateCosts(20))); + + Edge e3 = new Edge(0l, 2l, 30); + e3.addComponent(new SpatialEdgeComponent(new Geometry(new Point(10.,10.), new Point(10.,30.)))); + e3.addComponent(new CostListEdgeComponent(costsGenerator.generateCosts(30))); + + Edge e4 = new Edge(2l, 0l, 40); + e4.addComponent(new SpatialEdgeComponent(new Geometry(new Point(10.,30.), new Point(10.,10.)))); + e4.addComponent(new CostListEdgeComponent(costsGenerator.generateCosts(40))); + + Edge e5 = new Edge(0l, 3l, 50); + e5.addComponent(new SpatialEdgeComponent(new Geometry(new Point(10.,10.), new Point(10.,40.)))); + e5.addComponent(new CostListEdgeComponent(costsGenerator.generateCosts(50))); + + Edge e6 = new Edge(2l, 4l, 60); + + Edge e7 = new Edge(3l, 0l, 70); + + graph.addEdges(e1, e2, e3, e4, e5, e6, e7); + + return graph; + } + + public Graph generateExample2() { + + Graph graph = new Graph(); + + Node n0 = new Node(0l); + n0.addComponent(new SpatialNodeComponent(0., 10.)); + Node n1 = new Node(1l); + n1.addComponent(new SpatialNodeComponent(10., 0.)); + Node n2 = new Node(2l); + n2.addComponent(new SpatialNodeComponent(30., 20.)); + Node n3 = new Node(3l); + n3.addComponent(new SpatialNodeComponent(40., 20.)); + Node n4 = new Node(4l); + n4.addComponent(new SpatialNodeComponent(50., 30.)); + Node n5 = new Node(5l); + n5.addComponent(new SpatialNodeComponent(60., 20.)); + Node n6 = new Node(6l); + n6.addComponent(new SpatialNodeComponent(60., 0.)); + + graph.addNodes(n0, n1, n2, n3, n4, n5, n6); + + Edge e0 = new Edge(0l, 1l, 1); + e0.addComponent(new CostListEdgeComponent(3., 2., 3., 4.)); + Edge e1 = new Edge(0l, 2l, 5); + e1.addComponent(new CostListEdgeComponent(4., 2., 6., 8., 10.)); + Edge e2 = new Edge(1l, 2l, 3); + e2.addComponent(new CostListEdgeComponent(1., 2.)); + Edge e3 = new Edge(2l, 3l, 3); + e3.addComponent(new CostListEdgeComponent(4., 4., 7., 6., 11.)); + Edge e4 = new Edge(3l, 4l, 3); + e4.addComponent(new CostListEdgeComponent(1., 10.)); + Edge e5 = new Edge(3l, 5l, 4); + e5.addComponent(new CostListEdgeComponent(2., 12., 13.)); + Edge e6 = new Edge(4l, 5l, 2); + e6.addComponent(new CostListEdgeComponent(3., 9., 10., 11.)); + Edge e7 = new Edge(5l, 6l, 1); + e7.addComponent(new CostListEdgeComponent(5., 2., 4., 6., 8., 15.)); + + graph.addEdges(e0, e1, e2, e3, e4, e5, e6, e7); + + return graph; + + } + + public Graph generateExample4() { + Graph graph = new Graph(); + + Node n0 = new Node(0l); + n0.addComponent(new SpatialNodeComponent(-3.74077, -38.55735)); + Node n1 = new Node(1l); + n1.addComponent(new SpatialNodeComponent(-3.74003, -38.55693)); + Node n2 = new Node(2l); + n2.addComponent(new SpatialNodeComponent(-3.74049, -38.5563)); + Node n3 = new Node(3l); + n3.addComponent(new SpatialNodeComponent(-3.74035, -38.55526)); + Node n4 = new Node(4l); + n4.addComponent(new SpatialNodeComponent(-3.73958, -38.55479)); + Node n5 = new Node(5l); + n5.addComponent(new SpatialNodeComponent(-3.74001, -38.55415)); + Node n6 = new Node(6l); + n6.addComponent(new SpatialNodeComponent(-3.7412, -38.55388)); + + graph.addNodes(n0, n1, n2, n3, n4, n5, n6); + + Edge e0 = new Edge(0l, 1l, 1); + e0.addComponent(new CostListEdgeComponent(3., 1.)); + Edge e1 = new Edge(0l, 2l, 1); + e1.addComponent(new CostListEdgeComponent(5.)); + Edge e2 = new Edge(1l, 2l, 1); + e2.addComponent(new CostListEdgeComponent(3.)); + Edge e3 = new Edge(2l, 3l, 1); + e3.addComponent(new CostListEdgeComponent(3.)); + Edge e4 = new Edge(3l, 4l, 1); + e4.addComponent(new CostListEdgeComponent(3.)); + Edge e5 = new Edge(3l, 5l, 1); + e5.addComponent(new CostListEdgeComponent(6., 4.)); + Edge e6 = new Edge(4l, 5l, 1); + e6.addComponent(new CostListEdgeComponent(2.)); + Edge e7 = new Edge(5l, 6l, 1); + e7.addComponent(new CostListEdgeComponent(1.)); + + graph.addEdges(e0, e1, e2, e3, e4, e5, e6, e7); + + return graph; + } + + public Graph generateExample6() { + Graph graph = new Graph(); + Node n0 = new Node(60054477); + n0.addComponent(new SpatialNodeComponent(52.3524, 20.9440)); + Node n1 = new Node(60054510); + n1.addComponent(new SpatialNodeComponent(52.3515, 20.9447)); + Node n2 = new Node(249476123); + n2.addComponent(new SpatialNodeComponent(52.3499, 20.9461)); + Node n3 = new Node(252417127); + n3.addComponent(new SpatialNodeComponent(52.3509, 20.9452)); + Node n4 = new Node(252417130); + n4.addComponent(new SpatialNodeComponent(52.3514, 20.9449)); + + graph.addNodes(n0, n1, n2, n3, n4); + + graph.addEdge(new Edge(n4.getId(), n0.getId(), 121)); // 252417130 60054477 0.121 + graph.addEdge(new Edge(n0.getId(), n1.getId(), 112)); // 60054477 60054510 0.112 + graph.addEdge(new Edge(n3.getId(), n2.getId(), 123)); // 252417127 249476123 0.123 + graph.addEdge(new Edge(n2.getId(), n2.getId(), 0)); + graph.addEdge(new Edge(n1.getId(), n2.getId(), 195)); // 60054510 249476123 0.195 + + return graph; + } + + public Graph generateMonaco() { + GraphStorage storage = GraphStorageFactory.getOSMGraphStorage(); + String path = OSMGraphStorageTest.class.getClassLoader().getResource("monaco-latest.osm.pbf").getPath(); + try{ + Graph g = storage.load(path, new DefaultGraphStructure()); + CostsGenerator.getInstance().generateTemporalCosts(g); + return g; + } catch(FileNotFoundException e){ + e.printStackTrace(); + return null; + } + } + + + +} diff --git a/core/src/test/java/org/insightlab/graphast/model/DefaultGraphTest.java b/core/src/test/java/org/insightlab/graphast/model/DefaultGraphTest.java index 0964266..00e8fda 100755 --- a/core/src/test/java/org/insightlab/graphast/model/DefaultGraphTest.java +++ b/core/src/test/java/org/insightlab/graphast/model/DefaultGraphTest.java @@ -66,11 +66,11 @@ public void setUp() throws Exception { @Test public void testAddNode() { g.addNode(n0); - Iterator it = g.nodeIterator(); + Iterator it = g.getNodeIterator(); assertEquals("Add node n0", n0, it.next()); g.addNode(n1); g.addNode(n3); - it = g.nodeIterator(); + it = g.getNodeIterator(); it.next(); assertEquals("Add node n1", n1, it.next()); assertEquals("Add node n3", n3, it.next()); @@ -79,7 +79,7 @@ public void testAddNode() { @Test public void testAddNodes() { g.addNodes(n0, n1, n3); - Iterator it = g.nodeIterator(); + Iterator it = g.getNodeIterator(); assertEquals("Add nodes n0", n0, it.next()); assertEquals("Add nodes n1", n1, it.next()); assertEquals("Add nodes n3", n3, it.next()); @@ -89,11 +89,11 @@ public void testAddNodes() { public void testAddEdge() { g.addNodes(n0, n1, n2, n3, n4); g.addEdge(e0); - Iterator it = g.edgeIterator(); + Iterator it = g.getEdgeIterator(); assertEquals("Add edge e0", e0, it.next()); g.addEdge(e2); g.addEdge(e5); - it = g.edgeIterator(); + it = g.getEdgeIterator(); it.next(); assertEquals("Add edge e2", e2, it.next()); assertEquals("Add edge e5", e5, it.next()); @@ -103,7 +103,7 @@ public void testAddEdge() { public void testAddEdges() { g.addNodes(n0, n1, n2, n3, n4); g.addEdges(e0, e2, e4, e1, e6, e5, e3); - Iterator it = g.edgeIterator(); + Iterator it = g.getEdgeIterator(); assertEquals("Add edges e0", e0, it.next()); assertEquals("Add edges e2", e2, it.next()); assertEquals("Add edges e4", e4, it.next()); diff --git a/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java b/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java index f87c99c..fbf5d94 100644 --- a/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java +++ b/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java @@ -42,7 +42,7 @@ public void testConstructor1(){ e = new Edge(0,1); assertEquals(0l, e.getFromNodeId()); assertEquals(1l, e.getToNodeId()); - assertEquals(1l, e.getCost(),0); + assertEquals(1l, e.getWeight(),0); assertEquals(false, e.isBidirectional()); } @@ -51,7 +51,7 @@ public void testConstructor2(){ e = new Edge(0,1,3); assertEquals(0l, e.getFromNodeId()); assertEquals(1l, e.getToNodeId()); - assertEquals(3l, e.getCost(),0); + assertEquals(3l, e.getWeight(),0); assertEquals(false, e.isBidirectional()); } @@ -60,7 +60,7 @@ public void testConstructor3(){ e = new Edge(0, 1, true); assertEquals(0l, e.getFromNodeId()); assertEquals(1l, e.getToNodeId()); - assertEquals(1l, e.getCost(),0); + assertEquals(1l, e.getWeight(),0); assertEquals(true, e.isBidirectional()); } @@ -68,7 +68,7 @@ public void testConstructor3(){ public void testConstructor4(){ assertEquals(0l, e.getFromNodeId()); assertEquals(1l, e.getToNodeId()); - assertEquals(3l, e.getCost(),0); + assertEquals(3l, e.getWeight(),0); assertEquals(true, e.isBidirectional()); } @@ -84,7 +84,7 @@ public void testToNode() { @Test public void testCost() { - assertEquals("Cost is wrong",3.0,e.getCost(),0); + assertEquals("Cost is wrong",3.0,e.getWeight(),0); } @Test @@ -106,8 +106,8 @@ public void testSetToNode(){ @Test public void testSetCost(){ - e.setCost(100);; - assertEquals("Cost was not updated",100,e.getCost(),0); + e.setWeight(100);; + assertEquals("Cost was not updated",100,e.getWeight(),0); } @Test diff --git a/core/src/test/java/org/insightlab/graphast/model/MMapGraphTest.java b/core/src/test/java/org/insightlab/graphast/model/MMapGraphTest.java index b79827b..1642c55 100644 --- a/core/src/test/java/org/insightlab/graphast/model/MMapGraphTest.java +++ b/core/src/test/java/org/insightlab/graphast/model/MMapGraphTest.java @@ -80,9 +80,9 @@ public void testNumberOfEdges() { @Test public void testGetOutEdges() { - Edge e0Inv = new Edge(e0.getToNodeId(), e0.getFromNodeId(), e0.getCost()); - Edge e3Inv = new Edge(e3.getToNodeId(), e3.getFromNodeId(), e3.getCost()); - Edge e6Inv = new Edge(e6.getToNodeId(), e6.getFromNodeId(), e6.getCost()); + Edge e0Inv = new Edge(e0.getToNodeId(), e0.getFromNodeId(), e0.getWeight()); + Edge e3Inv = new Edge(e3.getToNodeId(), e3.getFromNodeId(), e3.getWeight()); + Edge e6Inv = new Edge(e6.getToNodeId(), e6.getFromNodeId(), e6.getWeight()); assertThat("Out Edges Test n0", Arrays.asList(e2, e6Inv), containsInAnyOrder(Iterators.toArray(g.getOutEdges(0), Edge.class))); assertThat("Out Edges Test n1", Arrays.asList(e0, e3Inv), containsInAnyOrder(Iterators.toArray(g.getOutEdges(1), Edge.class))); assertThat("Out Edges Test n2", Arrays.asList(e1, e4), containsInAnyOrder(Iterators.toArray(g.getOutEdges(2), Edge.class))); @@ -93,9 +93,9 @@ public void testGetOutEdges() { @Test public void testGetInEdges() { - Edge e0Inv = new Edge(e0.getToNodeId(), e0.getFromNodeId(), e0.getCost()); - Edge e3Inv = new Edge(e3.getToNodeId(), e3.getFromNodeId(), e3.getCost()); - Edge e6Inv = new Edge(e6.getToNodeId(), e6.getFromNodeId(), e6.getCost()); + Edge e0Inv = new Edge(e0.getToNodeId(), e0.getFromNodeId(), e0.getWeight()); + Edge e3Inv = new Edge(e3.getToNodeId(), e3.getFromNodeId(), e3.getWeight()); + Edge e6Inv = new Edge(e6.getToNodeId(), e6.getFromNodeId(), e6.getWeight()); assertThat("In Edges Test n0", Arrays.asList(e6), containsInAnyOrder(Iterators.toArray(g.getInEdges(0), Edge.class))); assertThat("In Edges Test n1", Arrays.asList(e0Inv, e2, e3), containsInAnyOrder(Iterators.toArray(g.getInEdges(1), Edge.class))); assertThat("In Edges Test n2", Arrays.asList(), containsInAnyOrder(Iterators.toArray(g.getInEdges(2), Edge.class))); @@ -118,9 +118,9 @@ public void testReopenGraph() throws IOException { assertEquals("Reoppened graph number of nodes", 5, g2.getNumberOfNodes()); assertEquals("Reoppened graph number of edges", 10, g2.getNumberOfEdges()); - Edge e0Inv = new Edge(e0.getToNodeId(), e0.getFromNodeId(), e0.getCost()); - Edge e3Inv = new Edge(e3.getToNodeId(), e3.getFromNodeId(), e3.getCost()); - Edge e6Inv = new Edge(e6.getToNodeId(), e6.getFromNodeId(), e6.getCost()); + Edge e0Inv = new Edge(e0.getToNodeId(), e0.getFromNodeId(), e0.getWeight()); + Edge e3Inv = new Edge(e3.getToNodeId(), e3.getFromNodeId(), e3.getWeight()); + Edge e6Inv = new Edge(e6.getToNodeId(), e6.getFromNodeId(), e6.getWeight()); assertThat("Reoppened Graph Out Edges Test n0", Arrays.asList(e2, e6Inv), containsInAnyOrder(Iterators.toArray(g2.getOutEdges(0), Edge.class))); assertThat("Reoppened Graph Out Edges Test n1", Arrays.asList(e0, e3Inv), containsInAnyOrder(Iterators.toArray(g2.getOutEdges(1), Edge.class))); From 86fd32fe7c7b7e85d0fa90e609889ab8b384bcdd Mon Sep 17 00:00:00 2001 From: ericklt Date: Sat, 17 Feb 2018 21:26:04 -0300 Subject: [PATCH 09/16] Added a cost function factory and the StepCostFunction --- .../query/cost_functions/CostFunction.java | 2 +- .../cost_functions/CostFunctionFactory.java | 26 ++++++++++ .../cost_functions/InterpolationMethod.java | 5 ++ .../TemporalLinearCostFunction.java | 48 ------------------- .../TemporalMeanCostFunction.java | 16 ------- .../TemporalSpecificCostFunction.java | 22 --------- .../TimeDependentCostFunction.java | 24 ++++++++++ .../TimeDependentLinearCostFunction.java | 39 +++++++++++++++ .../TimeDependentStepCostFunction.java | 32 +++++++++++++ .../graphast/components/ComponentTest.java | 43 ++++++++++------- 10 files changed, 152 insertions(+), 105 deletions(-) create mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunctionFactory.java create mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/InterpolationMethod.java delete mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalLinearCostFunction.java delete mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java delete mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java create mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentCostFunction.java create mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentLinearCostFunction.java create mode 100644 core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentStepCostFunction.java diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunction.java index 62ffc98..d0ccdee 100644 --- a/core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunction.java +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunction.java @@ -4,6 +4,6 @@ public interface CostFunction { - double getCost(Edge e) throws Exception; //TODO Create specific exception + double getCost(Edge e) throws RuntimeException; //TODO Create specific exception } diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunctionFactory.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunctionFactory.java new file mode 100644 index 0000000..e47c1b5 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/CostFunctionFactory.java @@ -0,0 +1,26 @@ +package org.insightlab.graphast.query.cost_functions; + +import java.util.Calendar; + +public class CostFunctionFactory { + + public static CostFunction getDefaultCostFunction() { + return new DefaultCostFunction(); + } + + public static CostFunction getTimeDependentCostFunction() { + return getTimeDependentCostFunction(InterpolationMethod.LINEAR); + } + + public static TimeDependentCostFunction getTimeDependentCostFunction(InterpolationMethod interpolationMethod) { + Calendar now = Calendar.getInstance(); + switch(interpolationMethod) { + case STEP: + return new TimeDependentStepCostFunction(now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE)); + case LINEAR: + default: + return new TimeDependentLinearCostFunction(now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE)); + } + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/InterpolationMethod.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/InterpolationMethod.java new file mode 100644 index 0000000..efaae9f --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/InterpolationMethod.java @@ -0,0 +1,5 @@ +package org.insightlab.graphast.query.cost_functions; + +public enum InterpolationMethod { + STEP, LINEAR +} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalLinearCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalLinearCostFunction.java deleted file mode 100644 index 6c42f42..0000000 --- a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalLinearCostFunction.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.insightlab.graphast.query.cost_functions; - -import java.util.List; - -import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; - -public class TemporalLinearCostFunction implements CostFunction { - - private int hour, min; - - public TemporalLinearCostFunction(int hour, int min) { - this.setTime(hour, min); - } - - public void setTime(int hour, int min) { - this.hour = hour; - this.min = min; - } - - private double getLinearInterpolation(double n1, double n2, double x) { - return n1 + x * (n2 - n1); - } - - public double getLinearCostByTime(List costList) { - if (hour >= 0 && hour < 24 && min >= 0 && min < 60) { - int totalMins = hour*60 + min; - double proportion = totalMins * costList.size() / (24*60.); - int index = (int) Math.floor(proportion); - - double x = proportion - index; - double n1 = costList.get(index); - double n2 = (index + 1 < costList.size()) ? costList.get(index + 1) : costList.get(0); - return getLinearInterpolation(n1, n2, x); - } - return -1; - } - - @Override - public double getCost(Edge e) throws Exception { - CostListEdgeComponent component = e.getComponent(CostListEdgeComponent.class); - if (component == null) - throw new Exception("Temporal component not found"); - return getLinearCostByTime(component.getCostList()); - } - - -} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java deleted file mode 100644 index b561aea..0000000 --- a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalMeanCostFunction.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.insightlab.graphast.query.cost_functions; - -import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; - -public class TemporalMeanCostFunction implements CostFunction { - - @Override - public double getCost(Edge e) throws Exception { - CostListEdgeComponent component = e.getComponent(CostListEdgeComponent.class); - if (component == null) - throw new Exception("Temporal component not found"); - return component.getMeanCost(); - } - -} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java deleted file mode 100644 index 4e539fa..0000000 --- a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TemporalSpecificCostFunction.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.insightlab.graphast.query.cost_functions; - -import org.insightlab.graphast.model.Edge; -import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; - -public class TemporalSpecificCostFunction implements CostFunction { - - private int index; - - public TemporalSpecificCostFunction(int index) { - this.index = index; - } - - @Override - public double getCost(Edge e) throws Exception { - CostListEdgeComponent component = e.getComponent(CostListEdgeComponent.class); - if (component == null) - throw new Exception("Temporal component not found"); - return component.getSpecificCost(index); - } - -} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentCostFunction.java new file mode 100644 index 0000000..b00de47 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentCostFunction.java @@ -0,0 +1,24 @@ +package org.insightlab.graphast.query.cost_functions; + +import org.insightlab.graphast.model.Edge; + +public abstract class TimeDependentCostFunction implements CostFunction { + + private int hour, min; + + public void setTime(int hour, int min) { + this.hour = hour; + this.min = min; + } + + protected double getRelativePositionInCostList(int listSize) { + if (hour >= 0 && hour < 24 && min >= 0 && min < 60) { + int totalMins = hour*60 + min; + return totalMins * listSize / (24*60.); + } + return -1; + } + + public abstract double getCost(Edge e) throws RuntimeException; + +} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentLinearCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentLinearCostFunction.java new file mode 100644 index 0000000..d0c1adf --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentLinearCostFunction.java @@ -0,0 +1,39 @@ +package org.insightlab.graphast.query.cost_functions; + +import java.util.List; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; + +public class TimeDependentLinearCostFunction extends TimeDependentCostFunction { + + public TimeDependentLinearCostFunction(int hour, int min) { + this.setTime(hour, min); + } + + private double getLinearInterpolation(double n1, double n2, double x) { + return n1 + x * (n2 - n1); + } + + public double getLinearCost(List costList) { + double relativePosition = this.getRelativePositionInCostList(costList.size()); + if (relativePosition == -1) return -1; + + int index = (int) Math.floor(relativePosition); + + double x = relativePosition - index; + double n1 = costList.get(index); + double n2 = (index + 1 < costList.size()) ? costList.get(index + 1) : costList.get(0); + return getLinearInterpolation(n1, n2, x); + } + + @Override + public double getCost(Edge e) throws RuntimeException { + CostListEdgeComponent component = e.getComponent(CostListEdgeComponent.class); + if (component == null) + throw new RuntimeException("Temporal component not found"); + return getLinearCost(component.getCostList()); + } + + +} diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentStepCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentStepCostFunction.java new file mode 100644 index 0000000..b459786 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentStepCostFunction.java @@ -0,0 +1,32 @@ +package org.insightlab.graphast.query.cost_functions; + +import java.util.List; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; + +public class TimeDependentStepCostFunction extends TimeDependentCostFunction { + + public TimeDependentStepCostFunction(int hour, int min) { + this.setTime(hour, min); + } + + public double getStepCost(List costList) { + double relativePosition = this.getRelativePositionInCostList(costList.size()); + if (relativePosition == -1) return -1; + + int index = (int) Math.floor(relativePosition); + + return costList.get(index); + } + + @Override + public double getCost(Edge e) throws RuntimeException { + CostListEdgeComponent component = e.getComponent(CostListEdgeComponent.class); + if (component == null) + throw new RuntimeException("Temporal component not found"); + + return getStepCost(component.getCostList()); + } + +} diff --git a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java index f84e641..f47d3eb 100644 --- a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java +++ b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java @@ -13,8 +13,9 @@ import org.insightlab.graphast.model.components.spatial_components.SpatialEdgeComponent; import org.insightlab.graphast.model.components.spatial_components.SpatialGraphComponent; import org.insightlab.graphast.model.components.spatial_components.SpatialNodeComponent; -import org.insightlab.graphast.query.cost_functions.TemporalLinearCostFunction; -import org.insightlab.graphast.query.cost_functions.TemporalSpecificCostFunction; +import org.insightlab.graphast.query.cost_functions.CostFunctionFactory; +import org.insightlab.graphast.query.cost_functions.InterpolationMethod; +import org.insightlab.graphast.query.cost_functions.TimeDependentCostFunction; import org.insightlab.graphast.query.shortestpath.DijkstraStrategy; import org.insightlab.graphast.query.shortestpath.ShortestPathStrategy; import org.insightlab.graphast.query.utils.DistanceVector; @@ -83,26 +84,13 @@ public void temporalTest() { } @Test - public void temporalDijkstraTest() { - ShortestPathStrategy dijkstra = new DijkstraStrategy(g); - DistanceVector result; - - dijkstra.setCostFunction(new TemporalSpecificCostFunction(2)); - result = dijkstra.run(2); - assertEquals("Temporal dijkstra test index 2", 3, result.getDistance(0), 0); - - dijkstra.setCostFunction(new TemporalSpecificCostFunction(3)); - result = dijkstra.run(2); - assertEquals("Temporal dijkstra test index 3", 8, result.getDistance(0), 0); - } - - @Test - public void temporalDijkstraTestExample4() { + public void linearTimeDependentDijkstraTest() { ShortestPathStrategy dijkstra = new DijkstraStrategy(graphExample4); - TemporalLinearCostFunction costFunction = new TemporalLinearCostFunction(6, 0); + TimeDependentCostFunction costFunction = CostFunctionFactory.getTimeDependentCostFunction(InterpolationMethod.LINEAR); dijkstra.setCostFunction(costFunction); DistanceVector result; + costFunction.setTime(6, 0); result = dijkstra.run(0, 6); assertEquals("Temporal dijkstra example4 6:00", 14, result.getDistance(6), 0); result.print(0, 6); @@ -123,5 +111,24 @@ public void temporalDijkstraTestExample4() { result.print(0, 6); } + + @Test + public void stepTimeDependentDijkstraTest() { + ShortestPathStrategy dijkstra = new DijkstraStrategy(graphExample4); + TimeDependentCostFunction costFunction = CostFunctionFactory.getTimeDependentCostFunction(InterpolationMethod.STEP); + dijkstra.setCostFunction(costFunction); + DistanceVector result; + + costFunction.setTime(6, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 6:00", 14, result.getDistance(6), 0); + result.print(0, 6); + + costFunction.setTime(18, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 18:00", 12, result.getDistance(6), 0); + result.print(0, 6); + + } } From ef26b73bbd01f3970022c4a118e97ad6e27b5f37 Mon Sep 17 00:00:00 2001 From: ericklt Date: Sat, 17 Feb 2018 21:28:37 -0300 Subject: [PATCH 10/16] Changed the call of a cost function constructor to the factory creation --- .../graphast/query/shortestpath/DijkstraStrategy.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java b/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java index 7fe54d6..ca7357f 100644 --- a/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java +++ b/core/src/main/java/org/insightlab/graphast/query/shortestpath/DijkstraStrategy.java @@ -32,7 +32,7 @@ import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Graph; import org.insightlab.graphast.query.cost_functions.CostFunction; -import org.insightlab.graphast.query.cost_functions.DefaultCostFunction; +import org.insightlab.graphast.query.cost_functions.CostFunctionFactory; import org.insightlab.graphast.query.utils.DistanceElement; import org.insightlab.graphast.query.utils.DistanceVector; @@ -55,7 +55,7 @@ public class DijkstraStrategy implements ShortestPathStrategy { */ public DijkstraStrategy(Graph g) { this.g = g; - costFunction = new DefaultCostFunction(); + costFunction = CostFunctionFactory.getDefaultCostFunction(); } public void setCostFunction(CostFunction costFunction) { From dd49ad16b409229521c3687615846778753e771f Mon Sep 17 00:00:00 2001 From: ericklt Date: Fri, 23 Feb 2018 10:45:48 -0300 Subject: [PATCH 11/16] Added storage option using java's Serializable --- .../insightlab/graphast/MainClassDiagram.ucls | 94 ++++++++-------- .../org/insightlab/graphast/model/Edge.java | 5 + .../org/insightlab/graphast/model/Graph.java | 21 +++- .../graphast/model/GraphObject.java | 7 +- .../org/insightlab/graphast/model/Node.java | 5 + .../model/components/EdgeComponent.java | 9 +- .../model/components/GraphComponent.java | 9 +- .../model/components/NodeComponent.java | 9 +- .../CostListEdgeComponent.java | 5 + .../CostListNodeComponent.java | 5 + .../spatial_components/Geometry.java | 8 +- .../components/spatial_components/Point.java | 9 +- .../SpatialEdgeComponent.java | 6 + .../SpatialGraphComponent.java | 5 + .../SpatialNodeComponent.java | 5 + .../graphast/storage/GraphStorage.java | 11 +- .../graphast/storage/GraphStorageFactory.java | 11 +- .../graphast/storage/OSMGraphStorage.java | 2 +- .../graphast/storage/SerializedStorage.java | 106 ++++++++++++++++++ .../graphast/storage/StorageUtils.java | 30 ++++- .../structure/DefaultGraphStructure.java | 16 +++ .../graphast/structure/GraphStructure.java | 2 + .../structure/MMapGraphStructure.java | 6 + .../graphast/components/ComponentTest.java | 2 + .../storage/SerializedStorageTest.java | 98 ++++++++++++++++ 25 files changed, 422 insertions(+), 64 deletions(-) create mode 100644 core/src/main/java/org/insightlab/graphast/storage/SerializedStorage.java create mode 100644 core/src/test/java/org/insightlab/graphast/storage/SerializedStorageTest.java diff --git a/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls index eff7554..1c4081a 100644 --- a/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls +++ b/core/src/main/java/org/insightlab/graphast/MainClassDiagram.ucls @@ -132,15 +132,15 @@ - - + + - + - + @@ -148,75 +148,75 @@ - - + + - + - + - - - - - + - + - + - - - - - - - - - - - - - - - - - + - + - + - + + + + + + + + + + + + + + + + + + + + + - - + + - + - + @@ -232,27 +232,27 @@ - - + + - + - + - - - + + + - + , EdgeComponent> edgeComponent = null; private long fromNodeId; diff --git a/core/src/main/java/org/insightlab/graphast/model/Graph.java b/core/src/main/java/org/insightlab/graphast/model/Graph.java index 2bcb916..304e55f 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Graph.java +++ b/core/src/main/java/org/insightlab/graphast/model/Graph.java @@ -41,6 +41,11 @@ */ public class Graph extends GraphObject { + /** + * + */ + private static final long serialVersionUID = -3661942047360629183L; + private GraphStructure structure; /** @@ -70,6 +75,11 @@ public void addNode(long id) { this.addNode(new Node(id)); } + public void addNodes(long ...ids) { + for (long id : ids) + this.addNode(id); + } + /** * Adds a new node to the graph, given the Node object. If a node already * exists with an id equal to the given node, a DuplicatedNodeException is thrown. @@ -215,7 +225,16 @@ public void addComponent(GraphComponent component) { component.setGraph(this); } - public Set> getAllCardNames() { + public Iterable getAllComponents() { + return new Iterable() { + @Override + public Iterator iterator() { + return structure.getAllComponents(); + } + }; + } + + public Set> getAllComponentNames() { return structure.getAllComponentClasses(); } diff --git a/core/src/main/java/org/insightlab/graphast/model/GraphObject.java b/core/src/main/java/org/insightlab/graphast/model/GraphObject.java index 6144a34..a10554c 100644 --- a/core/src/main/java/org/insightlab/graphast/model/GraphObject.java +++ b/core/src/main/java/org/insightlab/graphast/model/GraphObject.java @@ -24,14 +24,19 @@ package org.insightlab.graphast.model; +import java.io.Serializable; import java.util.HashMap; /** * The abstract class GraphObject. The basic models of graph elements * in the project extend from this class. */ -public abstract class GraphObject { +public abstract class GraphObject implements Serializable { + /** + * + */ + private static final long serialVersionUID = -5380199647561475338L; private HashMap data = null; /** diff --git a/core/src/main/java/org/insightlab/graphast/model/Node.java b/core/src/main/java/org/insightlab/graphast/model/Node.java index 87cce89..57472ba 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Node.java +++ b/core/src/main/java/org/insightlab/graphast/model/Node.java @@ -36,6 +36,11 @@ */ public class Node extends GraphObject { + /** + * + */ + private static final long serialVersionUID = -8614831471786755717L; + private Map, NodeComponent> nodeComponents = null; private long id; diff --git a/core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java index e3acaaa..d626444 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java @@ -1,8 +1,15 @@ package org.insightlab.graphast.model.components; +import java.io.Serializable; + import org.insightlab.graphast.model.Edge; -public abstract class EdgeComponent { +public abstract class EdgeComponent implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -6405905013226850089L; private Edge edge = null; diff --git a/core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java index 14917bd..465441a 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java @@ -1,9 +1,16 @@ package org.insightlab.graphast.model.components; +import java.io.Serializable; + import org.insightlab.graphast.model.Graph; -public abstract class GraphComponent { +public abstract class GraphComponent implements Serializable { + /** + * + */ + private static final long serialVersionUID = 5846392764694019776L; + private Graph graph = null; public void setGraph(Graph graph) { diff --git a/core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java index 2b65b70..2e2e34a 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java @@ -1,9 +1,16 @@ package org.insightlab.graphast.model.components; +import java.io.Serializable; + import org.insightlab.graphast.model.Node; -public abstract class NodeComponent { +public abstract class NodeComponent implements Serializable { + /** + * + */ + private static final long serialVersionUID = 7380836164433719107L; + private Node node = null; public void setNode(Node node) { diff --git a/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java index a973834..37f7271 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java @@ -7,6 +7,11 @@ public class CostListEdgeComponent extends EdgeComponent { + /** + * + */ + private static final long serialVersionUID = 2801818017386915449L; + private List costList; public CostListEdgeComponent(Double ...costs) { diff --git a/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java index 890176e..9934b29 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java @@ -7,6 +7,11 @@ public class CostListNodeComponent extends NodeComponent { + /** + * + */ + private static final long serialVersionUID = -4909900732877399952L; + private List costList; public CostListNodeComponent(Double ...costs) { diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java index 8c68287..1a831cd 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java @@ -1,10 +1,16 @@ package org.insightlab.graphast.model.components.spatial_components; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -public class Geometry { +public class Geometry implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 955338995597901145L; private List points; diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java index 94f1d6c..13ccabb 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java @@ -1,6 +1,13 @@ package org.insightlab.graphast.model.components.spatial_components; -public class Point { +import java.io.Serializable; + +public class Point implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 7597535743107576754L; private double lat; private double lng; diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java index 511cf70..5b546da 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java @@ -4,7 +4,13 @@ public class SpatialEdgeComponent extends EdgeComponent { + /** + * + */ + private static final long serialVersionUID = -5946241963056545943L; + private Geometry geometry; + public SpatialEdgeComponent(Geometry geometry) { this.geometry = geometry; } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java index 8a8dea9..eaf48e1 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java @@ -4,6 +4,11 @@ public class SpatialGraphComponent extends GraphComponent { + /** + * + */ + private static final long serialVersionUID = -8582067349649655434L; + public SpatialGraphComponent() { } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java index 1ba0643..2b04d3f 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java @@ -4,6 +4,11 @@ public class SpatialNodeComponent extends NodeComponent { + /** + * + */ + private static final long serialVersionUID = 4231579086439483117L; + private Point point; public SpatialNodeComponent(double lat, double lng) { diff --git a/core/src/main/java/org/insightlab/graphast/storage/GraphStorage.java b/core/src/main/java/org/insightlab/graphast/storage/GraphStorage.java index 71f4a58..d68a714 100644 --- a/core/src/main/java/org/insightlab/graphast/storage/GraphStorage.java +++ b/core/src/main/java/org/insightlab/graphast/storage/GraphStorage.java @@ -27,13 +27,14 @@ import java.io.FileNotFoundException; import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.structure.DefaultGraphStructure; import org.insightlab.graphast.structure.GraphStructure; /** * The GraphStorage interface. This interface contains declarations of general methods * for different GraphStorage's implementations. */ -public interface GraphStorage { +public abstract class GraphStorage { /** * Load a graph from the given path and structure. @@ -41,13 +42,17 @@ public interface GraphStorage { * @param structure that represents the structure of the graph. * @return the graph loaded. */ - Graph load(String path, GraphStructure structure) throws FileNotFoundException; + public abstract Graph load(String path, GraphStructure structure) throws FileNotFoundException; + + public Graph load(String path) throws FileNotFoundException { + return load(path, new DefaultGraphStructure()); + } /** * Save the graph into the given path. * @param path to save the file that contains the graph. * @param graph that will be saved. */ - void save(String path, Graph graph); + public abstract void save(String path, Graph graph); } \ No newline at end of file diff --git a/core/src/main/java/org/insightlab/graphast/storage/GraphStorageFactory.java b/core/src/main/java/org/insightlab/graphast/storage/GraphStorageFactory.java index 3a5da85..51f61ff 100644 --- a/core/src/main/java/org/insightlab/graphast/storage/GraphStorageFactory.java +++ b/core/src/main/java/org/insightlab/graphast/storage/GraphStorageFactory.java @@ -31,12 +31,21 @@ public class GraphStorageFactory { /** - * @return the current GraphStorage's instance. + * @return the OSM GraphStorage's instance. */ public static GraphStorage getOSMGraphStorage() { return OSMGraphStorage.getInstance(); } + + /** + * @return the Serialized GraphStorage's instance. + */ + public static GraphStorage getSerializedGraphStorage() { + + return SerializedStorage.getInstance(); + + } } diff --git a/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java b/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java index 20552bc..8264352 100644 --- a/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java +++ b/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java @@ -55,7 +55,7 @@ * This class implements a OSMGraphStorage. OpenStreetMap (OSM) is a manner to represents graphs. * */ -public class OSMGraphStorage implements GraphStorage { +public class OSMGraphStorage extends GraphStorage { private static GraphStorage instance = null; diff --git a/core/src/main/java/org/insightlab/graphast/storage/SerializedStorage.java b/core/src/main/java/org/insightlab/graphast/storage/SerializedStorage.java new file mode 100644 index 0000000..f977c2c --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/storage/SerializedStorage.java @@ -0,0 +1,106 @@ +package org.insightlab.graphast.storage; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.components.GraphComponent; +import org.insightlab.graphast.structure.GraphStructure; + +public class SerializedStorage extends GraphStorage { + +private static GraphStorage instance = null; + + private SerializedStorage() {} + + /** + * @return the current GraphStorage's instance. + */ + public static GraphStorage getInstance() { + if (instance == null) + instance = new SerializedStorage(); + + return instance; + } + + @Override + public Graph load(String path, GraphStructure structure) throws FileNotFoundException { + Graph g = new Graph(structure); + + String directory = StorageUtils.ensureDirectory(path); + ObjectInputStream oin; + Object obj; + + File f = new File(directory); + + boolean graphExists = f.exists(); + + if (!graphExists) + f.mkdirs(); + + try { + + oin = new ObjectInputStream(new FileInputStream(directory + "nodes.gobj")); + while((obj = oin.readObject()) != null) + g.addNode((Node) obj); + oin.close(); + + oin = new ObjectInputStream(new FileInputStream(directory + "edges.gobj")); + while((obj = oin.readObject()) != null) + g.addEdge((Edge) obj); + oin.close(); + + oin = new ObjectInputStream(new FileInputStream(directory + "graph_components.gobj")); + while((obj = oin.readObject()) != null) + g.addComponent((GraphComponent) obj); + oin.close(); + + } catch (IOException | ClassNotFoundException e) { + e.printStackTrace(); + } + + return g; + } + + @Override + public void save(String path, Graph graph) { + + String directory = StorageUtils.ensureDirectory(path); + ObjectOutputStream oout; + + File f = new File(directory); + + boolean graphExists = f.exists(); + + if (!graphExists) + f.mkdirs(); + + try { + oout = new ObjectOutputStream(new FileOutputStream(directory + "nodes.gobj")); + for (Node n : graph.getNodes()) + oout.writeObject(n); + oout.writeObject(null); + oout.close(); + oout = new ObjectOutputStream(new FileOutputStream(directory + "edges.gobj")); + for (Edge e : graph.getEdges()) + oout.writeObject(e); + oout.writeObject(null); + oout.close(); + oout = new ObjectOutputStream(new FileOutputStream(directory + "graph_components.gobj")); + for (GraphComponent component : graph.getAllComponents()) + oout.writeObject(component); + oout.writeObject(null); + oout.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/storage/StorageUtils.java b/core/src/main/java/org/insightlab/graphast/storage/StorageUtils.java index 78c20d1..a4302d5 100644 --- a/core/src/main/java/org/insightlab/graphast/storage/StorageUtils.java +++ b/core/src/main/java/org/insightlab/graphast/storage/StorageUtils.java @@ -35,16 +35,19 @@ public class StorageUtils { private StorageUtils() {} + public static String ensureDirectory(String path) { + if (!path.endsWith("/")) + return path + "/"; + return path; + } + /** * Delete a graph from the given path. * @param path to search the file that contains the graph that will be deleted. */ public static boolean deleteMMapGraph(String path) { - String directory = path; - - if (!directory.endsWith("/")) - directory += "/"; - + String directory = ensureDirectory(path); + File f = new File(directory); boolean ok = true; @@ -57,5 +60,22 @@ public static boolean deleteMMapGraph(String path) { return ok; } + + + public static boolean deleteSerializedGraph(String path) { + String directory = ensureDirectory(path); + + File f = new File(directory); + boolean ok = true; + + if (f.exists()) { + ok = new File(directory + "nodes.gobj").delete(); + ok = new File(directory + "edges.gobj").delete() && ok; + ok = new File(directory + "graph_components.gobj").delete() && ok; + ok = f.delete() && ok; + } + + return ok; + } } diff --git a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java index 0c74d9e..1ffcae4 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/DefaultGraphStructure.java @@ -199,4 +199,20 @@ public Set> getAllComponentClasses() { return graphComponents.keySet(); } + @Override + public Iterator getAllComponents() { + return (graphComponents != null) ? + graphComponents.values().iterator() : + new Iterator() { + @Override + public boolean hasNext() { + return false; + } + @Override + public GraphComponent next() { + return null; + } + }; + } + } diff --git a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java index 9172b49..ea57933 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java @@ -95,5 +95,7 @@ public interface GraphStructure { void addComponent(GraphComponent component); + + Iterator getAllComponents(); } diff --git a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java index 4ebabb4..a8c01d1 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java @@ -374,5 +374,11 @@ public void addComponent(GraphComponent component) { } + @Override + public Iterator getAllComponents() { + // TODO Auto-generated method stub + return null; + } + } diff --git a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java index f47d3eb..595698d 100644 --- a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java +++ b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java @@ -87,7 +87,9 @@ public void temporalTest() { public void linearTimeDependentDijkstraTest() { ShortestPathStrategy dijkstra = new DijkstraStrategy(graphExample4); TimeDependentCostFunction costFunction = CostFunctionFactory.getTimeDependentCostFunction(InterpolationMethod.LINEAR); + dijkstra.setCostFunction(costFunction); + DistanceVector result; costFunction.setTime(6, 0); diff --git a/core/src/test/java/org/insightlab/graphast/storage/SerializedStorageTest.java b/core/src/test/java/org/insightlab/graphast/storage/SerializedStorageTest.java new file mode 100644 index 0000000..765b5a3 --- /dev/null +++ b/core/src/test/java/org/insightlab/graphast/storage/SerializedStorageTest.java @@ -0,0 +1,98 @@ +package org.insightlab.graphast.storage; + +import static org.junit.Assert.*; + +import java.io.FileNotFoundException; + +import org.insightlab.graphast.generators.GraphGenerator; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.query.cost_functions.CostFunctionFactory; +import org.insightlab.graphast.query.cost_functions.InterpolationMethod; +import org.insightlab.graphast.query.cost_functions.TimeDependentCostFunction; +import org.insightlab.graphast.query.shortestpath.DijkstraStrategy; +import org.insightlab.graphast.query.shortestpath.ShortestPathStrategy; +import org.insightlab.graphast.query.utils.DistanceVector; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class SerializedStorageTest { + + private static GraphStorage storage; + private static Graph original, reloaded; + private static final String PATH = "serialized_graphs/"; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + storage = GraphStorageFactory.getSerializedGraphStorage(); + original = GraphGenerator.getInstance().generateExample4(); + storage.save(PATH, original); + + try { + reloaded = storage.load(PATH); + } catch (FileNotFoundException e) { + e.printStackTrace(); + fail("File Not Found!"); + } + } + + @Test + public void testNumberOfNodes() { + assertEquals("Number of nodes", original.getNumberOfNodes(), reloaded.getNumberOfNodes()); + } + + @Test + public void testNumberOfEdges() { + assertEquals("Number of edges", original.getNumberOfEdges(), reloaded.getNumberOfEdges()); + } + + @Test + public void linearTimeDependentDijkstraTest() { + ShortestPathStrategy dijkstra = new DijkstraStrategy(reloaded); + TimeDependentCostFunction costFunction = CostFunctionFactory.getTimeDependentCostFunction(InterpolationMethod.LINEAR); + + dijkstra.setCostFunction(costFunction); + + DistanceVector result; + + costFunction.setTime(6, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 6:00", 14, result.getDistance(6), 0); + + costFunction.setTime(12, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 12:00", 12, result.getDistance(6), 0); + + costFunction.setTime(15, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 15:00", 13, result.getDistance(6), 0); + + costFunction.setTime(20, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 20:00", 14, result.getDistance(6), 0); + + } + + @Test + public void stepTimeDependentDijkstraTest() { + ShortestPathStrategy dijkstra = new DijkstraStrategy(reloaded); + TimeDependentCostFunction costFunction = CostFunctionFactory.getTimeDependentCostFunction(InterpolationMethod.STEP); + dijkstra.setCostFunction(costFunction); + DistanceVector result; + + costFunction.setTime(6, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 6:00", 14, result.getDistance(6), 0); + + costFunction.setTime(18, 0); + result = dijkstra.run(0, 6); + assertEquals("Temporal dijkstra example4 18:00", 12, result.getDistance(6), 0); + + } + + @AfterClass + public static void tearDownAfterClass() { + StorageUtils.deleteSerializedGraph(PATH); + } + +} From e1f84cd3ea5205dd7a457e812b8fcd32125d9456 Mon Sep 17 00:00:00 2001 From: ericklt Date: Wed, 28 Feb 2018 12:42:30 -0300 Subject: [PATCH 12/16] Added Kryo serialization and the serialization test is now abstract --- core/pom.xml | 12 +- core/serialized_graphs/edges.bin | Bin 0 -> 1562 bytes core/serialized_graphs/graph_components.bin | 0 core/serialized_graphs/nodes.bin | Bin 0 -> 1771 bytes .../insightlab/graphast/MainClassDiagram.ucls | 120 +++++++++--------- .../org/insightlab/graphast/model/Edge.java | 3 + .../org/insightlab/graphast/model/Node.java | 6 + .../CostListEdgeComponent.java | 5 + .../CostListNodeComponent.java | 5 + .../components/spatial_components/Point.java | 4 + .../SpatialEdgeComponent.java | 4 + .../SpatialNodeComponent.java | 4 + .../graphast/storage/GraphStorageFactory.java | 15 ++- ...age.java => JavaSerializationStorage.java} | 8 +- .../graphast/storage/KryoStorage.java | 111 ++++++++++++++++ .../storage/JavaSerializableStorageTest.java | 12 ++ .../graphast/storage/KryoStorageTest.java | 11 ++ ...lizedStorageTest.java => StorageTest.java} | 33 ++--- 18 files changed, 269 insertions(+), 84 deletions(-) create mode 100644 core/serialized_graphs/edges.bin create mode 100644 core/serialized_graphs/graph_components.bin create mode 100644 core/serialized_graphs/nodes.bin rename core/src/main/java/org/insightlab/graphast/storage/{SerializedStorage.java => JavaSerializationStorage.java} (89%) create mode 100644 core/src/main/java/org/insightlab/graphast/storage/KryoStorage.java create mode 100644 core/src/test/java/org/insightlab/graphast/storage/JavaSerializableStorageTest.java create mode 100644 core/src/test/java/org/insightlab/graphast/storage/KryoStorageTest.java rename core/src/test/java/org/insightlab/graphast/storage/{SerializedStorageTest.java => StorageTest.java} (82%) diff --git a/core/pom.xml b/core/pom.xml index 5ac79be..8d40af2 100755 --- a/core/pom.xml +++ b/core/pom.xml @@ -86,7 +86,17 @@ 0.46 - + + com.esotericsoftware + kryo + 4.0.1 + + + + de.javakaffee + kryo-serializers + 0.41 + diff --git a/core/serialized_graphs/edges.bin b/core/serialized_graphs/edges.bin new file mode 100644 index 0000000000000000000000000000000000000000..362c77f6be6c61eff9e0a593ba8eeb5a25c0595d GIT binary patch literal 1562 zcmZQ%U|?j(N-Rs%D=o>)(ep?w&hSnAzz76j!JNdrbUo*s#NyA4j7(P;^NZ5;GV_Wv z(=$qP5|i}OixLYm5{papa`RJCbM%t)a|`nGQu9iRfz0BP_?%22fh6b*6!Za#xu&G2 zI>Xd5FfuXnFfws*IdCw50hj#;2!oLszjZ)ko-#2o!IcjVpD+S_B0`D>SO%d7pix0o z3@{CK53sNe@fcv^7-Sv*)(ep?w&hSnAzz76j!JNdrbUo*s#NyA4j7%39^NZ5;GV_Wv z(=$qP5|i}OixLYm5{papa`RJCbM%t)a|`nGQu9iR^@SjLi5=1!{Q8#K>}pBFh8vGxJIq5AeQ~xDvT;Q*Js` zOapq}v${lNDI){RNb>xfHr5Qevp~ - - - + + + + + + + - + - + - + + + + + - - - + + + - + - + - - - + + + - + - + - - - - - - - - + + + + - - + + - + - - - - + + + + - - + + - + - - - - - - - - - - - + + + - + - + - - - + + + - + - + - - - + + + - + - + - + - + - + + + + + diff --git a/core/src/main/java/org/insightlab/graphast/model/Edge.java b/core/src/main/java/org/insightlab/graphast/model/Edge.java index c198ac5..33f84d1 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Edge.java +++ b/core/src/main/java/org/insightlab/graphast/model/Edge.java @@ -48,6 +48,9 @@ public class Edge extends GraphObject { private double weight; private boolean bidirectional; + public Edge() { + this.weight = 1; + } /** * Instantiates a new edge. * diff --git a/core/src/main/java/org/insightlab/graphast/model/Node.java b/core/src/main/java/org/insightlab/graphast/model/Node.java index 57472ba..eeb6b7a 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Node.java +++ b/core/src/main/java/org/insightlab/graphast/model/Node.java @@ -45,6 +45,8 @@ public class Node extends GraphObject { private long id; + public Node() {} + /** * Instantiates a new node. * @@ -63,6 +65,10 @@ public long getId() { return id; } + public void setId(long id) { + this.id = id; + } + public void addComponent(NodeComponent component) { if (nodeComponents == null) nodeComponents = new HashMap<>(); diff --git a/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java index 37f7271..bacbe65 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListEdgeComponent.java @@ -1,5 +1,6 @@ package org.insightlab.graphast.model.components.cost_list_components; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -14,6 +15,10 @@ public class CostListEdgeComponent extends EdgeComponent { private List costList; + public CostListEdgeComponent() { + costList = new ArrayList<>(); + } + public CostListEdgeComponent(Double ...costs) { costList = Arrays.asList(costs); } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java index 9934b29..2fac683 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/cost_list_components/CostListNodeComponent.java @@ -1,5 +1,6 @@ package org.insightlab.graphast.model.components.cost_list_components; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -14,6 +15,10 @@ public class CostListNodeComponent extends NodeComponent { private List costList; + public CostListNodeComponent() { + costList = new ArrayList<>(); + } + public CostListNodeComponent(Double ...costs) { costList = Arrays.asList(costs); } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java index 13ccabb..17fd430 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Point.java @@ -12,6 +12,10 @@ public class Point implements Serializable { private double lat; private double lng; + public Point() { + this(0, 0); + } + public Point(double lat, double lng) { this.lat = lat; this.lng = lng; diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java index 5b546da..aae3019 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialEdgeComponent.java @@ -11,6 +11,10 @@ public class SpatialEdgeComponent extends EdgeComponent { private Geometry geometry; + public SpatialEdgeComponent() { + this(new Geometry()); + } + public SpatialEdgeComponent(Geometry geometry) { this.geometry = geometry; } diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java index 2b04d3f..8fa7632 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialNodeComponent.java @@ -11,6 +11,10 @@ public class SpatialNodeComponent extends NodeComponent { private Point point; + public SpatialNodeComponent() { + this(new Point()); + } + public SpatialNodeComponent(double lat, double lng) { this(new Point(lat, lng)); } diff --git a/core/src/main/java/org/insightlab/graphast/storage/GraphStorageFactory.java b/core/src/main/java/org/insightlab/graphast/storage/GraphStorageFactory.java index 51f61ff..78caa43 100644 --- a/core/src/main/java/org/insightlab/graphast/storage/GraphStorageFactory.java +++ b/core/src/main/java/org/insightlab/graphast/storage/GraphStorageFactory.java @@ -40,11 +40,20 @@ public static GraphStorage getOSMGraphStorage() { } /** - * @return the Serialized GraphStorage's instance. + * @return the Java Serializable GraphStorage's instance. */ - public static GraphStorage getSerializedGraphStorage() { + public static GraphStorage getJavaSerializableGraphStorage() { - return SerializedStorage.getInstance(); + return JavaSerializationStorage.getInstance(); + + } + + /** + * @return the Kryo GraphStorage's instance. + */ + public static GraphStorage getKryoGraphStorage() { + + return KryoStorage.getInstance(); } diff --git a/core/src/main/java/org/insightlab/graphast/storage/SerializedStorage.java b/core/src/main/java/org/insightlab/graphast/storage/JavaSerializationStorage.java similarity index 89% rename from core/src/main/java/org/insightlab/graphast/storage/SerializedStorage.java rename to core/src/main/java/org/insightlab/graphast/storage/JavaSerializationStorage.java index f977c2c..005de1b 100644 --- a/core/src/main/java/org/insightlab/graphast/storage/SerializedStorage.java +++ b/core/src/main/java/org/insightlab/graphast/storage/JavaSerializationStorage.java @@ -14,18 +14,18 @@ import org.insightlab.graphast.model.components.GraphComponent; import org.insightlab.graphast.structure.GraphStructure; -public class SerializedStorage extends GraphStorage { +public class JavaSerializationStorage extends GraphStorage { -private static GraphStorage instance = null; + private static GraphStorage instance = null; - private SerializedStorage() {} + private JavaSerializationStorage() {} /** * @return the current GraphStorage's instance. */ public static GraphStorage getInstance() { if (instance == null) - instance = new SerializedStorage(); + instance = new JavaSerializationStorage(); return instance; } diff --git a/core/src/main/java/org/insightlab/graphast/storage/KryoStorage.java b/core/src/main/java/org/insightlab/graphast/storage/KryoStorage.java new file mode 100644 index 0000000..454f12a --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/storage/KryoStorage.java @@ -0,0 +1,111 @@ +package org.insightlab.graphast.storage; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Arrays; + +import org.insightlab.graphast.model.Edge; +import org.insightlab.graphast.model.Graph; +import org.insightlab.graphast.model.Node; +import org.insightlab.graphast.model.components.GraphComponent; +import org.insightlab.graphast.structure.GraphStructure; + +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.io.Output; + +import de.javakaffee.kryoserializers.ArraysAsListSerializer; + +import com.esotericsoftware.kryo.io.Input; + +public class KryoStorage extends GraphStorage { + + private static GraphStorage instance = null; + private Kryo kryo; + + private KryoStorage() { + kryo = new Kryo(); + kryo.register( Arrays.asList( "" ).getClass(), new ArraysAsListSerializer() ); + } + + /** + * @return the current GraphStorage's instance. + */ + public static GraphStorage getInstance() { + if (instance == null) + instance = new KryoStorage(); + + return instance; + } + + @Override + public Graph load(String path, GraphStructure structure) throws FileNotFoundException { + Graph g = new Graph(structure); + + String directory = StorageUtils.ensureDirectory(path); + Input in; + + File f = new File(directory); + + boolean graphExists = f.exists(); + + if (!graphExists) + f.mkdirs(); + + try { + + in = new Input(new FileInputStream(directory + "nodes.bin")); + while(!in.eof()) + g.addNode(kryo.readObject(in, Node.class)); + in.close(); + + in = new Input(new FileInputStream(directory + "edges.bin")); + while(!in.eof()) + g.addEdge(kryo.readObject(in, Edge.class)); + in.close(); + + in = new Input(new FileInputStream(directory + "graph_components.bin")); + while(!in.eof()) + g.addComponent(kryo.readObject(in, GraphComponent.class)); + in.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + + return g; + } + + @Override + public void save(String path, Graph graph) { + String directory = StorageUtils.ensureDirectory(path); + Output out; + + File f = new File(directory); + + boolean graphExists = f.exists(); + + if (!graphExists) + f.mkdirs(); + + try { + out = new Output(new FileOutputStream(directory + "nodes.bin")); + for (Node n : graph.getNodes()) + kryo.writeObject(out, n); + out.close(); + out = new Output(new FileOutputStream(directory + "edges.bin")); + for (Edge e : graph.getEdges()) + kryo.writeObject(out, e); + out.close(); + out = new Output(new FileOutputStream(directory + "graph_components.bin")); + for (GraphComponent component : graph.getAllComponents()) + kryo.writeObject(out, component); + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/core/src/test/java/org/insightlab/graphast/storage/JavaSerializableStorageTest.java b/core/src/test/java/org/insightlab/graphast/storage/JavaSerializableStorageTest.java new file mode 100644 index 0000000..a410cd9 --- /dev/null +++ b/core/src/test/java/org/insightlab/graphast/storage/JavaSerializableStorageTest.java @@ -0,0 +1,12 @@ +package org.insightlab.graphast.storage; + +import org.junit.BeforeClass; + +public class JavaSerializableStorageTest extends StorageTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + storage = GraphStorageFactory.getJavaSerializableGraphStorage(); + } + +} diff --git a/core/src/test/java/org/insightlab/graphast/storage/KryoStorageTest.java b/core/src/test/java/org/insightlab/graphast/storage/KryoStorageTest.java new file mode 100644 index 0000000..28eae37 --- /dev/null +++ b/core/src/test/java/org/insightlab/graphast/storage/KryoStorageTest.java @@ -0,0 +1,11 @@ +package org.insightlab.graphast.storage; + +import org.junit.BeforeClass; + +public class KryoStorageTest extends StorageTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + storage = GraphStorageFactory.getKryoGraphStorage(); + } +} diff --git a/core/src/test/java/org/insightlab/graphast/storage/SerializedStorageTest.java b/core/src/test/java/org/insightlab/graphast/storage/StorageTest.java similarity index 82% rename from core/src/test/java/org/insightlab/graphast/storage/SerializedStorageTest.java rename to core/src/test/java/org/insightlab/graphast/storage/StorageTest.java index 765b5a3..01582b8 100644 --- a/core/src/test/java/org/insightlab/graphast/storage/SerializedStorageTest.java +++ b/core/src/test/java/org/insightlab/graphast/storage/StorageTest.java @@ -13,26 +13,27 @@ import org.insightlab.graphast.query.shortestpath.ShortestPathStrategy; import org.insightlab.graphast.query.utils.DistanceVector; import org.junit.AfterClass; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Test; -public class SerializedStorageTest { - - private static GraphStorage storage; +public abstract class StorageTest { + + protected static GraphStorage storage; private static Graph original, reloaded; private static final String PATH = "serialized_graphs/"; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - storage = GraphStorageFactory.getSerializedGraphStorage(); - original = GraphGenerator.getInstance().generateExample4(); - storage.save(PATH, original); - - try { - reloaded = storage.load(PATH); - } catch (FileNotFoundException e) { - e.printStackTrace(); - fail("File Not Found!"); + + @Before + public void setup() { + if (reloaded == null) { + original = GraphGenerator.getInstance().generateExample4(); + storage.save(PATH, original); + + try { + reloaded = storage.load(PATH); + } catch (FileNotFoundException e) { + e.printStackTrace(); + fail("File Not Found!"); + } } } From 557e5282678f71585f21f28715492008c875adbd Mon Sep 17 00:00:00 2001 From: ericklt Date: Fri, 2 Mar 2018 08:15:50 -0300 Subject: [PATCH 13/16] Some codacy improvements --- .../ComponentNotFoundException.java | 24 +++++++++++++++++++ .../exceptions/MissingCardException.java | 18 -------------- .../graphast/model/components/Component.java | 5 ++++ .../model/components/EdgeComponent.java | 2 +- .../model/components/GraphComponent.java | 2 +- .../model/components/NodeComponent.java | 2 +- .../SpatialGraphComponent.java | 3 --- .../TimeDependentLinearCostFunction.java | 3 ++- .../TimeDependentStepCostFunction.java | 3 ++- .../graphast/components/ComponentTest.java | 12 ++++------ .../graphast/storage/StorageTest.java | 2 +- 11 files changed, 41 insertions(+), 35 deletions(-) create mode 100644 core/src/main/java/org/insightlab/graphast/exceptions/ComponentNotFoundException.java delete mode 100644 core/src/main/java/org/insightlab/graphast/exceptions/MissingCardException.java create mode 100644 core/src/main/java/org/insightlab/graphast/model/components/Component.java diff --git a/core/src/main/java/org/insightlab/graphast/exceptions/ComponentNotFoundException.java b/core/src/main/java/org/insightlab/graphast/exceptions/ComponentNotFoundException.java new file mode 100644 index 0000000..737bfb5 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/exceptions/ComponentNotFoundException.java @@ -0,0 +1,24 @@ +package org.insightlab.graphast.exceptions; + +import org.insightlab.graphast.model.components.Component; + +public class ComponentNotFoundException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = -915981947597562490L; + + public ComponentNotFoundException() { + super(); + } + + public ComponentNotFoundException(Class component) { + this(component.getName()); + } + + public ComponentNotFoundException(String componentName) { + super("Component '" + componentName + "' not found!"); + } + +} diff --git a/core/src/main/java/org/insightlab/graphast/exceptions/MissingCardException.java b/core/src/main/java/org/insightlab/graphast/exceptions/MissingCardException.java deleted file mode 100644 index 1530d23..0000000 --- a/core/src/main/java/org/insightlab/graphast/exceptions/MissingCardException.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.insightlab.graphast.exceptions; - -public class MissingCardException extends RuntimeException { - - /** - * - */ - private static final long serialVersionUID = -915981947597562490L; - - public MissingCardException() { - super(); - } - - public MissingCardException(String cardName) { - super("'" + cardName + "' not found!"); - } - -} diff --git a/core/src/main/java/org/insightlab/graphast/model/components/Component.java b/core/src/main/java/org/insightlab/graphast/model/components/Component.java new file mode 100644 index 0000000..440b9c6 --- /dev/null +++ b/core/src/main/java/org/insightlab/graphast/model/components/Component.java @@ -0,0 +1,5 @@ +package org.insightlab.graphast.model.components; + +public interface Component { + +} diff --git a/core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java index d626444..65ebdde 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/EdgeComponent.java @@ -4,7 +4,7 @@ import org.insightlab.graphast.model.Edge; -public abstract class EdgeComponent implements Serializable { +public abstract class EdgeComponent implements Component, Serializable { /** * diff --git a/core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java index 465441a..9585c00 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/GraphComponent.java @@ -4,7 +4,7 @@ import org.insightlab.graphast.model.Graph; -public abstract class GraphComponent implements Serializable { +public abstract class GraphComponent implements Component, Serializable { /** * diff --git a/core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java index 2e2e34a..d15a359 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/NodeComponent.java @@ -4,7 +4,7 @@ import org.insightlab.graphast.model.Node; -public abstract class NodeComponent implements Serializable { +public abstract class NodeComponent implements Component, Serializable { /** * diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java index eaf48e1..b356c61 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/SpatialGraphComponent.java @@ -9,7 +9,4 @@ public class SpatialGraphComponent extends GraphComponent { */ private static final long serialVersionUID = -8582067349649655434L; - public SpatialGraphComponent() { - } - } diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentLinearCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentLinearCostFunction.java index d0c1adf..0d66cbc 100644 --- a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentLinearCostFunction.java +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentLinearCostFunction.java @@ -2,6 +2,7 @@ import java.util.List; +import org.insightlab.graphast.exceptions.ComponentNotFoundException; import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; @@ -31,7 +32,7 @@ public double getLinearCost(List costList) { public double getCost(Edge e) throws RuntimeException { CostListEdgeComponent component = e.getComponent(CostListEdgeComponent.class); if (component == null) - throw new RuntimeException("Temporal component not found"); + throw new ComponentNotFoundException(CostListEdgeComponent.class); return getLinearCost(component.getCostList()); } diff --git a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentStepCostFunction.java b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentStepCostFunction.java index b459786..81250a5 100644 --- a/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentStepCostFunction.java +++ b/core/src/main/java/org/insightlab/graphast/query/cost_functions/TimeDependentStepCostFunction.java @@ -2,6 +2,7 @@ import java.util.List; +import org.insightlab.graphast.exceptions.ComponentNotFoundException; import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.components.cost_list_components.CostListEdgeComponent; @@ -24,7 +25,7 @@ public double getStepCost(List costList) { public double getCost(Edge e) throws RuntimeException { CostListEdgeComponent component = e.getComponent(CostListEdgeComponent.class); if (component == null) - throw new RuntimeException("Temporal component not found"); + throw new ComponentNotFoundException(CostListEdgeComponent.class); return getStepCost(component.getCostList()); } diff --git a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java index 595698d..3d502a4 100644 --- a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java +++ b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java @@ -24,8 +24,8 @@ public class ComponentTest { - Graph g; - Graph graphExample4; + private Graph g; + private Graph graphExample4; private Node n0, n1, n2, n3; private Edge e0, e1, e2, e3; @@ -66,7 +66,9 @@ public void setUp() throws Exception { @Test public void spatialTest() { + assertEquals("N0 lat test", 4, n0.getComponent(SpatialNodeComponent.class).getLng(), 0); assertEquals("N1 lat test", 13, n1.getComponent(SpatialNodeComponent.class).getLat(), 0); + assertEquals("N2 lng test", 14, n2.getComponent(SpatialNodeComponent.class).getLat(), 0); assertEquals("N3 lng test", 1, n3.getComponent(SpatialNodeComponent.class).getLng(), 0); e3.getComponent(SpatialEdgeComponent.class).getGeometry(); @@ -95,22 +97,18 @@ public void linearTimeDependentDijkstraTest() { costFunction.setTime(6, 0); result = dijkstra.run(0, 6); assertEquals("Temporal dijkstra example4 6:00", 14, result.getDistance(6), 0); - result.print(0, 6); costFunction.setTime(12, 0); result = dijkstra.run(0, 6); assertEquals("Temporal dijkstra example4 12:00", 12, result.getDistance(6), 0); - result.print(0, 6); costFunction.setTime(15, 0); result = dijkstra.run(0, 6); assertEquals("Temporal dijkstra example4 15:00", 13, result.getDistance(6), 0); - result.print(0, 6); costFunction.setTime(20, 0); result = dijkstra.run(0, 6); assertEquals("Temporal dijkstra example4 20:00", 14, result.getDistance(6), 0); - result.print(0, 6); } @@ -124,12 +122,10 @@ public void stepTimeDependentDijkstraTest() { costFunction.setTime(6, 0); result = dijkstra.run(0, 6); assertEquals("Temporal dijkstra example4 6:00", 14, result.getDistance(6), 0); - result.print(0, 6); costFunction.setTime(18, 0); result = dijkstra.run(0, 6); assertEquals("Temporal dijkstra example4 18:00", 12, result.getDistance(6), 0); - result.print(0, 6); } diff --git a/core/src/test/java/org/insightlab/graphast/storage/StorageTest.java b/core/src/test/java/org/insightlab/graphast/storage/StorageTest.java index 01582b8..5e6dad6 100644 --- a/core/src/test/java/org/insightlab/graphast/storage/StorageTest.java +++ b/core/src/test/java/org/insightlab/graphast/storage/StorageTest.java @@ -23,7 +23,7 @@ public abstract class StorageTest { private static final String PATH = "serialized_graphs/"; @Before - public void setup() { + public void setUp() { if (reloaded == null) { original = GraphGenerator.getInstance().generateExample4(); storage.save(PATH, original); From ba80f4f306ac1cf8696ac32801fccc27b3161a17 Mon Sep 17 00:00:00 2001 From: ericklt Date: Fri, 2 Mar 2018 08:51:15 -0300 Subject: [PATCH 14/16] Minor improvements --- .../org/insightlab/graphast/model/Graph.java | 4 +++ .../graphast/storage/OSMGraphStorage.java | 32 ++++++++----------- .../graphast/structure/GraphStructure.java | 2 ++ .../structure/MMapGraphStructure.java | 4 +++ .../graphast/components/ComponentTest.java | 6 ++-- .../insightlab/graphast/model/EdgeTest.java | 5 +-- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/core/src/main/java/org/insightlab/graphast/model/Graph.java b/core/src/main/java/org/insightlab/graphast/model/Graph.java index 304e55f..47fe994 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Graph.java +++ b/core/src/main/java/org/insightlab/graphast/model/Graph.java @@ -137,6 +137,10 @@ public boolean containsNode(long id) { return structure.containsNode(id); } + public Node getNode(final long id) { + return structure.getNode(id); + } + /** * It returns an Iterator object of the Node elements contained in this graph. * diff --git a/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java b/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java index 8264352..0b75b74 100644 --- a/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java +++ b/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java @@ -36,7 +36,6 @@ import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer; import org.openstreetmap.osmosis.core.domain.v0_6.Entity; -import org.openstreetmap.osmosis.core.domain.v0_6.Tag; import org.openstreetmap.osmosis.core.domain.v0_6.Way; import org.openstreetmap.osmosis.core.domain.v0_6.WayNode; import org.openstreetmap.osmosis.core.task.v0_6.RunnableSource; @@ -58,8 +57,12 @@ public class OSMGraphStorage extends GraphStorage { private static GraphStorage instance = null; + private static HashSet importantTags = new HashSet<>(); - private OSMGraphStorage() {} + private OSMGraphStorage() { + String[] tags = new String[] { "highway", "access", "oneway", "motor_vehicle", "motorcar"}; + Arrays.stream(tags).forEach(importantTags::add); + } /** * @return the current GraphStorage's instance. @@ -183,17 +186,9 @@ public MySink(Graph graph) { private Map getImportantTags(Way w) { Map map = new HashMap<>(); if (!w.getTags().isEmpty()) { - for (Tag t : w.getTags()) { - switch (t.getKey()) { - case "highway": - case "access": - case "oneway": - case "motor_vehicle": - case "motorcar": - map.put(t.getKey(), t.getValue()); - } - - } + w.getTags().stream() + .filter(tag -> importantTags.contains(tag.getKey())) + .forEach(t -> map.put(t.getKey(), t.getValue())); } return map; } @@ -204,16 +199,14 @@ private boolean isValid(Map tags) { if (!allowedHighways.contains(tags.get("highway"))) return false; if (tags.get("highway").equals("path")) { - if (!( - (tags.containsKey("motor_vehicle") && tags.get("motor_vehicle").equals("yes")) || - (tags.containsKey("motorcar") && tags.get("motorcar").equals("yes")) - )) + if (!(tags.containsKey("motor_vehicle") && tags.get("motor_vehicle").equals("yes")) && + !(tags.containsKey("motorcar") && tags.get("motorcar").equals("yes"))) return false; } if (tags.containsKey("access")) { String accessValue = tags.get("access"); - if (!(accessValue.equals("yes") || accessValue.equals("permissive"))) + if (!("yes".equals(accessValue) || "permissive".equals(accessValue))) return false; } @@ -232,7 +225,8 @@ public void process(EntityContainer entityContainer) { if (wayNodeList.size() < 2 || w.getTags().isEmpty() || !isValid(wayTags)) return; - WayNode from, to = wayNodeList.get(0); + WayNode from; + WayNode to = wayNodeList.get(0); if (!graph.containsNode(to.getNodeId())) graph.addNode(to.getNodeId()); diff --git a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java index ea57933..3f549de 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/GraphStructure.java @@ -43,6 +43,8 @@ public interface GraphStructure { */ void addNode(Node node); + Node getNode(final long id); + /** * Add a new edge into the graph. * @param edge the edge that will be added into the graph. diff --git a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java index a8c01d1..55cc01b 100644 --- a/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java +++ b/core/src/main/java/org/insightlab/graphast/structure/MMapGraphStructure.java @@ -186,6 +186,10 @@ public void addEdge(Edge e) { if (e.isBidirectional()) addDirectionalEdge(new Edge(e.getToNodeId(), e.getFromNodeId(), e.getWeight())); } + + public Node getNode(final long id) { + return new Node(id); + } /** * Verify whether the node which has the given id is in the graph or not. diff --git a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java index 3d502a4..cbea0e9 100644 --- a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java +++ b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java @@ -66,11 +66,13 @@ public void setUp() throws Exception { @Test public void spatialTest() { - assertEquals("N0 lat test", 4, n0.getComponent(SpatialNodeComponent.class).getLng(), 0); + assertEquals("N0 lng test", 4, n0.getComponent(SpatialNodeComponent.class).getLng(), 0); assertEquals("N1 lat test", 13, n1.getComponent(SpatialNodeComponent.class).getLat(), 0); - assertEquals("N2 lng test", 14, n2.getComponent(SpatialNodeComponent.class).getLat(), 0); + assertEquals("N2 lat test", 14, n2.getComponent(SpatialNodeComponent.class).getLat(), 0); assertEquals("N3 lng test", 1, n3.getComponent(SpatialNodeComponent.class).getLng(), 0); + assertEquals("get node 0 lat test", 12, g.getNode(0).getComponent(SpatialNodeComponent.class).getLat(), 0); + e3.getComponent(SpatialEdgeComponent.class).getGeometry(); e3.getComponent(CostListEdgeComponent.class).getMeanCost(); diff --git a/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java b/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java index fbf5d94..66622cf 100644 --- a/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java +++ b/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java @@ -30,7 +30,8 @@ import org.junit.Test; public class EdgeTest { - Edge e; + + private Edge e; @Before public void setUp() throws Exception { @@ -106,7 +107,7 @@ public void testSetToNode(){ @Test public void testSetCost(){ - e.setWeight(100);; + e.setWeight(100); assertEquals("Cost was not updated",100,e.getWeight(),0); } From ecf66e572a35e89c373c7d6ffd93f3711722d75d Mon Sep 17 00:00:00 2001 From: ericklt Date: Fri, 2 Mar 2018 09:02:57 -0300 Subject: [PATCH 15/16] More minor improvements --- .../org/insightlab/graphast/storage/OSMGraphStorage.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java b/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java index 0b75b74..350e474 100644 --- a/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java +++ b/core/src/main/java/org/insightlab/graphast/storage/OSMGraphStorage.java @@ -198,11 +198,10 @@ private boolean isValid(Map tags) { if (!tags.containsKey("highway")) return false; if (!allowedHighways.contains(tags.get("highway"))) return false; - if (tags.get("highway").equals("path")) { - if (!(tags.containsKey("motor_vehicle") && tags.get("motor_vehicle").equals("yes")) && - !(tags.containsKey("motorcar") && tags.get("motorcar").equals("yes"))) - return false; - } + if (tags.get("highway").equals("path") && + !(tags.containsKey("motor_vehicle") && "yes".equals(tags.get("motor_vehicle"))) && + !(tags.containsKey("motorcar") && "yes".equals(tags.get("motorcar")))) + return false; if (tags.containsKey("access")) { String accessValue = tags.get("access"); From fc4eb40b5c7b43e819803486c710ce3efa10363f Mon Sep 17 00:00:00 2001 From: ericklt Date: Sat, 3 Mar 2018 15:24:09 -0300 Subject: [PATCH 16/16] Added id to Edge, removed some of the Edge constructors to make things clearer and some minor changes --- .../org/insightlab/graphast/model/Edge.java | 36 +++++++++---------- .../org/insightlab/graphast/model/Graph.java | 13 ++++++- .../spatial_components/Geometry.java | 7 ++-- .../graphast/storage/KryoStorage.java | 5 +++ .../storage/RandomGraphGenerator.java | 3 +- .../graphast/components/ComponentTest.java | 6 ++-- .../graphast/model/DefaultGraphTest.java | 17 ++++----- .../insightlab/graphast/model/EdgeTest.java | 19 ++++++---- .../graphast/model/MMapGraphTest.java | 9 +++-- .../insightlab/graphast/model/NodeTest.java | 1 - .../query/shortestpath/DijkstraTest.java | 18 ++++++---- .../query/shortestpath/MMapDijkstraTest.java | 18 ++++++---- 12 files changed, 92 insertions(+), 60 deletions(-) diff --git a/core/src/main/java/org/insightlab/graphast/model/Edge.java b/core/src/main/java/org/insightlab/graphast/model/Edge.java index 33f84d1..d51b41e 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Edge.java +++ b/core/src/main/java/org/insightlab/graphast/model/Edge.java @@ -43,6 +43,7 @@ public class Edge extends GraphObject { private Map, EdgeComponent> edgeComponent = null; + private long id; private long fromNodeId; private long toNodeId; private double weight; @@ -51,6 +52,7 @@ public class Edge extends GraphObject { public Edge() { this.weight = 1; } + /** * Instantiates a new edge. * @@ -74,28 +76,12 @@ public Edge(long from, long to, double cost) { this.weight = cost; } - /** - * Instantiates a new edge. - * - * @param from the id from the outgoing node. - * @param to the id from the incoming node. - * @param bidirectional true, if the edge is bidirectional. false, otherwise. - */ - public Edge(long from, long to, boolean bidirectional) { - this(from, to, 1, bidirectional); + public long getId() { + return id; } - /** - * Instantiates a new edge. - * - * @param from the id from the outgoing node. - * @param to the id from the incoming node. - * @param cost the cost value of the edge. - * @param bidirectional true, if the edge is bidirectional. false, otherwise. - */ - public Edge(long from, long to, double cost, boolean bidirectional) { - this(from, to, cost); - this.bidirectional = bidirectional; + public void setId(long id) { + this.id = id; } /** @@ -152,6 +138,10 @@ public void setWeight(double weight) { this.weight = weight; } + public void setBidirectional(boolean bidirectional) { + this.bidirectional = bidirectional; + } + /** * Checks if the edge is bidirectional, e.g. the * edge points both in and outward its two nodes. @@ -162,6 +152,12 @@ public boolean isBidirectional() { return bidirectional; } + public void invert() { + long aux = this.fromNodeId; + this.fromNodeId = this.toNodeId; + this.toNodeId = aux; + } + /** * Gets the id from a node adjacent to this edge in the graph, give a node id. * The given id is compared to the value of the incoming node id from this edge. diff --git a/core/src/main/java/org/insightlab/graphast/model/Graph.java b/core/src/main/java/org/insightlab/graphast/model/Graph.java index 47fe994..ca7b98c 100644 --- a/core/src/main/java/org/insightlab/graphast/model/Graph.java +++ b/core/src/main/java/org/insightlab/graphast/model/Graph.java @@ -27,6 +27,7 @@ import java.util.Iterator; import java.util.Set; +import org.insightlab.graphast.exceptions.DuplicatedNodeException; import org.insightlab.graphast.model.components.GraphComponent; import org.insightlab.graphast.structure.DefaultGraphStructure; import org.insightlab.graphast.structure.GraphStructure; @@ -46,6 +47,8 @@ public class Graph extends GraphObject { */ private static final long serialVersionUID = -3661942047360629183L; + private long duplicatedNodesCounter = 0; + private GraphStructure structure; /** @@ -87,7 +90,15 @@ public void addNodes(long ...ids) { * @param n the new node to be added to the graph. */ public void addNode(Node n) { - structure.addNode(n); + try { + structure.addNode(n); + } catch (DuplicatedNodeException e) { + duplicatedNodesCounter++; + } + } + + public long getDuplicatedNodesCounter() { + return duplicatedNodesCounter; } /** diff --git a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java index 1a831cd..2e08a53 100644 --- a/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java +++ b/core/src/main/java/org/insightlab/graphast/model/components/spatial_components/Geometry.java @@ -18,9 +18,12 @@ public Geometry() { this.points = new ArrayList<>(); } + public Geometry(List points) { + this.points = points; + } + public Geometry(Point ...points) { - this(); - this.points.addAll(Arrays.asList(points)); + this(Arrays.asList(points)); } public void addPoint(Point p) { diff --git a/core/src/main/java/org/insightlab/graphast/storage/KryoStorage.java b/core/src/main/java/org/insightlab/graphast/storage/KryoStorage.java index 454f12a..ad5970e 100644 --- a/core/src/main/java/org/insightlab/graphast/storage/KryoStorage.java +++ b/core/src/main/java/org/insightlab/graphast/storage/KryoStorage.java @@ -42,6 +42,7 @@ public static GraphStorage getInstance() { @Override public Graph load(String path, GraphStructure structure) throws FileNotFoundException { + long startTime = System.currentTimeMillis(); Graph g = new Graph(structure); String directory = StorageUtils.ensureDirectory(path); @@ -75,6 +76,10 @@ public Graph load(String path, GraphStructure structure) throws FileNotFoundExce e.printStackTrace(); } + long totalTime = System.currentTimeMillis() - startTime; + + System.out.println("Time to load using kryo: " + (totalTime/1000.) + " s"); + return g; } diff --git a/core/src/main/java/org/insightlab/graphast/storage/RandomGraphGenerator.java b/core/src/main/java/org/insightlab/graphast/storage/RandomGraphGenerator.java index 5948717..128c673 100644 --- a/core/src/main/java/org/insightlab/graphast/storage/RandomGraphGenerator.java +++ b/core/src/main/java/org/insightlab/graphast/storage/RandomGraphGenerator.java @@ -67,7 +67,8 @@ public Graph generateRandomMMapGraph(String graphName, int size, float dens) { if (rand.nextFloat() < dens) { int randomCost = Math.abs(rand.nextInt(50)) + 1; - Edge e = new Edge(i, j, randomCost, rand.nextBoolean()); + Edge e = new Edge(i, j, randomCost); + e.setBidirectional(rand.nextBoolean()); graph.addEdge(e); } diff --git a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java index cbea0e9..5963691 100644 --- a/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java +++ b/core/src/test/java/org/insightlab/graphast/components/ComponentTest.java @@ -42,7 +42,8 @@ public void setUp() throws Exception { n3 = new Node(3); n3.addComponent(new SpatialNodeComponent(15, 1)); - e0 = new Edge(1, 2, true); + e0 = new Edge(1, 2); + e0.setBidirectional(true); e0.addComponent(new SpatialEdgeComponent(new Geometry(new Point(1, 2)))); e0.addComponent(new CostListEdgeComponent(2., 3., 1., 5., 6., 3., 1.)); @@ -54,7 +55,8 @@ public void setUp() throws Exception { e2.addComponent(new SpatialEdgeComponent(new Geometry(new Point(1, 3)))); e2.addComponent(new CostListEdgeComponent(3., 4., 2., 6., 6., 4., 3.)); - e3 = new Edge(3, 0, true); + e3 = new Edge(3, 0); + e3.setBidirectional(true); e3.addComponent(new SpatialEdgeComponent(new Geometry())); e3.addComponent(new CostListEdgeComponent(2., 1., 2., 4., 8., 4., 2.)); diff --git a/core/src/test/java/org/insightlab/graphast/model/DefaultGraphTest.java b/core/src/test/java/org/insightlab/graphast/model/DefaultGraphTest.java index 00e8fda..0745bcd 100755 --- a/core/src/test/java/org/insightlab/graphast/model/DefaultGraphTest.java +++ b/core/src/test/java/org/insightlab/graphast/model/DefaultGraphTest.java @@ -30,7 +30,6 @@ import java.util.Arrays; import java.util.Iterator; -import org.insightlab.graphast.exceptions.DuplicatedNodeException; import org.insightlab.graphast.exceptions.NodeNotFoundException; import org.insightlab.graphast.model.Edge; import org.insightlab.graphast.model.Graph; @@ -54,13 +53,16 @@ public void setUp() throws Exception { n2 = new Node(2); n3 = new Node(3); n4 = new Node(4); - e0 = new Edge(1, 4, true); + e0 = new Edge(1, 4); + e0.setBidirectional(true); e1 = new Edge(2, 4); e2 = new Edge(0, 1); - e3 = new Edge(3, 1, true); + e3 = new Edge(3, 1); + e3.setBidirectional(true); e4 = new Edge(2, 3); e5 = new Edge(4, 3); - e6 = new Edge(3, 0, true); + e6 = new Edge(3, 0); + e6.setBidirectional(true); } @Test @@ -177,13 +179,6 @@ public void testContainsNode(){ assertEquals("Contains Test n3",g.containsNode(n3.getId()),false); } - @Test(expected = DuplicatedNodeException.class) - public void testAddNodeException(){ - g.addNode(n0); - g.addNode(n1); - g.addNode(n0); - } - @Test(expected = NodeNotFoundException.class) public void testAddEdgeException(){ g.addNode(n0); diff --git a/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java b/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java index 66622cf..c378cc2 100644 --- a/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java +++ b/core/src/test/java/org/insightlab/graphast/model/EdgeTest.java @@ -35,7 +35,8 @@ public class EdgeTest { @Before public void setUp() throws Exception { - e = new Edge(0, 1, 3, true); + e = new Edge(0, 1, 3); + e.setBidirectional(true); } @Test @@ -58,7 +59,8 @@ public void testConstructor2(){ @Test public void testConstructor3(){ - e = new Edge(0, 1, true); + e = new Edge(0, 1); + e.setBidirectional(true); assertEquals(0l, e.getFromNodeId()); assertEquals(1l, e.getToNodeId()); assertEquals(1l, e.getWeight(),0); @@ -119,16 +121,19 @@ public void testGetAdjacent(){ @Test public void testEquals(){ - Edge e1 = new Edge(0,1,3,true); - Edge e2 = new Edge(0,2,3,true); - Edge e3 = new Edge(3,1,3,true); - Edge e4 = new Edge(0,1,4,true); + Edge e1 = new Edge(0,1,3); + e1.setBidirectional(true); + Edge e2 = new Edge(0,2,3); + e2.setBidirectional(true); + Edge e3 = new Edge(3,1,3); + e3.setBidirectional(true); + Edge e4 = new Edge(0,1,4); + e4.setBidirectional(true); // Edge e5 = new Edge(0,1,3,false); // assertEquals(false, e.equals(new Long(5))); assertEquals(true, e.equals(e1)); - assertEquals(false, e.equals(e2)); assertEquals(false, e.equals(e3)); assertEquals(false, e.equals(e4)); diff --git a/core/src/test/java/org/insightlab/graphast/model/MMapGraphTest.java b/core/src/test/java/org/insightlab/graphast/model/MMapGraphTest.java index 1642c55..2f69c8f 100644 --- a/core/src/test/java/org/insightlab/graphast/model/MMapGraphTest.java +++ b/core/src/test/java/org/insightlab/graphast/model/MMapGraphTest.java @@ -56,13 +56,16 @@ public static void setUpBeforeClass() throws IOException { n2 = new Node(2); n3 = new Node(3); n4 = new Node(4); - e0 = new Edge(1, 4, true); + e0 = new Edge(1, 4); + e0.setBidirectional(true); e1 = new Edge(2, 4); e2 = new Edge(0, 1); - e3 = new Edge(3, 1, true); + e3 = new Edge(3, 1); + e3.setBidirectional(true); e4 = new Edge(2, 3); e5 = new Edge(4, 3); - e6 = new Edge(3, 0, true); + e6 = new Edge(3, 0); + e6.setBidirectional(true); g.addNodes(n0, n1, n2, n3, n4); g.addEdges(e0, e2, e4, e1, e6, e5, e3); diff --git a/core/src/test/java/org/insightlab/graphast/model/NodeTest.java b/core/src/test/java/org/insightlab/graphast/model/NodeTest.java index a4f6a2d..4adc8c3 100644 --- a/core/src/test/java/org/insightlab/graphast/model/NodeTest.java +++ b/core/src/test/java/org/insightlab/graphast/model/NodeTest.java @@ -55,7 +55,6 @@ public void testEquals() { assertEquals(true, n.equals(n1)); assertEquals(false, n.equals(n2)); - assertEquals(false, n.equals(new Long(0))); } } diff --git a/core/src/test/java/org/insightlab/graphast/query/shortestpath/DijkstraTest.java b/core/src/test/java/org/insightlab/graphast/query/shortestpath/DijkstraTest.java index b905a62..c5514b4 100644 --- a/core/src/test/java/org/insightlab/graphast/query/shortestpath/DijkstraTest.java +++ b/core/src/test/java/org/insightlab/graphast/query/shortestpath/DijkstraTest.java @@ -49,12 +49,18 @@ public void setUp() throws Exception { Node n3 = new Node(3); Node n4 = new Node(4); Node n5 = new Node(5); - Edge e0 = new Edge(0, 1, 3, true); - Edge e1 = new Edge(1, 2, 3, true); - Edge e2 = new Edge(2, 3, 3, true); - Edge e3 = new Edge(0, 4, 5, true); - Edge e4 = new Edge(4, 3, 5, true); - Edge e5 = new Edge(0, 5, 15, true); + Edge e0 = new Edge(0, 1, 3); + e0.setBidirectional(true); + Edge e1 = new Edge(1, 2, 3); + e1.setBidirectional(true); + Edge e2 = new Edge(2, 3, 3); + e2.setBidirectional(true); + Edge e3 = new Edge(0, 4, 5); + e3.setBidirectional(true); + Edge e4 = new Edge(4, 3, 5); + e4.setBidirectional(true); + Edge e5 = new Edge(0, 5, 15); + e5.setBidirectional(true); g.addNodes(n0, n1, n2, n3, n4, n5); g.addEdges(e0, e1, e2, e3, e4, e5); } diff --git a/core/src/test/java/org/insightlab/graphast/query/shortestpath/MMapDijkstraTest.java b/core/src/test/java/org/insightlab/graphast/query/shortestpath/MMapDijkstraTest.java index 5842847..cc9214c 100644 --- a/core/src/test/java/org/insightlab/graphast/query/shortestpath/MMapDijkstraTest.java +++ b/core/src/test/java/org/insightlab/graphast/query/shortestpath/MMapDijkstraTest.java @@ -52,12 +52,18 @@ public static void setUpBeforeClass() throws Exception { Node n3 = new Node(3); Node n4 = new Node(4); Node n5 = new Node(5); - Edge e0 = new Edge(0, 1, 3, true); - Edge e1 = new Edge(1, 2, 3, true); - Edge e2 = new Edge(2, 3, 3, true); - Edge e3 = new Edge(0, 4, 5, true); - Edge e4 = new Edge(4, 3, 5, true); - Edge e5 = new Edge(0, 5, 15, true); + Edge e0 = new Edge(0, 1, 3); + e0.setBidirectional(true); + Edge e1 = new Edge(1, 2, 3); + e1.setBidirectional(true); + Edge e2 = new Edge(2, 3, 3); + e2.setBidirectional(true); + Edge e3 = new Edge(0, 4, 5); + e3.setBidirectional(true); + Edge e4 = new Edge(4, 3, 5); + e4.setBidirectional(true); + Edge e5 = new Edge(0, 5, 15); + e5.setBidirectional(true); g.addNodes(n0, n1, n2, n3, n4, n5); g.addEdges(e0, e1, e2, e3, e4, e5); }