Turn PathBindingTlvCodec into an abstract class 81/85981/5
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 26 Nov 2019 15:34:06 +0000 (16:34 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Mon, 9 Dec 2019 11:05:13 +0000 (12:05 +0100)
Having PathBindingTlvCodec as a private interface is not completely
useful, as we can use an abstract class instead, simplifying
the API and speeding it up, by eliminating unneeded allocations.

Change-Id: Ia1e3eda5a8333c31a8b929dcb73079fcb6edf581
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
pcep/ietf-stateful07/src/main/java/org/opendaylight/protocol/pcep/ietf/stateful07/PathBindingTlvParser.java

index 66fff8dd5f39dcc6234f8bf80d272db63c7a91cd..f7c07f10dd3f43804cb362f8ce1548fdce942210 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.protocol.pcep.ietf.stateful07;
 
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
@@ -14,6 +16,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.Map;
+import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
 import org.opendaylight.protocol.pcep.spi.TlvParser;
 import org.opendaylight.protocol.pcep.spi.TlvSerializer;
@@ -28,7 +31,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.iet
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.path.binding.tlv.path.binding.binding.type.value.MplsLabelEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev181109.path.binding.tlv.path.binding.binding.type.value.MplsLabelEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.Tlv;
-import org.opendaylight.yangtools.concepts.IllegalArgumentCodec;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.common.Uint8;
@@ -51,8 +53,8 @@ public final class PathBindingTlvParser implements TlvParser, TlvSerializer {
     private static final int LABEL_SHIFT = 12;
     private static final int TC_SHIFT = LABEL_SHIFT - 3;
     private static final int S_SHIFT = TC_SHIFT - 1;
-    private static final int MPLS_ENTRY_LENGTH = 4;
-    private static final int MPLS_BINDING_LENGTH = MPLS_ENTRY_LENGTH + 2;
+    // 2 bytes type + 4 bytes binding
+    private static final int MPLS_BINDING_LENGTH = 6;
 
     private static final Map<Uint16, PathBindingTlvCodec> BT_PARSERS;
     private static final Map<Class<? extends BindingTypeValue>, PathBindingTlvCodec> BT_SERIALIZERS;
@@ -86,8 +88,7 @@ public final class PathBindingTlvParser implements TlvParser, TlvSerializer {
         final PathBindingTlvCodec codec = BT_SERIALIZERS.get(bindingTypeValue.implementedInterface());
         Preconditions.checkArgument(codec != null,
             "Unsupported Path Binding Type: %s", bindingTypeValue.implementedInterface());
-        ByteBufUtils.writeMandatory(body, codec.getBindingType(), "bindingType");
-        body.writeBytes(codec.serialize(bindingTypeValue));
+        codec.writeBinding(body, bindingTypeValue);
 
         TlvUtil.formatTlv(TYPE, body, buffer);
     }
@@ -102,68 +103,75 @@ public final class PathBindingTlvParser implements TlvParser, TlvSerializer {
         if (codec == null) {
             throw new PCEPDeserializerException("Unsupported Path Binding Type: " + type);
         }
-        return new PathBindingBuilder().setBindingTypeValue(codec.deserialize(buffer)).build();
+        return new PathBindingBuilder().setBindingTypeValue(codec.readEntry(buffer)).build();
     }
 
-    private static final class MplsLabelCodec implements PathBindingTlvCodec {
+    private static final class MplsLabelCodec extends PathBindingTlvCodec {
+        MplsLabelCodec() {
+            super(MPLS_LABEL);
+        }
 
         @Override
-        public ByteBuf serialize(final BindingTypeValue bindingValue) {
+        void writeEntry(final ByteBuf buf, final BindingTypeValue bindingValue) {
             Preconditions.checkArgument(bindingValue instanceof MplsLabel, "bindingValue is not MplsLabel");
             final MplsLabel mplsLabel = (MplsLabel) bindingValue;
-            final ByteBuf value = Unpooled.buffer(MPLS_ENTRY_LENGTH);
-            ByteBufWriteUtil.writeUnsignedInt(Uint32.valueOf(getMplsStackEntry(mplsLabel.getMplsLabel())), value);
-            return value;
-        }
-
-        @Override
-        public BindingTypeValue deserialize(final ByteBuf buffer) {
-            final MplsLabelBuilder builder = new MplsLabelBuilder();
-            builder.setMplsLabel(getMplsLabel(buffer.readUnsignedInt()));
-            return builder.build();
+            ByteBufWriteUtil.writeUnsignedInt(Uint32.valueOf(getMplsStackEntry(mplsLabel.getMplsLabel())), buf);
         }
 
         @Override
-        public Uint16 getBindingType() {
-            return MPLS_LABEL;
+        BindingTypeValue readEntry(final ByteBuf buffer) {
+            return new MplsLabelBuilder().setMplsLabel(getMplsLabel(buffer.readUnsignedInt())).build();
         }
     }
 
-    private static final class MplsLabelEntryCodec implements PathBindingTlvCodec {
+    private static final class MplsLabelEntryCodec extends PathBindingTlvCodec {
+        MplsLabelEntryCodec() {
+            super(MPLS_STACK_ENTRY);
+        }
 
         @Override
-        public ByteBuf serialize(final BindingTypeValue bindingValue) {
+        void writeEntry(final ByteBuf buf, final BindingTypeValue bindingValue) {
             Preconditions.checkArgument(bindingValue instanceof MplsLabelEntry,
                     "bindingValue is not MplsLabelEntry");
             final MplsLabelEntry mplsEntry = (MplsLabelEntry) bindingValue;
-            final ByteBuf value = Unpooled.buffer(MPLS_ENTRY_LENGTH);
             final long entry = getMplsStackEntry(mplsEntry.getLabel())
                     | mplsEntry.getTrafficClass().toJava() << TC_SHIFT
                     | (mplsEntry.isBottomOfStack() ? 1 : 0) << S_SHIFT
                     | mplsEntry.getTimeToLive().toJava();
-            ByteBufWriteUtil.writeUnsignedInt(Uint32.valueOf(entry), value);
-            return value;
+            ByteBufWriteUtil.writeUnsignedInt(Uint32.valueOf(entry), buf);
         }
 
         @Override
-        public BindingTypeValue deserialize(final ByteBuf buffer) {
+        BindingTypeValue readEntry(final ByteBuf buffer) {
             final long entry = buffer.readUnsignedInt();
-            final MplsLabelEntryBuilder builder = new MplsLabelEntryBuilder()
+            return new MplsLabelEntryBuilder()
                     .setLabel(getMplsLabel(entry))
                     .setTrafficClass(Uint8.valueOf(entry >> TC_SHIFT & TC_MASK))
                     .setBottomOfStack((entry >> S_SHIFT & S_MASK) == 1)
-                    .setTimeToLive(Uint8.valueOf(entry & TTL_MASK));
-            return builder.build();
+                    .setTimeToLive(Uint8.valueOf(entry & TTL_MASK))
+                    .build();
         }
+    }
 
-        @Override
-        public Uint16 getBindingType() {
-            return MPLS_STACK_ENTRY;
+    private abstract static class PathBindingTlvCodec {
+        private final @NonNull Uint16 bindingType;
+
+        PathBindingTlvCodec(final Uint16 bindingType) {
+            this.bindingType = requireNonNull(bindingType);
         }
-    }
 
-    private interface PathBindingTlvCodec extends IllegalArgumentCodec<ByteBuf, BindingTypeValue> {
-        Uint16 getBindingType();
+        final @NonNull Uint16 getBindingType() {
+            return bindingType;
+        }
+
+        final void writeBinding(final ByteBuf buf, final BindingTypeValue binding) {
+            ByteBufUtils.writeMandatory(buf, bindingType, "bindingType");
+            writeEntry(buf, binding);
+        }
+
+        abstract BindingTypeValue readEntry(ByteBuf buf);
+
+        abstract void writeEntry(ByteBuf buf, BindingTypeValue value);
     }
 
     @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",