Index: hbase-server/src/main/java/org/apache/hadoop/hbase/client/HTable.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/client/HTable.java (revision 1389206) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/client/HTable.java (working copy) @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.NavigableMap; @@ -525,22 +526,40 @@ */ public List getRegionsInRange(final byte [] startKey, final byte [] endKey) throws IOException { - final boolean endKeyIsEndOfTable = Bytes.equals(endKey, - HConstants.EMPTY_END_ROW); + return new ArrayList(getKeysToRegionsInRange(startKey, + endKey, false).values()); + } + + /** + * Get the corresponding start keys to regions map for an arbitrary range of + * keys. + *

+ * @param startRow Starting row in range, inclusive + * @param endRow Ending row in range + * @param includeEndRow true if endRow is inclusive, false if exclusive + * @return A map of start keys to HRegionLocations that contain the specified + * range + * @throws IOException if a remote or network exception occurs + */ + public LinkedHashMap getKeysToRegionsInRange( + final byte[] startKey, final byte[] endKey, final boolean includeEndKey) + 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 regionList = new ArrayList(); - byte [] currentKey = startKey; + final LinkedHashMap startKeysToRegionMap = new LinkedHashMap(); + byte[] currentKey = startKey; do { HRegionLocation regionLocation = getRegionLocation(currentKey, false); - regionList.add(regionLocation); + startKeysToRegionMap.put(currentKey, regionLocation); currentKey = regionLocation.getRegionInfo().getEndKey(); - } while (!Bytes.equals(currentKey, HConstants.EMPTY_END_ROW) && - (endKeyIsEndOfTable || Bytes.compareTo(currentKey, endKey) < 0)); - return regionList; + } while (!Bytes.equals(currentKey, HConstants.EMPTY_END_ROW) + && (endKeyIsEndOfTable || Bytes.compareTo(currentKey, endKey) < 0 + || (includeEndKey && Bytes.compareTo(currentKey, endKey) == 0))); + return startKeysToRegionMap; } /** @@ -1376,7 +1395,7 @@ throws IOException, Throwable { // get regions covered by the row range - List keys = getStartKeysInRange(startKey, endKey); + List keys = getStartKeysInRange(startKey, endKey, true); connection.processExecs(protocol, keys, tableName, pool, callable, callback); } @@ -1413,7 +1432,7 @@ final Batch.Callback callback) throws ServiceException, Throwable { // get regions covered by the row range - List keys = getStartKeysInRange(startKey, endKey); + List keys = getStartKeysInRange(startKey, endKey, true); Map> futures = new TreeMap>(Bytes.BYTES_COMPARATOR); @@ -1450,35 +1469,40 @@ } } - private List getStartKeysInRange(byte[] start, byte[] end) + private List getStartKeysInRange(byte[] start, byte[] end, + boolean useCache) throws IOException { - Pair startEndKeys = getStartEndKeys(); - byte[][] startKeys = startEndKeys.getFirst(); - byte[][] endKeys = startEndKeys.getSecond(); - if (start == null) { start = HConstants.EMPTY_START_ROW; } if (end == null) { end = HConstants.EMPTY_END_ROW; } + if (useCache) { + return new ArrayList(getKeysToRegionsInRange(start, end, true) + .keySet()); + } else { + Pair startEndKeys = getStartEndKeys(); + byte[][] startKeys = startEndKeys.getFirst(); + byte[][] endKeys = startEndKeys.getSecond(); - List rangeKeys = new ArrayList(); - for (int i=0; i= 0 ) { - if (Bytes.equals(endKeys[i], HConstants.EMPTY_END_ROW) || - Bytes.compareTo(start, endKeys[i]) < 0) { - rangeKeys.add(start); + List rangeKeys = new ArrayList(); + for (int i = 0; i < startKeys.length; i++) { + if (Bytes.compareTo(start, startKeys[i]) >= 0) { + if (Bytes.equals(endKeys[i], HConstants.EMPTY_END_ROW) + || Bytes.compareTo(start, endKeys[i]) < 0) { + rangeKeys.add(start); + } + } else if (Bytes.equals(end, HConstants.EMPTY_END_ROW) + || Bytes.compareTo(startKeys[i], end) <= 0) { + rangeKeys.add(startKeys[i]); + } else { + break; // past stop } - } else if (Bytes.equals(end, HConstants.EMPTY_END_ROW) || - Bytes.compareTo(startKeys[i], end) <= 0) { - rangeKeys.add(startKeys[i]); - } else { - break; // past stop } + + return rangeKeys; } - - return rangeKeys; } public void setOperationTimeout(int operationTimeout) {