From e6856f9f12bd229872965697182e9ddbbd7cb8a9 Mon Sep 17 00:00:00 2001 From: Duo Zhang Date: Wed, 27 Feb 2019 11:08:28 +0800 Subject: [PATCH] HBASE-21961 Infinite loop in AsyncNonMetaRegionLocator if there is only one region and we tried to locate before a non empty row --- .../hbase/client/AsyncNonMetaRegionLocator.java | 9 +++++---- .../hbase/client/TestAsyncNonMetaRegionLocator.java | 11 +++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java index 9246adbe98..9214c8e0fc 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/AsyncNonMetaRegionLocator.java @@ -18,7 +18,7 @@ package org.apache.hadoop.hbase.client; import static org.apache.hadoop.hbase.HConstants.NINES; -import static org.apache.hadoop.hbase.HConstants.ZEROES; +import static org.apache.hadoop.hbase.HConstants.*; import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME; import static org.apache.hadoop.hbase.client.AsyncRegionLocatorHelper.canUpdateOnError; import static org.apache.hadoop.hbase.client.AsyncRegionLocatorHelper.createRegionLocations; @@ -169,9 +169,10 @@ class AsyncNonMetaRegionLocator { // startKey < req.row and endKey >= req.row. Here we split it to endKey == req.row || // (endKey > req.row && startKey < req.row). The two conditions are equal since startKey < // endKey. - int c = Bytes.compareTo(loc.getRegion().getEndKey(), req.row); - completed = - c == 0 || (c > 0 && Bytes.compareTo(loc.getRegion().getStartKey(), req.row) < 0); + byte[] endKey = loc.getRegion().getEndKey(); + int c = Bytes.compareTo(endKey, req.row); + completed = c == 0 || ((c > 0 || Bytes.equals(EMPTY_END_ROW, endKey)) && + Bytes.compareTo(loc.getRegion().getStartKey(), req.row) < 0); } else { completed = loc.getRegion().containsRow(req.row); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java index eeaf99f9ec..cb09b79240 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java @@ -389,4 +389,15 @@ public class TestAsyncNonMetaRegionLocator { } }); } + + // Testcase for HBASE-21961 + @Test + public void testLocateBeforeInOnlyRegion() throws IOException, InterruptedException { + createSingleRegionTable(); + HRegionLocation loc = + getDefaultRegionLocation(TABLE_NAME, Bytes.toBytes(1), RegionLocateType.BEFORE, false).join(); + // should locate to the only region + assertArrayEquals(loc.getRegion().getStartKey(), EMPTY_START_ROW); + assertArrayEquals(loc.getRegion().getEndKey(), EMPTY_END_ROW); + } } -- 2.17.1