diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStates.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStates.java index 8d22c0e065f..356b0866976 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStates.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/RegionStates.java @@ -76,10 +76,17 @@ public class RegionStates { * RegionName -- i.e. RegionInfo.getRegionName() -- as bytes to {@link RegionStateNode} */ private final ConcurrentSkipListMap regionsMap = - new ConcurrentSkipListMap(Bytes.BYTES_COMPARATOR); + new ConcurrentSkipListMap<>(Bytes.BYTES_COMPARATOR); + + /** + * this map is a hack to lookup of region in master by encoded region name is O(n). + * must put and remove with regionsMap. + */ + private final ConcurrentSkipListMap encodedRegionsMap = + new ConcurrentSkipListMap<>(); private final ConcurrentSkipListMap regionInTransition = - new ConcurrentSkipListMap(RegionInfo.COMPARATOR); + new ConcurrentSkipListMap<>(RegionInfo.COMPARATOR); /** * Regions marked as offline on a read of hbase:meta. Unused or at least, once @@ -101,6 +108,7 @@ public class RegionStates { */ public void clear() { regionsMap.clear(); + encodedRegionsMap.clear(); regionInTransition.clear(); regionOffline.clear(); serverMap.clear(); @@ -117,8 +125,11 @@ public class RegionStates { // ========================================================================== @VisibleForTesting RegionStateNode createRegionStateNode(RegionInfo regionInfo) { - return regionsMap.computeIfAbsent(regionInfo.getRegionName(), - key -> new RegionStateNode(regionInfo, regionInTransition)); + return regionsMap.computeIfAbsent(regionInfo.getRegionName(), key -> { + final RegionStateNode node = new RegionStateNode(regionInfo, regionInTransition); + encodedRegionsMap.putIfAbsent(regionInfo.getEncodedName(), node); + return node; + }); } public RegionStateNode getOrCreateRegionStateNode(RegionInfo regionInfo) { @@ -136,6 +147,7 @@ public class RegionStates { public void deleteRegion(final RegionInfo regionInfo) { regionsMap.remove(regionInfo.getRegionName()); + encodedRegionsMap.remove(regionInfo.getEncodedName()); // See HBASE-20860 // After master restarts, merged regions' RIT state may not be cleaned, // making sure they are cleaned here @@ -203,13 +215,11 @@ public class RegionStates { } public RegionState getRegionState(final String encodedRegionName) { - // TODO: Need a map but it is just dispatch merge... - for (RegionStateNode node: regionsMap.values()) { - if (node.getRegionInfo().getEncodedName().equals(encodedRegionName)) { - return node.toRegionState(); - } + final RegionStateNode node = encodedRegionsMap.get(encodedRegionName); + if (node == null) { + return null; } - return null; + return node.toRegionState(); } // ============================================================================================