Search code examples
javamysqljung

how to add links or update existing links property to a JUNG graph


I have a result set coming from a mysql database and I am trying to build a JUNG graph using these values. I already have instantiated my empty graph as:

Graph<Node, Edge> g = new SparseMultigraph<>();

then I have added nodes (586). I am now in the process of adding links and now things get more complicated. The structure of my custom Edge is very simple, it just has a "time" property like:

Multiset<Timestamp> time;

The result set for links contains 3273684 entries in the form:

id  time                    sender  receiver
12  2014-03-20 09:26:04.000 2       99

Now, what I want to do is to create a link from node with id 2 and node with id 99 if the link does not exist, or to just add the timestamp to the already existing link. What I do is:

while (resultSet.next()) {
    // retrieve sender
    Node sender = findNode(resultSet.getInt("sender"), g);
    // retrieve receiver
    Node receiver = findNode(resultSet.getInt("receiver"), g);
    // if they are already linked
    if(g.isPredecessor(sender, receiver)){
        // just add the new timestamp to the existing link
        Collection<Edge> outEdges = g.getOutEdges(sender);
        // find the right edge
        for(Edge e:outEdges){
            // if this edge is connected to receiver
            if(g.getDest(e).equals(receiver)){
                // add the new timestamp to this edge
                e.setTime(resultSet.getTimestamp("time"));
            }
        }
    } else { // else a new link is added
        Information e = new Information();
        e.setId(resultSet.getInt("id"));
        e.setTime(resultSet.getTimestamp("time"));
        g.addEdge(e, sender, receiver, EdgeType.DIRECTED);
    }
}

My problem is that this is really slow, and I do not understand if it is normal, since the result set is quite big, or if I am missing a clearer/faster way to implement what I need.

For the sake of clarity, my findNode() method is like this:

private static Node findNode(int aInt, Graph<Node, Edge>g) {
    for(Node n:g.getVertices()){
        if(n.getId()== aInt){
            return n;
        }
    }
    return null;
}

Solution

  • This is slow for two reasons:

    (1) You don't have an efficient way to look up a node given an ID. For a graph of this size I'd recommend building a Map as you populate the graph, and using that map to implement findNode().

    (2) Once you have your two nodes and you want to get the edge that connects them (if any), just use Graph.findEdge().

    (1) is by far the biggest reason that your code is slow. (2) will not help as much, but it will also make your code easier to read and more elegant.