Squashed commit of the following:

commit 2c41cec9145674b3bd48556c42d329c8ed1ae614
Merge: faea0fb e96a4eb
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jan 9 21:28:52 2014 -0800

    Merge branch 'dbperf2' into mergetrial

    Conflicts:
    	src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
    	src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java

commit e96a4ebff6f4a67693da61fcbec9cc18a940839e
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jan 9 17:47:02 2014 -0800

    Modified API call counter.

commit cd0dceecc7cc6df51c7e0b85bff1a72cae5f15cc
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jan 9 15:41:57 2014 -0800

    Added counter.

commit 93baeb6bf14124520dfcf4efe769018c7c80a0ce
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jan 9 15:13:13 2014 -0800

    Added counter of DB access.

commit a460355ed57a67b69109855f57e26ef830754bfa
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jan 9 13:51:35 2014 -0800

    Fixed bugs.

commit 19493d2d769568a798c2619d4fc70fa0d43a44ac
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jan 9 12:15:11 2014 -0800

    Fixed measurment point

commit ffc64a6f4302dd955acc47b14c12fedd10c90ffc
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jan 9 11:54:08 2014 -0800

    Modified measuring points.

commit 819e010f6131e5d00a689ea9848d38b4a554e1bd
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jan 9 11:05:20 2014 -0800

    Interted measurement code.

commit 887d7c0884b84bc0b2c0e2cfdf772468161959fc
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jan 9 01:01:27 2014 -0800

    Fixed a bug that ports are not read to memory.

commit f490f5a0677ceedcc0ef5b9e43383464b67b11be
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Thu Jan 9 00:20:28 2014 -0800

    Fixed a bug that Link addition failed.

commit 8d12e8918a1fa80947d72d312f12cf132ca13335
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Wed Jan 8 21:53:45 2014 -0800

    Merged Pankaj's refactoring code.

commit d3e8ad2b397cc5898a8218b6156721ab5c7df7bf
Author: Naoki Shiota <n-shiota@onlab.us>
Date:   Tue Jan 7 11:36:48 2014 -0800

    Added periodic execution of readFromDatabase
diff --git a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
index 20c85ab..d1f2af4 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
@@ -6,10 +6,14 @@
 import java.util.TreeMap;
 
 import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.IDBOperation;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
 
 import org.openflow.util.HexString;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.tinkerpop.blueprints.Direction;
 import com.tinkerpop.blueprints.Vertex;
@@ -24,36 +28,37 @@
      * paths.
      */
     class Link {
-	public Node me;			// The node this link originates from
-	public Node neighbor;		// The neighbor node on the other side
-	public int myPort;		// Local port ID for the link
-	public int neighborPort;	// Neighbor port ID for the link
+    	public Node me;                        // The node this link originates from
+        public Node neighbor;                // The neighbor node on the other side
+        public int myPort;                // Local port ID for the link
+        public int neighborPort;        // Neighbor port ID for the link
 
-	/**
-	 * Link constructor.
-	 *
-	 * @param me the node this link originates from.
-	 * @param the neighbor node on the other side of the link.
-	 * @param myPort local port ID for the link.
-	 * @param neighborPort neighbor port ID for the link.
-	 */
-	public Link(Node me, Node neighbor, int myPort, int neighborPort) {
-	    this.me = me;
-	    this.neighbor = neighbor;
-	    this.myPort = myPort;
-	    this.neighborPort = neighborPort;
-	}
+        /**
+         * Link constructor.
+         *
+         * @param me the node this link originates from.
+         * @param the neighbor node on the other side of the link.
+         * @param myPort local port ID for the link.
+         * @param neighborPort neighbor port ID for the link.
+         */
+        public Link(Node me, Node neighbor, int myPort, int neighborPort) {
+        	this.me = me;
+        	this.neighbor = neighbor;
+        	this.myPort = myPort;
+        	this.neighborPort = neighborPort;
+        }
     };
 
     public long nodeId;				// The node ID
+    // TODO Change type of PortNumber to Short
     public TreeMap<Integer, Link> links;	// The links from this node:
-						//     (src PortID -> Link)
+						//     (src PortNumber -> Link)
     private TreeMap<Integer, Link> reverseLinksMap; // The links to this node:
-						//     (dst PortID -> Link)
+						//     (dst PortNumber -> Link)
     private TreeMap<Integer, Integer> portsMap;	// The ports on this node:
-						//     (PortID -> PortID)
+						//     (PortNumber -> PortNumber)
 						// TODO: In the future will be:
-						//     (PortID -> Port)
+						//     (PortNumber -> Port)
 
     /**
      * Node constructor.
@@ -187,6 +192,11 @@
  * A class for storing topology information.
  */
 public class Topology {
+    private final static Logger log = LoggerFactory.getLogger(Topology.class);
+    
+    // flag to use optimized readFromDatabase() method.
+    private static final boolean enableOptimizedRead = false;
+    
     private Map<Long, Node> nodesMap;	// The dpid->Node mapping
 
     /**
@@ -383,131 +393,171 @@
      * @param dbHandler the Graph Database handler to use.
      */
     public void readFromDatabase(GraphDBOperation dbHandler) {
-	//
-	// Fetch the relevant info from the Switch and Port vertices
-	// from the Titan Graph.
-	//
-    	nodesMap = new TreeMap<Long,Node>();
-	
-	Iterable<ISwitchObject> activeSwitches = dbHandler.getActiveSwitches();
-	for (ISwitchObject switchObj : activeSwitches) {
-	    Vertex nodeVertex = switchObj.asVertex();
-	    //
-	    // The Switch info
-	    //
-	    String nodeDpid = nodeVertex.getProperty("dpid").toString();
-	    long nodeId = HexString.toLong(nodeDpid);
-	    Node me = nodesMap.get(nodeId);
-	    if (me == null)
-		me = addNode(nodeId);
+    	if (enableOptimizedRead) {
+    		readFromDatabaseBodyOptimized(dbHandler);
+    	} else {
+    		readFromDatabaseBody(dbHandler);
+    	}
 
-	    //
-	    // The local Port info
-	    //
-	    for (Vertex myPortVertex : nodeVertex.getVertices(Direction.OUT, "on")) {
-		// Ignore inactive ports
-		if (! myPortVertex.getProperty("state").toString().equals("ACTIVE"))
-		    continue;
-
-		int myPort = 0;
-		Object obj = myPortVertex.getProperty("number");
-		if (obj instanceof Short) {
-		    myPort = (Short)obj;
-		} else if (obj instanceof Integer) {
-		    myPort = (Integer)obj;
-		}
-		me.addPort(myPort);
-
-		//
-		// The neighbor Port info
-		//
-		for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
-		    // Ignore inactive ports
-		    if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE"))
-			continue;
-
-		    int neighborPort = 0;
-		    obj = neighborPortVertex.getProperty("number");
-		    if (obj instanceof Short) {
-			neighborPort = (Short)obj;
-		    } else if (obj instanceof Integer) {
-			neighborPort = (Integer)obj;
-		    }
-		    //
-		    // The neighbor Switch info
-		    //
-		    for (Vertex neighborVertex : neighborPortVertex.getVertices(Direction.IN, "on")) {
-			// Ignore inactive switches
-			String state = neighborVertex.getProperty("state").toString();
-			if (! state.equals(SwitchState.ACTIVE.toString()))
-			    continue;
-
-			String neighborDpid = neighborVertex.getProperty("dpid").toString();
-			long neighborId = HexString.toLong(neighborDpid);
-			Node neighbor = nodesMap.get(neighborId);
-			if (neighbor == null)
-			    neighbor = addNode(neighborId);
-			neighbor.addPort(neighborPort);
-			me.addLink(myPort, neighbor, neighborPort);
-		    }
-		}
-	    }
-	}
-	dbHandler.commit();
     }
     
-    // TODO Merge into loops in readFromDatabase() can reduce execution time.
-    /**
-     * Check given two topology are identical or not.
-     * @param topo1
-     * @param topo2
-     * @return true if identical
-     */
-    private boolean compareTopology(Map<Long,Node> topo1, Map<Long,Node> topo2) {
-    	if (topo1.size() != topo2.size()) {
-    		return false;
+    private void readFromDatabaseBody(GraphDBOperation dbHandler) {
+    	//
+    	// Fetch the relevant info from the Switch and Port vertices
+    	// from the Titan Graph.
+    	//
+
+    	nodesMap.clear();
+    	Iterable<ISwitchObject> activeSwitches = dbHandler.getActiveSwitches();
+    	for (ISwitchObject switchObj : activeSwitches) {
+    	    Vertex nodeVertex = switchObj.asVertex();
+    	    //
+    	    // The Switch info
+    	    //
+    	    String nodeDpid = nodeVertex.getProperty("dpid").toString();
+    	    long nodeId = HexString.toLong(nodeDpid);
+    	    Node me = nodesMap.get(nodeId);
+    	    if (me == null)
+    		me = addNode(nodeId);
+
+    	    //
+    	    // The local Port info
+    	    //
+    	    for (Vertex myPortVertex : nodeVertex.getVertices(Direction.OUT, "on")) {
+    		// Ignore inactive ports
+    		if (! myPortVertex.getProperty("state").toString().equals("ACTIVE"))
+    		    continue;
+
+    		int myPort = 0;
+    		Object obj = myPortVertex.getProperty("number");
+    		if (obj instanceof Short) {
+    		    myPort = (Short)obj;
+    		} else if (obj instanceof Integer) {
+    		    myPort = (Integer)obj;
+    		}
+    		me.addPort(myPort);
+
+    		for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
+    		    // Ignore inactive ports
+    		    if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE")) {
+    		    	continue;
+    		    }
+
+    		    int neighborPort = 0;
+    		    obj = neighborPortVertex.getProperty("number");
+    		    if (obj instanceof Short) {
+    			neighborPort = (Short)obj;
+    		    } else if (obj instanceof Integer) {
+    			neighborPort = (Integer)obj;
+    		    }
+    		    //
+    		    // The neighbor Switch info
+    		    //
+    		    for (Vertex neighborVertex : neighborPortVertex.getVertices(Direction.IN, "on")) {
+    			// Ignore inactive switches
+    			String state = neighborVertex.getProperty("state").toString();
+    			if (! state.equals(SwitchState.ACTIVE.toString()))
+    			    continue;
+
+    			String neighborDpid = neighborVertex.getProperty("dpid").toString();
+    			long neighborId = HexString.toLong(neighborDpid);
+    			Node neighbor = nodesMap.get(neighborId);
+    			if (neighbor == null)
+    			    neighbor = addNode(neighborId);
+    			neighbor.addPort(neighborPort);
+    			me.addLink(myPort, neighbor, neighborPort);
+    		    }
+    		}
+    	    }
     	}
-    	
-    	for (Map.Entry<Long,Node> nodeEntry : topo1.entrySet()) {
-    		Long dpid = nodeEntry.getKey();
-    		if (! topo2.containsKey(dpid)) {
-    			return false;
-    		}
-    		
-    		Node n1 = nodeEntry.getValue();
-    		Node n2 = topo2.get(dpid);
-    		
-    		// check port identity
-    		if (n1.ports().size() != n2.ports().size()) {
-    			return false;
-    		}
-    		for (Integer port : n1.ports().keySet()) {
-    			if (! n2.ports().containsKey(port)) {
-    				return false;
-    			}
-    		}
-    		
-    		// check link identity
-    		if (n1.links.size() != n2.links.size()) {
-    			return false;
-    		}
-    		for (Map.Entry<Integer, Node.Link> linkEntry : n1.links.entrySet()) {
-    			Integer p1 = linkEntry.getKey();
-    			Node.Link l1 = linkEntry.getValue();
-    			
-    			if (! n2.links.containsKey(p1)) {
-    				return false;
-    			}
-    			Node.Link l2 = n2.links.get(p1);
-    			
-    		   	// Supposition: Link's "me" and "neighbor" is properly set.
-    			if (l1.myPort != l2.myPort ||
-    				l1.neighborPort != l2.neighborPort) {
-    				return false;
-    			}
-    		}
-    	}
-    	return true;
+    	dbHandler.commit();
+    }
+    
+    private void readFromDatabaseBodyOptimized(GraphDBOperation dbHandler) {
+	    nodesMap.clear();
+		    
+		// Load all switches into Map
+		Iterable<ISwitchObject> switches = dbHandler.getAllSwitches();
+		for (ISwitchObject switchObj : switches) {
+		        // Ignore inactive ports
+		    if (!switchObj.getState().equals(SwitchState.ACTIVE.toString())) {
+	            continue;
+		    }
+		    Vertex nodeVertex = switchObj.asVertex();
+		    //
+		    // The Switch info
+		    //
+		    String nodeDpid = nodeVertex.getProperty("dpid").toString();
+		    long nodeId = HexString.toLong(nodeDpid);
+		    addNode(nodeId);
+		}
+		
+		//
+		// Get All Ports
+		//
+		Iterable<IPortObject> ports = dbHandler.getAllPorts(); //TODO: Add to DB operations
+		for (IPortObject myPortObj : ports) {
+		    Vertex myPortVertex = myPortObj.asVertex();
+		    
+		    // Ignore inactive ports
+		    if (! myPortVertex.getProperty("state").toString().equals("ACTIVE")) {
+	            continue;
+		    }
+		    
+		    short myPort = 0;
+		    String idStr = myPortObj.getPortId();
+		    String[] splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
+		    if (splitter.length != 2) {
+	            log.error("Invalid port_id : {}", idStr);
+	            continue;
+		    }
+		    String myDpid = splitter[0];
+		    myPort = Short.parseShort(splitter[1]);
+		    long myId = HexString.toLong(myDpid);
+		    Node me = nodesMap.get(myId);
+		    
+		    if (me == null) {
+		        // cannot proceed ports and switches are out of sync
+		        //TODO: Restart the whole read
+		        continue;
+		    }
+		    
+		    if (me.getPort((int)myPort) == null) {
+	            me.addPort((int)myPort);
+		    } else if (me.getLink((int)myPort) != null) {
+		        // Link already added..probably by neighbor
+		        continue;
+		    }
+		
+		    //
+		    // The neighbor Port info
+		    //
+		    for (Vertex neighborPortVertex : myPortVertex.getVertices(Direction.OUT, "link")) {
+		        // Ignore inactive ports
+		        if (! neighborPortVertex.getProperty("state").toString().equals("ACTIVE")) {
+	                continue;
+		        }
+		        int neighborPort = 0;
+		        idStr = neighborPortVertex.getProperty("port_id").toString();
+		        splitter = idStr.split(IDBOperation.PORT_ID_DELIM);
+		        if (splitter.length != 2) {
+	                log.error("Invalid port_id : {}", idStr);
+	                continue;
+		        }
+		        String neighborDpid = splitter[0];
+		        neighborPort = Short.parseShort(splitter[1]);
+		        long neighborId = HexString.toLong(neighborDpid);                                
+		        Node neighbor = nodesMap.get(neighborId);
+		        if (neighbor == null) {
+	                continue;
+		        }
+		        if (neighbor.getPort(neighborPort) == null) {
+		        	neighbor.addPort(neighborPort);
+		        }
+		        me.addLink(myPort, neighbor, neighborPort);
+		    }
+		}
+		dbHandler.commit();
     }
     
     // Only for debug use