X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=bgp%2Fpath-selection-mode%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fprotocol%2Fbgp%2Fmode%2Fimpl%2Fbase%2FBaseRouteEntry.java;h=0105f22044c61bf18e970b6e4fbb3cec745e348f;hb=66855f3a2ab4b7675345c4bedd0b5f0c5a4f05aa;hp=a8be574a836d693593d0b6d5964c3ce0fde6ce54;hpb=30ed05f6e3062f5f45e3467be4ea27f042c0059c;p=bgpcep.git diff --git a/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseRouteEntry.java b/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseRouteEntry.java index a8be574a83..0105f22044 100644 --- a/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseRouteEntry.java +++ b/bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseRouteEntry.java @@ -7,135 +7,145 @@ */ package org.opendaylight.protocol.bgp.mode.impl.base; -import com.google.common.primitives.UnsignedInteger; import java.util.Collections; import java.util.List; import java.util.Optional; -import javax.annotation.concurrent.NotThreadSafe; import org.opendaylight.protocol.bgp.mode.api.RouteEntry; 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.path.attributes.Attributes; -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; import org.opendaylight.yangtools.yang.binding.ChildOf; 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.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@NotThreadSafe -final class BaseRouteEntry, - S extends ChildOf, - R extends Route & ChildOf & Identifiable, - I extends Identifier> implements RouteEntry { - private static final Logger LOG = LoggerFactory.getLogger(BaseRouteEntry.class); - private static final Route[] EMPTY_VALUES = new Route[0]; +final class BaseRouteEntry, S extends ChildOf> + implements RouteEntry { + private static final class Stale extends StaleBestPathRoute { + Stale(final NodeIdentifierWithPredicates nonAddPathRouteKeyIdentifier) { + super(nonAddPathRouteKeyIdentifier); + } - private OffsetMap offsets = OffsetMap.EMPTY; - private R[] values = (R[]) EMPTY_VALUES; - private BaseBestPath bestPath; - private BaseBestPath removedBestPath; + @Override + public List getStaleRouteKeyIdentifiers() { + return Collections.singletonList(getNonAddPathRouteKeyIdentifier()); + } + + @Override + public List getAddPathRouteKeyIdentifiers() { + return Collections.emptyList(); + } - BaseRouteEntry() { + @Override + public boolean isNonAddPathBestPathNew() { + return true; + } } + private static final Logger LOG = LoggerFactory.getLogger(BaseRouteEntry.class); + private static final MapEntryNode[] EMPTY_VALUES = new MapEntryNode[0]; + + private RouterIdOffsets offsets = RouterIdOffsets.EMPTY; + private MapEntryNode[] values = EMPTY_VALUES; + private BaseBestPath bestPath = null; + private BaseBestPath removedBestPath; + @Override - public boolean removeRoute(final UnsignedInteger routerId, final long remotePathId) { - final int offset = this.offsets.offsetOf(routerId); - this.values = this.offsets.removeValue(this.values, offset, (R[]) EMPTY_VALUES); - this.offsets = this.offsets.without(routerId); - return this.offsets.isEmpty(); + public boolean removeRoute(final RouterId routerId, final Uint32 remotePathId) { + final int offset = offsets.offsetOf(routerId); + values = offsets.removeValue(values, offset, EMPTY_VALUES); + offsets = offsets.without(routerId); + return offsets.isEmpty(); } - private R createRoute(final RIBSupport ribSup, final String routeKey, final long pathId, - final BaseBestPath path) { - final R route = this.offsets.getValue(this.values, this.offsets.offsetOf(path.getRouterId())); - return ribSup.createRoute(route, routeKey, pathId, path.getAttributes()); + private MapEntryNode createRoute(final RIBSupport ribSup, final String routeKey) { + final MapEntryNode route = offsets.getValue(values, offsets.offsetOf(bestPath.getRouterId())); + return ribSup.createRoute(route, ribSup.createRouteListArgument(routeKey), bestPath.getAttributes()); } @Override - public boolean selectBest(final long localAs) { + public boolean selectBest(final RIBSupport ribSupport, final long localAs) { /* * FIXME: optimize flaps by making sure we consider stability of currently-selected route. */ final BasePathSelector selector = new BasePathSelector(localAs); // Select the best route. - for (int i = 0; i < this.offsets.size(); ++i) { - final UnsignedInteger routerId = this.offsets.getRouterKey(i); - final Attributes attributes = this.offsets.getValue(this.values, i).getAttributes(); + for (int i = 0; i < offsets.size(); ++i) { + final RouterId routerId = offsets.getKey(i); + final ContainerNode attributes = ribSupport.extractAttributes(offsets.getValue(values, i)); LOG.trace("Processing router id {} attributes {}", routerId, attributes); selector.processPath(routerId, attributes); } // Get the newly-selected best path. final BaseBestPath newBestPath = selector.result(); - final boolean modified = newBestPath == null || !newBestPath.equals(this.bestPath); + final boolean modified = newBestPath == null || !newBestPath.equals(bestPath); if (modified) { - if (this.offsets.isEmpty()) { - this.removedBestPath = this.bestPath; + if (offsets.isEmpty()) { + removedBestPath = bestPath; } - LOG.trace("Previous best {}, current best {}", this.bestPath, newBestPath); - this.bestPath = newBestPath; + LOG.trace("Previous best {}, current best {}", bestPath, newBestPath); + bestPath = newBestPath; } return modified; } @Override - public int addRoute(final UnsignedInteger routerId, final long remotePathId, final R route) { - int offset = this.offsets.offsetOf(routerId); + public int addRoute(final RouterId routerId, final Uint32 remotePathId, final MapEntryNode route) { + int offset = offsets.offsetOf(routerId); if (offset < 0) { - final OffsetMap newOffsets = this.offsets.with(routerId); + final RouterIdOffsets newOffsets = offsets.with(routerId); offset = newOffsets.offsetOf(routerId); - this.values = newOffsets.expand(this.offsets, this.values, offset); - this.offsets = newOffsets; + values = newOffsets.expand(offsets, values, offset); + offsets = newOffsets; } - this.offsets.setValue(this.values, offset, route); + offsets.setValue(values, offset, route); LOG.trace("Added route {} from {}", route, routerId); return offset; } @Override - public Optional> removeStalePaths(final RIBSupport ribSupport, - final String routeKey) { - if (this.removedBestPath == null) { + public Optional removeStalePaths(final RIBSupport ribSupport, final String routeKey) { + if (removedBestPath == null) { return Optional.empty(); } - final StaleBestPathRoute stale = new StaleBestPathRoute<>(ribSupport, routeKey); - this.removedBestPath = null; - return Optional.of(stale); + removedBestPath = null; + return Optional.of(new Stale(ribSupport.createRouteListArgument(routeKey))); } @Override - public List> newBestPaths(final RIBSupport ribSupport, - final String routeKey) { - if (this.bestPath == null) { + public List> newBestPaths(final RIBSupport ribSupport, final String routeKey) { + if (bestPath == null) { return Collections.emptyList(); } - final R route = createRoute(ribSupport, routeKey, this.bestPath.getPathId(), this.bestPath); - final AdvertizedRoute adv = new AdvertizedRoute<>(ribSupport, route, this.bestPath.getAttributes(), - this.bestPath.getPeerId(), this.bestPath.isDepreferenced()); + final MapEntryNode route = createRoute(ribSupport, routeKey); + final AdvertizedRoute adv = new AdvertizedRoute<>(ribSupport, route, bestPath.getAttributes(), + bestPath.getPeerId(), bestPath.isDepreferenced()); LOG.trace("Selected best route {}", route); return Collections.singletonList(adv); } @Override - public List> actualBestPaths(final RIBSupport ribSupport, + public List> actualBestPaths(final RIBSupport ribSupport, final RouteEntryInfo entryInfo) { - if (this.bestPath == null) { + if (bestPath == null) { return Collections.emptyList(); } - final R route = createRoute(ribSupport, entryInfo.getRouteKey(), this.bestPath.getPathId(), this.bestPath); - return Collections.singletonList(new ActualBestPathRoutes<>(ribSupport, route, this.bestPath.getPeerId(), - this.bestPath.getAttributes(), this.bestPath.isDepreferenced())); + final MapEntryNode route = createRoute(ribSupport, entryInfo.getRouteKey()); + return Collections.singletonList(new ActualBestPathRoutes<>(ribSupport, route, bestPath.getPeerId(), + bestPath.getAttributes(), bestPath.isDepreferenced())); } } \ No newline at end of file