You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ns...@apache.org on 2011/10/11 04:10:12 UTC
svn commit: r1181458 - in /hbase/branches/0.89/src:
main/java/org/apache/hadoop/hbase/ main/java/org/apache/hadoop/hbase/client/
main/java/org/apache/hadoop/hbase/master/
main/java/org/apache/hadoop/hbase/regionserver/
test/java/org/apache/hadoop/hbase...
Author: nspiegelberg
Date: Tue Oct 11 02:10:11 2011
New Revision: 1181458
URL: http://svn.apache.org/viewvc?rev=1181458&view=rev
Log:
Explicit Split Points
Summary:
Added the ability to explicitly split an existing region at a
user-specified point. Note that significant changes will be required
for 0.90 version.
Test Plan:
- mvn test -Dtest=TestHeapSize
- mvn test -Dtest=TestAdmin
- mvn test (underway)
DiffCamp Revision: 191101
Reviewed By: kannan
Reviewers: jgray, kannan, kranganathan
Commenters: jgray
CC: jgray, nspiegelberg, kannan
Tasks:
#443065: increase the number of splits
Revert Plan:
OK
Modified:
hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/HConstants.java
hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/HRegionInfo.java
hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/Store.java
hbase/branches/0.89/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java
hbase/branches/0.89/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
Modified: hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/HConstants.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/HConstants.java?rev=1181458&r1=1181457&r2=1181458&view=diff
==============================================================================
--- hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/HConstants.java (original)
+++ hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/HConstants.java Tue Oct 11 02:10:11 2011
@@ -307,7 +307,8 @@ public final class HConstants {
TABLE_FLUSH,
TABLE_MAJOR_COMPACT,
TABLE_SET_HTD,
- TABLE_SPLIT
+ TABLE_SPLIT,
+ TABLE_EXPLICIT_SPLIT
}
/**
Modified: hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/HRegionInfo.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/HRegionInfo.java?rev=1181458&r1=1181457&r2=1181458&view=diff
==============================================================================
--- hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/HRegionInfo.java (original)
+++ hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/HRegionInfo.java Tue Oct 11 02:10:11 2011
@@ -127,6 +127,7 @@ public class HRegionInfo extends Version
private transient byte [] regionName = HConstants.EMPTY_BYTE_ARRAY;
private String regionNameStr = "";
private boolean split = false;
+ private byte [] splitPoint = null;
private byte [] startKey = HConstants.EMPTY_BYTE_ARRAY;
protected HTableDescriptor tableDesc = null;
private int hashCode = -1;
@@ -475,6 +476,22 @@ public class HRegionInfo extends Version
}
/**
+ * @return point to explicitly split the region on
+ */
+ public byte[] getSplitPoint() {
+ return (this.splitPoint != null && this.splitPoint.length > 0)
+ ? this.splitPoint : null;
+ }
+
+ /**
+ * @param splitPoint set split status & position to split on
+ */
+ public void setSplitPoint(byte[] splitPoint) {
+ this.split = true;
+ this.splitPoint = splitPoint;
+ }
+
+ /**
* @return True if this region is offline.
*/
public boolean isOffline() {
@@ -547,6 +564,9 @@ public class HRegionInfo extends Version
out.writeLong(regionId);
Bytes.writeByteArray(out, regionName);
out.writeBoolean(split);
+ if (split) {
+ Bytes.writeByteArray(out, splitPoint);
+ }
Bytes.writeByteArray(out, startKey);
tableDesc.write(out);
out.writeInt(hashCode);
@@ -561,6 +581,9 @@ public class HRegionInfo extends Version
this.regionName = Bytes.readByteArray(in);
this.regionNameStr = Bytes.toStringBinary(this.regionName);
this.split = in.readBoolean();
+ if (this.split) {
+ this.splitPoint = Bytes.readByteArray(in);
+ }
this.startKey = Bytes.readByteArray(in);
this.tableDesc.readFields(in);
this.hashCode = in.readInt();
Modified: hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java?rev=1181458&r1=1181457&r2=1181458&view=diff
==============================================================================
--- hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (original)
+++ hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java Tue Oct 11 02:10:11 2011
@@ -761,8 +761,8 @@ public class HBaseAdmin {
}
/**
- * Split a table or an individual region.
- * Asynchronous operation.
+ * Split a table or an individual region. Implicitly finds an optimal split
+ * point. Asynchronous operation.
*
* @param tableNameOrRegionName table to region to split
* @throws IOException if a remote or network exception occurs
@@ -771,6 +771,27 @@ public class HBaseAdmin {
modifyTable(tableNameOrRegionName, HConstants.Modify.TABLE_SPLIT);
}
+ /**
+ * Split a table or an individual region.
+ * Asynchronous operation.
+ *
+ * @param tableNameOrRegionName table to region to split
+ * @param splitPoint the explicit position to split on
+ * @throws IOException if a remote or network exception occurs
+ */
+ public void split(final byte [] tableNameOrRegionName,
+ final byte [] splitPoint) throws IOException {
+ if (tableNameOrRegionName == null) {
+ throw new IllegalArgumentException("Pass a table name or region name");
+ }
+ byte [] tableName = tableExists(tableNameOrRegionName)?
+ tableNameOrRegionName: null;
+ byte [] regionName = tableName == null? tableNameOrRegionName: null;
+ Object [] args = regionName == null?
+ new byte [][] {splitPoint}: new byte [][] {regionName, splitPoint};
+ modifyTable(tableName, HConstants.Modify.TABLE_EXPLICIT_SPLIT, args);
+ }
+
/*
* Call modifyTable using passed tableName or region name String. If no
* such table, presume we have been passed a region name.
@@ -840,19 +861,13 @@ public class HBaseAdmin {
case TABLE_COMPACT:
case TABLE_SPLIT:
+ case TABLE_EXPLICIT_SPLIT:
case TABLE_MAJOR_COMPACT:
case TABLE_FLUSH:
if (args != null && args.length > 0) {
- arr = new Writable[1];
- if (args[0] instanceof byte[]) {
- arr[0] = new ImmutableBytesWritable((byte[])args[0]);
- } else if (args[0] instanceof ImmutableBytesWritable) {
- arr[0] = (ImmutableBytesWritable)args[0];
- } else if (args[0] instanceof String) {
- arr[0] = new ImmutableBytesWritable(Bytes.toBytes((String)args[0]));
- } else {
- throw new IllegalArgumentException("Requires byte[], String, or" +
- "ImmutableBytesWritable");
+ arr = new Writable[args.length];
+ for (int i = 0; i < args.length; i++) {
+ arr[i] = toWritable(args[i]);
}
}
this.master.modifyTable(tableName, op, arr);
@@ -864,18 +879,7 @@ public class HBaseAdmin {
}
arr = new Writable[args.length];
for (int i = 0; i < args.length; i++) {
- if (args[i] instanceof byte[]) {
- arr[i] = new ImmutableBytesWritable((byte[])args[i]);
- } else if (args[i] instanceof ImmutableBytesWritable) {
- arr[i] = (ImmutableBytesWritable)args[i];
- } else if (args[i] instanceof String) {
- arr[i] = new ImmutableBytesWritable(Bytes.toBytes((String)args[i]));
- } else if (args[i] instanceof Boolean) {
- arr[i] = new BooleanWritable((Boolean) args[i]);
- } else {
- throw new IllegalArgumentException("Requires byte [] or " +
- "ImmutableBytesWritable, not " + args[i]);
- }
+ arr[i] = toWritable(args[i]);
}
this.master.modifyTable(tableName, op, arr);
break;
@@ -888,6 +892,24 @@ public class HBaseAdmin {
}
}
+ private static Writable toWritable(Object o) {
+ if (o == null) {
+ return null;
+ }
+ if (o instanceof byte[]) {
+ return new ImmutableBytesWritable((byte[])o);
+ } else if (o instanceof ImmutableBytesWritable) {
+ return (ImmutableBytesWritable)o;
+ } else if (o instanceof String) {
+ return new ImmutableBytesWritable(Bytes.toBytes((String)o));
+ } else if (o instanceof Boolean) {
+ return new BooleanWritable((Boolean) o);
+ } else {
+ throw new IllegalArgumentException("Requires byte [] or " +
+ "ImmutableBytesWritable, not " + o.getClass() + " : " + o);
+ }
+ }
+
/**
* Shuts down the HBase instance
* @throws IOException if a remote or network exception occurs
Modified: hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/master/HMaster.java?rev=1181458&r1=1181457&r2=1181458&view=diff
==============================================================================
--- hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/master/HMaster.java (original)
+++ hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/master/HMaster.java Tue Oct 11 02:10:11 2011
@@ -64,6 +64,7 @@ import org.apache.hadoop.hbase.MasterNot
import org.apache.hadoop.hbase.MiniZooKeeperCluster;
import org.apache.hadoop.hbase.RemoteExceptionHandler;
import org.apache.hadoop.hbase.TableExistsException;
+import org.apache.hadoop.hbase.HConstants.Modify;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.MetaScanner;
@@ -1076,6 +1077,42 @@ public class HMaster extends Thread impl
}
break;
+ // format : {tableName row | region} splitPoint
+ case TABLE_EXPLICIT_SPLIT:
+ if (args == null || args.length < (tableName == null? 2 : 1)) {
+ throw new IOException("incorrect number of arguments given");
+ }
+ Pair<HRegionInfo,HServerAddress> pair = null;
+ byte[] splitPoint = null;
+
+ // split a single region
+ if(tableName == null) {
+ byte [] regionName = ((ImmutableBytesWritable)args[0]).get();
+ pair = getTableRegionFromName(regionName);
+ splitPoint = ((ImmutableBytesWritable)args[1]).get();
+ } else {
+ splitPoint = ((ImmutableBytesWritable)args[0]).get();
+ pair = getTableRegionForRow(tableName, splitPoint);
+ }
+ if (pair == null) {
+ throw new IOException("couldn't find RegionInfo from region name");
+ } else if (splitPoint == null) {
+ throw new IOException("must give explicit split point");
+ } else if (!pair.getFirst().containsRow(splitPoint)) {
+ throw new IOException("split point outside specified region's range");
+ }
+ HRegionInfo r = pair.getFirst();
+ r.setSplitPoint(splitPoint);
+ LOG.info("About to " + op.toString() + " on " +
+ Bytes.toString(pair.getFirst().getTableDesc().getName()) +
+ " at " + Bytes.toString(splitPoint) +
+ " and pair is " + pair);
+ if (pair.getSecond() != null) {
+ this.regionManager.startAction(pair.getFirst().getRegionName(),
+ pair.getFirst(), pair.getSecond(), Modify.TABLE_SPLIT);
+ }
+ break;
+
case CLOSE_REGION:
if (args == null || args.length < 1 || args.length > 2) {
throw new IOException("Requires at least a region name; " +
Modified: hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java?rev=1181458&r1=1181457&r2=1181458&view=diff
==============================================================================
--- hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java (original)
+++ hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java Tue Oct 11 02:10:11 2011
@@ -234,6 +234,7 @@ public class HRegion implements HeapSize
new ReentrantReadWriteLock();
private final Object splitLock = new Object();
private boolean splitRequest;
+ private byte[] splitPoint = null;
private final ReadWriteConsistencyControl rwcc =
new ReadWriteConsistencyControl();
@@ -881,6 +882,10 @@ public class HRegion implements HeapSize
writestate.notifyAll();
}
}
+ if (splitRow != null) {
+ assert splitPoint == null || Bytes.equals(splitRow, splitPoint);
+ this.splitPoint = null; // clear the split point (if set)
+ }
return splitRow;
} finally {
splitsAndClosesLock.readLock().unlock();
@@ -3139,8 +3144,8 @@ public class HRegion implements HeapSize
}
public static final long FIXED_OVERHEAD = ClassSize.align(
- (4 * Bytes.SIZEOF_LONG) + Bytes.SIZEOF_BOOLEAN +
- (22 * ClassSize.REFERENCE) + ClassSize.OBJECT + Bytes.SIZEOF_INT);
+ (4 * Bytes.SIZEOF_LONG) + Bytes.SIZEOF_BOOLEAN + ClassSize.ARRAY +
+ (23 * ClassSize.REFERENCE) + ClassSize.OBJECT + Bytes.SIZEOF_INT);
public static final long DEEP_OVERHEAD = ClassSize.align(FIXED_OVERHEAD +
ClassSize.OBJECT + (2 * ClassSize.ATOMIC_BOOLEAN) +
@@ -3243,6 +3248,14 @@ public class HRegion implements HeapSize
return old;
}
+ byte[] getSplitPoint() {
+ return this.splitPoint;
+ }
+
+ void setSplitPoint(byte[] sp) {
+ this.splitPoint = sp;
+ }
+
/**
* @return The priority that this region should have in the compaction queue
*/
Modified: hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java?rev=1181458&r1=1181457&r2=1181458&view=diff
==============================================================================
--- hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (original)
+++ hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java Tue Oct 11 02:10:11 2011
@@ -1349,6 +1349,7 @@ public class HRegionServer implements HR
region = getRegion(info.getRegionName());
region.flushcache();
region.shouldSplit(true);
+ region.setSplitPoint(info.getSplitPoint());
// force a compaction; split will be side-effect.
compactSplitThread.requestCompaction(region,
false, e.msg.getType().name(),
Modified: hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/Store.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/Store.java?rev=1181458&r1=1181457&r2=1181458&view=diff
==============================================================================
--- hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/Store.java (original)
+++ hbase/branches/0.89/src/main/java/org/apache/hadoop/hbase/regionserver/Store.java Tue Oct 11 02:10:11 2011
@@ -1310,6 +1310,10 @@ public class Store implements HeapSize {
largestSf = sf;
}
}
+ // if the user explicit set a split point, use that
+ if (this.region.getSplitPoint() != null) {
+ return new StoreSize(maxSize, this.region.getSplitPoint());
+ }
StoreFile.Reader r = largestSf.getReader();
if (r == null) {
LOG.warn("Storefile " + largestSf + " Reader is null");
Modified: hbase/branches/0.89/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java?rev=1181458&r1=1181457&r2=1181458&view=diff
==============================================================================
--- hbase/branches/0.89/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java (original)
+++ hbase/branches/0.89/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java Tue Oct 11 02:10:11 2011
@@ -456,6 +456,12 @@ public class HBaseTestingUtility {
return new HTable(getConfiguration(), tableName);
}
+ public void deleteTable(byte[] tableName) throws IOException {
+ HBaseAdmin hba = new HBaseAdmin(getConfiguration());
+ hba.disableTable(tableName);
+ hba.deleteTable(tableName);
+ }
+
/**
* Provide an existing table name to truncate
* @param tableName existing table
Modified: hbase/branches/0.89/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java?rev=1181458&r1=1181457&r2=1181458&view=diff
==============================================================================
--- hbase/branches/0.89/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java (original)
+++ hbase/branches/0.89/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java Tue Oct 11 02:10:11 2011
@@ -297,85 +297,115 @@ public class TestAdmin {
*/
@Test
public void testForceSplit() throws Exception {
+ splitTest(null);
+ splitTest(Bytes.toBytes("pwn"));
+ }
+
+ void splitTest(byte[] splitPoint) throws Exception {
byte [] familyName = HConstants.CATALOG_FAMILY;
byte [] tableName = Bytes.toBytes("testForceSplit");
final HTable table = TEST_UTIL.createTable(tableName, familyName);
- byte[] k = new byte[3];
- int rowCount = 0;
- for (byte b1 = 'a'; b1 < 'z'; b1++) {
- for (byte b2 = 'a'; b2 < 'z'; b2++) {
- for (byte b3 = 'a'; b3 < 'z'; b3++) {
- k[0] = b1;
- k[1] = b2;
- k[2] = b3;
- Put put = new Put(k);
- put.add(familyName, new byte[0], k);
- table.put(put);
- rowCount++;
+ try {
+ byte[] k = new byte[3];
+ int rowCount = 0;
+ for (byte b1 = 'a'; b1 < 'z'; b1++) {
+ for (byte b2 = 'a'; b2 < 'z'; b2++) {
+ for (byte b3 = 'a'; b3 < 'z'; b3++) {
+ k[0] = b1;
+ k[1] = b2;
+ k[2] = b3;
+ Put put = new Put(k);
+ put.add(familyName, new byte[0], k);
+ table.put(put);
+ rowCount++;
+ }
}
}
- }
- // get the initial layout (should just be one region)
- Map<HRegionInfo,HServerAddress> m = table.getRegionsInfo();
- System.out.println("Initial regions (" + m.size() + "): " + m);
- assertTrue(m.size() == 1);
-
- // Verify row count
- Scan scan = new Scan();
- ResultScanner scanner = table.getScanner(scan);
- int rows = 0;
- for(@SuppressWarnings("unused") Result result : scanner) {
- rows++;
- }
- scanner.close();
- assertEquals(rowCount, rows);
-
- // Have an outstanding scan going on to make sure we can scan over splits.
- scan = new Scan();
- scanner = table.getScanner(scan);
- // Scan first row so we are into first region before split happens.
- scanner.next();
-
- final AtomicInteger count = new AtomicInteger(0);
- Thread t = new Thread("CheckForSplit") {
- public void run() {
- for (int i = 0; i < 20; i++) {
- try {
- sleep(1000);
- } catch (InterruptedException e) {
- continue;
- }
- // check again table = new HTable(conf, tableName);
- Map<HRegionInfo, HServerAddress> regions = null;
- try {
- regions = table.getRegionsInfo();
- } catch (IOException e) {
- e.printStackTrace();
+ // get the initial layout (should just be one region)
+ Map<HRegionInfo,HServerAddress> m = table.getRegionsInfo();
+ System.out.println("Initial regions (" + m.size() + "): " + m);
+ assertTrue(m.size() == 1);
+
+ // Verify row count
+ Scan scan = new Scan();
+ ResultScanner scanner = table.getScanner(scan);
+ int rows = 0;
+ for(@SuppressWarnings("unused") Result result : scanner) {
+ rows++;
+ }
+ scanner.close();
+ assertEquals(rowCount, rows);
+
+ // Have an outstanding scan going on to make sure we can scan over splits.
+ scan = new Scan();
+ scanner = table.getScanner(scan);
+ // Scan first row so we are into first region before split happens.
+ scanner.next();
+
+ final AtomicInteger count = new AtomicInteger(0);
+ Thread t = new Thread("CheckForSplit") {
+ public void run() {
+ for (int i = 0; i < 20; i++) {
+ try {
+ sleep(1000);
+ } catch (InterruptedException e) {
+ continue;
+ }
+ // check again table = new HTable(conf, tableName);
+ Map<HRegionInfo, HServerAddress> regions = null;
+ try {
+ regions = table.getRegionsInfo();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ if (regions == null) continue;
+ count.set(regions.size());
+ if (count.get() >= 2) break;
+ LOG.debug("Cycle waiting on split");
}
- if (regions == null) continue;
- count.set(regions.size());
- if (count.get() >= 2) break;
- LOG.debug("Cycle waiting on split");
}
+ };
+ t.start();
+ // tell the master to split the table
+ if (splitPoint != null) {
+ admin.split(tableName, splitPoint);
+ } else {
+ admin.split(tableName);
}
- };
- t.start();
- // tell the master to split the table
- admin.split(Bytes.toString(tableName));
- t.join();
-
- // Verify row count
- rows = 1; // We counted one row above.
- for (@SuppressWarnings("unused") Result result : scanner) {
- rows++;
- if (rows > rowCount) {
- scanner.close();
- assertTrue("Scanned more than expected (" + rowCount + ")", false);
+ t.join();
+
+ // Verify row count
+ rows = 1; // We counted one row above.
+ for (@SuppressWarnings("unused") Result result : scanner) {
+ rows++;
+ if (rows > rowCount) {
+ scanner.close();
+ assertTrue("Scanned more than expected (" + rowCount + ")", false);
+ }
+ }
+ scanner.close();
+ assertEquals(rowCount, rows);
+
+ if (splitPoint != null) {
+ // make sure the split point matches our explicit configuration
+ Map<HRegionInfo, HServerAddress> regions = null;
+ try {
+ regions = table.getRegionsInfo();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ assertEquals(2, regions.size());
+ HRegionInfo[] r = regions.keySet().toArray(new HRegionInfo[0]);
+ assertEquals(Bytes.toString(splitPoint),
+ Bytes.toString(r[0].getEndKey()));
+ assertEquals(Bytes.toString(splitPoint),
+ Bytes.toString(r[1].getStartKey()));
+ LOG.debug("Properly split on " + Bytes.toString(splitPoint));
}
+ } finally {
+ TEST_UTIL.deleteTable(tableName);
}
- scanner.close();
- assertEquals(rowCount, rows);
}
/**