hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From st...@apache.org
Subject svn commit: r1295767 - in /hbase/branches/0.92: CHANGES.txt src/main/java/org/apache/hadoop/hbase/client/HTable.java src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
Date Thu, 01 Mar 2012 20:12:07 GMT
Author: stack
Date: Thu Mar  1 20:12:07 2012
New Revision: 1295767

URL: http://svn.apache.org/viewvc?rev=1295767&view=rev
Log:
HBASE-5489 Add HTable accessor to get regions for a key range

Modified:
    hbase/branches/0.92/CHANGES.txt
    hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/client/HTable.java
    hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java

Modified: hbase/branches/0.92/CHANGES.txt
URL: http://svn.apache.org/viewvc/hbase/branches/0.92/CHANGES.txt?rev=1295767&r1=1295766&r2=1295767&view=diff
==============================================================================
--- hbase/branches/0.92/CHANGES.txt (original)
+++ hbase/branches/0.92/CHANGES.txt Thu Mar  1 20:12:07 2012
@@ -56,6 +56,8 @@ Release 0.92.1 - Unreleased
    HBASE-5502  region_mover.rb fails to load regions back to original
                server for regions only containing empty tables.
                (James Page)
+   HBASE-5489  Add HTable accessor to get regions for a key range
+               (David S. Wang)
  
  
   IMPROVEMENTS

Modified: hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/client/HTable.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/client/HTable.java?rev=1295767&r1=1295766&r2=1295767&view=diff
==============================================================================
--- hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/client/HTable.java (original)
+++ hbase/branches/0.92/src/main/java/org/apache/hadoop/hbase/client/HTable.java Thu Mar 
1 20:12:07 2012
@@ -348,6 +348,7 @@ public class HTable implements HTableInt
    * @param row Row to find.
    * @return Location of the row.
    * @throws IOException if a remote or network exception occurs
+   * @deprecated use {@link #getRegionLocation(byte [], boolean)} instead
    */
   public HRegionLocation getRegionLocation(final byte [] row)
   throws IOException {
@@ -355,6 +356,19 @@ public class HTable implements HTableInt
   }
 
   /**
+   * Finds the region on which the given row is being served.
+   * @param row Row to find.
+   * @param reload whether or not to reload information or just use cached
+   * information
+   * @return Location of the row.
+   * @throws IOException if a remote or network exception occurs
+   */
+  public HRegionLocation getRegionLocation(final byte [] row, boolean reload)
+  throws IOException {
+    return connection.getRegionLocation(tableName, row, reload);
+  }
+     
+  /**
    * {@inheritDoc}
    */
   @Override
@@ -515,6 +529,35 @@ public class HTable implements HTableInt
   }
 
   /**
+   * 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.
    * <p>

Modified: hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java?rev=1295767&r1=1295766&r2=1295767&view=diff
==============================================================================
--- hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
(original)
+++ hbase/branches/0.92/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide.java
Thu Mar  1 20:12:07 2012
@@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.client;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -51,11 +52,14 @@ import org.apache.hadoop.hbase.HBaseTest
 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;
+import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.filter.BinaryComparator;
 import org.apache.hadoop.hbase.filter.CompareFilter;
+import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
 import org.apache.hadoop.hbase.filter.Filter;
 import org.apache.hadoop.hbase.filter.FilterList;
 import org.apache.hadoop.hbase.filter.KeyOnlyFilter;
@@ -65,10 +69,10 @@ import org.apache.hadoop.hbase.filter.Re
 import org.apache.hadoop.hbase.filter.RowFilter;
 import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
 import org.apache.hadoop.hbase.filter.WhileMatchFilter;
-import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
 import org.apache.hadoop.hbase.io.hfile.BlockCache;
 import org.apache.hadoop.hbase.io.hfile.CacheConfig;
 import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.regionserver.HRegionServer;
 import org.apache.hadoop.hbase.regionserver.Store;
 import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
 import org.apache.hadoop.hbase.util.Bytes;
@@ -91,6 +95,7 @@ public class TestFromClientSide {
   private static byte [] FAMILY = Bytes.toBytes("testFamily");
   private static byte [] QUALIFIER = Bytes.toBytes("testQualifier");
   private static byte [] VALUE = Bytes.toBytes("testValue");
+  private static int SLAVES = 3;
 
   /**
    * @throws java.lang.Exception
@@ -98,7 +103,7 @@ public class TestFromClientSide {
   @BeforeClass
   public static void setUpBeforeClass() throws Exception {
     // We need more than one region server in this test
-    TEST_UTIL.startMiniCluster(3);
+    TEST_UTIL.startMiniCluster(SLAVES);
   }
 
   /**
@@ -4308,4 +4313,115 @@ public class TestFromClientSide {
         System.currentTimeMillis() + ", cur=" + store.getNumberOfstorefiles());
     assertEquals(count, store.getNumberOfstorefiles());
   }
+
+  @Test
+  /**
+   * Tests the non cached version of getRegionLocation by moving a region.
+   */
+  public void testNonCachedGetRegionLocation() throws Exception {
+    // Test Initialization.
+    String tableName = "testNonCachedGetRegionLocation";
+    byte [] TABLE = Bytes.toBytes(tableName);
+    byte [] family1 = Bytes.toBytes("f1");
+    byte [] family2 = Bytes.toBytes("f2");
+    HTable table = TEST_UTIL.createTable(TABLE, new byte[][] {family1, family2}, 10);
+    HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
+    Map <HRegionInfo, ServerName> regionsMap = table.getRegionLocations();
+    assertEquals(1, regionsMap.size());
+    HRegionInfo regionInfo = regionsMap.keySet().iterator().next();
+    ServerName addrBefore = regionsMap.get(regionInfo);
+    // Verify region location before move.
+    HServerAddress addrCache =
+      table.getRegionLocation(regionInfo.getStartKey(), false).getServerAddress();
+    HServerAddress addrNoCache =
+      table.getRegionLocation(regionInfo.getStartKey(),
+          true).getServerAddress();
+
+    assertEquals(addrBefore.getPort(), addrCache.getPort());
+    assertEquals(addrBefore.getPort(), addrNoCache.getPort());
+
+    ServerName addrAfter = null;
+    // Now move the region to a different server.
+    for (int i = 0; i < SLAVES; i++) {
+      HRegionServer regionServer = TEST_UTIL.getHBaseCluster().getRegionServer(i);
+      ServerName addr = regionServer.getServerName();
+      if (addr.getPort() != addrBefore.getPort()) {
+        admin.move(regionInfo.getEncodedNameAsBytes(),
+            Bytes.toBytes(addr.toString()));
+        // Wait for the region to move.
+        Thread.sleep(5000);
+        addrAfter = addr;
+        break;
+      }
+    }
+
+    // Verify the region was moved.
+    addrCache =
+      table.getRegionLocation(regionInfo.getStartKey(), false).getServerAddress();
+    addrNoCache =
+      table.getRegionLocation(regionInfo.getStartKey(),
+          true).getServerAddress();
+    assertNotNull(addrAfter);
+    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());
+  }
 }



Mime
View raw message