Reimplement the backend for the Flow getsummary REST call.
After the change, the speedup is approximately 100x.
E.g., previously it was taking 15 seconds to getsummary for 100 flows;
now it takes approximately 150milliseconds.
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 47ef3b7..6c200fa 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowEventHandler.java
@@ -7,6 +7,8 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -27,6 +29,9 @@
import net.onrc.onos.ofcontroller.util.FlowId;
import net.onrc.onos.ofcontroller.util.FlowPath;
import net.onrc.onos.ofcontroller.util.FlowPathUserState;
+import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
+
+import com.esotericsoftware.kryo2.Kryo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,6 +50,7 @@
private FlowManager flowManager; // The Flow Manager to use
private IDatagridService datagridService; // The Datagrid Service to use
private Topology topology; // The network topology
+ private KryoFactory kryoFactory = new KryoFactory();
// The queue with Flow Path and Topology Element updates
private BlockingQueue<EventEntry<?>> networkEvents =
@@ -129,7 +135,9 @@
}
// Process the initial events (if any)
- processEvents();
+ synchronized (allFlowPaths) {
+ processEvents();
+ }
}
/**
@@ -183,7 +191,9 @@
collection.clear();
// Process the events (if any)
- processEvents();
+ synchronized (allFlowPaths) {
+ processEvents();
+ }
}
} catch (Exception exception) {
log.debug("Exception processing Network Events: ", exception);
@@ -852,4 +862,31 @@
new EventEntry<TopologyElement>(EventEntry.Type.ENTRY_ADD, topologyElement);
networkEvents.add(eventEntry);
}
+
+ /**
+ * Get a sorted copy of all Flow Paths.
+ *
+ * @return a sorted copy of all Flow Paths.
+ */
+ synchronized SortedMap<Long, FlowPath> getAllFlowPathsCopy() {
+ SortedMap<Long, FlowPath> sortedFlowPaths =
+ new TreeMap<Long, FlowPath>();
+
+ //
+ // TODO: For now we use serialization/deserialization to create
+ // a copy of each Flow Path. In the future, we should use proper
+ // copy constructors.
+ //
+ Kryo kryo = kryoFactory.newKryo();
+ synchronized (allFlowPaths) {
+ for (Map.Entry<Long, FlowPath> entry : allFlowPaths.entrySet()) {
+ FlowPath origFlowPath = entry.getValue();
+ FlowPath copyFlowPath = kryo.copy(origFlowPath);
+ sortedFlowPaths.put(entry.getKey(), copyFlowPath);
+ }
+ }
+ kryoFactory.deleteKryo(kryo);
+
+ return sortedFlowPaths;
+ }
}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
index d794ced..3fe47a0 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/flowmanager/FlowManager.java
@@ -2,12 +2,12 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
+import java.util.SortedMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
@@ -303,21 +303,27 @@
@Override
public ArrayList<FlowPath> getAllFlowsSummary(FlowId flowId,
int maxFlows) {
- ArrayList<FlowPath> flowPaths =
- FlowDatabaseOperation.getAllFlows(dbHandlerApi);
+ ArrayList<FlowPath> flowPaths = new ArrayList<FlowPath>();
+ SortedMap<Long, FlowPath> sortedFlowPaths =
+ flowEventHandler.getAllFlowPathsCopy();
+ //
// Truncate each Flow Path and Flow Entry
- for (FlowPath flowPath : flowPaths) {
+ //
+ for (FlowPath flowPath : sortedFlowPaths.values()) {
+ //
+ // TODO: Add only the Flow Paths that have been successfully
+ // installed.
+ //
flowPath.setFlowEntryMatch(null);
flowPath.setFlowEntryActions(null);
for (FlowEntry flowEntry : flowPath.flowEntries()) {
flowEntry.setFlowEntryMatch(null);
flowEntry.setFlowEntryActions(null);
}
+ flowPaths.add(flowPath);
}
- Collections.sort(flowPaths);
-
return flowPaths;
}