Use removedSwitchEvents and removedPortEvents for rerouting

Change-Id: I8ef66c8220c30ec0254279555913aa57eedd12d9
diff --git a/src/main/java/net/onrc/onos/intent/PathIntentMap.java b/src/main/java/net/onrc/onos/intent/PathIntentMap.java
index d70def2..85ea16c 100644
--- a/src/main/java/net/onrc/onos/intent/PathIntentMap.java
+++ b/src/main/java/net/onrc/onos/intent/PathIntentMap.java
@@ -7,22 +7,47 @@
 
 import net.onrc.onos.ofcontroller.networkgraph.Link;
 import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
+import net.onrc.onos.ofcontroller.networkgraph.PortEvent.SwitchPort;
 
 /**
  * @author Toshio Koide (t-koide@onlab.us)
  */
 public class PathIntentMap extends IntentMap {
-	protected HashMap<LinkEvent, HashSet<PathIntent>> linkToIntents = new HashMap<>();
+	private HashMap<Long, HashMap<Long, HashSet<PathIntent>>> intents;
+
+	public PathIntentMap() {
+		intents = new HashMap<>();
+	}
+
+	private HashSet<PathIntent> get(SwitchPort swPort) {
+		Long dpid = swPort.getDpid();
+		Long port = swPort.getNumber();
+		HashMap<Long, HashSet<PathIntent>> portToIntents = intents.get(dpid);
+		if (portToIntents == null) {
+			portToIntents = new HashMap<>();
+			intents.put(dpid, portToIntents);
+		}
+		HashSet<PathIntent> targetIntents = portToIntents.get(port);
+		if (targetIntents == null) {
+			targetIntents = new HashSet<>();
+			portToIntents.put(port, targetIntents);
+		}
+		return targetIntents;
+	}
+
+	private void put(SwitchPort swPort, PathIntent intent) {
+		get(swPort).add(intent);
+	}
 
 	@Override
 	protected void putIntent(Intent intent) {
+		if (!(intent instanceof PathIntent)) return; // TODO throw exception
 		super.putIntent(intent);
-		for (LinkEvent linkEvent: ((PathIntent) intent).getPath()) {
-			HashSet<PathIntent> value = linkToIntents.get(linkEvent);
-			if (value == null)
-				value = new HashSet<PathIntent>();
-			value.add((PathIntent) intent);
-			linkToIntents.put(linkEvent, value);
+
+		PathIntent pathIntent = (PathIntent) intent;
+		for (LinkEvent linkEvent: pathIntent.getPath()) {
+			put(linkEvent.getSrc(), (PathIntent) intent);
+			put(linkEvent.getDst(), (PathIntent) intent);
 		}
 	}
 
@@ -30,20 +55,38 @@
 	protected void removeIntent(String intentId) {
 		PathIntent intent = (PathIntent) getIntent(intentId);
 		for (LinkEvent linkEvent: intent.getPath()) {
-			HashSet<PathIntent> value = linkToIntents.get(linkEvent);
-			value.remove(intent);
+			get(linkEvent.getSrc()).remove(intent);
+			get(linkEvent.getDst()).remove(intent);
 		}
 		super.removeIntent(intentId);
 	}
 
 	public Collection<PathIntent> getIntentsByLink(LinkEvent linkEvent) {
-		Collection<PathIntent> intents = linkToIntents.get(linkEvent);
-		if (intents == null) {
-			return null;
+		return getIntentsByPort(
+				linkEvent.getSrc().getDpid(),
+				linkEvent.getSrc().getNumber());
+	}
+
+	public Collection<PathIntent> getIntentsByPort(Long dpid, Long port) {
+		HashMap<Long, HashSet<PathIntent>> portToIntents = intents.get(dpid);
+		if (portToIntents != null) {
+			HashSet<PathIntent> targetIntents = portToIntents.get(port);
+			if (targetIntents != null) {
+				return Collections.unmodifiableCollection(targetIntents);
+			}
 		}
-		else {
-			return Collections.unmodifiableCollection(intents);
+		return new HashSet<>();
+	}
+
+	public Collection<PathIntent> getIntentsByDpid(Long dpid) {
+		HashSet<PathIntent> result = new HashSet<>();
+		HashMap<Long, HashSet<PathIntent>> portToIntents = intents.get(dpid);
+		if (portToIntents != null) {
+			for (HashSet<PathIntent> targetIntents: portToIntents.values()) {
+				result.addAll(targetIntents);
+			}
 		}
+		return result;
 	}
 
 	/**
@@ -55,7 +98,7 @@
 		if (link == null) return null;
 		Double bandwidth = link.getCapacity();
 		LinkEvent linkEvent = new LinkEvent(link);
-		if (!bandwidth.isInfinite() && linkToIntents.containsKey(linkEvent)) {
+		if (!bandwidth.isInfinite()) {
 			for (PathIntent intent: getIntentsByLink(linkEvent)) {
 				Double intentBandwidth = intent.getBandwidth();
 				if (intentBandwidth == null || intentBandwidth.isInfinite() || intentBandwidth.isNaN())
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
index 67902dd..8cb935f 100755
--- a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
@@ -53,16 +53,8 @@
 	// private methods
 	// ================================================================================
 
-	private void reroutePaths(Collection<LinkEvent> removedLinkEvents) {
-		HashSet<PathIntent> oldPaths = new HashSet<>();
-		for (LinkEvent linkEvent : removedLinkEvents) {
-			Collection<PathIntent> intents = pathIntents.getIntentsByLink(linkEvent);
-			if (intents == null)
-				continue;
-			oldPaths.addAll(intents);
-		}
-
-		if (oldPaths.isEmpty())
+	private void reroutePaths(Collection<PathIntent> oldPaths) {
+		if (oldPaths == null || oldPaths.isEmpty())
 			return;
 
 		IntentOperationList reroutingOperation = new IntentOperationList();
@@ -85,14 +77,14 @@
 
 	@Override
 	public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-		Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<>(1);
+		Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<>();
 		m.put(IPathCalcRuntimeService.class, this);
 		return m;
 	}
 
 	@Override
 	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-		Collection<Class<? extends IFloodlightService>> l = new ArrayList<>();
+		Collection<Class<? extends IFloodlightService>> l = new ArrayList<>(2);
 		l.add(IDatagridService.class);
 		l.add(INetworkGraphService.class);
 		return l;
@@ -199,8 +191,19 @@
 			Collection<LinkEvent> removedLinkEvents,
 			Collection<DeviceEvent> addedDeviceEvents,
 			Collection<DeviceEvent> removedDeviceEvents) {
-		// TODO add getIntentsByPort() and getIntentsBySwitch() to PathIntentMap.
-		reroutePaths(removedLinkEvents);
+
+		HashSet<PathIntent> affectedPaths = new HashSet<>();
+
+		for (SwitchEvent switchEvent: removedSwitchEvents)
+			affectedPaths.addAll(pathIntents.getIntentsByDpid(switchEvent.getDpid()));
+
+		for (PortEvent portEvent: removedPortEvents)
+			affectedPaths.addAll(pathIntents.getIntentsByPort(portEvent.getDpid(), portEvent.getNumber()));
+
+		for (LinkEvent linkEvent: removedLinkEvents)
+			affectedPaths.addAll(pathIntents.getIntentsByLink(linkEvent));
+
+		reroutePaths(affectedPaths);
 	}
 
 	// ================================================================================
@@ -246,4 +249,4 @@
 		highLevelIntents.changeStates(parentStates);
 		pathIntents.changeStates(value);
 	}
-}
\ No newline at end of file
+}