public void cacheLocation(final TableName tableName, final ServerName source,
final HRegionLocation location) {
assert source != null;
byte [] startKey = location.getRegionInfo().getStartKey();
ConcurrentMap<byte[], RegionLocations> tableLocations = getTableLocations(tableName);
RegionLocations locations = new RegionLocations(new HRegionLocation[] {location}) ;
RegionLocations oldLocations = tableLocations.putIfAbsent(startKey, locations);
boolean isNewCacheEntry = (oldLocations == null);
if (isNewCacheEntry) {
if (LOG.isTraceEnabled()) {
LOG.trace("Cached location: " + location);
}
addToCachedServers(locations);
return;
}
// If the server in cache sends us a redirect, assume it's always valid.
HRegionLocation oldLocation = oldLocations.getRegionLocation(
location.getRegionInfo().getReplicaId());
boolean force = oldLocation != null && oldLocation.getServerName() != null
&& oldLocation.getServerName().equals(source);
// For redirect if the number is equal to previous
// record, the most common case is that first the region was closed with seqNum, and then
// opened with the same seqNum; hence we will ignore the redirect.
// There are so many corner cases with various combinations of opens and closes that
// an additional counter on top of seqNum would be necessary to handle them all.
RegionLocations updatedLocations = oldLocations.updateLocation(location, false, force);
if (oldLocations != updatedLocations) {
boolean replaced = tableLocations.replace(startKey, oldLocations, updatedLocations);
if (replaced && LOG.isTraceEnabled()) {
LOG.trace("Changed cached location to: " + location);
}