BUG-1120: fold GenerationalListenerMap back 93/7593/1
authorRobert Varga <rovarga@cisco.com>
Mon, 2 Jun 2014 13:46:28 +0000 (15:46 +0200)
committerRobert Varga <rovarga@cisco.com>
Mon, 2 Jun 2014 14:17:12 +0000 (16:17 +0200)
This moves needless indirection code form GenerationalListenerMap back
to NotificaitonBrokerImpl. Now the contract is directly between
NotificationBrokerImpl and ListenerMapGeneration

Change-Id: I0b401fa4b10e06afbc7206323d1c1f4afb19d422
Signed-off-by: Robert Varga <rovarga@cisco.com>
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GenerationalListenerMap.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/ListenerMapGeneration.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java

diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GenerationalListenerMap.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GenerationalListenerMap.java
deleted file mode 100644 (file)
index 85265e8..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.impl;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.annotation.concurrent.GuardedBy;
-
-import org.opendaylight.yangtools.yang.binding.Notification;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-
-/**
- * A multi-generation, isolated notification type to listener map.
- */
-final class GenerationalListenerMap {
-    private final AtomicReference<ListenerMapGeneration> current = new AtomicReference<>(new ListenerMapGeneration());
-
-    Iterable<NotificationListenerRegistration<?>> listenersFor(final Notification notification) {
-        return current.get().listenersFor(notification);
-    }
-
-    Iterable<Class<? extends Notification>> getKnownTypes() {
-        // Note: this relies on current having immutable listeners
-        return current.get().getListeners().keySet();
-    }
-
-    @GuardedBy("this")
-    private Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> mutableListeners() {
-        return HashMultimap.create(current.get().getListeners());
-    }
-
-    synchronized void addRegistrations(final NotificationListenerRegistration<?>... registrations) {
-        Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> listeners =
-                mutableListeners();
-
-        for (NotificationListenerRegistration<?> reg : registrations) {
-            listeners.put(reg.getType(), reg);
-        }
-
-        current.set(new ListenerMapGeneration(listeners));
-    }
-
-    synchronized void removeRegistrations(final NotificationListenerRegistration<?>... registrations) {
-        Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> listeners =
-                mutableListeners();
-
-        for (NotificationListenerRegistration<?> reg : registrations) {
-            listeners.remove(reg.getType(), reg);
-        }
-
-        current.set(new ListenerMapGeneration(listeners));
-    }
-}
index fd0b263..258ba51 100644 (file)
@@ -9,6 +9,9 @@ package org.opendaylight.controller.sal.binding.impl;
 
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.concurrent.GuardedBy;
 
 import org.opendaylight.controller.sal.binding.api.NotificationListener;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
@@ -22,13 +25,15 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
 
 public class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(NotificationBrokerImpl.class);
 
     private final ListenerRegistry<NotificationInterestListener> interestListeners =
             ListenerRegistry.create();
-    private final GenerationalListenerMap listeners = new GenerationalListenerMap();
+    private final AtomicReference<ListenerMapGeneration> listeners = new AtomicReference<>(new ListenerMapGeneration());
     private final ExecutorService executor;
 
     public NotificationBrokerImpl(final ExecutorService executor) {
@@ -42,18 +47,44 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto
 
     @Override
     public void publish(final Notification notification, final ExecutorService service) {
-        for (NotificationListenerRegistration<?> r : listeners.listenersFor(notification)) {
+        for (NotificationListenerRegistration<?> r : listeners.get().listenersFor(notification)) {
             service.submit(new NotifyTask(r, notification));
         }
     }
 
+    @GuardedBy("this")
+    private Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> mutableListeners() {
+        return HashMultimap.create(listeners.get().getListeners());
+    }
+
     private final void addRegistrations(final NotificationListenerRegistration<?>... registrations) {
-        listeners.addRegistrations(registrations);
+        synchronized (this) {
+            final Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> newListeners =
+                    mutableListeners();
+            for (NotificationListenerRegistration<?> reg : registrations) {
+                newListeners.put(reg.getType(), reg);
+            }
+
+            listeners.set(new ListenerMapGeneration(newListeners));
+        }
+
+        // Notifications are dispatched out of lock...
         for (NotificationListenerRegistration<?> reg : registrations) {
             announceNotificationSubscription(reg.getType());
         }
     }
 
+    private synchronized void removeRegistrations(final NotificationListenerRegistration<?>... registrations) {
+        final Multimap<Class<? extends Notification>, NotificationListenerRegistration<?>> newListeners =
+                mutableListeners();
+
+        for (NotificationListenerRegistration<?> reg : registrations) {
+            newListeners.remove(reg.getType(), reg);
+        }
+
+        listeners.set(new ListenerMapGeneration(newListeners));
+    }
+
     private void announceNotificationSubscription(final Class<? extends Notification> notification) {
         for (final ListenerRegistration<NotificationInterestListener> listener : interestListeners) {
             try {
@@ -68,7 +99,8 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto
     @Override
     public ListenerRegistration<NotificationInterestListener> registerInterestListener(final NotificationInterestListener interestListener) {
         final ListenerRegistration<NotificationInterestListener> registration = this.interestListeners.register(interestListener);
-        for (final Class<? extends Notification> notification : listeners.getKnownTypes()) {
+
+        for (final Class<? extends Notification> notification : listeners.get().getKnownTypes()) {
             interestListener.onNotificationSubscribtion(notification);
         }
         return registration;
@@ -79,7 +111,7 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto
         final NotificationListenerRegistration<T> reg = new AbstractNotificationListenerRegistration<T>(notificationType, listener) {
             @Override
             protected void removeRegistration() {
-                listeners.removeRegistrations(this);
+                removeRegistrations(this);
             }
         };
 
@@ -112,7 +144,7 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto
         return new AbstractListenerRegistration<org.opendaylight.yangtools.yang.binding.NotificationListener>(listener) {
             @Override
             protected void removeRegistration() {
-                listeners.removeRegistrations(regs);
+                removeRegistrations(regs);
                 for (ListenerRegistration<?> reg : regs) {
                     reg.close();
                 }

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.