YANG revision dates mass-update
[bgpcep.git] / bgp / path-selection-mode / src / main / java / org / opendaylight / protocol / bgp / mode / impl / add / AddPathAbstractRouteEntry.java
index 2854630872e593dcc47164f89fd5741f92529355..56eab86aeff32fc1cba342d1f7821663efb1e930 100644 (file)
@@ -12,21 +12,21 @@ import static org.opendaylight.protocol.bgp.parser.spi.PathIdUtil.NON_PATH_ID;
 import static org.opendaylight.protocol.bgp.parser.spi.PathIdUtil.NON_PATH_ID_VALUE;
 
 import com.google.common.collect.ImmutableList;
-import com.google.common.primitives.UnsignedInteger;
+import com.google.common.collect.Lists;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
-import javax.annotation.concurrent.NotThreadSafe;
 import org.opendaylight.protocol.bgp.mode.api.RouteEntry;
 import org.opendaylight.protocol.bgp.mode.impl.BestPathStateImpl;
 import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
+import org.opendaylight.protocol.bgp.rib.spi.RouterId;
 import org.opendaylight.protocol.bgp.rib.spi.entry.ActualBestPathRoutes;
 import org.opendaylight.protocol.bgp.rib.spi.entry.AdvertizedRoute;
 import org.opendaylight.protocol.bgp.rib.spi.entry.RouteEntryInfo;
 import org.opendaylight.protocol.bgp.rib.spi.entry.StaleBestPathRoute;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.PathId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.Route;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
@@ -35,57 +35,94 @@ import org.opendaylight.yangtools.yang.binding.ChoiceIn;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.Identifiable;
 import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.common.Uint32;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * A single route entry inside a route table. Maintains the attributes of
- * from all contributing peers. The information is stored in arrays with a
- * shared map of offsets for peers to allow lookups. This is needed to
- * maintain low memory overhead in face of large number of routes and peers,
- * where individual object overhead becomes the dominating factor.
+ * A single route entry inside a route table. Maintains the attributes from all contributing peers. The information is
+ * stored in arrays with a shared map of offsets for peers to allow lookups. This is needed to maintain low memory
+ * overhead in face of large number of routes and peers, where individual object overhead becomes the dominating factor.
+ *
+ * <p>
+ * This class is NOT thread-safe.
  */
-@NotThreadSafe
 public abstract class AddPathAbstractRouteEntry<C extends Routes & DataObject & ChoiceIn<Tables>,
-        S extends ChildOf<? super C>,
-        R extends Route & ChildOf<? super S> & Identifiable<I>, I extends Identifier<R>>
+        S extends ChildOf<? super C>, R extends Route & ChildOf<? super S> & Identifiable<I>, I extends Identifier<R>>
         implements RouteEntry<C, S, R, I> {
+    private static final class Stale<C extends Routes & DataObject & ChoiceIn<Tables>,
+            S extends ChildOf<? super C>, R extends Route & ChildOf<? super S> & Identifiable<I>,
+            I extends Identifier<R>> extends StaleBestPathRoute<C, S, R, I> {
+        private final List<I> addPathRouteKeyIdentifier;
+        private final List<I> staleRouteKeyIdentifier;
+        private final boolean isNonAddPathBestPathNew;
+
+        Stale(final RIBSupport<C, S, R, I> ribSupport, final String routeKey, final List<PathId> staleRoutesPathIds,
+            final List<PathId> withdrawalRoutePathIds, final boolean isNonAddPathBestPathNew) {
+            super(ribSupport.createRouteListKey(routeKey));
+            this.isNonAddPathBestPathNew = isNonAddPathBestPathNew;
+
+            this.staleRouteKeyIdentifier = staleRoutesPathIds.stream()
+                    .map(pathId -> ribSupport.createRouteListKey(pathId, routeKey)).collect(Collectors.toList());
+            if (withdrawalRoutePathIds != null) {
+                this.addPathRouteKeyIdentifier = withdrawalRoutePathIds.stream()
+                        .map(pathId -> ribSupport.createRouteListKey(pathId, routeKey)).collect(Collectors.toList());
+            } else {
+                this.addPathRouteKeyIdentifier = Collections.emptyList();
+            }
+        }
+
+        @Override
+        public List<I> getStaleRouteKeyIdentifiers() {
+            return this.staleRouteKeyIdentifier;
+        }
+
+        @Override
+        public List<I> getAddPathRouteKeyIdentifiers() {
+            return addPathRouteKeyIdentifier;
+        }
+
+        @Override
+        public boolean isNonAddPathBestPathNew() {
+            return isNonAddPathBestPathNew;
+        }
+    }
 
     private static final Logger LOG = LoggerFactory.getLogger(AddPathAbstractRouteEntry.class);
-    private static final Long[] EMPTY_PATHS_ID = new Long[0];
+    private static final Uint32[] EMPTY_PATHS_ID = new Uint32[0];
     private static final Route[] EMPTY_VALUES = new Route[0];
 
-    private OffsetMap offsets = OffsetMap.EMPTY;
+    private RouteKeyOffsets offsets = RouteKeyOffsets.EMPTY;
     private R[] values = (R[]) EMPTY_VALUES;
-    private Long[] pathsId = EMPTY_PATHS_ID;
+    private Uint32[] pathsId = EMPTY_PATHS_ID;
     private List<AddPathBestPath> bestPath;
     private List<AddPathBestPath> bestPathRemoved;
     private List<AddPathBestPath> newBestPathToBeAdvertised;
-    private List<Long> removedPathsId;
+    private List<Uint32> removedPathsId;
 
     private long pathIdCounter = 0L;
     private boolean isNonAddPathBestPathNew;
 
     private R createRoute(final RIBSupport<C, S, R, I> ribSup, final String routeKey, final AddPathBestPath path) {
-        final OffsetMap map = this.offsets;
+        final RouteKeyOffsets map = this.offsets;
         final R route = map.getValue(this.values, map.offsetOf(path.getRouteKey()));
         return ribSup.createRoute(route, ribSup.createRouteListKey(pathIdObj(path.getPathIdLong()), routeKey),
             path.getAttributes());
     }
 
     @Override
-    public final int addRoute(final UnsignedInteger routerId, final Long remotePathId, final R route) {
+    public final int addRoute(final RouterId routerId, final Uint32 remotePathId, final R route) {
         final RouteKey key = new RouteKey(routerId, remotePathId);
         int offset = this.offsets.offsetOf(key);
         if (offset < 0) {
-            final OffsetMap newOffsets = this.offsets.with(key);
+            final RouteKeyOffsets newOffsets = this.offsets.with(key);
             offset = newOffsets.offsetOf(key);
             final R[] newRoute = newOffsets.expand(this.offsets, this.values, offset);
-            final Long[] newPathsId = newOffsets.expand(this.offsets, this.pathsId, offset);
+            final Uint32[] newPathsId = newOffsets.expand(this.offsets, this.pathsId, offset);
             this.values = newRoute;
             this.offsets = newOffsets;
             this.pathsId = newPathsId;
-            this.offsets.setValue(this.pathsId, offset, ++this.pathIdCounter);
+            this.offsets.setValue(this.pathsId, offset, Uint32.valueOf(++this.pathIdCounter));
         }
         this.offsets.setValue(this.values, offset, route);
         LOG.trace("Added route {} from {}", route, routerId);
@@ -93,10 +130,10 @@ public abstract class AddPathAbstractRouteEntry<C extends Routes & DataObject &
     }
 
     @Override
-    public final boolean removeRoute(final UnsignedInteger routerId, final Long remotePathId) {
+    public final boolean removeRoute(final RouterId routerId, final Uint32 remotePathId) {
         final RouteKey key = new RouteKey(routerId, remotePathId);
         final int offset = this.offsets.offsetOf(key);
-        final Long pathId = this.offsets.getValue(this.pathsId, offset);
+        final Uint32 pathId = this.offsets.getValue(this.pathsId, offset);
         this.values = this.offsets.removeValue(this.values, offset, (R[]) EMPTY_VALUES);
         this.pathsId = this.offsets.removeValue(this.pathsId, offset, EMPTY_PATHS_ID);
         this.offsets = this.offsets.without(key);
@@ -110,18 +147,25 @@ public abstract class AddPathAbstractRouteEntry<C extends Routes & DataObject &
     @Override
     public final Optional<StaleBestPathRoute<C, S, R, I>> removeStalePaths(final RIBSupport<C, S, R, I> ribSupport,
             final String routeKey) {
-        if ((this.bestPathRemoved == null || this.bestPathRemoved.isEmpty()) && this.removedPathsId == null) {
-            return Optional.empty();
+        final List<PathId> stalePaths;
+        if (bestPathRemoved != null && !bestPathRemoved.isEmpty()) {
+            stalePaths = bestPathRemoved.stream().map(AddPathBestPath::getPathIdLong)
+                    .map(AddPathAbstractRouteEntry::pathIdObj).collect(Collectors.toList());
+            bestPathRemoved = null;
+        } else {
+            stalePaths = Collections.emptyList();
         }
-        List<Long> stalePaths = Collections.emptyList();
-        if (this.bestPathRemoved != null && !this.bestPathRemoved.isEmpty()) {
-            stalePaths = this.bestPathRemoved.stream().map(AddPathBestPath::getPathId).collect(Collectors.toList());
-            this.bestPathRemoved = null;
+
+        List<PathId> removedPaths;
+        if (removedPathsId != null) {
+            removedPaths = Lists.transform(removedPathsId, AddPathAbstractRouteEntry::pathIdObj);
+            this.removedPathsId = null;
+        } else {
+            removedPaths = Collections.emptyList();
         }
-        final StaleBestPathRoute<C, S, R, I> stale = new StaleBestPathRoute<>(ribSupport, routeKey, stalePaths,
-                this.removedPathsId, this.isNonAddPathBestPathNew);
-        this.removedPathsId = null;
-        return Optional.of(stale);
+
+        return stalePaths.isEmpty() && removedPaths.isEmpty() ? Optional.empty()
+                : Optional.of(new Stale<>(ribSupport, routeKey, stalePaths, removedPaths, isNonAddPathBestPathNew));
     }
 
     @Override
@@ -177,7 +221,7 @@ public abstract class AddPathAbstractRouteEntry<C extends Routes & DataObject &
     protected final void processOffset(final AddPathSelector selector, final int offset) {
         final RouteKey key = offsets.getKey(offset);
         final R route = offsets.getValue(values, offset);
-        final Long pathId = offsets.getValue(pathsId, offset);
+        final Uint32 pathId = offsets.getValue(pathsId, offset);
         LOG.trace("Processing router key {} route {}", key, route);
         selector.processPath(route.getAttributes(), key, offset, pathId);
     }
@@ -229,7 +273,7 @@ public abstract class AddPathAbstractRouteEntry<C extends Routes & DataObject &
         });
     }
 
-    private static PathId pathIdObj(final Long pathId) {
-        return pathId == NON_PATH_ID_VALUE ? NON_PATH_ID : new PathId(pathId);
+    private static PathId pathIdObj(final Uint32 pathId) {
+        return NON_PATH_ID_VALUE.equals(pathId) ? NON_PATH_ID : new PathId(pathId);
     }
 }