You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by ap...@apache.org on 2009/06/07 21:57:43 UTC
svn commit: r782445 [12/17] - in /hadoop/hbase/trunk_on_hadoop-0.18.3: ./
bin/ src/java/org/apache/hadoop/hbase/
src/java/org/apache/hadoop/hbase/client/
src/java/org/apache/hadoop/hbase/client/tableindexed/
src/java/org/apache/hadoop/hbase/client/tran...
Added: hadoop/hbase/trunk_on_hadoop-0.18.3/src/test/org/apache/hadoop/hbase/client/TestClient.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk_on_hadoop-0.18.3/src/test/org/apache/hadoop/hbase/client/TestClient.java?rev=782445&view=auto
==============================================================================
--- hadoop/hbase/trunk_on_hadoop-0.18.3/src/test/org/apache/hadoop/hbase/client/TestClient.java (added)
+++ hadoop/hbase/trunk_on_hadoop-0.18.3/src/test/org/apache/hadoop/hbase/client/TestClient.java Sun Jun 7 19:57:37 2009
@@ -0,0 +1,2460 @@
+package org.apache.hadoop.hbase.client;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hbase.HBaseClusterTestCase;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.util.Bytes;
+
+public class TestClient extends HBaseClusterTestCase {
+
+ private static byte [] ROW = Bytes.toBytes("testRow");
+ private static byte [] FAMILY = Bytes.toBytes("testFamily");
+ private static byte [] QUALIFIER = Bytes.toBytes("testQualifier");
+ private static byte [] VALUE = Bytes.toBytes("testValue");
+
+ private static byte [] EMPTY = new byte[0];
+
+ /**
+ * Constructor does nothing special, start cluster.
+ */
+ public TestClient() {
+ super();
+ }
+
+ public void XtestSuperSimple() throws Exception {
+ byte [] TABLE = Bytes.toBytes("testSuperSimple");
+ HTable ht = createTable(TABLE, FAMILY);
+ Put put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, VALUE);
+ ht.put(put);
+ Scan scan = new Scan();
+ scan.addColumn(FAMILY, TABLE);
+ ResultScanner scanner = ht.getScanner(scan);
+ Result result = scanner.next();
+ assertTrue("Expected null result", result == null);
+ scanner.close();
+ System.out.println("Done.");
+ }
+
+ /**
+ * Test simple table and non-existent row cases.
+ */
+ public void testSimpleMissing() throws Exception {
+
+ byte [] TABLE = Bytes.toBytes("testSimpleMissing");
+
+ HTable ht = createTable(TABLE, FAMILY);
+
+ byte [][] ROWS = makeN(ROW, 4);
+
+ // Try to get a row on an empty table
+
+ Get get = new Get(ROWS[0]);
+ Result result = ht.get(get);
+ assertEmptyResult(result);
+
+ get = new Get(ROWS[0]);
+ get.addFamily(FAMILY);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILY, QUALIFIER);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ Scan scan = new Scan();
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+
+ scan = new Scan(ROWS[0]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ scan = new Scan(ROWS[0],ROWS[1]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ scan = new Scan();
+ scan.addFamily(FAMILY);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ scan = new Scan();
+ scan.addColumn(FAMILY, QUALIFIER);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ // Insert a row
+
+ Put put = new Put(ROWS[2]);
+ put.add(FAMILY, QUALIFIER, VALUE);
+ ht.put(put);
+
+ // Try to get empty rows around it
+
+ get = new Get(ROWS[1]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ get = new Get(ROWS[0]);
+ get.addFamily(FAMILY);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ get = new Get(ROWS[3]);
+ get.addColumn(FAMILY, QUALIFIER);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ // Try to scan empty rows around it
+
+ scan = new Scan(ROWS[3]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ scan = new Scan(ROWS[0],ROWS[2]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ // Make sure we can actually get the row
+
+ get = new Get(ROWS[2]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+
+ get = new Get(ROWS[2]);
+ get.addFamily(FAMILY);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+
+ get = new Get(ROWS[2]);
+ get.addColumn(FAMILY, QUALIFIER);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+
+ // Make sure we can scan the row
+
+ scan = new Scan();
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+
+ scan = new Scan(ROWS[0],ROWS[3]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+
+ scan = new Scan(ROWS[2],ROWS[3]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[2], FAMILY, QUALIFIER, VALUE);
+ }
+
+ /**
+ * Test basic puts, gets, scans, and deletes for a single row
+ * in a multiple family table.
+ */
+ public void testSingleRowMultipleFamily() throws Exception {
+
+ byte [] TABLE = Bytes.toBytes("testSingleRowMultipleFamily");
+
+ byte [][] ROWS = makeN(ROW, 3);
+ byte [][] FAMILIES = makeN(FAMILY, 10);
+ byte [][] QUALIFIERS = makeN(QUALIFIER, 10);
+ byte [][] VALUES = makeN(VALUE, 10);
+
+ HTable ht = createTable(TABLE, FAMILIES);
+
+ Get get;
+ Scan scan;
+ Delete delete;
+ Put put;
+ Result result;
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Insert one column to one family
+ ////////////////////////////////////////////////////////////////////////////
+
+ put = new Put(ROWS[0]);
+ put.add(FAMILIES[4], QUALIFIERS[0], VALUES[0]);
+ ht.put(put);
+
+ // Get the single column
+ getVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
+
+ // Scan the single column
+ scanVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
+
+ // Get empty results around inserted column
+ getVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
+
+ // Scan empty results around inserted column
+ scanVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Flush memcache and run same tests from storefiles
+ ////////////////////////////////////////////////////////////////////////////
+
+ flushMemcache(TABLE);
+
+ // Redo get and scan tests from storefile
+
+ getVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
+ scanVerifySingleColumn(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0, VALUES, 0);
+ getVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
+ scanVerifySingleEmpty(ht, ROWS, 0, FAMILIES, 4, QUALIFIERS, 0);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Now, Test reading from memcache and storefiles at once
+ ////////////////////////////////////////////////////////////////////////////
+
+ // Insert multiple columns to two other families
+
+ put = new Put(ROWS[0]);
+ put.add(FAMILIES[2], QUALIFIERS[2], VALUES[2]);
+ put.add(FAMILIES[2], QUALIFIERS[4], VALUES[4]);
+ put.add(FAMILIES[4], QUALIFIERS[4], VALUES[4]);
+ put.add(FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+ put.add(FAMILIES[6], QUALIFIERS[7], VALUES[7]);
+ put.add(FAMILIES[7], QUALIFIERS[7], VALUES[7]);
+ put.add(FAMILIES[9], QUALIFIERS[0], VALUES[0]);
+ ht.put(put);
+
+ // Get multiple columns across multiple families and get empties around it
+ singleRowGetTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
+
+ // Scan multiple columns across multiple families and scan empties around it
+ singleRowScanTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Flush the table again
+ ////////////////////////////////////////////////////////////////////////////
+
+ flushMemcache(TABLE);
+
+ // Redo tests again
+
+ singleRowGetTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
+ singleRowScanTest(ht, ROWS, FAMILIES, QUALIFIERS, VALUES);
+
+ // Insert more data to memcache
+
+ put = new Put(ROWS[0]);
+ put.add(FAMILIES[6], QUALIFIERS[5], VALUES[5]);
+ put.add(FAMILIES[6], QUALIFIERS[8], VALUES[8]);
+ put.add(FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+ put.add(FAMILIES[4], QUALIFIERS[3], VALUES[3]);
+ ht.put(put);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Delete a storefile column
+ ////////////////////////////////////////////////////////////////////////////
+ delete = new Delete(ROWS[0]);
+ delete.deleteColumns(FAMILIES[6], QUALIFIERS[7]);
+ ht.delete(delete);
+
+ // Try to get deleted column
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[6], QUALIFIERS[7]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ // Try to scan deleted column
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[6], QUALIFIERS[7]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ // Make sure we can still get a column before it and after it
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[6], QUALIFIERS[6]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[6], QUALIFIERS[8]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[8], VALUES[8]);
+
+ // Make sure we can still scan a column before it and after it
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[6], QUALIFIERS[8]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[8], VALUES[8]);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Delete a memcache column
+ ////////////////////////////////////////////////////////////////////////////
+ delete = new Delete(ROWS[0]);
+ delete.deleteColumns(FAMILIES[6], QUALIFIERS[8]);
+ ht.delete(delete);
+
+ // Try to get deleted column
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[6], QUALIFIERS[8]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ // Try to scan deleted column
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[6], QUALIFIERS[8]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ // Make sure we can still get a column before it and after it
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[6], QUALIFIERS[6]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[6], QUALIFIERS[9]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+
+ // Make sure we can still scan a column before it and after it
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[6], QUALIFIERS[9]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Delete joint storefile/memcache family
+ ////////////////////////////////////////////////////////////////////////////
+
+ delete = new Delete(ROWS[0]);
+ delete.deleteFamily(FAMILIES[4]);
+ ht.delete(delete);
+
+ // Try to get storefile column in deleted family
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[4]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ // Try to get memcache column in deleted family
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[3]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ // Try to get deleted family
+ get = new Get(ROWS[0]);
+ get.addFamily(FAMILIES[4]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ // Try to scan storefile column in deleted family
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[4], QUALIFIERS[4]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ // Try to scan memcache column in deleted family
+ scan = new Scan();
+ scan.addColumn(FAMILIES[4], QUALIFIERS[3]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ // Try to scan deleted family
+ scan = new Scan();
+ scan.addFamily(FAMILIES[4]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ // Make sure we can still get another family
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[2], QUALIFIERS[2]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]);
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[6], QUALIFIERS[9]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+
+ // Make sure we can still scan another family
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[6], QUALIFIERS[9]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Flush everything and rerun delete tests
+ ////////////////////////////////////////////////////////////////////////////
+
+ flushMemcache(TABLE);
+
+ // Try to get storefile column in deleted family
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[4]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ // Try to get memcache column in deleted family
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[3]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ // Try to get deleted family
+ get = new Get(ROWS[0]);
+ get.addFamily(FAMILIES[4]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ // Try to scan storefile column in deleted family
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[4], QUALIFIERS[4]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ // Try to scan memcache column in deleted family
+ scan = new Scan();
+ scan.addColumn(FAMILIES[4], QUALIFIERS[3]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ // Try to scan deleted family
+ scan = new Scan();
+ scan.addFamily(FAMILIES[4]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ // Make sure we can still get another family
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[2], QUALIFIERS[2]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]);
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[6], QUALIFIERS[9]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+
+ // Make sure we can still scan another family
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[6], VALUES[6]);
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[6], QUALIFIERS[9]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[6], QUALIFIERS[9], VALUES[9]);
+
+ }
+
+ @SuppressWarnings("unused")
+ public void testNull() throws Exception {
+
+ byte [] TABLE = Bytes.toBytes("testNull");
+
+ // Null table name (should NOT work)
+ try {
+ HTable htFail = createTable(null, FAMILY);
+ assertTrue("Creating a table with null name passed, should have failed",
+ false);
+ } catch(Exception e) {}
+
+ // Null family (should NOT work)
+ try {
+ HTable htFail = createTable(TABLE, (byte[])null);
+ assertTrue("Creating a table with a null family passed, should fail",
+ false);
+ } catch(Exception e) {}
+
+ HTable ht = createTable(TABLE, FAMILY);
+
+ // Null row (should NOT work)
+ try {
+ Put put = new Put((byte[])null);
+ put.add(FAMILY, QUALIFIER, VALUE);
+ ht.put(put);
+ assertTrue("Inserting a null row worked, should throw exception",
+ false);
+ } catch(Exception e) {}
+
+ // Null qualifier (should work)
+ try {
+
+ Put put = new Put(ROW);
+ put.add(FAMILY, null, VALUE);
+ ht.put(put);
+
+ getTestNull(ht, ROW, FAMILY, VALUE);
+
+ scanTestNull(ht, ROW, FAMILY, VALUE);
+
+ Delete delete = new Delete(ROW);
+ delete.deleteColumns(FAMILY, null);
+ ht.delete(delete);
+
+ Get get = new Get(ROW);
+ Result result = ht.get(get);
+ assertEmptyResult(result);
+
+ } catch(Exception e) {
+ e.printStackTrace();
+ assertTrue("Using a row with null qualifier threw exception, should "
+ + "pass", false);
+ }
+
+ // Use a new table
+
+ byte [] TABLE2 = Bytes.toBytes("testNull2");
+ ht = createTable(TABLE2, FAMILY);
+
+ // Empty qualifier, byte[0] instead of null (should work)
+ try {
+
+ Put put = new Put(ROW);
+ put.add(FAMILY, EMPTY, VALUE);
+ ht.put(put);
+
+ getTestNull(ht, ROW, FAMILY, VALUE);
+
+ scanTestNull(ht, ROW, FAMILY, VALUE);
+
+ // Flush and try again
+
+ flushMemcache(TABLE2);
+
+ getTestNull(ht, ROW, FAMILY, VALUE);
+
+ scanTestNull(ht, ROW, FAMILY, VALUE);
+
+ Delete delete = new Delete(ROW);
+ delete.deleteColumns(FAMILY, EMPTY);
+ ht.delete(delete);
+
+ Get get = new Get(ROW);
+ Result result = ht.get(get);
+ assertEmptyResult(result);
+
+ } catch(Exception e) {
+ e.printStackTrace();
+ assertTrue("Using a row with null qualifier threw exception, should "
+ + "pass", false);
+ }
+
+ // Null value
+ try {
+
+ Put put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, null);
+ ht.put(put);
+
+ Get get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIER);
+ Result result = ht.get(get);
+ assertSingleResult(result, ROW, FAMILY, QUALIFIER, null);
+
+ Scan scan = new Scan();
+ scan.addColumn(FAMILY, QUALIFIER);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROW, FAMILY, QUALIFIER, null);
+
+ Delete delete = new Delete(ROW);
+ delete.deleteColumns(FAMILY, QUALIFIER);
+ ht.delete(delete);
+
+ get = new Get(ROW);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ } catch(Exception e) {
+ e.printStackTrace();
+ assertTrue("Null values should be allowed, but threw exception",
+ false);
+ }
+
+ }
+
+ public void testVersions() throws Exception {
+
+ byte [] TABLE = Bytes.toBytes("testSimpleVersions");
+
+ long [] STAMPS = makeStamps(20);
+ byte [][] VALUES = makeNAscii(VALUE, 20);
+
+ HTable ht = createTable(TABLE, FAMILY, 10);
+
+ // Insert 4 versions of same column
+ Put put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ put.add(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ put.add(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ put.add(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+ ht.put(put);
+
+ // Verify we can get each one properly
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+
+ // Verify we don't accidentally get others
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+
+ // Ensure maxVersions in query is respected
+ Get get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIER);
+ get.setMaxVersions(2);
+ Result result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[4], STAMPS[5]},
+ new byte[][] {VALUES[4], VALUES[5]},
+ 0, 1);
+
+ Scan scan = new Scan(ROW);
+ scan.addColumn(FAMILY, QUALIFIER);
+ scan.setMaxVersions(2);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[4], STAMPS[5]},
+ new byte[][] {VALUES[4], VALUES[5]},
+ 0, 1);
+
+ // Flush and redo
+
+ flushMemcache(TABLE);
+
+ // Verify we can get each one properly
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+
+ // Verify we don't accidentally get others
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+
+ // Ensure maxVersions in query is respected
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIER);
+ get.setMaxVersions(2);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[4], STAMPS[5]},
+ new byte[][] {VALUES[4], VALUES[5]},
+ 0, 1);
+
+ scan = new Scan(ROW);
+ scan.addColumn(FAMILY, QUALIFIER);
+ scan.setMaxVersions(2);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[4], STAMPS[5]},
+ new byte[][] {VALUES[4], VALUES[5]},
+ 0, 1);
+
+
+ // Add some memcache and retest
+
+ // Insert 4 more versions of same column and a dupe
+ put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+ put.add(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+ put.add(FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+ put.add(FAMILY, QUALIFIER, STAMPS[8], VALUES[8]);
+ ht.put(put);
+
+ // Ensure maxVersions in query is respected
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIER);
+ get.setMaxVersions();
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+ new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
+ 0, 7);
+
+ scan = new Scan(ROW);
+ scan.addColumn(FAMILY, QUALIFIER);
+ scan.setMaxVersions();
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+ new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
+ 0, 7);
+
+ get = new Get(ROW);
+ get.setMaxVersions();
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+ new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
+ 0, 7);
+
+ scan = new Scan(ROW);
+ scan.setMaxVersions();
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+ new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
+ 0, 7);
+
+ // Verify we can get each one properly
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+
+ // Verify we don't accidentally get others
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
+
+ // Ensure maxVersions of table is respected
+
+ flushMemcache(TABLE);
+
+ // Insert 4 more versions of same column and a dupe
+ put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, STAMPS[9], VALUES[9]);
+ put.add(FAMILY, QUALIFIER, STAMPS[11], VALUES[11]);
+ put.add(FAMILY, QUALIFIER, STAMPS[13], VALUES[13]);
+ put.add(FAMILY, QUALIFIER, STAMPS[15], VALUES[15]);
+ ht.put(put);
+
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIER);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], STAMPS[11], STAMPS[13], STAMPS[15]},
+ new byte[][] {VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], VALUES[11], VALUES[13], VALUES[15]},
+ 0, 9);
+
+ scan = new Scan(ROW);
+ scan.addColumn(FAMILY, QUALIFIER);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8], STAMPS[9], STAMPS[11], STAMPS[13], STAMPS[15]},
+ new byte[][] {VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[7], VALUES[8], VALUES[9], VALUES[11], VALUES[13], VALUES[15]},
+ 0, 9);
+
+ // Delete a version in the memcache and a version in a storefile
+ Delete delete = new Delete(ROW);
+ delete.deleteColumn(FAMILY, QUALIFIER, STAMPS[11]);
+ delete.deleteColumn(FAMILY, QUALIFIER, STAMPS[7]);
+ ht.delete(delete);
+
+ // Test that it's gone
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIER);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], STAMPS[9], STAMPS[13], STAMPS[15]},
+ new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[8], VALUES[9], VALUES[13], VALUES[15]},
+ 0, 9);
+
+ scan = new Scan(ROW);
+ scan.addColumn(FAMILY, QUALIFIER);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[1], STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[8], STAMPS[9], STAMPS[13], STAMPS[15]},
+ new byte[][] {VALUES[1], VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6], VALUES[8], VALUES[9], VALUES[13], VALUES[15]},
+ 0, 9);
+
+ }
+
+ public void testVersionLimits() throws Exception {
+ byte [] TABLE = Bytes.toBytes("testVersionLimits");
+ byte [][] FAMILIES = makeNAscii(FAMILY, 3);
+ int [] LIMITS = {1,3,5};
+ long [] STAMPS = makeStamps(10);
+ byte [][] VALUES = makeNAscii(VALUE, 10);
+ HTable ht = createTable(TABLE, FAMILIES, LIMITS);
+
+ // Insert limit + 1 on each family
+ Put put = new Put(ROW);
+ put.add(FAMILIES[0], QUALIFIER, STAMPS[0], VALUES[0]);
+ put.add(FAMILIES[0], QUALIFIER, STAMPS[1], VALUES[1]);
+ put.add(FAMILIES[1], QUALIFIER, STAMPS[0], VALUES[0]);
+ put.add(FAMILIES[1], QUALIFIER, STAMPS[1], VALUES[1]);
+ put.add(FAMILIES[1], QUALIFIER, STAMPS[2], VALUES[2]);
+ put.add(FAMILIES[1], QUALIFIER, STAMPS[3], VALUES[3]);
+ put.add(FAMILIES[2], QUALIFIER, STAMPS[0], VALUES[0]);
+ put.add(FAMILIES[2], QUALIFIER, STAMPS[1], VALUES[1]);
+ put.add(FAMILIES[2], QUALIFIER, STAMPS[2], VALUES[2]);
+ put.add(FAMILIES[2], QUALIFIER, STAMPS[3], VALUES[3]);
+ put.add(FAMILIES[2], QUALIFIER, STAMPS[4], VALUES[4]);
+ put.add(FAMILIES[2], QUALIFIER, STAMPS[5], VALUES[5]);
+ put.add(FAMILIES[2], QUALIFIER, STAMPS[6], VALUES[6]);
+ ht.put(put);
+
+ // Verify we only get the right number out of each
+
+ // Family0
+
+ Get get = new Get(ROW);
+ get.addColumn(FAMILIES[0], QUALIFIER);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ Result result = ht.get(get);
+ assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+ new long [] {STAMPS[1]},
+ new byte[][] {VALUES[1]},
+ 0, 0);
+
+ get = new Get(ROW);
+ get.addFamily(FAMILIES[0]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+ new long [] {STAMPS[1]},
+ new byte[][] {VALUES[1]},
+ 0, 0);
+
+ Scan scan = new Scan(ROW);
+ scan.addColumn(FAMILIES[0], QUALIFIER);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+ new long [] {STAMPS[1]},
+ new byte[][] {VALUES[1]},
+ 0, 0);
+
+ scan = new Scan(ROW);
+ scan.addFamily(FAMILIES[0]);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILIES[0], QUALIFIER,
+ new long [] {STAMPS[1]},
+ new byte[][] {VALUES[1]},
+ 0, 0);
+
+ // Family1
+
+ get = new Get(ROW);
+ get.addColumn(FAMILIES[1], QUALIFIER);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
+ new long [] {STAMPS[1], STAMPS[2], STAMPS[3]},
+ new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
+ 0, 2);
+
+ get = new Get(ROW);
+ get.addFamily(FAMILIES[1]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
+ new long [] {STAMPS[1], STAMPS[2], STAMPS[3]},
+ new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
+ 0, 2);
+
+ scan = new Scan(ROW);
+ scan.addColumn(FAMILIES[1], QUALIFIER);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
+ new long [] {STAMPS[1], STAMPS[2], STAMPS[3]},
+ new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
+ 0, 2);
+
+ scan = new Scan(ROW);
+ scan.addFamily(FAMILIES[1]);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILIES[1], QUALIFIER,
+ new long [] {STAMPS[1], STAMPS[2], STAMPS[3]},
+ new byte[][] {VALUES[1], VALUES[2], VALUES[3]},
+ 0, 2);
+
+ // Family2
+
+ get = new Get(ROW);
+ get.addColumn(FAMILIES[2], QUALIFIER);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
+ new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
+ new byte[][] {VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
+ 0, 4);
+
+ get = new Get(ROW);
+ get.addFamily(FAMILIES[2]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
+ new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
+ new byte[][] {VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
+ 0, 4);
+
+ scan = new Scan(ROW);
+ scan.addColumn(FAMILIES[2], QUALIFIER);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
+ new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
+ new byte[][] {VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
+ 0, 4);
+
+ scan = new Scan(ROW);
+ scan.addFamily(FAMILIES[2]);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILIES[2], QUALIFIER,
+ new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6]},
+ new byte[][] {VALUES[2], VALUES[3], VALUES[4], VALUES[5], VALUES[6]},
+ 0, 4);
+
+ // Try all families
+
+ get = new Get(ROW);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertTrue("Expected 9 keys but received " + result.size(),
+ result.size() == 9);
+
+ get = new Get(ROW);
+ get.addFamily(FAMILIES[0]);
+ get.addFamily(FAMILIES[1]);
+ get.addFamily(FAMILIES[2]);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertTrue("Expected 9 keys but received " + result.size(),
+ result.size() == 9);
+
+ get = new Get(ROW);
+ get.addColumn(FAMILIES[0], QUALIFIER);
+ get.addColumn(FAMILIES[1], QUALIFIER);
+ get.addColumn(FAMILIES[2], QUALIFIER);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ result = ht.get(get);
+ assertTrue("Expected 9 keys but received " + result.size(),
+ result.size() == 9);
+
+ scan = new Scan(ROW);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ result = getSingleScanResult(ht, scan);
+ assertTrue("Expected 9 keys but received " + result.size(),
+ result.size() == 9);
+
+ scan = new Scan(ROW);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ scan.addFamily(FAMILIES[0]);
+ scan.addFamily(FAMILIES[1]);
+ scan.addFamily(FAMILIES[2]);
+ result = getSingleScanResult(ht, scan);
+ assertTrue("Expected 9 keys but received " + result.size(),
+ result.size() == 9);
+
+ scan = new Scan(ROW);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ scan.addColumn(FAMILIES[0], QUALIFIER);
+ scan.addColumn(FAMILIES[1], QUALIFIER);
+ scan.addColumn(FAMILIES[2], QUALIFIER);
+ result = getSingleScanResult(ht, scan);
+ assertTrue("Expected 9 keys but received " + result.size(),
+ result.size() == 9);
+
+ }
+
+ public void XtestDeletes() throws Exception {
+
+ // Test delete latest version
+ }
+
+ /**
+ * Baseline "scalability" test.
+ *
+ * Tests one hundred families, one million columns, one million versions
+ */
+ public void XtestMillions() throws Exception {
+
+ // 100 families
+
+ // millions of columns
+
+ // millions of versions
+
+ }
+
+ public void XtestMultipleRegionsAndBatchPuts() throws Exception {
+ // Two family table
+
+ // Insert lots of rows
+
+ // Insert to the same row with batched puts
+
+ // Insert to multiple rows with batched puts
+
+ // Split the table
+
+ // Get row from first region
+
+ // Get row from second region
+
+ // Scan all rows
+
+ // Insert to multiple regions with batched puts
+
+ // Get row from first region
+
+ // Get row from second region
+
+ // Scan all rows
+
+
+ }
+
+ public void XtestMultipleRowMultipleFamily() throws Exception {
+
+ }
+
+ /**
+ * Explicitly test JIRAs related to HBASE-880 / Client API
+ */
+ public void testJIRAs() throws Exception {
+ jiraTest867();
+ jiraTest861();
+ jiraTest33();
+ jiraTest1014();
+ jiraTest1182();
+ jiraTest52();
+ }
+
+ //
+ // JIRA Testers
+ //
+
+ /**
+ * HBASE-867
+ * If millions of columns in a column family, hbase scanner won't come up
+ *
+ * Test will create numRows rows, each with numColsPerRow columns
+ * (1 version each), and attempt to scan them all.
+ *
+ * To test at scale, up numColsPerRow to the millions
+ * (have not gotten that to work running as junit though)
+ */
+ private void jiraTest867() throws Exception {
+
+ int numRows = 10;
+ int numColsPerRow = 2000;
+
+ byte [] TABLE = Bytes.toBytes("jiraTest867");
+
+ byte [][] ROWS = makeN(ROW, numRows);
+ byte [][] QUALIFIERS = makeN(QUALIFIER, numColsPerRow);
+
+ HTable ht = createTable(TABLE, FAMILY);
+
+ // Insert rows
+
+ for(int i=0;i<numRows;i++) {
+ Put put = new Put(ROWS[i]);
+ for(int j=0;j<numColsPerRow;j++) {
+ put.add(FAMILY, QUALIFIERS[j], QUALIFIERS[j]);
+ }
+ assertTrue("Put expected to contain " + numColsPerRow + " columns but " +
+ "only contains " + put.size(), put.size() == numColsPerRow);
+ ht.put(put);
+ }
+
+ // Get a row
+ Get get = new Get(ROWS[numRows-1]);
+ Result result = ht.get(get);
+ assertNumKeys(result, numColsPerRow);
+ KeyValue [] keys = result.sorted();
+ for(int i=0;i<result.size();i++) {
+ assertKey(keys[i], ROWS[numRows-1], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
+ }
+
+ // Scan the rows
+ Scan scan = new Scan();
+ ResultScanner scanner = ht.getScanner(scan);
+ int rowCount = 0;
+ while((result = scanner.next()) != null) {
+ assertNumKeys(result, numColsPerRow);
+ KeyValue [] kvs = result.sorted();
+ for(int i=0;i<numColsPerRow;i++) {
+ assertKey(kvs[i], ROWS[rowCount], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
+ }
+ rowCount++;
+ }
+ scanner.close();
+ assertTrue("Expected to scan " + numRows + " rows but actually scanned "
+ + rowCount + " rows", rowCount == numRows);
+
+ // flush and try again
+
+ flushMemcache(TABLE);
+
+ // Get a row
+ get = new Get(ROWS[numRows-1]);
+ result = ht.get(get);
+ assertNumKeys(result, numColsPerRow);
+ keys = result.sorted();
+ for(int i=0;i<result.size();i++) {
+ assertKey(keys[i], ROWS[numRows-1], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
+ }
+
+ // Scan the rows
+ scan = new Scan();
+ scanner = ht.getScanner(scan);
+ rowCount = 0;
+ while((result = scanner.next()) != null) {
+ assertNumKeys(result, numColsPerRow);
+ KeyValue [] kvs = result.sorted();
+ for(int i=0;i<numColsPerRow;i++) {
+ assertKey(kvs[i], ROWS[rowCount], FAMILY, QUALIFIERS[i], QUALIFIERS[i]);
+ }
+ rowCount++;
+ }
+ scanner.close();
+ assertTrue("Expected to scan " + numRows + " rows but actually scanned "
+ + rowCount + " rows", rowCount == numRows);
+
+ }
+
+ /**
+ * HBASE-861
+ * get with timestamp will return a value if there is a version with an
+ * earlier timestamp
+ */
+ private void jiraTest861() throws Exception {
+
+ byte [] TABLE = Bytes.toBytes("jiraTest861");
+ byte [][] VALUES = makeNAscii(VALUE, 7);
+ long [] STAMPS = makeStamps(7);
+
+ HTable ht = createTable(TABLE, FAMILY, 10);
+
+ // Insert three versions
+
+ Put put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+ put.add(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ put.add(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ ht.put(put);
+
+ // Get the middle value
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+
+ // Try to get one version before (expect fail)
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
+
+ // Try to get one version after (expect fail)
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
+
+ // Try same from storefile
+ flushMemcache(TABLE);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
+
+ // Insert two more versions surrounding others, into memcache
+ put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+ put.add(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+ ht.put(put);
+
+ // Check we can get everything we should and can't get what we shouldn't
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+
+ // Try same from two storefiles
+ flushMemcache(TABLE);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[1]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[5]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+
+ }
+
+ /**
+ * HBASE-33
+ * Add a HTable get/obtainScanner method that retrieves all versions of a
+ * particular column and row between two timestamps
+ */
+ private void jiraTest33() throws Exception {
+
+ byte [] TABLE = Bytes.toBytes("jiraTest33");
+ byte [][] VALUES = makeNAscii(VALUE, 7);
+ long [] STAMPS = makeStamps(7);
+
+ HTable ht = createTable(TABLE, FAMILY, 10);
+
+ // Insert lots versions
+
+ Put put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+ put.add(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ put.add(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ put.add(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+ put.add(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ put.add(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+ ht.put(put);
+
+ getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+ getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
+ getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+ getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
+
+ scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+ scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
+ scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+ scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
+
+ // Try same from storefile
+ flushMemcache(TABLE);
+
+ getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+ getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
+ getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+ getVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
+
+ scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+ scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 2);
+ scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+ scanVersionRangeAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 3);
+
+ }
+
+ /**
+ * HBASE-1014
+ * commit(BatchUpdate) method should return timestamp
+ */
+ private void jiraTest1014() throws Exception {
+
+ byte [] TABLE = Bytes.toBytes("jiraTest1014");
+
+ HTable ht = createTable(TABLE, FAMILY, 10);
+
+ long manualStamp = 12345;
+
+ // Insert lots versions
+
+ Put put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, manualStamp, VALUE);
+ ht.put(put);
+
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, manualStamp, VALUE);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, manualStamp-1);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, manualStamp+1);
+
+ }
+
+ /**
+ * HBASE-1182
+ * Scan for columns > some timestamp
+ */
+ private void jiraTest1182() throws Exception {
+
+ byte [] TABLE = Bytes.toBytes("jiraTest1182");
+ byte [][] VALUES = makeNAscii(VALUE, 7);
+ long [] STAMPS = makeStamps(7);
+
+ HTable ht = createTable(TABLE, FAMILY, 10);
+
+ // Insert lots versions
+
+ Put put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+ put.add(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ put.add(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ put.add(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+ put.add(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ put.add(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+ ht.put(put);
+
+ getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+ getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
+ getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+
+ scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+ scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
+ scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+
+ // Try same from storefile
+ flushMemcache(TABLE);
+
+ getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+ getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
+ getVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+
+ scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+ scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 2, 5);
+ scanVersionRangeAndVerifyGreaterThan(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 4, 5);
+
+
+ }
+
+ /**
+ * HBASE-52
+ * Add a means of scanning over all versions
+ */
+ private void jiraTest52() throws Exception {
+
+ byte [] TABLE = Bytes.toBytes("jiraTest52");
+ byte [][] VALUES = makeNAscii(VALUE, 7);
+ long [] STAMPS = makeStamps(7);
+
+ HTable ht = createTable(TABLE, FAMILY, 10);
+
+ // Insert lots versions
+
+ Put put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, STAMPS[0], VALUES[0]);
+ put.add(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ put.add(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ put.add(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+ put.add(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ put.add(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+ ht.put(put);
+
+ getAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+
+ scanAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+
+ // Try same from storefile
+ flushMemcache(TABLE);
+
+ getAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+
+ scanAllVersionsAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS, VALUES, 0, 5);
+
+
+ }
+
+ //
+ // Bulk Testers
+ //
+
+ private void getVersionRangeAndVerifyGreaterThan(HTable ht, byte [] row,
+ byte [] family, byte [] qualifier, long [] stamps, byte [][] values,
+ int start, int end)
+ throws IOException {
+ Get get = new Get(row);
+ get.addColumn(family, qualifier);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ get.setTimeRange(stamps[start+1], Long.MAX_VALUE);
+ Result result = ht.get(get);
+ assertNResult(result, row, family, qualifier, stamps, values, start+1, end);
+ }
+
+ private void getVersionRangeAndVerify(HTable ht, byte [] row, byte [] family,
+ byte [] qualifier, long [] stamps, byte [][] values, int start, int end)
+ throws IOException {
+ Get get = new Get(row);
+ get.addColumn(family, qualifier);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ get.setTimeRange(stamps[start], stamps[end]+1);
+ Result result = ht.get(get);
+ assertNResult(result, row, family, qualifier, stamps, values, start, end);
+ }
+
+ private void getAllVersionsAndVerify(HTable ht, byte [] row, byte [] family,
+ byte [] qualifier, long [] stamps, byte [][] values, int start, int end)
+ throws IOException {
+ Get get = new Get(row);
+ get.addColumn(family, qualifier);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ Result result = ht.get(get);
+ assertNResult(result, row, family, qualifier, stamps, values, start, end);
+ }
+
+ private void scanVersionRangeAndVerifyGreaterThan(HTable ht, byte [] row,
+ byte [] family, byte [] qualifier, long [] stamps, byte [][] values,
+ int start, int end)
+ throws IOException {
+ Scan scan = new Scan(row);
+ scan.addColumn(family, qualifier);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ scan.setTimeRange(stamps[start+1], Long.MAX_VALUE);
+ Result result = getSingleScanResult(ht, scan);
+ assertNResult(result, row, family, qualifier, stamps, values, start+1, end);
+ }
+
+ private void scanVersionRangeAndVerify(HTable ht, byte [] row, byte [] family,
+ byte [] qualifier, long [] stamps, byte [][] values, int start, int end)
+ throws IOException {
+ Scan scan = new Scan(row);
+ scan.addColumn(family, qualifier);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ scan.setTimeRange(stamps[start], stamps[end]+1);
+ Result result = getSingleScanResult(ht, scan);
+ assertNResult(result, row, family, qualifier, stamps, values, start, end);
+ }
+
+ private void scanAllVersionsAndVerify(HTable ht, byte [] row, byte [] family,
+ byte [] qualifier, long [] stamps, byte [][] values, int start, int end)
+ throws IOException {
+ Scan scan = new Scan(row);
+ scan.addColumn(family, qualifier);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ Result result = getSingleScanResult(ht, scan);
+ assertNResult(result, row, family, qualifier, stamps, values, start, end);
+ }
+
+ private void getVersionAndVerify(HTable ht, byte [] row, byte [] family,
+ byte [] qualifier, long stamp, byte [] value)
+ throws Exception {
+ Get get = new Get(row);
+ get.addColumn(family, qualifier);
+ get.setTimeStamp(stamp);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ Result result = ht.get(get);
+ assertSingleResult(result, row, family, qualifier, stamp, value);
+ }
+
+ private void getVersionAndVerifyMissing(HTable ht, byte [] row, byte [] family,
+ byte [] qualifier, long stamp)
+ throws Exception {
+ Get get = new Get(row);
+ get.addColumn(family, qualifier);
+ get.setTimeStamp(stamp);
+ get.setMaxVersions(Integer.MAX_VALUE);
+ Result result = ht.get(get);
+ assertEmptyResult(result);
+ }
+
+ private void scanVersionAndVerify(HTable ht, byte [] row, byte [] family,
+ byte [] qualifier, long stamp, byte [] value)
+ throws Exception {
+ Scan scan = new Scan(row);
+ scan.addColumn(family, qualifier);
+ scan.setTimeStamp(stamp);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ Result result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, row, family, qualifier, stamp, value);
+ }
+
+ private void scanVersionAndVerifyMissing(HTable ht, byte [] row,
+ byte [] family, byte [] qualifier, long stamp)
+ throws Exception {
+ Scan scan = new Scan(row);
+ scan.addColumn(family, qualifier);
+ scan.setTimeStamp(stamp);
+ scan.setMaxVersions(Integer.MAX_VALUE);
+ Result result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+ }
+
+ private void getTestNull(HTable ht, byte [] row, byte [] family,
+ byte [] value)
+ throws Exception {
+
+ Get get = new Get(row);
+ get.addColumn(family, null);
+ Result result = ht.get(get);
+ assertSingleResult(result, row, family, null, value);
+
+ get = new Get(row);
+ get.addColumn(family, EMPTY);
+ result = ht.get(get);
+ assertSingleResult(result, row, family, EMPTY, value);
+
+ get = new Get(row);
+ get.addFamily(family);
+ result = ht.get(get);
+ assertSingleResult(result, row, family, EMPTY, value);
+
+ get = new Get(row);
+ result = ht.get(get);
+ assertSingleResult(result, row, family, EMPTY, value);
+
+ }
+
+ private void scanTestNull(HTable ht, byte [] row, byte [] family,
+ byte [] value)
+ throws Exception {
+
+ Scan scan = new Scan();
+ scan.addColumn(family, null);
+ Result result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, row, family, EMPTY, value);
+
+ scan = new Scan();
+ scan.addColumn(family, EMPTY);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, row, family, EMPTY, value);
+
+ scan = new Scan();
+ scan.addFamily(family);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, row, family, EMPTY, value);
+
+ scan = new Scan();
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, row, family, EMPTY, value);
+
+ }
+
+ private void singleRowGetTest(HTable ht, byte [][] ROWS, byte [][] FAMILIES,
+ byte [][] QUALIFIERS, byte [][] VALUES)
+ throws Exception {
+
+ // Single column from memcache
+ Get get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[0]);
+ Result result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0]);
+
+ // Single column from storefile
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[2], QUALIFIERS[2]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]);
+
+ // Single column from storefile, family match
+ get = new Get(ROWS[0]);
+ get.addFamily(FAMILIES[7]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[0], FAMILIES[7], QUALIFIERS[7], VALUES[7]);
+
+ // Two columns, one from memcache one from storefile, same family,
+ // wildcard match
+ get = new Get(ROWS[0]);
+ get.addFamily(FAMILIES[4]);
+ result = ht.get(get);
+ assertDoubleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0],
+ FAMILIES[4], QUALIFIERS[4], VALUES[4]);
+
+ // Two columns, one from memcache one from storefile, same family,
+ // explicit match
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[0]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[4]);
+ result = ht.get(get);
+ assertDoubleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0],
+ FAMILIES[4], QUALIFIERS[4], VALUES[4]);
+
+ // Three column, one from memcache two from storefile, different families,
+ // wildcard match
+ get = new Get(ROWS[0]);
+ get.addFamily(FAMILIES[4]);
+ get.addFamily(FAMILIES[7]);
+ result = ht.get(get);
+ assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES,
+ new int [][] { {4, 0, 0}, {4, 4, 4}, {7, 7, 7} });
+
+ // Multiple columns from everywhere storefile, many family, wildcard
+ get = new Get(ROWS[0]);
+ get.addFamily(FAMILIES[2]);
+ get.addFamily(FAMILIES[4]);
+ get.addFamily(FAMILIES[6]);
+ get.addFamily(FAMILIES[7]);
+ result = ht.get(get);
+ assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES,
+ new int [][] {
+ {2, 2, 2}, {2, 4, 4}, {4, 0, 0}, {4, 4, 4}, {6, 6, 6}, {6, 7, 7}, {7, 7, 7}
+ });
+
+ // Multiple columns from everywhere storefile, many family, wildcard
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[2], QUALIFIERS[2]);
+ get.addColumn(FAMILIES[2], QUALIFIERS[4]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[0]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[4]);
+ get.addColumn(FAMILIES[6], QUALIFIERS[6]);
+ get.addColumn(FAMILIES[6], QUALIFIERS[7]);
+ get.addColumn(FAMILIES[7], QUALIFIERS[7]);
+ get.addColumn(FAMILIES[7], QUALIFIERS[8]);
+ result = ht.get(get);
+ assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES,
+ new int [][] {
+ {2, 2, 2}, {2, 4, 4}, {4, 0, 0}, {4, 4, 4}, {6, 6, 6}, {6, 7, 7}, {7, 7, 7}
+ });
+
+ // Everything
+ get = new Get(ROWS[0]);
+ result = ht.get(get);
+ assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES,
+ new int [][] {
+ {2, 2, 2}, {2, 4, 4}, {4, 0, 0}, {4, 4, 4}, {6, 6, 6}, {6, 7, 7}, {7, 7, 7}, {9, 0, 0}
+ });
+
+ // Get around inserted columns
+
+ get = new Get(ROWS[1]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ get = new Get(ROWS[0]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[3]);
+ get.addColumn(FAMILIES[2], QUALIFIERS[3]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ }
+
+ private void singleRowScanTest(HTable ht, byte [][] ROWS, byte [][] FAMILIES,
+ byte [][] QUALIFIERS, byte [][] VALUES)
+ throws Exception {
+
+ // Single column from memcache
+ Scan scan = new Scan();
+ scan.addColumn(FAMILIES[4], QUALIFIERS[0]);
+ Result result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0]);
+
+ // Single column from storefile
+ scan = new Scan();
+ scan.addColumn(FAMILIES[2], QUALIFIERS[2]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[2], QUALIFIERS[2], VALUES[2]);
+
+ // Single column from storefile, family match
+ scan = new Scan();
+ scan.addFamily(FAMILIES[7]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[0], FAMILIES[7], QUALIFIERS[7], VALUES[7]);
+
+ // Two columns, one from memcache one from storefile, same family,
+ // wildcard match
+ scan = new Scan();
+ scan.addFamily(FAMILIES[4]);
+ result = getSingleScanResult(ht, scan);
+ assertDoubleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0],
+ FAMILIES[4], QUALIFIERS[4], VALUES[4]);
+
+ // Two columns, one from memcache one from storefile, same family,
+ // explicit match
+ scan = new Scan();
+ scan.addColumn(FAMILIES[4], QUALIFIERS[0]);
+ scan.addColumn(FAMILIES[4], QUALIFIERS[4]);
+ result = getSingleScanResult(ht, scan);
+ assertDoubleResult(result, ROWS[0], FAMILIES[4], QUALIFIERS[0], VALUES[0],
+ FAMILIES[4], QUALIFIERS[4], VALUES[4]);
+
+ // Three column, one from memcache two from storefile, different families,
+ // wildcard match
+ scan = new Scan();
+ scan.addFamily(FAMILIES[4]);
+ scan.addFamily(FAMILIES[7]);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES,
+ new int [][] { {4, 0, 0}, {4, 4, 4}, {7, 7, 7} });
+
+ // Multiple columns from everywhere storefile, many family, wildcard
+ scan = new Scan();
+ scan.addFamily(FAMILIES[2]);
+ scan.addFamily(FAMILIES[4]);
+ scan.addFamily(FAMILIES[6]);
+ scan.addFamily(FAMILIES[7]);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES,
+ new int [][] {
+ {2, 2, 2}, {2, 4, 4}, {4, 0, 0}, {4, 4, 4}, {6, 6, 6}, {6, 7, 7}, {7, 7, 7}
+ });
+
+ // Multiple columns from everywhere storefile, many family, wildcard
+ scan = new Scan();
+ scan.addColumn(FAMILIES[2], QUALIFIERS[2]);
+ scan.addColumn(FAMILIES[2], QUALIFIERS[4]);
+ scan.addColumn(FAMILIES[4], QUALIFIERS[0]);
+ scan.addColumn(FAMILIES[4], QUALIFIERS[4]);
+ scan.addColumn(FAMILIES[6], QUALIFIERS[6]);
+ scan.addColumn(FAMILIES[6], QUALIFIERS[7]);
+ scan.addColumn(FAMILIES[7], QUALIFIERS[7]);
+ scan.addColumn(FAMILIES[7], QUALIFIERS[8]);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES,
+ new int [][] {
+ {2, 2, 2}, {2, 4, 4}, {4, 0, 0}, {4, 4, 4}, {6, 6, 6}, {6, 7, 7}, {7, 7, 7}
+ });
+
+ // Everything
+ scan = new Scan();
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROWS[0], FAMILIES, QUALIFIERS, VALUES,
+ new int [][] {
+ {2, 2, 2}, {2, 4, 4}, {4, 0, 0}, {4, 4, 4}, {6, 6, 6}, {6, 7, 7}, {7, 7, 7}, {9, 0, 0}
+ });
+
+ // Scan around inserted columns
+
+ scan = new Scan(ROWS[1]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[4], QUALIFIERS[3]);
+ scan.addColumn(FAMILIES[2], QUALIFIERS[3]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+ }
+
+
+
+ /**
+ * Verify a single column using gets.
+ * Expects family and qualifier arrays to be valid for at least
+ * the range: idx-2 < idx < idx+2
+ */
+ private void getVerifySingleColumn(HTable ht,
+ byte [][] ROWS, int ROWIDX,
+ byte [][] FAMILIES, int FAMILYIDX,
+ byte [][] QUALIFIERS, int QUALIFIERIDX,
+ byte [][] VALUES, int VALUEIDX)
+ throws Exception {
+
+ Get get = new Get(ROWS[ROWIDX]);
+ Result result = ht.get(get);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ get = new Get(ROWS[ROWIDX]);
+ get.addFamily(FAMILIES[FAMILYIDX]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ get = new Get(ROWS[ROWIDX]);
+ get.addFamily(FAMILIES[FAMILYIDX-2]);
+ get.addFamily(FAMILIES[FAMILYIDX]);
+ get.addFamily(FAMILIES[FAMILYIDX+2]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ get = new Get(ROWS[ROWIDX]);
+ get.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[0]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ get = new Get(ROWS[ROWIDX]);
+ get.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[1]);
+ get.addFamily(FAMILIES[FAMILYIDX]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ get = new Get(ROWS[ROWIDX]);
+ get.addFamily(FAMILIES[FAMILYIDX]);
+ get.addColumn(FAMILIES[FAMILYIDX+1], QUALIFIERS[1]);
+ get.addColumn(FAMILIES[FAMILYIDX-2], QUALIFIERS[1]);
+ get.addFamily(FAMILIES[FAMILYIDX-1]);
+ get.addFamily(FAMILIES[FAMILYIDX+2]);
+ result = ht.get(get);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ }
+
+
+ /**
+ * Verify a single column using scanners.
+ * Expects family and qualifier arrays to be valid for at least
+ * the range: idx-2 to idx+2
+ * Expects row array to be valid for at least idx to idx+2
+ */
+ private void scanVerifySingleColumn(HTable ht,
+ byte [][] ROWS, int ROWIDX,
+ byte [][] FAMILIES, int FAMILYIDX,
+ byte [][] QUALIFIERS, int QUALIFIERIDX,
+ byte [][] VALUES, int VALUEIDX)
+ throws Exception {
+
+ Scan scan = new Scan();
+ Result result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ scan = new Scan(ROWS[ROWIDX]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ scan = new Scan(ROWS[ROWIDX], ROWS[ROWIDX+1]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ scan = new Scan(HConstants.EMPTY_START_ROW, ROWS[ROWIDX+1]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ scan = new Scan();
+ scan.addFamily(FAMILIES[FAMILYIDX]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX+1]);
+ scan.addFamily(FAMILIES[FAMILYIDX]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[FAMILYIDX-1], QUALIFIERS[QUALIFIERIDX+1]);
+ scan.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX]);
+ scan.addFamily(FAMILIES[FAMILYIDX+1]);
+ result = getSingleScanResult(ht, scan);
+ assertSingleResult(result, ROWS[ROWIDX], FAMILIES[FAMILYIDX],
+ QUALIFIERS[QUALIFIERIDX], VALUES[VALUEIDX]);
+
+ }
+
+ /**
+ * Verify we do not read any values by accident around a single column
+ * Same requirements as getVerifySingleColumn
+ */
+ private void getVerifySingleEmpty(HTable ht,
+ byte [][] ROWS, int ROWIDX,
+ byte [][] FAMILIES, int FAMILYIDX,
+ byte [][] QUALIFIERS, int QUALIFIERIDX)
+ throws Exception {
+
+ Get get = new Get(ROWS[ROWIDX]);
+ get.addFamily(FAMILIES[4]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[1]);
+ Result result = ht.get(get);
+ assertEmptyResult(result);
+
+ get = new Get(ROWS[ROWIDX]);
+ get.addFamily(FAMILIES[4]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[2]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ get = new Get(ROWS[ROWIDX]);
+ get.addFamily(FAMILIES[3]);
+ get.addColumn(FAMILIES[4], QUALIFIERS[2]);
+ get.addFamily(FAMILIES[5]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ get = new Get(ROWS[ROWIDX+1]);
+ result = ht.get(get);
+ assertEmptyResult(result);
+
+ }
+
+ private void scanVerifySingleEmpty(HTable ht,
+ byte [][] ROWS, int ROWIDX,
+ byte [][] FAMILIES, int FAMILYIDX,
+ byte [][] QUALIFIERS, int QUALIFIERIDX)
+ throws Exception {
+
+ Scan scan = new Scan(ROWS[ROWIDX+1]);
+ Result result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ scan = new Scan(ROWS[ROWIDX+1],ROWS[ROWIDX+2]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ scan = new Scan(HConstants.EMPTY_START_ROW, ROWS[ROWIDX]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ scan = new Scan();
+ scan.addColumn(FAMILIES[FAMILYIDX], QUALIFIERS[QUALIFIERIDX+1]);
+ scan.addFamily(FAMILIES[FAMILYIDX-1]);
+ result = getSingleScanResult(ht, scan);
+ assertNullResult(result);
+
+ }
+
+ //
+ // Verifiers
+ //
+
+ private void assertKey(KeyValue key, byte [] row, byte [] family,
+ byte [] qualifier, byte [] value)
+ throws Exception {
+ assertTrue("Expected row [" + Bytes.toString(row) + "] " +
+ "Got row [" + Bytes.toString(key.getRow()) +"]",
+ equals(row, key.getRow()));
+ assertTrue("Expected family [" + Bytes.toString(family) + "] " +
+ "Got family [" + Bytes.toString(key.getFamily()) + "]",
+ equals(family, key.getFamily()));
+ assertTrue("Expected qualifier [" + Bytes.toString(qualifier) + "] " +
+ "Got qualifier [" + Bytes.toString(key.getQualifier()) + "]",
+ equals(qualifier, key.getQualifier()));
+ assertTrue("Expected value [" + Bytes.toString(value) + "] " +
+ "Got value [" + Bytes.toString(key.getValue()) + "]",
+ equals(value, key.getValue()));
+ }
+
+ private void assertNumKeys(Result result, int n) throws Exception {
+ assertTrue("Expected " + n + " keys but got " + result.size(),
+ result.size() == n);
+ }
+
+
+ private void assertNResult(Result result, byte [] row,
+ byte [][] families, byte [][] qualifiers, byte [][] values,
+ int [][] idxs)
+ throws Exception {
+ assertTrue("Expected row [" + Bytes.toString(row) + "] " +
+ "Got row [" + Bytes.toString(result.getRow()) +"]",
+ equals(row, result.getRow()));
+ assertTrue("Expected " + idxs.length + " keys but result contains "
+ + result.size(), result.size() == idxs.length);
+
+ KeyValue [] keys = result.sorted();
+
+ for(int i=0;i<keys.length;i++) {
+ byte [] family = families[idxs[i][0]];
+ byte [] qualifier = qualifiers[idxs[i][1]];
+ byte [] value = values[idxs[i][2]];
+ KeyValue key = keys[i];
+
+ assertTrue("(" + i + ") Expected family [" + Bytes.toString(family)
+ + "] " + "Got family [" + Bytes.toString(key.getFamily()) + "]",
+ equals(family, key.getFamily()));
+ assertTrue("(" + i + ") Expected qualifier [" + Bytes.toString(qualifier)
+ + "] " + "Got qualifier [" + Bytes.toString(key.getQualifier()) + "]",
+ equals(qualifier, key.getQualifier()));
+ assertTrue("(" + i + ") Expected value [" + Bytes.toString(value) + "] "
+ + "Got value [" + Bytes.toString(key.getValue()) + "]",
+ equals(value, key.getValue()));
+ }
+ }
+
+ private void assertNResult(Result result, byte [] row,
+ byte [] family, byte [] qualifier, long [] stamps, byte [][] values,
+ int start, int end)
+ throws IOException {
+ assertTrue("Expected row [" + Bytes.toString(row) + "] " +
+ "Got row [" + Bytes.toString(result.getRow()) +"]",
+ equals(row, result.getRow()));
+ int expectedResults = end - start + 1;
+ assertTrue("Expected " + expectedResults + " keys but result contains "
+ + result.size(), result.size() == expectedResults);
+
+ KeyValue [] keys = result.sorted();
+
+ for(int i=0;i<keys.length;i++) {
+ byte [] value = values[end-i];
+ long ts = stamps[end-i];
+ KeyValue key = keys[i];
+
+ assertTrue("(" + i + ") Expected family [" + Bytes.toString(family)
+ + "] " + "Got family [" + Bytes.toString(key.getFamily()) + "]",
+ equals(family, key.getFamily()));
+ assertTrue("(" + i + ") Expected qualifier [" + Bytes.toString(qualifier)
+ + "] " + "Got qualifier [" + Bytes.toString(key.getQualifier()) + "]",
+ equals(qualifier, key.getQualifier()));
+ assertTrue("Expected ts [" + ts + "] " +
+ "Got ts [" + key.getTimestamp() + "]", ts == key.getTimestamp());
+ assertTrue("(" + i + ") Expected value [" + Bytes.toString(value) + "] "
+ + "Got value [" + Bytes.toString(key.getValue()) + "]",
+ equals(value, key.getValue()));
+ }
+ }
+
+ /**
+ * Validate that result contains two specified keys, exactly.
+ * It is assumed key A sorts before key B.
+ */
+ private void assertDoubleResult(Result result, byte [] row,
+ byte [] familyA, byte [] qualifierA, byte [] valueA,
+ byte [] familyB, byte [] qualifierB, byte [] valueB)
+ throws Exception {
+ assertTrue("Expected row [" + Bytes.toString(row) + "] " +
+ "Got row [" + Bytes.toString(result.getRow()) +"]",
+ equals(row, result.getRow()));
+ assertTrue("Expected two keys but result contains " + result.size(),
+ result.size() == 2);
+ KeyValue [] kv = result.sorted();
+ KeyValue kvA = kv[0];
+ assertTrue("(A) Expected family [" + Bytes.toString(familyA) + "] " +
+ "Got family [" + Bytes.toString(kvA.getFamily()) + "]",
+ equals(familyA, kvA.getFamily()));
+ assertTrue("(A) Expected qualifier [" + Bytes.toString(qualifierA) + "] " +
+ "Got qualifier [" + Bytes.toString(kvA.getQualifier()) + "]",
+ equals(qualifierA, kvA.getQualifier()));
+ assertTrue("(A) Expected value [" + Bytes.toString(valueA) + "] " +
+ "Got value [" + Bytes.toString(kvA.getValue()) + "]",
+ equals(valueA, kvA.getValue()));
+ KeyValue kvB = kv[1];
+ assertTrue("(B) Expected family [" + Bytes.toString(familyB) + "] " +
+ "Got family [" + Bytes.toString(kvB.getFamily()) + "]",
+ equals(familyB, kvB.getFamily()));
+ assertTrue("(B) Expected qualifier [" + Bytes.toString(qualifierB) + "] " +
+ "Got qualifier [" + Bytes.toString(kvB.getQualifier()) + "]",
+ equals(qualifierB, kvB.getQualifier()));
+ assertTrue("(B) Expected value [" + Bytes.toString(valueB) + "] " +
+ "Got value [" + Bytes.toString(kvB.getValue()) + "]",
+ equals(valueB, kvB.getValue()));
+ }
+
+ /**
+ *
+ */
+ private void assertSingleResult(Result result, byte [] row, byte [] family,
+ byte [] qualifier, byte [] value)
+ throws Exception {
+ assertTrue("Expected row [" + Bytes.toString(row) + "] " +
+ "Got row [" + Bytes.toString(result.getRow()) +"]",
+ equals(row, result.getRow()));
+ assertTrue("Expected a single key but result contains " + result.size(),
+ result.size() == 1);
+ KeyValue kv = result.sorted()[0];
+ assertTrue("Expected family [" + Bytes.toString(family) + "] " +
+ "Got family [" + Bytes.toString(kv.getFamily()) + "]",
+ equals(family, kv.getFamily()));
+ assertTrue("Expected qualifier [" + Bytes.toString(qualifier) + "] " +
+ "Got qualifier [" + Bytes.toString(kv.getQualifier()) + "]",
+ equals(qualifier, kv.getQualifier()));
+ assertTrue("Expected value [" + Bytes.toString(value) + "] " +
+ "Got value [" + Bytes.toString(kv.getValue()) + "]",
+ equals(value, kv.getValue()));
+ }
+
+ private void assertSingleResult(Result result, byte [] row, byte [] family,
+ byte [] qualifier, long ts, byte [] value)
+ throws Exception {
+ assertTrue("Expected row [" + Bytes.toString(row) + "] " +
+ "Got row [" + Bytes.toString(result.getRow()) +"]",
+ equals(row, result.getRow()));
+ assertTrue("Expected a single key but result contains " + result.size(),
+ result.size() == 1);
+ KeyValue kv = result.sorted()[0];
+ assertTrue("Expected family [" + Bytes.toString(family) + "] " +
+ "Got family [" + Bytes.toString(kv.getFamily()) + "]",
+ equals(family, kv.getFamily()));
+ assertTrue("Expected qualifier [" + Bytes.toString(qualifier) + "] " +
+ "Got qualifier [" + Bytes.toString(kv.getQualifier()) + "]",
+ equals(qualifier, kv.getQualifier()));
+ assertTrue("Expected ts [" + ts + "] " +
+ "Got ts [" + kv.getTimestamp() + "]", ts == kv.getTimestamp());
+ assertTrue("Expected value [" + Bytes.toString(value) + "] " +
+ "Got value [" + Bytes.toString(kv.getValue()) + "]",
+ equals(value, kv.getValue()));
+ }
+
+ private void assertEmptyResult(Result result) throws Exception {
+ assertTrue("expected an empty result but result contains " +
+ result.size() + " keys", result.isEmpty());
+ }
+
+ private void assertNullResult(Result result) throws Exception {
+ assertTrue("expected null result but received a non-null result",
+ result == null);
+ }
+
+ //
+ // Helpers
+ //
+
+ private void flushMemcache(byte [] tableName) throws Exception {
+ System.out.println("\n\nFlushing table [" + Bytes.toString(tableName) + "]...\n");
+// HBaseAdmin hba = new HBaseAdmin(conf);
+// hba.flush(tableName);
+ cluster.flushcache();
+ System.out.println("\nTable flushed.\n\n");
+ }
+
+ private Result getSingleScanResult(HTable ht, Scan scan) throws IOException {
+ ResultScanner scanner = ht.getScanner(scan);
+ Result result = scanner.next();
+ scanner.close();
+ return result;
+ }
+
+ private byte [][] makeNAscii(byte [] base, int n) {
+ if(n > 256) {
+ return makeNBig(base, n);
+ }
+ byte [][] ret = new byte[n][];
+ for(int i=0;i<n;i++) {
+ byte [] tail = Bytes.toBytes(new Integer(i).toString());
+ ret[i] = Bytes.add(base, tail);
+ }
+ return ret;
+ }
+
+ private byte [][] makeN(byte [] base, int n) {
+ if(n > 256) {
+ return makeNBig(base, n);
+ }
+ byte [][] ret = new byte[n][];
+ for(int i=0;i<n;i++) {
+ ret[i] = Bytes.add(base, new byte[]{(byte)i});
+ }
+ return ret;
+ }
+
+ private byte [][] makeNBig(byte [] base, int n) {
+ byte [][] ret = new byte[n][];
+ for(int i=0;i<n;i++) {
+ int byteA = (i % 256);
+ int byteB = (i >> 8);
+ ret[i] = Bytes.add(base, new byte[]{(byte)byteB,(byte)byteA});
+ }
+ return ret;
+ }
+
+ private long [] makeStamps(int n) {
+ long [] stamps = new long[n];
+ for(int i=0;i<n;i++) stamps[i] = i+1;
+ return stamps;
+ }
+
+ private HTable createTable(byte [] tableName, byte [] family)
+ throws IOException{
+ return createTable(tableName, new byte[][]{family});
+ }
+
+ private HTable createTable(byte [] tableName, byte [][] families)
+ throws IOException {
+ HTableDescriptor desc = new HTableDescriptor(tableName);
+ for(byte [] family : families) {
+ desc.addFamily(new HColumnDescriptor(family));
+ }
+ HBaseAdmin admin = new HBaseAdmin(conf);
+ admin.createTable(desc);
+ return new HTable(conf, tableName);
+ }
+
+ private HTable createTable(byte [] tableName, byte [] family, int numVersions)
+ throws IOException {
+ return createTable(tableName, new byte[][]{family}, numVersions);
+ }
+
+ private HTable createTable(byte [] tableName, byte [][] families,
+ int numVersions)
+ throws IOException {
+ HTableDescriptor desc = new HTableDescriptor(tableName);
+ for(byte [] family : families) {
+ HColumnDescriptor hcd = new HColumnDescriptor(family, numVersions,
+ HColumnDescriptor.DEFAULT_COMPRESSION,
+ HColumnDescriptor.DEFAULT_IN_MEMORY,
+ HColumnDescriptor.DEFAULT_BLOCKCACHE,
+ Integer.MAX_VALUE, HColumnDescriptor.DEFAULT_TTL, false);
+ desc.addFamily(hcd);
+ }
+ HBaseAdmin admin = new HBaseAdmin(conf);
+ admin.createTable(desc);
+ return new HTable(conf, tableName);
+ }
+
+ private HTable createTable(byte [] tableName, byte [][] families,
+ int [] numVersions)
+ throws IOException {
+ HTableDescriptor desc = new HTableDescriptor(tableName);
+ int i = 0;
+ for(byte [] family : families) {
+ HColumnDescriptor hcd = new HColumnDescriptor(family, numVersions[i],
+ HColumnDescriptor.DEFAULT_COMPRESSION,
+ HColumnDescriptor.DEFAULT_IN_MEMORY,
+ HColumnDescriptor.DEFAULT_BLOCKCACHE,
+ Integer.MAX_VALUE, HColumnDescriptor.DEFAULT_TTL, false);
+ desc.addFamily(hcd);
+ i++;
+ }
+ HBaseAdmin admin = new HBaseAdmin(conf);
+ admin.createTable(desc);
+ return new HTable(conf, tableName);
+ }
+
+ private boolean equals(byte [] left, byte [] right) {
+ if(left == null && right == null) return true;
+ if(left == null && right.length == 0) return true;
+ if(right == null && left.length == 0) return true;
+ return Bytes.equals(left, right);
+ }
+
+
+
+
+
+
+
+
+
+
+ public void XtestDuplicateVersions() throws Exception {
+
+ byte [] TABLE = Bytes.toBytes("testDuplicateVersions");
+
+ long [] STAMPS = makeStamps(20);
+ byte [][] VALUES = makeNAscii(VALUE, 20);
+
+ HTable ht = createTable(TABLE, FAMILY, 10);
+
+ // Insert 4 versions of same column
+ Put put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ put.add(FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ put.add(FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ put.add(FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+ ht.put(put);
+
+ // Verify we can get each one properly
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+
+ // Verify we don't accidentally get others
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+
+ // Ensure maxVersions in query is respected
+ Get get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIER);
+ get.setMaxVersions(2);
+ Result result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[4], STAMPS[5]},
+ new byte[][] {VALUES[4], VALUES[5]},
+ 0, 1);
+
+ Scan scan = new Scan(ROW);
+ scan.addColumn(FAMILY, QUALIFIER);
+ scan.setMaxVersions(2);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[4], STAMPS[5]},
+ new byte[][] {VALUES[4], VALUES[5]},
+ 0, 1);
+
+ // Flush and redo
+
+ flushMemcache(TABLE);
+
+ // Verify we can get each one properly
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[4]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[5], VALUES[5]);
+
+ // Verify we don't accidentally get others
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[3]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[6]);
+
+ // Ensure maxVersions in query is respected
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIER);
+ get.setMaxVersions(2);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[4], STAMPS[5]},
+ new byte[][] {VALUES[4], VALUES[5]},
+ 0, 1);
+
+ scan = new Scan(ROW);
+ scan.addColumn(FAMILY, QUALIFIER);
+ scan.setMaxVersions(2);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[4], STAMPS[5]},
+ new byte[][] {VALUES[4], VALUES[5]},
+ 0, 1);
+
+
+ // Add some memcache and retest
+
+ // Insert 4 more versions of same column and a dupe
+ put = new Put(ROW);
+ put.add(FAMILY, QUALIFIER, STAMPS[3], VALUES[3]);
+ put.add(FAMILY, QUALIFIER, STAMPS[4], VALUES[14]);
+ put.add(FAMILY, QUALIFIER, STAMPS[6], VALUES[6]);
+ put.add(FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+ put.add(FAMILY, QUALIFIER, STAMPS[8], VALUES[8]);
+ ht.put(put);
+
+ // Ensure maxVersions in query is respected
+ get = new Get(ROW);
+ get.addColumn(FAMILY, QUALIFIER);
+ get.setMaxVersions(7);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+ new byte[][] {VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
+ 0, 6);
+
+ scan = new Scan(ROW);
+ scan.addColumn(FAMILY, QUALIFIER);
+ scan.setMaxVersions(7);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+ new byte[][] {VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
+ 0, 6);
+
+ get = new Get(ROW);
+ get.setMaxVersions(7);
+ result = ht.get(get);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+ new byte[][] {VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
+ 0, 6);
+
+ scan = new Scan(ROW);
+ scan.setMaxVersions(7);
+ result = getSingleScanResult(ht, scan);
+ assertNResult(result, ROW, FAMILY, QUALIFIER,
+ new long [] {STAMPS[2], STAMPS[3], STAMPS[4], STAMPS[5], STAMPS[6], STAMPS[7], STAMPS[8]},
+ new byte[][] {VALUES[2], VALUES[3], VALUES[14], VALUES[5], VALUES[6], VALUES[7], VALUES[8]},
+ 0, 6);
+
+ // Verify we can get each one properly
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[14]);
+ getVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[1], VALUES[1]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[2], VALUES[2]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[4], VALUES[14]);
+ scanVersionAndVerify(ht, ROW, FAMILY, QUALIFIER, STAMPS[7], VALUES[7]);
+
+ // Verify we don't accidentally get others
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ getVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[0]);
+ scanVersionAndVerifyMissing(ht, ROW, FAMILY, QUALIFIER, STAMPS[9]);
+
+ // Ensure maxVersions of table is respected
+
+ flushMemcache(TABLE);
+
+ // Insert 4 more versions of same column and a dupe
+ put = new Put(ROW);
[... 55 lines stripped ...]