[AETHER-72] Refactoring RouteService
- to use bulk updates interface
- to use new getRoutesForNextHops API
- to use multi-thread resolver
- to use multi-thread hostexec
- to use a concurrent hashmap instead of synchronized
- to use a non-blocking resolved store
Additionally updates unit tests
Change-Id: Id960abd0f2a1b03066ce34b6a2f72b76566bb58c
diff --git a/apps/route-service/app/src/main/java/org/onosproject/routeservice/store/DefaultRouteTable.java b/apps/route-service/app/src/main/java/org/onosproject/routeservice/store/DefaultRouteTable.java
index f052f04..c24f005 100644
--- a/apps/route-service/app/src/main/java/org/onosproject/routeservice/store/DefaultRouteTable.java
+++ b/apps/route-service/app/src/main/java/org/onosproject/routeservice/store/DefaultRouteTable.java
@@ -18,6 +18,7 @@
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
@@ -43,6 +44,7 @@
import org.onosproject.store.service.StorageService;
import org.onosproject.store.service.Versioned;
+
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -133,6 +135,14 @@
}
@Override
+ public void update(Collection<Route> routesAdded) {
+ Map<String, Collection<? extends RawRoute>> computedRoutes = new HashMap<>();
+ computeRoutesToAdd(routesAdded).forEach((prefix, routes) -> computedRoutes.computeIfAbsent(
+ prefix, k -> Sets.newHashSet(routes)));
+ routes.putAll(computedRoutes);
+ }
+
+ @Override
public void remove(Route route) {
getRoutes(route.prefix())
.routes()
@@ -145,6 +155,14 @@
}
@Override
+ public void remove(Collection<Route> routesRemoved) {
+ Map<String, Collection<? extends RawRoute>> computedRoutes = new HashMap<>();
+ computeRoutesToRemove(routesRemoved).forEach((prefix, routes) -> computedRoutes.computeIfAbsent(
+ prefix, k -> Sets.newHashSet(routes)));
+ routes.removeAll(computedRoutes);
+ }
+
+ @Override
public void replace(Route route) {
routes.replaceValues(route.prefix().toString(), Sets.newHashSet(new RawRoute(route)));
}
@@ -180,6 +198,53 @@
.collect(Collectors.toSet());
}
+ @Override
+ public Collection<RouteSet> getRoutesForNextHops(Collection<IpAddress> nextHops) {
+ // First create a reduced snapshot of the store iterating one time the map
+ Map<String, Collection<? extends RawRoute>> filteredRouteStore = new HashMap<>();
+ routes.values().stream()
+ .filter(r -> nextHops.contains(IpAddress.valueOf(r.nextHop())))
+ .forEach(r -> filteredRouteStore.computeIfAbsent(r.prefix, k -> {
+ // We need to get all the routes because the resolve logic
+ // will use the alternatives as well
+ Versioned<Collection<? extends RawRoute>> routeSet = routes.get(k);
+ if (routeSet != null) {
+ return routeSet.value();
+ }
+ return null;
+ }));
+ // Return the collection of the routeSet we have to resolve
+ return filteredRouteStore.entrySet().stream()
+ .map(entry -> new RouteSet(id, IpPrefix.valueOf(entry.getKey()),
+ entry.getValue().stream().map(RawRoute::route).collect(Collectors.toSet())))
+ .collect(Collectors.toSet());
+ }
+
+ private Map<String, Collection<RawRoute>> computeRoutesToAdd(Collection<Route> routesAdded) {
+ Map<String, Collection<RawRoute>> computedRoutes = new HashMap<>();
+ routesAdded.forEach(route -> {
+ Collection<RawRoute> tempRoutes = computedRoutes.computeIfAbsent(
+ route.prefix().toString(), k -> Sets.newHashSet());
+ tempRoutes.add(new RawRoute(route));
+ });
+ return computedRoutes;
+ }
+
+ private Map<String, Collection<RawRoute>> computeRoutesToRemove(Collection<Route> routesRemoved) {
+ Map<String, Collection<RawRoute>> computedRoutes = new HashMap<>();
+ routesRemoved.forEach(route -> getRoutes(route.prefix())
+ .routes()
+ .stream()
+ .filter(r -> r.equals(route))
+ .findAny()
+ .ifPresent(matchRoute -> {
+ Collection<RawRoute> tempRoutes = computedRoutes.computeIfAbsent(
+ matchRoute.prefix().toString(), k -> Sets.newHashSet());
+ tempRoutes.add(new RawRoute(matchRoute));
+ }));
+ return computedRoutes;
+ }
+
private class RouteTableListener
implements MultimapEventListener<String, RawRoute> {