2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.remote.rpc.registry;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.ImmutableSet;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
16 import java.util.Collections;
17 import java.util.Iterator;
18 import java.util.LinkedHashSet;
20 import java.util.concurrent.ConcurrentHashMap;
21 import java.util.concurrent.ConcurrentMap;
23 public class RoutingTableOld<I, R> {
25 private final Logger LOG = LoggerFactory.getLogger(RoutingTableOld.class);
27 private ConcurrentMap<I,R> globalRpcMap = new ConcurrentHashMap<>();
28 private ConcurrentMap<I, LinkedHashSet<R>> routedRpcMap = new ConcurrentHashMap<>();
30 public ConcurrentMap<I, R> getGlobalRpcMap() {
34 public ConcurrentMap<I, LinkedHashSet<R>> getRoutedRpcMap() {
38 public R getGlobalRoute(final I routeId) {
39 Preconditions.checkNotNull(routeId, "getGlobalRoute: routeId cannot be null!");
40 return globalRpcMap.get(routeId);
43 public void addGlobalRoute(final I routeId, final R route) {
44 Preconditions.checkNotNull(routeId, "addGlobalRoute: routeId cannot be null!");
45 Preconditions.checkNotNull(route, "addGlobalRoute: route cannot be null!");
46 LOG.debug("addGlobalRoute: adding a new route with id[{}] and value [{}]", routeId, route);
47 if(globalRpcMap.putIfAbsent(routeId, route) != null) {
48 LOG.debug("A route already exist for route id [{}] ", routeId);
52 public void removeGlobalRoute(final I routeId) {
53 Preconditions.checkNotNull(routeId, "removeGlobalRoute: routeId cannot be null!");
54 LOG.debug("removeGlobalRoute: removing a new route with id [{}]", routeId);
55 globalRpcMap.remove(routeId);
58 public Set<R> getRoutedRpc(final I routeId) {
59 Preconditions.checkNotNull(routeId, "getRoutes: routeId cannot be null!");
60 Set<R> routes = routedRpcMap.get(routeId);
63 return Collections.emptySet();
66 return ImmutableSet.copyOf(routes);
69 public R getLastAddedRoutedRpc(final I routeId) {
71 Set<R> routes = getRoutedRpc(routeId);
73 if (routes.isEmpty()) {
78 Iterator<R> iter = routes.iterator();
79 while (iter.hasNext()) {
86 public void addRoutedRpc(final I routeId, final R route) {
87 Preconditions.checkNotNull(routeId, "addRoute: routeId cannot be null");
88 Preconditions.checkNotNull(route, "addRoute: route cannot be null");
89 LOG.debug("addRoute: adding a route with k/v [{}/{}]", routeId, route);
90 threadSafeAdd(routeId, route);
93 public void addRoutedRpcs(final Set<I> routeIds, final R route) {
94 Preconditions.checkNotNull(routeIds, "addRoutes: routeIds must not be null");
95 for (I routeId : routeIds){
96 addRoutedRpc(routeId, route);
100 public void removeRoute(final I routeId, final R route) {
101 Preconditions.checkNotNull(routeId, "removeRoute: routeId cannot be null!");
102 Preconditions.checkNotNull(route, "removeRoute: route cannot be null!");
104 LinkedHashSet<R> routes = routedRpcMap.get(routeId);
105 if (routes == null) {
108 LOG.debug("removeRoute: removing a new route with k/v [{}/{}]", routeId, route);
109 threadSafeRemove(routeId, route);
112 public void removeRoutes(final Set<I> routeIds, final R route) {
113 Preconditions.checkNotNull(routeIds, "removeRoutes: routeIds must not be null");
114 for (I routeId : routeIds){
115 removeRoute(routeId, route);
120 * This method guarantees that no 2 thread over write each other's changes.
121 * Just so that we dont end up in infinite loop, it tries for 100 times then throw
123 private void threadSafeAdd(final I routeId, final R route) {
125 for (int i=0;i<100;i++){
127 LinkedHashSet<R> updatedRoutes = new LinkedHashSet<>();
128 updatedRoutes.add(route);
129 LinkedHashSet<R> oldRoutes = routedRpcMap.putIfAbsent(routeId, updatedRoutes);
130 if (oldRoutes == null) {
134 updatedRoutes = new LinkedHashSet<>(oldRoutes);
135 updatedRoutes.add(route);
137 if (routedRpcMap.replace(routeId, oldRoutes, updatedRoutes)) {
141 //the method did not already return means it failed to add route in 100 attempts
142 throw new IllegalStateException("Failed to add route [" + routeId + "]");
146 * This method guarantees that no 2 thread over write each other's changes.
147 * Just so that we dont end up in infinite loop, it tries for 100 times then throw
149 private void threadSafeRemove(final I routeId, final R route) {
150 LinkedHashSet<R> updatedRoutes = null;
151 for (int i=0;i<100;i++){
152 LinkedHashSet<R> oldRoutes = routedRpcMap.get(routeId);
154 // if route to be deleted is the only entry in the set then remove routeId from the cache
155 if ((oldRoutes.size() == 1) && oldRoutes.contains(route)){
156 routedRpcMap.remove(routeId);
160 // if there are multiple routes for this routeId, remove the route to be deleted only from the set.
161 updatedRoutes = new LinkedHashSet<>(oldRoutes);
162 updatedRoutes.remove(route);
163 if (routedRpcMap.replace(routeId, oldRoutes, updatedRoutes)) {
168 //the method did not already return means it failed to remove route in 100 attempts
169 throw new IllegalStateException("Failed to remove route [" + routeId + "]");