2222import java .util .ArrayList ;
2323import java .util .Collection ;
2424import java .util .Collections ;
25+ import java .util .Comparator ;
2526import java .util .HashMap ;
2627import java .util .HashSet ;
2728import java .util .List ;
2829import java .util .Map ;
2930import java .util .Set ;
31+ import java .util .SortedSet ;
32+ import java .util .TreeSet ;
3033import java .util .concurrent .CompletableFuture ;
3134import java .util .concurrent .Future ;
3235import java .util .concurrent .TimeUnit ;
@@ -232,12 +235,15 @@ public class AssignmentManager {
232235
233236 private final int forceRegionRetainmentRetries ;
234237
238+ private final RegionInTransitionTracker regionInTransitionTracker ;
239+
235240 public AssignmentManager (MasterServices master , MasterRegion masterRegion ) {
236241 this (master , masterRegion , new RegionStateStore (master , masterRegion ));
237242 }
238243
239244 AssignmentManager (MasterServices master , MasterRegion masterRegion , RegionStateStore stateStore ) {
240245 this .master = master ;
246+ regionInTransitionTracker = new RegionInTransitionTracker (master .getTableStateManager ());
241247 this .regionStateStore = stateStore ;
242248 this .metrics = new MetricsAssignmentManager ();
243249 this .masterRegion = masterRegion ;
@@ -411,6 +417,7 @@ public void stop() {
411417
412418 // Stop the RegionStateStore
413419 regionStates .clear ();
420+ regionInTransitionTracker .clear ();
414421
415422 // Update meta events (for testing)
416423 if (hasProcExecutor ) {
@@ -1093,7 +1100,7 @@ private int submitUnassignProcedure(TableName tableName,
10931100 regionNode .lock ();
10941101 try {
10951102 if (shouldSubmit .apply (regionNode )) {
1096- if (regionNode .isInTransition ()) {
1103+ if (regionNode .isOngoingTRSP ()) {
10971104 logRIT .accept (regionNode );
10981105 inTransitionCount ++;
10991106 continue ;
@@ -1704,7 +1711,7 @@ public boolean isRegionTwiceOverThreshold(final RegionInfo regionInfo) {
17041711 protected void update (final AssignmentManager am ) {
17051712 final RegionStates regionStates = am .getRegionStates ();
17061713 this .statTimestamp = EnvironmentEdgeManager .currentTime ();
1707- update (regionStates .getRegionsStateInTransition (), statTimestamp );
1714+ update (am .getRegionsStateInTransition (), statTimestamp );
17081715 update (regionStates .getRegionFailedOpen (), statTimestamp );
17091716
17101717 if (LOG .isDebugEnabled () && ritsOverThreshold != null && !ritsOverThreshold .isEmpty ()) {
@@ -1794,6 +1801,7 @@ public void joinCluster() throws IOException {
17941801 */
17951802 // Public so can be run by the Master as part of the startup. Needs hbase:meta to be online.
17961803 // Needs to be done after the table state manager has been started.
1804+ //TODO umesh we can update the rit map here
17971805 public void processOfflineRegions () {
17981806 TransitRegionStateProcedure [] procs =
17991807 regionStates .getRegionStateNodes ().stream ().filter (rsn -> rsn .isInState (State .OFFLINE ))
@@ -1873,6 +1881,7 @@ public void visitRegionState(Result result, final RegionInfo regionInfo, final S
18731881 if (regionNode .getProcedure () != null ) {
18741882 regionNode .getProcedure ().stateLoaded (AssignmentManager .this , regionNode );
18751883 }
1884+ regionInTransitionTracker .handleRegionStateNodeOperation (regionNode );
18761885 }
18771886 };
18781887
@@ -2046,17 +2055,59 @@ public Pair<Integer, Integer> getReopenStatus(TableName tableName) {
20462055 return new Pair <Integer , Integer >(ritCount , states .size ());
20472056 }
20482057
2058+ // This comparator sorts the RegionStates by time stamp then Region name.
2059+ // Comparing by timestamp alone can lead us to discard different RegionStates that happen
2060+ // to share a timestamp.
2061+ private static class RegionStateStampComparator implements Comparator <RegionState > {
2062+ @ Override
2063+ public int compare (final RegionState l , final RegionState r ) {
2064+ int stampCmp = Long .compare (l .getStamp (), r .getStamp ());
2065+ return stampCmp != 0 ? stampCmp : RegionInfo .COMPARATOR .compare (l .getRegion (), r .getRegion ());
2066+ }
2067+ }
2068+
2069+ public final static RegionStateStampComparator REGION_STATE_STAMP_COMPARATOR =
2070+ new RegionStateStampComparator ();
2071+
20492072 // ============================================================================================
20502073 // TODO: Region State In Transition
20512074 // ============================================================================================
20522075 public boolean hasRegionsInTransition () {
2053- return regionStates .hasRegionsInTransition ();
2076+ return regionInTransitionTracker .hasRegionsInTransition ();
20542077 }
20552078
20562079 public List <RegionStateNode > getRegionsInTransition () {
2057- return regionStates .getRegionsInTransition ();
2080+ return new ArrayList < RegionStateNode >( regionInTransitionTracker .getRegionsInTransition (). values () );
20582081 }
20592082
2083+ public boolean isRegionInTransition (final RegionInfo regionInfo ) {
2084+ return regionInTransitionTracker .isRegionInTransition (regionInfo );
2085+ }
2086+
2087+ /**
2088+ * Get the number of regions in transition.
2089+ */
2090+ public int getRegionsInTransitionCount () {
2091+ return regionInTransitionTracker .getRegionsInTransition ().size ();
2092+ }
2093+
2094+ public List <RegionState > getRegionsStateInTransition () {
2095+ final List <RegionState > rit = new ArrayList <RegionState >(getRegionsInTransitionCount ());
2096+ for (RegionStateNode node : getRegionsInTransition ()) {
2097+ rit .add (node .toRegionState ());
2098+ }
2099+ return rit ;
2100+ }
2101+
2102+ public SortedSet <RegionState > getRegionsInTransitionOrderedByTimestamp () {
2103+ final SortedSet <RegionState > rit = new TreeSet <RegionState >(REGION_STATE_STAMP_COMPARATOR );
2104+ for (RegionStateNode node : getRegionsInTransition ()) {
2105+ rit .add (node .toRegionState ());
2106+ }
2107+ return rit ;
2108+ }
2109+
2110+
20602111 public List <RegionInfo > getAssignedRegions () {
20612112 return regionStates .getAssignedRegions ();
20622113 }
@@ -2122,6 +2173,8 @@ private CompletableFuture<Void> transitStateAndUpdate(RegionStateNode regionNode
21222173 if (e != null ) {
21232174 // revert
21242175 regionNode .setState (state );
2176+ }else {
2177+ regionInTransitionTracker .handleRegionStateNodeOperation (regionNode );
21252178 }
21262179 });
21272180 return future ;
@@ -2170,6 +2223,7 @@ CompletableFuture<Void> regionFailedOpen(RegionStateNode regionNode, boolean giv
21702223 if (regionLocation != null ) {
21712224 regionStates .removeRegionFromServer (regionLocation , regionNode );
21722225 }
2226+ regionInTransitionTracker .handleRegionStateNodeOperation (regionNode );
21732227 } else {
21742228 // revert
21752229 regionNode .setState (state );
@@ -2230,6 +2284,7 @@ CompletableFuture<Void> persistToMeta(RegionStateNode regionNode) {
22302284 // on table that contains state.
22312285 setMetaAssigned (regionInfo , true );
22322286 }
2287+ regionInTransitionTracker .handleRegionStateNodeOperation (regionNode );
22332288 });
22342289 }
22352290
@@ -2247,6 +2302,7 @@ public CompletableFuture<Void> regionClosedAbnormally(RegionStateNode regionNode
22472302 regionNode .setLastHost (regionLocation );
22482303 regionStates .removeRegionFromServer (regionLocation , regionNode );
22492304 }
2305+ regionInTransitionTracker .handleRegionStateNodeOperation (regionNode );
22502306 } else {
22512307 // revert
22522308 regionNode .setState (state );
@@ -2307,6 +2363,7 @@ public void markRegionAsMerged(final RegionInfo child, final ServerName serverNa
23072363 for (RegionInfo ri : mergeParents ) {
23082364 regionStates .deleteRegion (ri );
23092365 }
2366+ //TODO need to handle delete and new region
23102367 TableDescriptor td = master .getTableDescriptors ().get (child .getTable ());
23112368 regionStateStore .mergeRegions (child , mergeParents , serverName , td );
23122369 if (shouldAssignFavoredNodes (child )) {
0 commit comments