Coverage Report - edu.uci.ics.jung.graph.DirectedSparseGraph
 
Classes in this File Line Coverage Branch Coverage Complexity
DirectedSparseGraph
32%
34/104
20%
11/54
2.567
DirectedSparseGraph$1
100%
2/2
N/A
2.567
 
 1  
 /*
 2  
  * Created on Mar 26, 2007
 3  
  *
 4  
  * Copyright (c) 2007, the JUNG Project and the Regents of the University 
 5  
  * of California
 6  
  * All rights reserved.
 7  
  *
 8  
  * This software is open-source under the BSD license; see either
 9  
  * "license.txt" or
 10  
  * http://jung.sourceforge.net/license.txt for a description.
 11  
  */
 12  
 package edu.uci.ics.jung.graph;
 13  
 
 14  
 import java.util.ArrayList;
 15  
 import java.util.Collection;
 16  
 import java.util.Collections;
 17  
 import java.util.HashMap;
 18  
 import java.util.HashSet;
 19  
 import java.util.Map;
 20  
 
 21  
 import org.apache.commons.collections15.Factory;
 22  
 
 23  
 import edu.uci.ics.jung.graph.util.EdgeType;
 24  
 import edu.uci.ics.jung.graph.util.Pair;
 25  
 
 26  
 /**
 27  
  * An implementation of <code>DirectedGraph</code> suitable for sparse graphs.
 28  
  */
 29  
 @SuppressWarnings("serial")
 30  
 public class DirectedSparseGraph<V,E> extends AbstractTypedGraph<V, E> implements
 31  
         DirectedGraph<V, E>
 32  
 {
 33  
     /**
 34  
      * Returns a {@code Factory} that creates an instance of this graph type.
 35  
      * @param <V> the vertex type for the graph factory
 36  
      * @param <E> the edge type for the graph factory
 37  
      */
 38  
    public static final <V,E> Factory<DirectedGraph<V,E>> getFactory() {
 39  2
         return new Factory<DirectedGraph<V,E>> () {
 40  6
             public DirectedGraph<V,E> create() {
 41  4
                 return new DirectedSparseGraph<V,E>();
 42  
             }
 43  
         };
 44  
     }
 45  
 
 46  
     protected Map<V, Pair<Map<V,E>>> vertices;  // Map of vertices to Pair of adjacency maps {incoming, outgoing} 
 47  
                                                 // of neighboring vertices to incident edges
 48  
     protected Map<E, Pair<V>> edges;            // Map of edges to incident vertex pairs
 49  
 
 50  
     /**
 51  
      * Creates an instance.
 52  
      */
 53  
     public DirectedSparseGraph() 
 54  
     {
 55  4
             super(EdgeType.DIRECTED);
 56  4
         vertices = new HashMap<V, Pair<Map<V,E>>>();
 57  4
         edges = new HashMap<E, Pair<V>>();
 58  4
     }
 59  
     
 60  
     @Override
 61  
     public boolean addEdge(E edge, Pair<? extends V> endpoints, EdgeType edgeType)
 62  
     {
 63  8
             this.validateEdgeType(edgeType);
 64  8
         Pair<V> new_endpoints = getValidatedEndpoints(edge, endpoints);
 65  6
         if (new_endpoints == null)
 66  4
             return false;
 67  
         
 68  2
         V source = new_endpoints.getFirst();
 69  2
         V dest = new_endpoints.getSecond();
 70  
         
 71  2
         if (findEdge(source, dest) != null)
 72  0
             return false;
 73  
         
 74  2
         edges.put(edge, new_endpoints);
 75  
 
 76  2
         if (!vertices.containsKey(source))
 77  2
             this.addVertex(source);
 78  
         
 79  2
         if (!vertices.containsKey(dest))
 80  2
             this.addVertex(dest);
 81  
         
 82  
         // map source of this edge to <dest, edge> and vice versa
 83  2
         vertices.get(source).getSecond().put(dest, edge);
 84  2
         vertices.get(dest).getFirst().put(source, edge);
 85  
 
 86  2
         return true;
 87  
     }
 88  
 
 89  
     @Override
 90  
     public E findEdge(V v1, V v2)
 91  
     {
 92  2
         if (!containsVertex(v1) || !containsVertex(v2))
 93  2
             return null;
 94  0
         return vertices.get(v1).getSecond().get(v2);
 95  
     }
 96  
 
 97  
     @Override
 98  
     public Collection<E> findEdgeSet(V v1, V v2)
 99  
     {
 100  0
         if (!containsVertex(v1) || !containsVertex(v2))
 101  0
             return null;
 102  0
         ArrayList<E> edge_collection = new ArrayList<E>(1);
 103  0
         E e = findEdge(v1, v2);
 104  0
         if (e == null)
 105  0
             return edge_collection;
 106  0
         edge_collection.add(e);
 107  0
         return edge_collection;
 108  
     }
 109  
     
 110  
     protected Collection<E> getIncoming_internal(V vertex)
 111  
     {
 112  0
         return vertices.get(vertex).getFirst().values();
 113  
     }
 114  
     
 115  
     protected Collection<E> getOutgoing_internal(V vertex)
 116  
     {
 117  0
         return vertices.get(vertex).getSecond().values();
 118  
     }
 119  
     
 120  
     protected Collection<V> getPreds_internal(V vertex)
 121  
     {
 122  0
         return vertices.get(vertex).getFirst().keySet();
 123  
     }
 124  
     
 125  
     protected Collection<V> getSuccs_internal(V vertex)
 126  
     {
 127  0
         return vertices.get(vertex).getSecond().keySet();
 128  
     }
 129  
     
 130  
     public Collection<E> getInEdges(V vertex)
 131  
     {
 132  0
         if (!containsVertex(vertex))
 133  0
             return null;
 134  0
         return Collections.unmodifiableCollection(getIncoming_internal(vertex));
 135  
     }
 136  
 
 137  
     public Collection<E> getOutEdges(V vertex)
 138  
     {
 139  0
         if (!containsVertex(vertex))
 140  0
             return null;
 141  0
         return Collections.unmodifiableCollection(getOutgoing_internal(vertex));
 142  
     }
 143  
 
 144  
     public Collection<V> getPredecessors(V vertex)
 145  
     {
 146  0
         if (!containsVertex(vertex))
 147  0
             return null;
 148  0
         return Collections.unmodifiableCollection(getPreds_internal(vertex));
 149  
     }
 150  
 
 151  
     public Collection<V> getSuccessors(V vertex)
 152  
     {
 153  0
         if (!containsVertex(vertex))
 154  0
             return null;
 155  0
         return Collections.unmodifiableCollection(getSuccs_internal(vertex));
 156  
     }
 157  
 
 158  
     public Pair<V> getEndpoints(E edge)
 159  
     {
 160  6
         if (!containsEdge(edge))
 161  0
             return null;
 162  6
         return edges.get(edge);
 163  
     }
 164  
 
 165  
     public V getSource(E directed_edge)
 166  
     {
 167  0
         if (!containsEdge(directed_edge))
 168  0
             return null;
 169  0
         return edges.get(directed_edge).getFirst();
 170  
     }
 171  
 
 172  
     public V getDest(E directed_edge)
 173  
     {
 174  0
         if (!containsEdge(directed_edge))
 175  0
             return null;
 176  0
         return edges.get(directed_edge).getSecond();
 177  
     }
 178  
 
 179  
     public boolean isSource(V vertex, E edge)
 180  
     {
 181  0
         if (!containsEdge(edge) || !containsVertex(vertex))
 182  0
             return false;
 183  0
         return vertex.equals(this.getEndpoints(edge).getFirst());
 184  
     }
 185  
 
 186  
     public boolean isDest(V vertex, E edge)
 187  
     {
 188  0
         if (!containsEdge(edge) || !containsVertex(vertex))
 189  0
             return false;
 190  0
         return vertex.equals(this.getEndpoints(edge).getSecond());
 191  
     }
 192  
 
 193  
     public Collection<E> getEdges()
 194  
     {
 195  0
         return Collections.unmodifiableCollection(edges.keySet());
 196  
     }
 197  
 
 198  
     public Collection<V> getVertices()
 199  
     {
 200  0
         return Collections.unmodifiableCollection(vertices.keySet());
 201  
     }
 202  
 
 203  
     public boolean containsVertex(V vertex)
 204  
     {
 205  14
         return vertices.containsKey(vertex);
 206  
     }
 207  
 
 208  
     public boolean containsEdge(E edge)
 209  
     {
 210  18
         return edges.containsKey(edge);
 211  
     }
 212  
 
 213  
     public int getEdgeCount()
 214  
     {
 215  6
         return edges.size();
 216  
     }
 217  
 
 218  
     public int getVertexCount()
 219  
     {
 220  10
         return vertices.size();
 221  
     }
 222  
 
 223  
     public Collection<V> getNeighbors(V vertex)
 224  
     {
 225  0
         if (!containsVertex(vertex))
 226  0
             return null;
 227  
         
 228  0
         Collection<V> neighbors = new HashSet<V>();
 229  0
         neighbors.addAll(getPreds_internal(vertex));
 230  0
         neighbors.addAll(getSuccs_internal(vertex));
 231  0
         return Collections.unmodifiableCollection(neighbors);
 232  
     }
 233  
 
 234  
     public Collection<E> getIncidentEdges(V vertex)
 235  
     {
 236  0
         if (!containsVertex(vertex))
 237  0
             return null;
 238  
         
 239  0
         Collection<E> incident_edges = new HashSet<E>();
 240  0
         incident_edges.addAll(getIncoming_internal(vertex));
 241  0
         incident_edges.addAll(getOutgoing_internal(vertex));
 242  0
         return Collections.unmodifiableCollection(incident_edges);
 243  
     }
 244  
 
 245  
     public boolean addVertex(V vertex)
 246  
     {
 247  10
         if(vertex == null) {
 248  2
             throw new IllegalArgumentException("vertex may not be null");
 249  
         }
 250  8
         if (!containsVertex(vertex)) {
 251  6
             vertices.put(vertex, new Pair<Map<V,E>>(new HashMap<V,E>(), new HashMap<V,E>()));
 252  6
             return true;
 253  
         } else {
 254  2
             return false;
 255  
         }
 256  
     }
 257  
 
 258  
     public boolean removeVertex(V vertex) {
 259  0
         if (!containsVertex(vertex))
 260  0
             return false;
 261  
         
 262  
         // copy to avoid concurrent modification in removeEdge
 263  0
         ArrayList<E> incident = new ArrayList<E>(getIncoming_internal(vertex));
 264  0
         incident.addAll(getOutgoing_internal(vertex));
 265  
         
 266  0
         for (E edge : incident)
 267  0
             removeEdge(edge);
 268  
         
 269  0
         vertices.remove(vertex);
 270  
         
 271  0
         return true;
 272  
     }
 273  
     
 274  
     public boolean removeEdge(E edge) {
 275  0
         if (!containsEdge(edge))
 276  0
             return false;
 277  
         
 278  0
         Pair<V> endpoints = this.getEndpoints(edge);
 279  0
         V source = endpoints.getFirst();
 280  0
         V dest = endpoints.getSecond();
 281  
         
 282  
         // remove vertices from each others' adjacency maps
 283  0
         vertices.get(source).getSecond().remove(dest);
 284  0
         vertices.get(dest).getFirst().remove(source);
 285  
         
 286  0
         edges.remove(edge);
 287  0
         return true;
 288  
     }
 289  
 }