Index: src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (revision 1461214) +++ src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (working copy) @@ -381,6 +381,10 @@ } else if(Bytes.compareTo(startKey, endKey) >= 0) { throw new IllegalArgumentException("Start key must be smaller than end key"); } + if (numRegions == 3) { + createTable(desc, new byte[][] { startKey, endKey }); + return; + } byte [][] splitKeys = Bytes.split(startKey, endKey, numRegions - 3); if(splitKeys == null || splitKeys.length != numRegions - 1) { throw new IllegalArgumentException("Unable to split key range into enough regions"); Index: src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java =================================================================== --- src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (revision 1461214) +++ src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (working copy) @@ -548,6 +548,55 @@ } @Test + public void testCreateTableNumberOfRegions() throws IOException, InterruptedException { + byte[] tableName = Bytes.toBytes("testCreateTableNumberOfRegions"); + HTableDescriptor desc = new HTableDescriptor(tableName); + desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); + admin.createTable(desc); + HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName); + Map regions = ht.getRegionLocations(); + assertEquals("Table should have only 1 region", 1, regions.size()); + ht.close(); + + byte[] TABLE_2 = Bytes.add(tableName, Bytes.toBytes("_2")); + desc = new HTableDescriptor(TABLE_2); + desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); + admin.createTable(desc, new byte[][] { new byte[] { 42 } }); + HTable ht2 = new HTable(TEST_UTIL.getConfiguration(), TABLE_2); + regions = ht2.getRegionLocations(); + assertEquals("Table should have only 2 region", 2, regions.size()); + ht2.close(); + + byte[] TABLE_3 = Bytes.add(tableName, Bytes.toBytes("_3")); + desc = new HTableDescriptor(TABLE_3); + desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); + admin.createTable(desc, "a".getBytes(), "z".getBytes(), 3); + HTable ht3 = new HTable(TEST_UTIL.getConfiguration(), TABLE_3); + regions = ht3.getRegionLocations(); + assertEquals("Table should have only 3 region", 3, regions.size()); + ht3.close(); + + byte[] TABLE_4 = Bytes.add(tableName, Bytes.toBytes("_4")); + desc = new HTableDescriptor(TABLE_4); + desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); + try { + admin.createTable(desc, "a".getBytes(), "z".getBytes(), 2); + fail("Should not be able to create a table with only 2 regions using this API."); + } catch (IllegalArgumentException eae) { + // Expected + } + + byte[] TABLE_5 = Bytes.add(tableName, Bytes.toBytes("_5")); + desc = new HTableDescriptor(TABLE_5); + desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); + admin.createTable(desc, new byte[] { 1 }, new byte[] { 127 }, 16); + HTable ht5 = new HTable(TEST_UTIL.getConfiguration(), TABLE_5); + regions = ht5.getRegionLocations(); + assertEquals("Table should have 16 region", 16, regions.size()); + ht5.close(); + } + + @Test public void testCreateTableWithRegions() throws IOException, InterruptedException { byte[] tableName = Bytes.toBytes("testCreateTableWithRegions");