HBASE-5923 Cleanup checkAndXXX logic

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1555351 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Zhihong Yu 2014-01-04 14:38:14 +00:00
parent 9bc4cec254
commit ae8ad4ac78
6 changed files with 236 additions and 0 deletions

View File

@ -53,6 +53,7 @@ import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.client.coprocessor.Batch;
import org.apache.hadoop.hbase.filter.BinaryComparator; import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
import org.apache.hadoop.hbase.ipc.PayloadCarryingRpcController; import org.apache.hadoop.hbase.ipc.PayloadCarryingRpcController;
import org.apache.hadoop.hbase.ipc.RegionCoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.RegionCoprocessorRpcChannel;
@ -1148,6 +1149,31 @@ public class HTable implements HTableInterface {
return rpcCallerFactory.<Boolean> newCaller().callWithRetries(callable, this.operationTimeout); return rpcCallerFactory.<Boolean> newCaller().callWithRetries(callable, this.operationTimeout);
} }
/**
* {@inheritDoc}
*/
@Override
public boolean checkAndPut(final byte [] row, final byte [] family,
final byte [] qualifier, final CompareOp compareOp, final byte [] value,
final Put put)
throws IOException {
RegionServerCallable<Boolean> callable =
new RegionServerCallable<Boolean>(connection, getName(), row) {
public Boolean call() throws IOException {
try {
CompareType compareType = CompareType.valueOf(compareOp.name());
MutateRequest request = RequestConverter.buildMutateRequest(
getLocation().getRegionInfo().getRegionName(), row, family, qualifier,
new BinaryComparator(value), compareType, put);
MutateResponse response = getStub().mutate(null, request);
return Boolean.valueOf(response.getProcessed());
} catch (ServiceException se) {
throw ProtobufUtil.getRemoteException(se);
}
}
};
return rpcCallerFactory.<Boolean> newCaller().callWithRetries(callable, this.operationTimeout);
}
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -1174,6 +1200,32 @@ public class HTable implements HTableInterface {
return rpcCallerFactory.<Boolean> newCaller().callWithRetries(callable, this.operationTimeout); return rpcCallerFactory.<Boolean> newCaller().callWithRetries(callable, this.operationTimeout);
} }
/**
* {@inheritDoc}
*/
@Override
public boolean checkAndDelete(final byte [] row, final byte [] family,
final byte [] qualifier, final CompareOp compareOp, final byte [] value,
final Delete delete)
throws IOException {
RegionServerCallable<Boolean> callable =
new RegionServerCallable<Boolean>(connection, getName(), row) {
public Boolean call() throws IOException {
try {
CompareType compareType = CompareType.valueOf(compareOp.name());
MutateRequest request = RequestConverter.buildMutateRequest(
getLocation().getRegionInfo().getRegionName(), row, family, qualifier,
new BinaryComparator(value), compareType, delete);
MutateResponse response = getStub().mutate(null, request);
return Boolean.valueOf(response.getProcessed());
} catch (ServiceException se) {
throw ProtobufUtil.getRemoteException(se);
}
}
};
return rpcCallerFactory.<Boolean> newCaller().callWithRetries(callable, this.operationTimeout);
}
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */

View File

@ -28,6 +28,7 @@ import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.client.coprocessor.Batch;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
import java.io.Closeable; import java.io.Closeable;
@ -280,6 +281,8 @@ public interface HTableInterface extends Closeable {
boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,
byte[] value, Put put) throws IOException; byte[] value, Put put) throws IOException;
boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,
CompareOp compareOp, byte[] value, Put put) throws IOException;
/** /**
* Deletes the specified cells/row. * Deletes the specified cells/row.
* *
@ -318,6 +321,9 @@ public interface HTableInterface extends Closeable {
boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
byte[] value, Delete delete) throws IOException; byte[] value, Delete delete) throws IOException;
boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
CompareOp compareOp, byte[] value, Delete delete) throws IOException;
/** /**
* Performs multiple mutations atomically on a single row. Currently * Performs multiple mutations atomically on a single row. Currently
* {@link Put} and {@link Delete} are supported. * {@link Put} and {@link Delete} are supported.

View File

@ -31,6 +31,8 @@ import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.client.coprocessor.Batch;
import org.apache.hadoop.hbase.client.coprocessor.Batch.Callback; import org.apache.hadoop.hbase.client.coprocessor.Batch.Callback;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.PoolMap; import org.apache.hadoop.hbase.util.PoolMap;
@ -445,6 +447,13 @@ public class HTablePool implements Closeable {
return table.checkAndPut(row, family, qualifier, value, put); return table.checkAndPut(row, family, qualifier, value, put);
} }
@Override
public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,
CompareOp compareOp, byte[] value, Put put) throws IOException {
checkState();
return table.checkAndPut(row, family, qualifier, compareOp, value, put);
}
@Override @Override
public void delete(Delete delete) throws IOException { public void delete(Delete delete) throws IOException {
checkState(); checkState();
@ -464,6 +473,13 @@ public class HTablePool implements Closeable {
return table.checkAndDelete(row, family, qualifier, value, delete); return table.checkAndDelete(row, family, qualifier, value, delete);
} }
@Override
public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
CompareOp compareOp, byte[] value, Delete delete) throws IOException {
checkState();
return table.checkAndDelete(row, family, qualifier, compareOp, value, delete);
}
@Override @Override
public Result increment(Increment increment) throws IOException { public Result increment(Increment increment) throws IOException {
checkState(); checkState();

View File

@ -62,6 +62,7 @@ import org.apache.hadoop.hbase.client.Row;
import org.apache.hadoop.hbase.client.RowMutations; import org.apache.hadoop.hbase.client.RowMutations;
import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.client.coprocessor.Batch;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.CoprocessorClassLoader; import org.apache.hadoop.hbase.util.CoprocessorClassLoader;
@ -453,11 +454,21 @@ public abstract class CoprocessorHost<E extends CoprocessorEnvironment> {
return table.checkAndPut(row, family, qualifier, value, put); return table.checkAndPut(row, family, qualifier, value, put);
} }
public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,
CompareOp compareOp, byte[] value, Put put) throws IOException {
return table.checkAndPut(row, family, qualifier, compareOp, value, put);
}
public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
byte[] value, Delete delete) throws IOException { byte[] value, Delete delete) throws IOException {
return table.checkAndDelete(row, family, qualifier, value, delete); return table.checkAndDelete(row, family, qualifier, value, delete);
} }
public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
CompareOp compareOp, byte[] value, Delete delete) throws IOException {
return table.checkAndDelete(row, family, qualifier, compareOp, value, delete);
}
public long incrementColumnValue(byte[] row, byte[] family, public long incrementColumnValue(byte[] row, byte[] family,
byte[] qualifier, long amount) throws IOException { byte[] qualifier, long amount) throws IOException {
return table.incrementColumnValue(row, family, qualifier, amount); return table.incrementColumnValue(row, family, qualifier, amount);

View File

@ -53,6 +53,7 @@ import org.apache.hadoop.hbase.client.Row;
import org.apache.hadoop.hbase.client.RowMutations; import org.apache.hadoop.hbase.client.RowMutations;
import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.client.coprocessor.Batch;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.io.TimeRange; import org.apache.hadoop.hbase.io.TimeRange;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
import org.apache.hadoop.hbase.rest.Constants; import org.apache.hadoop.hbase.rest.Constants;
@ -668,6 +669,11 @@ public class RemoteHTable implements HTableInterface {
throw new IOException("checkAndPut request timed out"); throw new IOException("checkAndPut request timed out");
} }
public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,
CompareOp compareOp, byte[] value, Put put) throws IOException {
throw new IOException("checkAndPut for non-equal comparison not implemented");
}
public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
byte[] value, Delete delete) throws IOException { byte[] value, Delete delete) throws IOException {
Put put = new Put(row); Put put = new Put(row);
@ -703,6 +709,11 @@ public class RemoteHTable implements HTableInterface {
throw new IOException("checkAndDelete request timed out"); throw new IOException("checkAndDelete request timed out");
} }
public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
CompareOp compareOp, byte[] value, Delete delete) throws IOException {
throw new IOException("checkAndDelete for non-equal comparison not implemented");
}
public Result increment(Increment increment) throws IOException { public Result increment(Increment increment) throws IOException {
throw new IOException("Increment not supported"); throw new IOException("Increment not supported");
} }

View File

@ -4775,6 +4775,146 @@ public class TestFromClientSide {
} }
@Test
public void testCheckAndPutWithCompareOp() throws IOException {
final byte [] value1 = Bytes.toBytes("aaaa");
final byte [] value2 = Bytes.toBytes("bbbb");
final byte [] value3 = Bytes.toBytes("cccc");
final byte [] value4 = Bytes.toBytes("dddd");
HTable table = TEST_UTIL.createTable(Bytes.toBytes("testCheckAndPutWithCompareOp"),
new byte [][] {FAMILY});
Put put2 = new Put(ROW);
put2.add(FAMILY, QUALIFIER, value2);
Put put3 = new Put(ROW);
put3.add(FAMILY, QUALIFIER, value3);
// row doesn't exist, so using "null" to check for existence should be considered "match".
boolean ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, null, put2);
assertEquals(ok, true);
// cell = "bbbb", using "aaaa" to compare only LESS/LESS_OR_EQUAL/NOT_EQUAL
// turns out "match"
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.GREATER, value1, put2);
assertEquals(ok, false);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.EQUAL, value1, put2);
assertEquals(ok, false);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.GREATER_OR_EQUAL, value1, put2);
assertEquals(ok, false);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.LESS, value1, put2);
assertEquals(ok, true);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.LESS_OR_EQUAL, value1, put2);
assertEquals(ok, true);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.NOT_EQUAL, value1, put3);
assertEquals(ok, true);
// cell = "cccc", using "dddd" to compare only LARGER/LARGER_OR_EQUAL/NOT_EQUAL
// turns out "match"
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.LESS, value4, put3);
assertEquals(ok, false);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.LESS_OR_EQUAL, value4, put3);
assertEquals(ok, false);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.EQUAL, value4, put3);
assertEquals(ok, false);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.GREATER, value4, put3);
assertEquals(ok, true);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.GREATER_OR_EQUAL, value4, put3);
assertEquals(ok, true);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.NOT_EQUAL, value4, put2);
assertEquals(ok, true);
// cell = "bbbb", using "bbbb" to compare only GREATER_OR_EQUAL/LESS_OR_EQUAL/EQUAL
// turns out "match"
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.GREATER, value2, put2);
assertEquals(ok, false);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.NOT_EQUAL, value2, put2);
assertEquals(ok, false);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.LESS, value2, put2);
assertEquals(ok, false);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.GREATER_OR_EQUAL, value2, put2);
assertEquals(ok, true);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.LESS_OR_EQUAL, value2, put2);
assertEquals(ok, true);
ok = table.checkAndPut(ROW, FAMILY, QUALIFIER, CompareOp.EQUAL, value2, put3);
assertEquals(ok, true);
}
@Test
public void testCheckAndDeleteWithCompareOp() throws IOException {
final byte [] value1 = Bytes.toBytes("aaaa");
final byte [] value2 = Bytes.toBytes("bbbb");
final byte [] value3 = Bytes.toBytes("cccc");
final byte [] value4 = Bytes.toBytes("dddd");
HTable table = TEST_UTIL.createTable(Bytes.toBytes("testCheckAndDeleteWithCompareOp"),
new byte [][] {FAMILY});
Put put2 = new Put(ROW);
put2.add(FAMILY, QUALIFIER, value2);
table.put(put2);
Put put3 = new Put(ROW);
put3.add(FAMILY, QUALIFIER, value3);
Delete delete = new Delete(ROW);
delete.deleteColumns(FAMILY, QUALIFIER);
// cell = "bbbb", using "aaaa" to compare only LESS/LESS_OR_EQUAL/NOT_EQUAL
// turns out "match"
boolean ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.GREATER, value1, delete);
assertEquals(ok, false);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.EQUAL, value1, delete);
assertEquals(ok, false);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.GREATER_OR_EQUAL, value1, delete);
assertEquals(ok, false);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.LESS, value1, delete);
assertEquals(ok, true);
table.put(put2);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.LESS_OR_EQUAL, value1, delete);
assertEquals(ok, true);
table.put(put2);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.NOT_EQUAL, value1, delete);
assertEquals(ok, true);
// cell = "cccc", using "dddd" to compare only LARGER/LARGER_OR_EQUAL/NOT_EQUAL
// turns out "match"
table.put(put3);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.LESS, value4, delete);
assertEquals(ok, false);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.LESS_OR_EQUAL, value4, delete);
assertEquals(ok, false);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.EQUAL, value4, delete);
assertEquals(ok, false);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.GREATER, value4, delete);
assertEquals(ok, true);
table.put(put3);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.GREATER_OR_EQUAL, value4, delete);
assertEquals(ok, true);
table.put(put3);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.NOT_EQUAL, value4, delete);
assertEquals(ok, true);
// cell = "bbbb", using "bbbb" to compare only GREATER_OR_EQUAL/LESS_OR_EQUAL/EQUAL
// turns out "match"
table.put(put2);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.GREATER, value2, delete);
assertEquals(ok, false);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.NOT_EQUAL, value2, delete);
assertEquals(ok, false);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.LESS, value2, delete);
assertEquals(ok, false);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.GREATER_OR_EQUAL, value2, delete);
assertEquals(ok, true);
table.put(put2);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.LESS_OR_EQUAL, value2, delete);
assertEquals(ok, true);
table.put(put2);
ok = table.checkAndDelete(ROW, FAMILY, QUALIFIER, CompareOp.EQUAL, value2, delete);
assertEquals(ok, true);
}
/** /**
* Test ScanMetrics * Test ScanMetrics
* @throws Exception * @throws Exception