BUG-5076: OffSetMap reworked 57/33457/3
authorClaudio D. Gasparini <cgaspari@cisco.com>
Sat, 23 Jan 2016 11:45:09 +0000 (12:45 +0100)
committerClaudio D. Gasparini <cgaspari@cisco.com>
Mon, 25 Jan 2016 20:16:56 +0000 (20:16 +0000)
OffSetMap reworked, removed previously introduced ArrayList

Change-Id: Id429fda477c8a038c1d64ec103b62e625637c1fd
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/OffsetMap.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/OffsetMapTest.java

index 6819ba42f33271f8b1dc364683e0ca20e63e6f04..33b2db4b7674917e6838dd401b4e50da23136ade 100644 (file)
@@ -15,11 +15,12 @@ import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSet.Builder;
 import com.google.common.primitives.UnsignedInteger;
 import java.lang.reflect.Array;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * A map of Router identifier to an offset. Used to maintain a simple
@@ -30,6 +31,7 @@ import java.util.Set;
  * array members and array management features.
  */
 final class OffsetMap {
+    private static final Logger LOG = LoggerFactory.getLogger(OffsetMap.class);
     static final OffsetMap EMPTY = new OffsetMap(Collections.<UnsignedInteger>emptySet());
     private static final LoadingCache<Set<UnsignedInteger>, OffsetMap> OFFSETMAPS = CacheBuilder.newBuilder().weakValues().build(new CacheLoader<Set<UnsignedInteger>, OffsetMap>() {
         @Override
@@ -78,13 +80,24 @@ final class OffsetMap {
 
     OffsetMap without(final UnsignedInteger routerId) {
         final Builder<UnsignedInteger> b = ImmutableSet.builder();
-        final ArrayList<UnsignedInteger> newArray = new ArrayList(Arrays.asList(this.routerIds));
-        newArray.remove(routerId);
-        final UnsignedInteger[] ret = new UnsignedInteger[newArray.size()];
-        b.add(newArray.toArray(ret));
+        int index = indexOfRouterId(routerId);
+        if (index < 0) {
+            LOG.trace("RouterId not found", routerId);
+        }
+        b.add(removeValue(this.routerIds, index));
         return OFFSETMAPS.getUnchecked(b.build());
     }
 
+    private int indexOfRouterId(final UnsignedInteger routerId) {
+        final int startIndex = 0;
+        for (int i = startIndex; i < this.routerIds.length; i++) {
+            if (routerId.equals(this.routerIds[i])) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
     <T> T getValue(final T[] array, final int offset) {
         Preconditions.checkArgument(offset >= 0, "Invalid negative offset %s", offset);
         Preconditions.checkArgument(offset < routerIds.length, "Invalid offset %s for %s router IDs", offset, routerIds.length);
@@ -108,12 +121,17 @@ final class OffsetMap {
         return ret;
     }
 
-    <T> T[] removeValue(final T[] array, final int offset) {
+    <T> T[] removeValue(final T[] oldArray, final int offset) {
+        final int length = oldArray.length;
         Preconditions.checkArgument(offset >= 0, "Invalid negative offset %s", offset);
-        Preconditions.checkArgument(offset < routerIds.length, "Invalid offset %s for %s router IDs", offset, routerIds.length);
-        final ArrayList<T> newArray = new ArrayList(Arrays.asList(array));
-        newArray.remove(offset);
-        final T[] ret = (T[]) Array.newInstance(array.getClass().getComponentType(), newArray.size());
-        return newArray.toArray(ret);
+        Preconditions.checkArgument(offset < routerIds.length, "Invalid offset %s for %s router IDs", offset, length);
+
+        final T[] ret = (T[]) Array.newInstance(oldArray.getClass().getComponentType(), length - 1);
+        System.arraycopy(oldArray, 0, ret, 0, offset);
+        if (offset < length - 1) {
+            System.arraycopy(oldArray, offset + 1, ret, offset, length - offset - 1);
+        }
+
+        return ret;
     }
 }
index 0421e61e9efaef3b5013963cc3769d57711879e1..04dae500ad0fcc1349a1ebec98a7d2fb4de1366e 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.protocol.bgp.rib.impl;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
 import org.junit.Test;
@@ -16,6 +17,7 @@ public class OffsetMapTest {
     private final String LOCAL_ADDRESS = "127.0.0.1";
     private final int LOCAL_ADDRESS_DECIMAL = 0x7f000001;
     private final Integer[] TESTED_VALUES = { 1, 2, 3, 4, 5, 6, 7 };
+    private final Integer[] TESTED_VALUES_REMOVE = {2, 3, 4, 5, 6, 7 };
     private final int EXPECTED_ROUTER_OFFSET = 0;
     private final int EXPECTED_VALUE = 1;
     private final int CHANGED_VALUE = 111;
@@ -29,7 +31,7 @@ public class OffsetMapTest {
         assertEquals(EXPECTED_VALUE, (int) offsetMap.getValue(TESTED_VALUES, EXPECTED_ROUTER_OFFSET));
         offsetMap.setValue(TESTED_VALUES, EXPECTED_ROUTER_OFFSET, CHANGED_VALUE);
         assertEquals(CHANGED_VALUE, (int) offsetMap.getValue(TESTED_VALUES, EXPECTED_ROUTER_OFFSET));
-        assertEquals(TESTED_VALUES.length -1,offsetMap.removeValue(TESTED_VALUES, 0).length);
+        assertArrayEquals(TESTED_VALUES_REMOVE, offsetMap.removeValue(TESTED_VALUES, 0));
         assertEquals(0, offsetMap.without(RouterIds.routerIdForAddress(LOCAL_ADDRESS)).size());
     }
 }