Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.client;
import static org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil.findException;
import static org.apache.hadoop.hbase.exceptions.ClientExceptionsUtil.isMetaClearingException;
import java.util.Arrays;
import java.util.function.Consumer;
import java.util.function.Function;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.RegionLocations;
import org.apache.hadoop.hbase.exceptions.RegionMovedException;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Helper class for asynchronous region locator.
*/
@InterfaceAudience.Private
final class AsyncRegionLocatorHelper {
private static final Logger LOG = LoggerFactory.getLogger(AsyncRegionLocatorHelper.class);
private AsyncRegionLocatorHelper() {
}
static boolean canUpdateOnError(HRegionLocation loc, HRegionLocation oldLoc) {
// Do not need to update if no such location, or the location is newer, or the location is not
// the same with us
return oldLoc != null && oldLoc.getSeqNum() <= loc.getSeqNum() &&
oldLoc.getServerName().equals(loc.getServerName());
}
static void updateCachedLocationOnError(HRegionLocation loc, Throwable exception,
Function cachedLocationSupplier,
Consumer addToCache, Consumer removeFromCache) {
HRegionLocation oldLoc = cachedLocationSupplier.apply(loc);
LOG.debug("Try updating {} , the old value is {}", loc, oldLoc, exception);
if (!canUpdateOnError(loc, oldLoc)) {
return;
}
Throwable cause = findException(exception);
LOG.debug("The actual exception when updating {}", loc, cause);
if (cause == null || !isMetaClearingException(cause)) {
LOG.debug("Will not update {} because the exception is null or not the one we care about",
loc);
return;
}
if (cause instanceof RegionMovedException) {
RegionMovedException rme = (RegionMovedException) cause;
HRegionLocation newLoc =
new HRegionLocation(loc.getRegion(), rme.getServerName(), rme.getLocationSeqNum());
LOG.debug("Try updating {} with the new location {} constructed by {}", loc, newLoc, rme);
addToCache.accept(newLoc);
} else {
LOG.debug("Try removing {} from cache", loc);
removeFromCache.accept(loc);
}
}
static RegionLocations createRegionLocations(HRegionLocation loc) {
int replicaId = loc.getRegion().getReplicaId();
HRegionLocation[] locs = new HRegionLocation[replicaId + 1];
locs[replicaId] = loc;
return new RegionLocations(locs);
}
/**
* Create a new {@link RegionLocations} based on the given {@code oldLocs}, and replace the
* location for the given {@code replicaId} with the given {@code loc}.
*
* All the {@link RegionLocations} in async locator related class are immutable because we want to
* access them concurrently, so here we need to create a new one, instead of calling
* {@link RegionLocations#updateLocation(HRegionLocation, boolean, boolean)}.
*/
static RegionLocations replaceRegionLocation(RegionLocations oldLocs, HRegionLocation loc) {
int replicaId = loc.getRegion().getReplicaId();
HRegionLocation[] locs = oldLocs.getRegionLocations();
locs = Arrays.copyOf(locs, Math.max(replicaId + 1, locs.length));
locs[replicaId] = loc;
return new RegionLocations(locs);
}
/**
* Create a new {@link RegionLocations} based on the given {@code oldLocs}, and remove the
* location for the given {@code replicaId}.
*
* All the {@link RegionLocations} in async locator related class are immutable because we want to
* access them concurrently, so here we need to create a new one, instead of calling
* {@link RegionLocations#remove(int)}.
*/
static RegionLocations removeRegionLocation(RegionLocations oldLocs, int replicaId) {
HRegionLocation[] locs = oldLocs.getRegionLocations();
if (locs.length < replicaId + 1) {
// Here we do not modify the oldLocs so it is safe to return it.
return oldLocs;
}
locs = Arrays.copyOf(locs, locs.length);
locs[replicaId] = null;
if (ObjectUtils.firstNonNull(locs) != null) {
return new RegionLocations(locs);
} else {
// if all the locations are null, just return null
return null;
}
}
/**
* Create a new {@link RegionLocations} which is the merging result for the given two
* {@link RegionLocations}.
*
* All the {@link RegionLocations} in async locator related class are immutable because we want to
* access them concurrently, so here we need to create a new one, instead of calling
* {@link RegionLocations#mergeLocations(RegionLocations)} directly.
*/
static RegionLocations mergeRegionLocations(RegionLocations newLocs, RegionLocations oldLocs) {
RegionLocations locs = new RegionLocations(newLocs.getRegionLocations());
locs.mergeLocations(oldLocs);
return locs;
}
static boolean isGood(RegionLocations locs, int replicaId) {
if (locs == null) {
return false;
}
HRegionLocation loc = locs.getRegionLocation(replicaId);
return loc != null && loc.getServerName() != null;
}
}