diff --git a/xds/src/main/java/io/grpc/xds/LocalityStore.java b/xds/src/main/java/io/grpc/xds/LocalityStore.java index 27da4a8aff..05f75eb1f3 100644 --- a/xds/src/main/java/io/grpc/xds/LocalityStore.java +++ b/xds/src/main/java/io/grpc/xds/LocalityStore.java @@ -26,6 +26,7 @@ import static io.grpc.ConnectivityState.TRANSIENT_FAILURE; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import io.grpc.ConnectivityState; import io.grpc.ConnectivityStateInfo; import io.grpc.EquivalentAddressGroup; @@ -49,9 +50,8 @@ import io.grpc.xds.XdsComms.LocalityInfo; import io.grpc.xds.XdsSubchannelPickers.ErrorPicker; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -84,7 +84,7 @@ interface LocalityStore { private final StatsStore statsStore; private final OrcaPerRequestUtil orcaPerRequestUtil; - private Map localityMap = new HashMap<>(); + private Map localityMap = ImmutableMap.of(); private ImmutableList dropOverloads = ImmutableList.of(); LocalityStoreImpl(Helper helper, LoadBalancerRegistry lbRegistry) { @@ -177,7 +177,7 @@ interface LocalityStore { localityMap.get(locality).shutdown(); statsStore.removeLocality(locality); } - localityMap = new HashMap<>(); + localityMap = ImmutableMap.of(); } // This is triggered by EDS response. @@ -185,20 +185,14 @@ interface LocalityStore { public void updateLocalityStore(Map localityInfoMap) { Set oldLocalities = localityMap.keySet(); Set newLocalities = localityInfoMap.keySet(); + Map updatedLocalityMap = new LinkedHashMap<>(); final Set toRemove = new HashSet<>(); - Iterator iterator = oldLocalities.iterator(); - while (iterator.hasNext()) { - XdsLocality oldLocality = iterator.next(); + for (XdsLocality oldLocality : oldLocalities) { if (!newLocalities.contains(oldLocality)) { toRemove.add(oldLocality); // No graceful transition until a high-level lb graceful transition design is available. localityMap.get(oldLocality).shutdown(); - iterator.remove(); - if (localityMap.isEmpty()) { - // down-size the map - localityMap = new HashMap<>(); - } } } @@ -211,13 +205,12 @@ interface LocalityStore { LocalityLbInfo localityLbInfo; ChildHelper childHelper; if (oldLocalities.contains(newLocality)) { - LocalityLbInfo oldLocalityLbInfo - = localityMap.get(newLocality); + LocalityLbInfo oldLocalityLbInfo = localityMap.get(newLocality); childHelper = oldLocalityLbInfo.childHelper; - localityLbInfo = new LocalityLbInfo( - localityInfoMap.get(newLocality).localityWeight, - oldLocalityLbInfo.childBalancer, - childHelper); + localityLbInfo = + new LocalityLbInfo(oldLocalityLbInfo.localityWeight, + oldLocalityLbInfo.childBalancer, + childHelper); } else { statsStore.addLocality(newLocality); childHelper = new ChildHelper(newLocality, statsStore.getLocalityCounter(newLocality)); @@ -226,8 +219,8 @@ interface LocalityStore { localityInfoMap.get(newLocality).localityWeight, loadBalancerProvider.newLoadBalancer(childHelper), childHelper); - localityMap.put(newLocality, localityLbInfo); } + updatedLocalityMap.put(newLocality, localityLbInfo); // TODO: put endPointWeights into attributes for WRR. localityLbInfo.childBalancer .handleResolvedAddresses( @@ -241,6 +234,7 @@ interface LocalityStore { } newState = aggregateState(newState, childHelper.currentChildState); } + localityMap = Collections.unmodifiableMap(updatedLocalityMap); updatePicker(newState, childPickers);