BUG-2400 : Memory optimizations for AS-Path and Origin attributes 20/12920/1
authorDana Kutenicsova <dkutenic@cisco.com>
Wed, 22 Oct 2014 14:25:17 +0000 (16:25 +0200)
committerDana Kutenicsova <dkutenic@cisco.com>
Tue, 18 Nov 2014 15:45:12 +0000 (15:45 +0000)
- AS-Path: minimized empty lists
- Origin: reusing Origin container

Change-Id: I424169873ad1bfae0e3cd928bf285f59c70141ec
Signed-off-by: Dana Kutenicsova <dkutenic@cisco.com>
(cherry picked from commit 6954a433170a38623f5e7621f0821d6cfcb6c6be)

bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathAttributeParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/AsPathSegmentParser.java
bgp/parser-impl/src/main/java/org/opendaylight/protocol/bgp/parser/impl/message/update/OriginAttributeParser.java
bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/BGPParserTest.java

index fe860cb58a896cbc7211317befee95df9e005190..b4ae4ded5c8af4f9424fd60008422ccbd86ffab5 100644 (file)
@@ -8,10 +8,11 @@
 package org.opendaylight.protocol.bgp.parser.impl.message.update;
 
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
 import com.google.common.primitives.UnsignedBytes;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPError;
@@ -47,6 +48,8 @@ public final class AsPathAttributeParser implements AttributeParser, AttributeSe
     private final ReferenceCache refCache;
     private static final Logger LOG = LoggerFactory.getLogger(AsPathAttributeParser.class);
 
+    private static final AsPath EMPTY = new AsPathBuilder().setSegments(Collections.<Segments> emptyList()).build();
+
     public AsPathAttributeParser(final ReferenceCache refCache) {
         this.refCache = Preconditions.checkNotNull(refCache);
     }
@@ -59,7 +62,10 @@ public final class AsPathAttributeParser implements AttributeParser, AttributeSe
      * @throws BGPParsingException
      */
     private static AsPath parseAsPath(final ReferenceCache refCache, final ByteBuf buffer) throws BGPDocumentedException, BGPParsingException {
-        final List<Segments> ases = Lists.newArrayList();
+        if (!buffer.isReadable()) {
+            return EMPTY;
+        }
+        final List<Segments> ases = new ArrayList<>();
         boolean isSequence = false;
         while (buffer.isReadable()) {
             final int type = UnsignedBytes.toInt(buffer.readByte());
@@ -83,8 +89,7 @@ public final class AsPathAttributeParser implements AttributeParser, AttributeSe
             }
             buffer.skipBytes(count * AsPathSegmentParser.AS_NUMBER_LENGTH);
         }
-
-        if (!isSequence && buffer.readableBytes() != 0) {
+        if (!isSequence) {
             throw new BGPDocumentedException("AS_SEQUENCE must be present in AS_PATH attribute.", BGPError.AS_PATH_MALFORMED);
         }
         return new AsPathBuilder().setSegments(ases).build();
index fb174412ae18181c33e5e297be9cbc58ac9114ff..8f70be354736b4ba74e23a6c5e183598de4a9953 100644 (file)
@@ -13,6 +13,7 @@ import static org.opendaylight.protocol.bgp.parser.impl.message.update.AsPathSeg
 
 import io.netty.buffer.ByteBuf;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import org.opendaylight.protocol.util.ReferenceCache;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
@@ -71,7 +72,7 @@ public final class AsPathSegmentParser {
             coll.add(
                     refCache.getSharedReference(new AsSequenceBuilder().setAs(refCache.getSharedReference(new AsNumber(buffer.readUnsignedInt()))).build()));
         }
-        return coll;
+        return (coll.isEmpty()) ? Collections.<AsSequence>emptyList() : coll;
     }
 
     static List<AsNumber> parseAsSet(final ReferenceCache refCache, final int count, final ByteBuf buffer) {
@@ -80,29 +81,29 @@ public final class AsPathSegmentParser {
             coll.add(refCache.getSharedReference(
                     new AsNumber(buffer.readUnsignedInt())));
         }
-        return coll;
+        return (coll.isEmpty()) ? Collections.<AsNumber>emptyList() : coll;
     }
 
-    static void serializeAsSet(ASetCase aSetCase, ByteBuf byteAggregator) {
-        ASet aset = aSetCase.getASet();
+    static void serializeAsSet(final ASetCase aSetCase, final ByteBuf byteAggregator) {
+        final ASet aset = aSetCase.getASet();
         if (aset == null || aset.getAsSet() == null) {
             return;
         }
         byteAggregator.writeByte(serializeType(AS_SET));
         byteAggregator.writeByte(aset.getAsSet().size());
-        for (AsNumber asNumber : aset.getAsSet()) {
+        for (final AsNumber asNumber : aset.getAsSet()) {
             byteAggregator.writeInt(asNumber.getValue().intValue());
         }
     }
 
-    static void serializeAsSequence(AListCase aListCase, ByteBuf byteAggregator) {
-        AList alist = aListCase.getAList();
+    static void serializeAsSequence(final AListCase aListCase, final ByteBuf byteAggregator) {
+        final AList alist = aListCase.getAList();
         if (alist == null || alist.getAsSequence() == null) {
             return;
         }
         byteAggregator.writeByte(serializeType(AS_SEQUENCE));
         byteAggregator.writeByte(alist.getAsSequence().size());
-        for (AsSequence value : alist.getAsSequence()) {
+        for (final AsSequence value : alist.getAsSequence()) {
             byteAggregator.writeInt(value.getAs().getValue().intValue());
         }
     }
index 3e570fb840398fc0f117b4bfd174e5eed7a87152..bd1d33d79199c51f6dfb120bdd8a414294aae6eb 100644 (file)
@@ -27,6 +27,10 @@ public final class OriginAttributeParser implements AttributeParser, AttributeSe
 
     public static final int TYPE = 1;
 
+    private static final Origin IGP = new OriginBuilder().setValue(BgpOrigin.Igp).build();
+    private static final Origin EGP = new OriginBuilder().setValue(BgpOrigin.Egp).build();
+    private static final Origin INC = new OriginBuilder().setValue(BgpOrigin.Incomplete).build();
+
     @Override
     public void parseAttribute(final ByteBuf buffer, final PathAttributesBuilder builder) throws BGPDocumentedException {
         final byte rawOrigin = buffer.readByte();
@@ -34,7 +38,17 @@ public final class OriginAttributeParser implements AttributeParser, AttributeSe
         if (borigin == null) {
             throw new BGPDocumentedException("Unknown Origin type.", BGPError.ORIGIN_ATTR_NOT_VALID, new byte[] { (byte) 0x01, (byte) 0x01, rawOrigin} );
         }
-        builder.setOrigin(new OriginBuilder().setValue(borigin).build());
+        switch (borigin) {
+        case Egp:
+            builder.setOrigin(EGP);
+            return;
+        case Igp:
+            builder.setOrigin(IGP);
+            return;
+        case Incomplete:
+            builder.setOrigin(INC);
+            return;
+        }
     }
 
     @Override
index 46add4dc18569f3bf770147b573e3c0d06c26e8f..b9c56b1e064dda31fa5fb44f52cb7dec2d80b085 100644 (file)
@@ -21,6 +21,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import org.junit.BeforeClass;
@@ -575,8 +576,6 @@ public class BGPParserTest {
                 new Inet4SpecificExtendedCommunityBuilder().setTransitive(false).setGlobalAdministrator(
                     new Ipv4Address("192.168.1.0")).setLocalAdministrator(new byte[] { 0x12, 0x34 }).build()).build()).build());
 
-        final List<Segments> asPath = Lists.newArrayList();
-
         // check path attributes
         final PathAttributes attrs = message.getPathAttributes();
 
@@ -585,7 +584,7 @@ public class BGPParserTest {
         paBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Egp).build());
         assertEquals(paBuilder.getOrigin(), attrs.getOrigin());
 
-        paBuilder.setAsPath(new AsPathBuilder().setSegments(asPath).build());
+        paBuilder.setAsPath(new AsPathBuilder().setSegments(Collections.<Segments> emptyList()).build());
         assertEquals(paBuilder.getAsPath(), attrs.getAsPath());
 
         paBuilder.setCNextHop(nextHop);
@@ -918,8 +917,6 @@ public class BGPParserTest {
         final Ipv4NextHopCase nextHop = new Ipv4NextHopCaseBuilder().setIpv4NextHop(
             new Ipv4NextHopBuilder().setGlobal(new Ipv4Address("25.25.25.1")).build()).build();
 
-        final List<Segments> asPath = Lists.newArrayList();
-
         final LocalNodeDescriptorsBuilder lndBuilder = new LocalNodeDescriptorsBuilder().setAsNumber(new AsNumber((long) 100)).setDomainId(
             new DomainIdentifier(0x19191901L)).setAreaId(new AreaIdentifier(0L));
 
@@ -975,7 +972,7 @@ public class BGPParserTest {
         paBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build());
         assertEquals(paBuilder.getOrigin(), attrs.getOrigin());
 
-        paBuilder.setAsPath(new AsPathBuilder().setSegments(asPath).build());
+        paBuilder.setAsPath(new AsPathBuilder().setSegments(Collections.<Segments> emptyList()).build());
         assertEquals(paBuilder.getAsPath(), attrs.getAsPath());
 
         paBuilder.setLocalPref(new LocalPrefBuilder().setPref(100L).build());
@@ -1157,8 +1154,6 @@ public class BGPParserTest {
             new DestinationLinkstateCaseBuilder().setDestinationLinkstate(dBuilder.build()).build()).build());
         lsBuilder.setMpReachNlri(mpBuilder.build());
 
-        final List<Segments> asPath = Lists.newArrayList();
-
         // check path attributes
         final PathAttributes attrs = message.getPathAttributes();
 
@@ -1167,7 +1162,7 @@ public class BGPParserTest {
         paBuilder.setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build());
         assertEquals(paBuilder.getOrigin(), attrs.getOrigin());
 
-        paBuilder.setAsPath(new AsPathBuilder().setSegments(asPath).build());
+        paBuilder.setAsPath(new AsPathBuilder().setSegments(Collections.<Segments> emptyList()).build());
         assertEquals(paBuilder.getAsPath(), attrs.getAsPath());
 
         paBuilder.setLocalPref(new LocalPrefBuilder().setPref(100L).build());