diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Get.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Get.java index 3fa145c..272b7a6 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Get.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Get.java @@ -107,7 +107,18 @@ public class Get extends Query this.tr = get.getTimeRange(); this.checkExistenceOnly = get.isCheckExistenceOnly(); this.closestRowBefore = get.isClosestRowBefore(); - this.familyMap = get.getFamilyMap(); + Map> fams = get.getFamilyMap(); + for (Map.Entry> entry : fams.entrySet()) { + byte [] fam = entry.getKey(); + NavigableSet cols = entry.getValue(); + if (cols != null && cols.size() > 0) { + for (byte[] col : cols) { + addColumn(fam, col); + } + } else { + addFamily(fam); + } + } for (Map.Entry attr : get.getAttributesMap().entrySet()) { setAttribute(attr.getKey(), attr.getValue()); } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java index 6ba0b87..59fce15 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java @@ -71,6 +71,7 @@ import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescripto import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.GetTableDescriptorsResponse; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Pair; +import org.apache.hadoop.hbase.util.ReflectionUtils; import org.apache.hadoop.hbase.util.Threads; import com.google.common.annotations.VisibleForTesting; @@ -613,6 +614,7 @@ public class HTable implements HTableInterface { if (scan.getBatch() > 0 && scan.isSmall()) { throw new IllegalArgumentException("Small scan should not be used with batching"); } + if (scan.getCaching() <= 0) { scan.setCaching(scannerCaching); } @@ -682,18 +684,28 @@ public class HTable implements HTableInterface { */ @Override public Result get(final Get get) throws IOException { - if (get.getConsistency() == null){ - get.setConsistency(defaultConsistency); + return get(get, false); + } + + private Result get(Get get, final boolean checkExistenceOnly) throws IOException { + // if we are changing settings to the get, clone it. + if (get.isCheckExistenceOnly() != checkExistenceOnly || get.getConsistency() == null) { + get = ReflectionUtils.newInstance(get.getClass(), get); + get.setCheckExistenceOnly(checkExistenceOnly); + if (get.getConsistency() == null){ + get.setConsistency(defaultConsistency); + } } if (get.getConsistency() == Consistency.STRONG) { // Good old call. + final Get getReq = get; RegionServerCallable callable = new RegionServerCallable(this.connection, getName(), get.getRow()) { @Override public Result call(int callTimeout) throws IOException { ClientProtos.GetRequest request = - RequestConverter.buildGetRequest(getLocation().getRegionInfo().getRegionName(), get); + RequestConverter.buildGetRequest(getLocation().getRegionInfo().getRegionName(), getReq); PayloadCarryingRpcController controller = rpcControllerFactory.newController(); controller.setPriority(tableName); controller.setCallTimeout(callTimeout); @@ -1189,8 +1201,7 @@ public class HTable implements HTableInterface { */ @Override public boolean exists(final Get get) throws IOException { - get.setCheckExistenceOnly(true); - Result r = get(get); + Result r = get(get, true); assert r.getExists() != null; return r.getExists(); } @@ -1203,13 +1214,16 @@ public class HTable implements HTableInterface { if (gets.isEmpty()) return new boolean[]{}; if (gets.size() == 1) return new boolean[]{exists(gets.get(0))}; + ArrayList exists = new ArrayList(gets.size()); for (Get g: gets){ - g.setCheckExistenceOnly(true); + Get ge = new Get(g); + ge.setCheckExistenceOnly(true); + exists.add(ge); } Object[] r1; try { - r1 = batch(gets); + r1 = batch(exists); } catch (InterruptedException e) { throw (InterruptedIOException)new InterruptedIOException().initCause(e); } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java index 0b51150..a2e4449 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Scan.java @@ -235,6 +235,7 @@ public class Scan extends Query { loadColumnFamiliesOnDemand = scan.getLoadColumnFamiliesOnDemandValue(); consistency = scan.getConsistency(); reversed = scan.isReversed(); + asyncPrefetch = scan.isAsyncPrefetch(); small = scan.isSmall(); TimeRange ctr = scan.getTimeRange(); tr = new TimeRange(ctr.getMin(), ctr.getMax()); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java index 52f4c89..1e7fbc7 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFromClientSide3.java @@ -97,7 +97,10 @@ public class TestFromClientSide3 { */ @After public void tearDown() throws Exception { - // Nothing to do. + for (HTableDescriptor htd: TEST_UTIL.getHBaseAdmin().listTables()) { + LOG.info("Tear down, remove table=" + htd.getTableName()); + TEST_UTIL.deleteTable(htd.getTableName()); + } } private void randomCFPuts(Table table, byte[] row, byte[] family, int nPuts) @@ -277,20 +280,20 @@ public class TestFromClientSide3 { // create an empty Put Put put1 = new Put(ROW); actions.add(put1); - + Put put2 = new Put(ANOTHERROW); put2.add(FAMILY, QUALIFIER, VALUE); actions.add(put2); - + table.batch(actions, results); fail("Empty Put should have failed the batch call"); } catch (IllegalArgumentException iae) { - + } finally { table.close(); } } - + @Test public void testHTableExistsMethodSingleRegionSingleGet() throws Exception { @@ -334,6 +337,61 @@ public class TestFromClientSide3 { } @Test + public void testHTableExistsBeforeGet() throws Exception { + Table table = TEST_UTIL.createTable( + Bytes.toBytes("testHTableExistsBeforeGet"), new byte[][] { FAMILY }); + try { + Put put = new Put(ROW); + put.add(FAMILY, QUALIFIER, VALUE); + table.put(put); + + Get get = new Get(ROW); + + boolean exist = table.exists(get); + assertEquals(true, exist); + + Result result = table.get(get); + assertEquals(false, result.isEmpty()); + assertTrue(Bytes.equals(VALUE, result.getValue(FAMILY, QUALIFIER))); + } finally { + table.close(); + } + } + + @Test + public void testHTableExistsAllBeforeGet() throws Exception { + final byte[] ROW2 = Bytes.add(ROW, Bytes.toBytes("2")); + Table table = TEST_UTIL.createTable( + Bytes.toBytes("testHTableExistsAllBeforeGet"), new byte[][] { FAMILY }); + try { + Put put = new Put(ROW); + put.add(FAMILY, QUALIFIER, VALUE); + table.put(put); + put = new Put(ROW2); + put.add(FAMILY, QUALIFIER, VALUE); + table.put(put); + + Get get = new Get(ROW); + Get get2 = new Get(ROW2); + ArrayList getList = new ArrayList(2); + getList.add(get); + getList.add(get2); + + boolean[] exists = table.existsAll(getList); + assertEquals(true, exists[0]); + assertEquals(true, exists[1]); + + Result[] result = table.get(getList); + assertEquals(false, result[0].isEmpty()); + assertTrue(Bytes.equals(VALUE, result[0].getValue(FAMILY, QUALIFIER))); + assertEquals(false, result[1].isEmpty()); + assertTrue(Bytes.equals(VALUE, result[1].getValue(FAMILY, QUALIFIER))); + } finally { + table.close(); + } + } + + @Test public void testHTableExistsMethodMultipleRegionsSingleGet() throws Exception { Table table = TEST_UTIL.createTable( @@ -356,7 +414,7 @@ public class TestFromClientSide3 { @Test public void testHTableExistsMethodMultipleRegionsMultipleGets() throws Exception { HTable table = TEST_UTIL.createTable( - TableName.valueOf("testHTableExistsMethodMultipleRegionsMultipleGets"), + TableName.valueOf("testHTableExistsMethodMultipleRegionsMultipleGets"), new byte[][] { FAMILY }, 1, new byte[] { 0x00 }, new byte[] { (byte) 0xff }, 255); Put put = new Put(ROW); put.add(FAMILY, QUALIFIER, VALUE);