BUG-1279: keep an insertion-sorted iterable of serializers 64/8564/2
authorRobert Varga <rovarga@cisco.com>
Wed, 2 Jul 2014 17:18:50 +0000 (19:18 +0200)
committerRobert Varga <rovarga@cisco.com>
Thu, 3 Jul 2014 12:09:28 +0000 (12:09 +0000)
This will retain the order in which the AttributeSerializers have been
registered, so we can iterate over them in that order.

Change-Id: I0adbec38e79febd2c3084d1f6db65c524c2465c2
Signed-off-by: Robert Varga <rovarga@cisco.com>
bgp/parser-spi/src/main/java/org/opendaylight/protocol/bgp/parser/spi/pojo/SimpleAttributeRegistry.java
concepts/src/main/java/org/opendaylight/protocol/concepts/MultiRegistry.java

index 75c8ac5b549583dadc8128e4e509d4a5fe3b696a..485c955e0eb2c6573901a82420fe704ed5ae3444 100644 (file)
@@ -12,9 +12,11 @@ import com.google.common.primitives.UnsignedBytes;
 
 import io.netty.buffer.ByteBuf;
 
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
@@ -22,6 +24,7 @@ import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeParser;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeRegistry;
 import org.opendaylight.protocol.bgp.parser.spi.AttributeSerializer;
+import org.opendaylight.protocol.concepts.AbstractRegistration;
 import org.opendaylight.protocol.concepts.HandlerRegistry;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.protocol.util.Values;
@@ -49,14 +52,30 @@ final class SimpleAttributeRegistry implements AttributeRegistry {
     private static final int PARTIAL_BIT = 2;
     private static final int EXTENDED_LENGTH_BIT = 3;
     private final HandlerRegistry<DataContainer, AttributeParser, AttributeSerializer> handlers = new HandlerRegistry<>();
+    private final Map<AbstractRegistration, AttributeSerializer> serializers = new LinkedHashMap<>();
+    private final AtomicReference<Iterable<AttributeSerializer>> roSerializers =
+            new AtomicReference<Iterable<AttributeSerializer>>(serializers.values());
 
     AutoCloseable registerAttributeParser(final int attributeType, final AttributeParser parser) {
         Preconditions.checkArgument(attributeType >= 0 && attributeType <= Values.UNSIGNED_BYTE_MAX_VALUE);
         return this.handlers.registerParser(attributeType, parser);
     }
 
-    AutoCloseable registerAttributeSerializer(final Class<? extends DataObject> paramClass, final AttributeSerializer serializer) {
-        return this.handlers.registerSerializer(paramClass, serializer);
+    synchronized AutoCloseable registerAttributeSerializer(final Class<? extends DataObject> paramClass, final AttributeSerializer serializer) {
+        final AbstractRegistration reg = this.handlers.registerSerializer(paramClass, serializer);
+
+        serializers.put(reg, serializer);
+        return new AbstractRegistration() {
+            @Override
+            protected void removeRegistration() {
+                synchronized (SimpleAttributeRegistry.this) {
+                    serializers.remove(reg);
+                    roSerializers.set(serializers.values());
+                }
+
+                reg.close();
+            }
+        };
     }
 
     private int addAttribute(final ByteBuf buffer, final Map<Integer, RawAttribute> attributes) throws BGPDocumentedException {
@@ -116,7 +135,7 @@ final class SimpleAttributeRegistry implements AttributeRegistry {
 
     @Override
     public void serializeAttribute(final DataObject attribute,final ByteBuf byteAggregator) {
-        for (AttributeSerializer serializer : this.handlers.getAllSerializers()) {
+        for (AttributeSerializer serializer : this.roSerializers.get()) {
             serializer.serializeAttribute(attribute, byteAggregator);
         }
     }
index 61192f99bd56bb74acecd8f7b2341fd9afb55a2b..7ccb54e5d460a097170d955bb79538947d6008de 100644 (file)
@@ -10,11 +10,14 @@ package org.opendaylight.protocol.concepts;
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.ListMultimap;
+
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+
 import javax.annotation.concurrent.GuardedBy;
 import javax.annotation.concurrent.ThreadSafe;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -68,11 +71,10 @@ public final class MultiRegistry<K, V> {
         this.candidates.put(key, value);
         updateCurrent(key);
 
-        final Object lock = this;
         return new AbstractRegistration() {
             @Override
             protected void removeRegistration() {
-                synchronized (lock) {
+                synchronized (MultiRegistry.this) {
                     MultiRegistry.this.candidates.remove(key, value);
                     updateCurrent(key);
                 }