From 11624c63e3fa95b850e9a4d0e6b4e25e0aa63fb4 Mon Sep 17 00:00:00 2001 From: Duo Zhang Date: Wed, 27 Feb 2019 17:54:30 +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 Signed-off-by: Guanghao Zhang --- .../hbase/client/AsyncNonMetaRegionLocator.java | 8 +++++--- .../hbase/client/TestAsyncNonMetaRegionLocator.java | 11 +++++++++++ 2 files changed, 16 insertions(+), 3 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 9246adbe986..7f25708df2e 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 @@ -17,6 +17,7 @@ */ package org.apache.hadoop.hbase.client; +import static org.apache.hadoop.hbase.HConstants.EMPTY_END_ROW; import static org.apache.hadoop.hbase.HConstants.NINES; import static org.apache.hadoop.hbase.HConstants.ZEROES; import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME; @@ -169,9 +170,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 eeaf99f9ec6..cb09b79240a 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); + } }