Index: hbase-server/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java (revision 1524797) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/rest/client/RemoteHTable.java (working copy) @@ -53,8 +53,10 @@ import org.apache.hadoop.hbase.client.RowMutations; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.coprocessor.Batch; +import org.apache.hadoop.hbase.filter.ByteArrayComparable; import org.apache.hadoop.hbase.io.TimeRange; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; +import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos; import org.apache.hadoop.hbase.rest.Constants; import org.apache.hadoop.hbase.rest.model.CellModel; import org.apache.hadoop.hbase.rest.model.CellSetModel; @@ -703,6 +705,16 @@ throw new IOException("checkAndDelete request timed out"); } + public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, + HBaseProtos.CompareType compareType, ByteArrayComparable comparator, Put put) throws IOException { + throw new IOException("checkAndPut with comparator not supported"); + } + + public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, + HBaseProtos.CompareType compareType, ByteArrayComparable comparator, Delete delete) throws IOException { + throw new IOException("checkAndDelete with comparator not supported"); + } + public Result increment(Increment increment) throws IOException { throw new IOException("Increment not supported"); } Index: hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java (revision 1524797) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java (working copy) @@ -59,7 +59,9 @@ import org.apache.hadoop.hbase.client.RowMutations; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.coprocessor.Batch; +import org.apache.hadoop.hbase.filter.ByteArrayComparable; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; +import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.CoprocessorClassLoader; import org.apache.hadoop.hbase.util.SortedCopyOnWriteSet; @@ -451,11 +453,21 @@ return table.checkAndPut(row, family, qualifier, value, put); } + public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, + HBaseProtos.CompareType compareType, ByteArrayComparable comparator, Put put) throws IOException { + return table.checkAndPut(row, family, qualifier, compareType, comparator, put); + } + public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, byte[] value, Delete delete) throws IOException { return table.checkAndDelete(row, family, qualifier, value, delete); } + public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, + HBaseProtos.CompareType compareType, ByteArrayComparable comparator, Delete delete) throws IOException { + return table.checkAndDelete(row, family, qualifier, compareType, comparator, delete); + } + public long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, long amount) throws IOException { return table.incrementColumnValue(row, family, qualifier, amount); Index: hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTableInterface.java =================================================================== --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTableInterface.java (revision 1524797) +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTableInterface.java (working copy) @@ -28,7 +28,10 @@ import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.coprocessor.Batch; +import org.apache.hadoop.hbase.filter.ByteArrayComparable; +import org.apache.hadoop.hbase.filter.CompareFilter; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; +import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos; import java.io.Closeable; import java.io.IOException; @@ -273,7 +276,25 @@ boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put) throws IOException; - /** + /** + * Atomically checks if a row/family/qualifier value matches the expected + * value. If it does, it adds the put. If the passed value is null, the check + * is for the lack of column (ie: non-existance) + * + * @param row to check + * @param family column family to check + * @param qualifier column qualifier to check + * @param compareType the comparison operator to use + * @param comparator the value to compare against + * @param put data to put if check succeeds + * @throws IOException e + * @return true if the new put was executed, false otherwise + */ + boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, + HBaseProtos.CompareType compareType, ByteArrayComparable comparator, + Put put) throws IOException; + + /** * Deletes the specified cells/row. * * @param delete The object that specifies what to delete. @@ -311,6 +332,24 @@ boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, byte[] value, Delete delete) throws IOException; + /** + * Atomically checks if a row/family/qualifier value matches the expected + * value. If it does, it adds the delete. If the passed value is null, the + * check is for the lack of column (ie: non-existance) + * + * @param row to check + * @param family column family to check + * @param qualifier column qualifier to check + * @param compareType the comparison operator to use + * @param comparator the value to compare against + * @param delete data to delete if check succeeds + * @throws IOException e + * @return true if the new delete was executed, false otherwise + */ + boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, + HBaseProtos.CompareType compareType, ByteArrayComparable comparator, + Delete delete) throws IOException; + /** * Performs multiple mutations atomically on a single row. Currently * {@link Put} and {@link Delete} are supported. Index: hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java =================================================================== --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java (revision 1524797) +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTablePool.java (working copy) @@ -31,7 +31,9 @@ import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.client.coprocessor.Batch.Callback; +import org.apache.hadoop.hbase.filter.ByteArrayComparable; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; +import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.PoolMap; import org.apache.hadoop.hbase.util.PoolMap.PoolType; @@ -441,6 +443,13 @@ } @Override + public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, + HBaseProtos.CompareType compareType, ByteArrayComparable comparator, Put put) throws IOException { + checkState(); + return table.checkAndPut(row, family, qualifier, compareType, comparator, put); + } + + @Override public void delete(Delete delete) throws IOException { checkState(); table.delete(delete); @@ -460,6 +469,13 @@ } @Override + public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, + HBaseProtos.CompareType compareType, ByteArrayComparable comparator, Delete delete) throws IOException { + checkState(); + return table.checkAndDelete(row, family, qualifier, compareType, comparator, delete); + } + + @Override public Result increment(Increment increment) throws IOException { checkState(); return table.increment(increment); Index: hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java =================================================================== --- hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java (revision 1524797) +++ hbase-client/src/main/java/org/apache/hadoop/hbase/client/HTable.java (working copy) @@ -54,6 +54,8 @@ import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.filter.BinaryComparator; +import org.apache.hadoop.hbase.filter.ByteArrayComparable; +import org.apache.hadoop.hbase.filter.CompareFilter; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; import org.apache.hadoop.hbase.ipc.PayloadCarryingRpcController; import org.apache.hadoop.hbase.ipc.RegionCoprocessorRpcChannel; @@ -66,6 +68,7 @@ import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiRequest; import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateRequest; import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateResponse; +import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos; import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.CompareType; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Pair; @@ -1094,24 +1097,35 @@ final byte [] family, final byte [] qualifier, final byte [] value, final Put put) throws IOException { + return checkAndPut(row, family, qualifier, CompareType.EQUAL, new BinaryComparator(value), put); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean checkAndPut(final byte[] row, + final byte[] family, final byte[] qualifier, + final CompareType compareType, final ByteArrayComparable comparator, + final Put put) + throws IOException { RegionServerCallable callable = - new RegionServerCallable(connection, getName(), row) { - public Boolean call() throws IOException { - try { - MutateRequest request = RequestConverter.buildMutateRequest( - getLocation().getRegionInfo().getRegionName(), row, family, qualifier, - new BinaryComparator(value), CompareType.EQUAL, put); - MutateResponse response = getStub().mutate(null, request); - return Boolean.valueOf(response.getProcessed()); - } catch (ServiceException se) { - throw ProtobufUtil.getRemoteException(se); + new RegionServerCallable(connection, getName(), row) { + public Boolean call() throws IOException { + try { + MutateRequest request = RequestConverter.buildMutateRequest( + getLocation().getRegionInfo().getRegionName(), row, family, qualifier, + comparator, compareType, put); + MutateResponse response = getStub().mutate(null, request); + return Boolean.valueOf(response.getProcessed()); + } catch (ServiceException se) { + throw ProtobufUtil.getRemoteException(se); + } } - } - }; + }; return rpcCallerFactory. newCaller().callWithRetries(callable, this.operationTimeout); } - /** * {@inheritDoc} */ @@ -1120,20 +1134,31 @@ final byte [] family, final byte [] qualifier, final byte [] value, final Delete delete) throws IOException { + return checkAndDelete(row, family, qualifier, CompareType.EQUAL, new BinaryComparator(value), delete); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean checkAndDelete(final byte[] row, + final byte[] family, final byte[] qualifier, final CompareType compareType, final ByteArrayComparable comparator, + final Delete delete) + throws IOException { RegionServerCallable callable = - new RegionServerCallable(connection, getName(), row) { - public Boolean call() throws IOException { - try { - MutateRequest request = RequestConverter.buildMutateRequest( - getLocation().getRegionInfo().getRegionName(), row, family, qualifier, - new BinaryComparator(value), CompareType.EQUAL, delete); - MutateResponse response = getStub().mutate(null, request); - return Boolean.valueOf(response.getProcessed()); - } catch (ServiceException se) { - throw ProtobufUtil.getRemoteException(se); + new RegionServerCallable(connection, getName(), row) { + public Boolean call() throws IOException { + try { + MutateRequest request = RequestConverter.buildMutateRequest( + getLocation().getRegionInfo().getRegionName(), row, family, qualifier, + comparator, compareType, delete); + MutateResponse response = getStub().mutate(null, request); + return Boolean.valueOf(response.getProcessed()); + } catch (ServiceException se) { + throw ProtobufUtil.getRemoteException(se); + } } - } - }; + }; return rpcCallerFactory. newCaller().callWithRetries(callable, this.operationTimeout); }