HBASE-5489 Add HTable accessor to get regions for a key range

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1295729 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Stack 2012-03-01 18:43:29 +00:00
parent dace419238
commit 7147bc5424
2 changed files with 89 additions and 0 deletions

View File

@ -491,6 +491,35 @@ public class HTable implements HTableInterface {
return MetaScanner.allTableRegions(getConfiguration(), getTableName(), false);
}
/**
* Get the corresponding regions for an arbitrary range of keys.
* <p>
* @param startRow Starting row in range, inclusive
* @param endRow Ending row in range, inclusive
* @return A list of HRegionLocations corresponding to the regions that
* contain the specified range
* @throws IOException if a remote or network exception occurs
*/
public List<HRegionLocation> getRegionsInRange(final byte [] startKey,
final byte [] endKey) throws IOException {
final boolean endKeyIsEndOfTable = Bytes.equals(endKey,
HConstants.EMPTY_END_ROW);
if ((Bytes.compareTo(startKey, endKey) > 0) && !endKeyIsEndOfTable) {
throw new IllegalArgumentException(
"Invalid range: " + Bytes.toStringBinary(startKey) +
" > " + Bytes.toStringBinary(endKey));
}
final List<HRegionLocation> regionList = new ArrayList<HRegionLocation>();
byte [] currentKey = startKey;
do {
HRegionLocation regionLocation = getRegionLocation(currentKey, false);
regionList.add(regionLocation);
currentKey = regionLocation.getRegionInfo().getEndKey();
} while (!Bytes.equals(currentKey, HConstants.EMPTY_END_ROW) &&
(endKeyIsEndOfTable || Bytes.compareTo(currentKey, endKey) < 0));
return regionList;
}
/**
* Save the passed region information and the table's regions
* cache.

View File

@ -57,6 +57,7 @@ import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.HServerAddress;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
@ -4594,6 +4595,65 @@ public class TestFromClientSide {
assertTrue(addrAfter.getPort() != addrCache.getPort());
assertEquals(addrAfter.getPort(), addrNoCache.getPort());
}
@Test
/**
* Tests getRegionsInRange by creating some regions over which a range of
* keys spans; then changing the key range.
*/
public void testGetRegionsInRange() throws Exception {
// Test Initialization.
byte [] startKey = Bytes.toBytes("ddc");
byte [] endKey = Bytes.toBytes("mmm");
byte [] TABLE = Bytes.toBytes("testGetRegionsInRange");
HTable table = TEST_UTIL.createTable(TABLE, new byte[][] {FAMILY}, 10);
int numOfRegions = TEST_UTIL.createMultiRegions(table, FAMILY);
assertEquals(25, numOfRegions);
HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
// Get the regions in this range
List<HRegionLocation> regionsList = table.getRegionsInRange(startKey,
endKey);
assertEquals(10, regionsList.size());
// Change the start key
startKey = Bytes.toBytes("fff");
regionsList = table.getRegionsInRange(startKey, endKey);
assertEquals(7, regionsList.size());
// Change the end key
endKey = Bytes.toBytes("nnn");
regionsList = table.getRegionsInRange(startKey, endKey);
assertEquals(8, regionsList.size());
// Empty start key
regionsList = table.getRegionsInRange(HConstants.EMPTY_START_ROW, endKey);
assertEquals(13, regionsList.size());
// Empty end key
regionsList = table.getRegionsInRange(startKey, HConstants.EMPTY_END_ROW);
assertEquals(20, regionsList.size());
// Both start and end keys empty
regionsList = table.getRegionsInRange(HConstants.EMPTY_START_ROW,
HConstants.EMPTY_END_ROW);
assertEquals(25, regionsList.size());
// Change the end key to somewhere in the last block
endKey = Bytes.toBytes("yyz");
regionsList = table.getRegionsInRange(startKey, endKey);
assertEquals(20, regionsList.size());
// Change the start key to somewhere in the first block
startKey = Bytes.toBytes("aac");
regionsList = table.getRegionsInRange(startKey, endKey);
assertEquals(25, regionsList.size());
// Make start and end key the same
startKey = endKey = Bytes.toBytes("ccc");
regionsList = table.getRegionsInRange(startKey, endKey);
assertEquals(1, regionsList.size());
}
@org.junit.Rule
public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();