Merge pull request #11 from y-higuchi/RAMCloud-yoshi

Whole Topology read
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
index b944a01..c04d8ad 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowDatabaseOperation.java
@@ -391,11 +391,11 @@
 	IFlowEntry flowEntryObj = null;
 	boolean found = false;
 	try {
-	    if ((flowEntryObj =
-		dbHandler.searchFlowEntry(flowEntry.flowEntryId())) != null) {
-		if (measureONOSFlowEntryTimeProp) {
-			endSearchFlowEntry = System.nanoTime();
-		}
+	    flowEntryObj = dbHandler.searchFlowEntry(flowEntry.flowEntryId());
+	    if (measureONOSFlowEntryTimeProp) {
+		endSearchFlowEntry = System.nanoTime();
+	    }
+	    if (flowEntryObj != null) {
 		found = true;
 	    } else {
 		if (measureONOSFlowEntryTimeProp) {
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
index 8b1f7c0..17b125a 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -8,6 +8,8 @@
 import java.util.List;
 import java.util.Map;
 import java.util.SortedMap;
+import java.util.Timer;
+import java.util.TimerTask;
 import java.util.TreeMap;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -32,6 +34,7 @@
 import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
 
 import com.esotericsoftware.kryo2.Kryo;
+import com.tinkerpop.blueprints.impls.ramcloud.PerfMon;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,6 +50,14 @@
     /** The logger. */
     private final static Logger log = LoggerFactory.getLogger(FlowEventHandler.class);
 
+    // Flag to refresh Topology object periodically
+    private final static boolean refreshTopology = true;
+    // Refresh delay(ms)
+    private final static long refreshTopologyDelay = 5000;
+    // Refresh interval(ms)
+    private final static long refreshTopologyInterval = 5000;
+    private Timer refreshTopologyTimer;
+
     private FlowManager flowManager;		// The Flow Manager to use
     private IDatagridService datagridService;	// The Datagrid Service to use
     private Topology topology;			// The network topology
@@ -141,6 +152,28 @@
 	synchronized (allFlowPaths) {
 	    processEvents();
 	}
+
+	if (refreshTopology) {
+		refreshTopologyTimer = new Timer();
+		refreshTopologyTimer.schedule(new TimerTask() {
+			private PerfMon pm = PerfMon.getInstance();
+			@Override
+			public void run() {
+				log.debug("[BEFORE] {}", topology.toString());
+				long begin, end;
+				synchronized(topology) {
+					begin = System.nanoTime();
+					pm.read_whole_topology_start();
+					topology.readFromDatabase(flowManager.dbHandlerInner);
+					pm.read_whole_topology_end();
+					end = System.nanoTime();
+				}
+				// FIXME level raised for measurement. Was debug
+				log.error("[AFTER] {}", topology.toString());
+				log.error("refresh takes : {}[us]", (end - begin) / 1000.0);
+			}
+		}, refreshTopologyDelay, refreshTopologyInterval);
+	}
     }
 
     /**
@@ -443,10 +476,14 @@
 
 	    switch (eventEntry.eventType()) {
 	    case ENTRY_ADD:
-		isTopologyModified |= topology.addTopologyElement(topologyElement);
+    	synchronized (topology) {
+    		isTopologyModified |= topology.addTopologyElement(topologyElement);
+    	}
 		break;
 	    case ENTRY_REMOVE:
-		isTopologyModified |= topology.removeTopologyElement(topologyElement);
+    	synchronized (topology) {
+    		isTopologyModified |= topology.removeTopologyElement(topologyElement);
+    	}
 		break;
 	    }
 	}
@@ -730,8 +767,12 @@
 	DataPath oldDataPath = flowPath.dataPath();
 
 	// Compute the new path
-	DataPath newDataPath = TopologyManager.computeNetworkPath(topology,
+	DataPath newDataPath;
+	synchronized (topology) {
+	newDataPath = TopologyManager.computeNetworkPath(topology,
 								  flowPath);
+	}
+
 	if (newDataPath == null) {
 	    // We need the DataPath to compare the paths
 	    newDataPath = new DataPath();
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 761189c..98a517c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/topology/Topology.java
@@ -1,11 +1,11 @@
 package net.onrc.onos.ofcontroller.topology;
 
-import java.util.List;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
 
-import net.onrc.onos.graph.GraphDBOperation;
+import net.onrc.onos.graph.DBOperation;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.ISwitchStorage.SwitchState;
 
@@ -13,7 +13,6 @@
 
 import com.tinkerpop.blueprints.Direction;
 import com.tinkerpop.blueprints.Vertex;
-import net.onrc.onos.graph.DBOperation;
 
 /**
  * A class for storing Node and Link information for fast computation
@@ -452,4 +451,20 @@
 	}
 	dbHandler.commit();
     }
+
+    // Only for debug use
+    @Override
+    public String toString() {
+    	long numNodes = nodesMap.size();
+    	long numLinks = 0;
+    	for (Map.Entry<Long, Node> entry : nodesMap.entrySet()) {
+    		Node n = entry.getValue();
+    		for (Map.Entry<Integer, Node.Link> linkEntry : n.links.entrySet()) {
+    			if (n.nodeId > linkEntry.getValue().neighbor.nodeId) {
+    				++numLinks;
+    			}
+    		}
+    	}
+    	return "Topology has " + numNodes + " Nodes and " + numLinks + " Links.";
+    }
 }