Author: jgray Date: Thu May 6 15:13:51 2010 New Revision: 941773 URL: http://svn.apache.org/viewvc?rev=941773&view=rev Log: HBASE-2473 Add to admin create table start and end key params and desired number of regions
Modified: hadoop/hbase/trunk/CHANGES.txt hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/ipc/HBaseRPCProtocolVersion.java hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/master/HMaster.java hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/util/Bytes.java hadoop/hbase/trunk/core/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java hadoop/hbase/trunk/core/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java Modified: hadoop/hbase/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/CHANGES.txt?rev=941773&r1=941772&r2=941773&view=diff ============================================================================== --- hadoop/hbase/trunk/CHANGES.txt (original) +++ hadoop/hbase/trunk/CHANGES.txt Thu May 6 15:13:51 2010 @@ -579,6 +579,8 @@ Release 0.21.0 - Unreleased HBASE-2319 [stargate] multiuser mode: request shaping HBASE-2403 [stargate] client HTable interface to REST connector HBASE-2438 Addition of a Column Pagination Filter (Paul Kist via Stack) + HBASE-2473 Add to admin create table start and end key params and + desired number of regions OPTIMIZATIONS HBASE-410 [testing] Speed up the test suite Modified: hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java?rev=941773&r1=941772&r2=941773&view=diff ============================================================================== --- hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (original) +++ hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java Thu May 6 15:13:51 2010 @@ -44,6 +44,7 @@ import org.apache.hadoop.io.Writable; import org.apache.hadoop.ipc.RemoteException; import java.io.IOException; +import java.util.Arrays; import java.util.Map; import java.util.NavigableMap; @@ -162,14 +163,87 @@ public class HBaseAdmin { */ public void createTable(HTableDescriptor desc) throws IOException { + createTable(desc, null); + } + + /** + * Creates a new table with the specified number of regions. The start key + * specified will become the end key of the first region of the table, and + * the end key specified will become the start key of the last region of the + * table (the first region has a null start key and the last region has a + * null end key). + * + * BigInteger math will be used to divide the key range specified into + * enough segments to make the required number of total regions. + * + * Synchronous operation. + * + * @param desc table descriptor for table + * @param startKey beginning of key range + * @param endKey end of key range + * @param numRegions the total number of regions to create + * + * @throws IllegalArgumentException if the table name is reserved + * @throws MasterNotRunningException if master is not running + * @throws TableExistsException if table already exists (If concurrent + * threads, the table may have been created between test-for-existence + * and attempt-at-creation). + * @throws IOException + */ + public void createTable(HTableDescriptor desc, byte [] startKey, + byte [] endKey, int numRegions) + throws IOException { HTableDescriptor.isLegalTableName(desc.getName()); - createTableAsync(desc); + if(numRegions < 3) { + throw new IllegalArgumentException("Must create at least three regions"); + } else if(Bytes.compareTo(startKey, endKey) >= 0) { + throw new IllegalArgumentException("Start key must be smaller than end key"); + } + 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"); + } + createTable(desc, splitKeys); + } + + /** + * Creates a new table with an initial set of empty regions defined by the + * specified split keys. The total number of regions created will be the + * number of split keys plus one (the first region has a null start key and + * the last region has a null end key). + * Synchronous operation. + * + * @param desc table descriptor for table + * @param splitKeys array of split keys for the initial regions of the table + * + * @throws IllegalArgumentException if the table name is reserved + * @throws MasterNotRunningException if master is not running + * @throws TableExistsException if table already exists (If concurrent + * threads, the table may have been created between test-for-existence + * and attempt-at-creation). + * @throws IOException + */ + public void createTable(HTableDescriptor desc, byte [][] splitKeys) + throws IOException { + HTableDescriptor.isLegalTableName(desc.getName()); + if(splitKeys != null && splitKeys.length > 1) { + Arrays.sort(splitKeys, Bytes.BYTES_COMPARATOR); + // Verify there are no duplicate split keys + byte [] lastKey = null; + for(byte [] splitKey : splitKeys) { + if(lastKey != null && Bytes.equals(splitKey, lastKey)) { + throw new IllegalArgumentException("All split keys must be unique, found duplicate"); + } + lastKey = splitKey; + } + } + createTableAsync(desc, splitKeys); for (int tries = 0; tries < numRetries; tries++) { try { // Wait for new table to come on-line connection.locateRegion(desc.getName(), HConstants.EMPTY_START_ROW); break; - + } catch (RegionException e) { if (tries == numRetries - 1) { // Ran out of tries @@ -183,28 +257,28 @@ public class HBaseAdmin { } } } - + /** * Creates a new table but does not block and wait for it to come online. * Asynchronous operation. - * + * * @param desc table descriptor for table - * + * * @throws IllegalArgumentException Bad table name. * @throws MasterNotRunningException if master is not running * @throws TableExistsException if table already exists (If concurrent * threads, the table may have been created between test-for-existence * and attempt-at-creation). - * @throws IOException if a remote or network exception occurs + * @throws IOException */ - public void createTableAsync(HTableDescriptor desc) + public void createTableAsync(HTableDescriptor desc, byte [][] splitKeys) throws IOException { if (this.master == null) { throw new MasterNotRunningException("master has been shut down"); } HTableDescriptor.isLegalTableName(desc.getName()); try { - this.master.createTable(desc); + this.master.createTable(desc, splitKeys); } catch (RemoteException e) { throw RemoteExceptionHandler.decodeRemoteException(e); } Modified: hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/ipc/HBaseRPCProtocolVersion.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/ipc/HBaseRPCProtocolVersion.java?rev=941773&r1=941772&r2=941773&view=diff ============================================================================== --- hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/ipc/HBaseRPCProtocolVersion.java (original) +++ hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/ipc/HBaseRPCProtocolVersion.java Thu May 6 15:13:51 2010 @@ -75,7 +75,8 @@ public interface HBaseRPCProtocolVersion * <li>Version 21: HBASE-1665.</li> * <li>Version 22: HBASE-2209. Added List support to RPC</li> * <li>Version 23: HBASE-2066, multi-put.</li> + * <li>Version 24: HBASE-2473, create table with regions.</li> * </ul> */ - public static final long versionID = 23L; + public static final long versionID = 24L; } Modified: hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java?rev=941773&r1=941772&r2=941773&view=diff ============================================================================== --- hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java (original) +++ hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java Thu May 6 15:13:51 2010 @@ -44,11 +44,15 @@ public interface HMasterInterface extend // Admin tools would use these cmds /** - * Creates a new table + * Creates a new table. If splitKeys are specified, then the table will be + * created with an initial set of multiple regions. If splitKeys is null, + * the table will be created with a single region. * @param desc table descriptor - * @throws IOException e + * @param splitKeys + * @throws IOException */ - public void createTable(HTableDescriptor desc) throws IOException; + public void createTable(HTableDescriptor desc, byte [][] splitKeys) + throws IOException; /** * Deletes a table Modified: hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/master/HMaster.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/master/HMaster.java?rev=941773&r1=941772&r2=941773&view=diff ============================================================================== --- hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/master/HMaster.java (original) +++ hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/master/HMaster.java Thu May 6 15:13:51 2010 @@ -694,12 +694,25 @@ public class HMaster extends Thread impl this.zooKeeperWrapper.setClusterState(false); } - public void createTable(HTableDescriptor desc) + public void createTable(HTableDescriptor desc, byte [][] splitKeys) throws IOException { if (!isMasterRunning()) { throw new MasterNotRunningException(); } - HRegionInfo newRegion = new HRegionInfo(desc, null, null); + HRegionInfo [] newRegions = null; + if(splitKeys == null || splitKeys.length == 0) { + newRegions = new HRegionInfo [] { new HRegionInfo(desc, null, null) }; + } else { + int numRegions = splitKeys.length + 1; + newRegions = new HRegionInfo[numRegions]; + byte [] startKey = null; + byte [] endKey = null; + for(int i=0;i<numRegions;i++) { + endKey = (i == splitKeys.length) ? null : splitKeys[i]; + newRegions[i] = new HRegionInfo(desc, startKey, endKey); + startKey = endKey; + } + } for (int tries = 0; tries < this.numRetries; tries++) { try { // We can not create a table unless meta regions have already been @@ -710,7 +723,7 @@ public class HMaster extends Thread impl if (!this.serverManager.canAssignUserRegions()) { throw new IOException("not enough servers to create table yet"); } - createTable(newRegion); + createTable(newRegions); LOG.info("created table " + desc.getNameAsString()); break; } catch (TableExistsException e) { @@ -724,14 +737,14 @@ public class HMaster extends Thread impl } } - private synchronized void createTable(final HRegionInfo newRegion) + private synchronized void createTable(final HRegionInfo [] newRegions) throws IOException { - String tableName = newRegion.getTableDesc().getNameAsString(); + String tableName = newRegions[0].getTableDesc().getNameAsString(); // 1. Check to see if table already exists. Get meta region where // table would sit should it exist. Open scanner on it. If a region // for the table we want to create already exists, then table already // created. Throw already-exists exception. - MetaRegion m = this.regionManager.getFirstMetaRegionForRegion(newRegion); + MetaRegion m = regionManager.getFirstMetaRegionForRegion(newRegions[0]); byte [] metaRegionName = m.getRegionName(); HRegionInterface srvr = this.connection.getHRegionConnection(m.getServer()); byte[] firstRowInTable = Bytes.toBytes(tableName + ",,"); @@ -751,7 +764,9 @@ public class HMaster extends Thread impl } finally { srvr.close(scannerid); } - this.regionManager.createRegion(newRegion, srvr, metaRegionName); + for(HRegionInfo newRegion : newRegions) { + regionManager.createRegion(newRegion, srvr, metaRegionName); + } } public void deleteTable(final byte [] tableName) throws IOException { Modified: hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/util/Bytes.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/util/Bytes.java?rev=941773&r1=941772&r2=941773&view=diff ============================================================================== --- hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/util/Bytes.java (original) +++ hadoop/hbase/trunk/core/src/main/java/org/apache/hadoop/hbase/util/Bytes.java Thu May 6 15:13:51 2010 @@ -1028,8 +1028,8 @@ public class Bytes { aPadded = a; bPadded = b; } - if (compareTo(aPadded, bPadded) > 1) { - throw new IllegalArgumentException("b > a"); + if (compareTo(aPadded,bPadded) >= 0) { + throw new IllegalArgumentException("b <= a"); } if (num <= 0) { throw new IllegalArgumentException("num cannot be < 0"); @@ -1039,7 +1039,7 @@ public class Bytes { BigInteger stopBI = new BigInteger(add(prependHeader, bPadded)); BigInteger diffBI = stopBI.subtract(startBI); BigInteger splitsBI = BigInteger.valueOf(num + 1); - if(diffBI.compareTo(splitsBI) <= 0) { + if(diffBI.compareTo(splitsBI) < 0) { return null; } BigInteger intervalBI; Modified: hadoop/hbase/trunk/core/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/core/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java?rev=941773&r1=941772&r2=941773&view=diff ============================================================================== --- hadoop/hbase/trunk/core/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (original) +++ hadoop/hbase/trunk/core/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java Thu May 6 15:13:51 2010 @@ -25,6 +25,7 @@ import static org.junit.Assert.assertTru import static org.junit.Assert.fail; import java.io.IOException; +import java.util.Iterator; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -85,6 +86,166 @@ public class TestAdmin { } @Test + public void testCreateTableWithRegions() throws IOException { + + byte[] tableName = Bytes.toBytes("testCreateTableWithRegions"); + + byte [][] splitKeys = { + new byte [] { 1, 1, 1 }, + new byte [] { 2, 2, 2 }, + new byte [] { 3, 3, 3 }, + new byte [] { 4, 4, 4 }, + new byte [] { 5, 5, 5 }, + new byte [] { 6, 6, 6 }, + new byte [] { 7, 7, 7 }, + new byte [] { 8, 8, 8 }, + new byte [] { 9, 9, 9 }, + }; + int expectedRegions = splitKeys.length + 1; + + HTableDescriptor desc = new HTableDescriptor(tableName); + desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); + admin.createTable(desc, splitKeys); + + HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName); + Map<HRegionInfo,HServerAddress> regions = ht.getRegionsInfo(); + assertEquals("Tried to create " + expectedRegions + " regions " + + "but only found " + regions.size(), + expectedRegions, regions.size()); + System.err.println("Found " + regions.size() + " regions"); + + Iterator<HRegionInfo> hris = regions.keySet().iterator(); + HRegionInfo hri = hris.next(); + assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0); + assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[0])); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[0])); + assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[1])); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[1])); + assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[2])); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[2])); + assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[3])); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[3])); + assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[4])); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[4])); + assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[5])); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[5])); + assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[6])); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[6])); + assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[7])); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[7])); + assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[8])); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[8])); + assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0); + + // Now test using start/end with a number of regions + + // Use 80 bit numbers to make sure we aren't limited + byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; + byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; + + // Splitting into 10 regions, we expect (null,1) ... (9, null) + // with (1,2) (2,3) (3,4) (4,5) (5,6) (6,7) (7,8) (8,9) in the middle + + expectedRegions = 10; + + byte [] TABLE_2 = Bytes.add(tableName, Bytes.toBytes("_2")); + + desc = new HTableDescriptor(TABLE_2); + desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); + admin = new HBaseAdmin(TEST_UTIL.getConfiguration()); + admin.createTable(desc, startKey, endKey, expectedRegions); + + ht = new HTable(TEST_UTIL.getConfiguration(), TABLE_2); + regions = ht.getRegionsInfo(); + assertEquals("Tried to create " + expectedRegions + " regions " + + "but only found " + regions.size(), + expectedRegions, regions.size()); + System.err.println("Found " + regions.size() + " regions"); + + hris = regions.keySet().iterator(); + hri = hris.next(); + assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0); + assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {1,1,1,1,1,1,1,1,1,1})); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {1,1,1,1,1,1,1,1,1,1})); + assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {2,2,2,2,2,2,2,2,2,2})); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {2,2,2,2,2,2,2,2,2,2})); + assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {3,3,3,3,3,3,3,3,3,3})); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {3,3,3,3,3,3,3,3,3,3})); + assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {4,4,4,4,4,4,4,4,4,4})); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {4,4,4,4,4,4,4,4,4,4})); + assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {5,5,5,5,5,5,5,5,5,5})); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {5,5,5,5,5,5,5,5,5,5})); + assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {6,6,6,6,6,6,6,6,6,6})); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {6,6,6,6,6,6,6,6,6,6})); + assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {7,7,7,7,7,7,7,7,7,7})); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {7,7,7,7,7,7,7,7,7,7})); + assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {8,8,8,8,8,8,8,8,8,8})); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {8,8,8,8,8,8,8,8,8,8})); + assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {9,9,9,9,9,9,9,9,9,9})); + hri = hris.next(); + assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {9,9,9,9,9,9,9,9,9,9})); + assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0); + + // Try once more with something that divides into something infinite + + startKey = new byte [] { 0, 0, 0, 0, 0, 0 }; + endKey = new byte [] { 1, 0, 0, 0, 0, 0 }; + + expectedRegions = 5; + + byte [] TABLE_3 = Bytes.add(tableName, Bytes.toBytes("_3")); + + desc = new HTableDescriptor(TABLE_3); + desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); + admin = new HBaseAdmin(TEST_UTIL.getConfiguration()); + admin.createTable(desc, startKey, endKey, expectedRegions); + + ht = new HTable(TEST_UTIL.getConfiguration(), TABLE_3); + regions = ht.getRegionsInfo(); + assertEquals("Tried to create " + expectedRegions + " regions " + + "but only found " + regions.size(), + expectedRegions, regions.size()); + System.err.println("Found " + regions.size() + " regions"); + + // Try an invalid case where there are duplicate split keys + splitKeys = new byte [][] { + new byte [] { 1, 1, 1 }, + new byte [] { 2, 2, 2 }, + new byte [] { 3, 3, 3 }, + new byte [] { 2, 2, 2 } + }; + + byte [] TABLE_4 = Bytes.add(tableName, Bytes.toBytes("_4")); + desc = new HTableDescriptor(TABLE_4); + desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY)); + admin = new HBaseAdmin(TEST_UTIL.getConfiguration()); + try { + admin.createTable(desc, splitKeys); + assertTrue("Should not be able to create this table because of " + + "duplicate split keys", false); + } catch(IllegalArgumentException iae) { + // Expected + } + } + + @Test public void testDisableAndEnableTable() throws IOException { final byte [] row = Bytes.toBytes("row"); final byte [] qualifier = Bytes.toBytes("qualifier"); Modified: hadoop/hbase/trunk/core/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/core/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java?rev=941773&r1=941772&r2=941773&view=diff ============================================================================== --- hadoop/hbase/trunk/core/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java (original) +++ hadoop/hbase/trunk/core/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java Thu May 6 15:13:51 2010 @@ -70,6 +70,31 @@ public class TestBytes extends TestCase assertTrue(Bytes.equals(parts[1], middle)); } + public void testSplit3() throws Exception { + // Test invalid split cases + byte [] low = { 1, 1, 1 }; + byte [] high = { 1, 1, 3 }; + + // If swapped, should throw IAE + try { + Bytes.split(high, low, 1); + assertTrue("Should not be able to split if low > high", false); + } catch(IllegalArgumentException iae) { + // Correct + } + + // Single split should work + byte [][] parts = Bytes.split(low, high, 1); + for (int i = 0; i < parts.length; i++) { + System.out.println("" + i + " -> " + Bytes.toStringBinary(parts[i])); + } + assertTrue("Returned split should have 3 parts but has " + parts.length, parts.length == 3); + + // If split more than once, this should fail + parts = Bytes.split(low, high, 2); + assertTrue("Returned split but should have failed", parts == null); + } + public void testToLong() throws Exception { long [] longs = {-1l, 123l, 122232323232l}; for (int i = 0; i < longs.length; i++) {