You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by zg...@apache.org on 2019/03/12 12:46:25 UTC

[hbase] 97/133: HBASE-18210 Implement Table#checkAndDelete()

This is an automated email from the ASF dual-hosted git repository.

zghao pushed a commit to branch HBASE-14850
in repository https://gitbox.apache.org/repos/asf/hbase.git

commit fad9bcd9707176850adc963b48b148e6c91a0774
Author: tedyu <yu...@gmail.com>
AuthorDate: Tue Jun 20 18:41:14 2017 -0700

    HBASE-18210 Implement Table#checkAndDelete()
---
 hbase-native-client/core/client-test.cc       | 31 +++++++++++++++++++++++++++
 hbase-native-client/core/raw-async-table.cc   | 27 +++++++++++++++++++++++
 hbase-native-client/core/raw-async-table.h    |  5 +++++
 hbase-native-client/core/request-converter.cc | 21 ++++++++++++++++++
 hbase-native-client/core/request-converter.h  |  5 +++++
 hbase-native-client/core/table.cc             |  7 ++++++
 hbase-native-client/core/table.h              | 23 ++++++++++++++++++++
 7 files changed, 119 insertions(+)

diff --git a/hbase-native-client/core/client-test.cc b/hbase-native-client/core/client-test.cc
index 6462e6a..1a9fe11 100644
--- a/hbase-native-client/core/client-test.cc
+++ b/hbase-native-client/core/client-test.cc
@@ -278,6 +278,37 @@ TEST_F(ClientTest, CheckAndPut) {
   ASSERT_FALSE(result) << "CheckAndPut shouldn't replace value";
 }
 
+TEST_F(ClientTest, CheckAndDelete) {
+  // Using TestUtil to populate test data
+  ClientTest::test_util->CreateTable("checkDel", "d");
+
+  // Create TableName and Row to be fetched from HBase
+  auto tn = folly::to<hbase::pb::TableName>("checkDel");
+  auto row = "test1";
+
+  // Create a client
+  hbase::Client client(*ClientTest::test_util->conf());
+
+  // Get connection to HBase Table
+  auto table = client.Table(tn);
+  ASSERT_TRUE(table) << "Unable to get connection to Table.";
+
+  auto val1 = "value1";
+
+  // Perform Puts
+  table->Put(Put{row}.AddColumn("d", "1", val1));
+  table->Put(Put{row}.AddColumn("d", "2", "value2"));
+  auto result =
+      table->CheckAndDelete(row, "d", "1", val1, hbase::Delete{row}.AddColumn("d", "2"));
+  ASSERT_TRUE(result) << "CheckAndDelete didn't replace value";
+
+  // Perform the Get
+  hbase::Get get(row);
+  auto result1 = table->Get(get);
+  EXPECT_EQ(val1, *(result1->Value("d", "1")));
+  ASSERT_FALSE(result1->Value("d", "2")) << "Column 2 should be gone";
+}
+
 TEST_F(ClientTest, PutGet) {
   // Using TestUtil to populate test data
   ClientTest::test_util->CreateTable("t", "d");
diff --git a/hbase-native-client/core/raw-async-table.cc b/hbase-native-client/core/raw-async-table.cc
index 46d9dfd..53ab526 100644
--- a/hbase-native-client/core/raw-async-table.cc
+++ b/hbase-native-client/core/raw-async-table.cc
@@ -137,6 +137,33 @@ folly::Future<bool> RawAsyncTable::CheckAndPut(const std::string& row, const std
   return caller->Call().then([caller](const auto r) { return r; });
 }
 
+folly::Future<bool> RawAsyncTable::CheckAndDelete(const std::string& row, const std::string& family,
+                                                  const std::string& qualifier,
+                                                  const std::string& value,
+                                                  const hbase::Delete& del,
+                                                  const pb::CompareType& compare_op) {
+  auto caller =
+      CreateCallerBuilder<bool>(row, connection_conf_->write_rpc_timeout())
+          ->action([=, &del](std::shared_ptr<hbase::HBaseRpcController> controller,
+                             std::shared_ptr<hbase::RegionLocation> loc,
+                             std::shared_ptr<hbase::RpcClient> rpc_client) -> folly::Future<bool> {
+            return Call<hbase::Delete, hbase::Request, hbase::Response, bool>(
+                rpc_client, controller, loc, del,
+                // request conversion
+                [=, &del](const hbase::Delete& del,
+                          const std::string& region_name) -> std::unique_ptr<Request> {
+                  auto checkReq = RequestConverter::CheckAndDeleteToMutateRequest(
+                      row, family, qualifier, value, compare_op, del, region_name);
+                  return checkReq;
+                },
+                // response conversion
+                &ResponseConverter::BoolFromMutateResponse);
+          })
+          ->Build();
+
+  return caller->Call().then([caller](const auto r) { return r; });
+}
+
 folly::Future<folly::Unit> RawAsyncTable::Delete(const hbase::Delete& del) {
   auto caller =
       CreateCallerBuilder<folly::Unit>(del.row(), connection_conf_->write_rpc_timeout())
diff --git a/hbase-native-client/core/raw-async-table.h b/hbase-native-client/core/raw-async-table.h
index 068f230..ca12be6 100644
--- a/hbase-native-client/core/raw-async-table.h
+++ b/hbase-native-client/core/raw-async-table.h
@@ -72,6 +72,11 @@ class RawAsyncTable {
                                   const hbase::Put& put,
                                   const pb::CompareType& compare_op = pb::CompareType::EQUAL);
 
+  folly::Future<bool> CheckAndDelete(const std::string& row, const std::string& family,
+                                     const std::string& qualifier, const std::string& value,
+                                     const hbase::Delete& del,
+                                     const pb::CompareType& compare_op = pb::CompareType::EQUAL);
+
   void Scan(const hbase::Scan& scan, std::shared_ptr<RawScanResultConsumer> consumer);
 
   void Close() {}
diff --git a/hbase-native-client/core/request-converter.cc b/hbase-native-client/core/request-converter.cc
index 0cd9c7c..47c09d1 100644
--- a/hbase-native-client/core/request-converter.cc
+++ b/hbase-native-client/core/request-converter.cc
@@ -297,6 +297,27 @@ std::unique_ptr<Request> RequestConverter::CheckAndPutToMutateRequest(
   return pb_req;
 }
 
+std::unique_ptr<Request> RequestConverter::CheckAndDeleteToMutateRequest(
+    const std::string &row, const std::string &family, const std::string &qualifier,
+    const std::string &value, const pb::CompareType compare_op, const hbase::Delete &del,
+    const std::string &region_name) {
+  auto pb_req = Request::mutate();
+  auto pb_msg = std::static_pointer_cast<hbase::pb::MutateRequest>(pb_req->req_msg());
+
+  pb_msg->set_allocated_mutation(
+      ToMutation(MutationType::MutationProto_MutationType_DELETE, del, -1).release());
+  ::hbase::pb::Condition *cond = pb_msg->mutable_condition();
+  cond->set_row(row);
+  cond->set_family(family);
+  cond->set_qualifier(qualifier);
+  cond->set_allocated_comparator(
+      Comparator::ToProto(*(ComparatorFactory::BinaryComparator(value).get())).release());
+  cond->set_compare_type(compare_op);
+
+  RequestConverter::SetRegion(region_name, pb_msg->mutable_region());
+  return pb_req;
+}
+
 std::unique_ptr<Request> RequestConverter::DeleteToMutateRequest(const Delete &del,
                                                                  const std::string &region_name) {
   auto pb_req = Request::mutate();
diff --git a/hbase-native-client/core/request-converter.h b/hbase-native-client/core/request-converter.h
index 0755f42..bcea278 100644
--- a/hbase-native-client/core/request-converter.h
+++ b/hbase-native-client/core/request-converter.h
@@ -89,6 +89,11 @@ class RequestConverter {
       const std::string &value, const pb::CompareType compare_op, const hbase::Put &put,
       const std::string &region_name);
 
+  static std::unique_ptr<Request> CheckAndDeleteToMutateRequest(
+      const std::string &row, const std::string &family, const std::string &qualifier,
+      const std::string &value, const pb::CompareType compare_op, const hbase::Delete &del,
+      const std::string &region_name);
+
   static std::unique_ptr<Request> IncrementToMutateRequest(const Increment &incr,
                                                            const std::string &region_name);
 
diff --git a/hbase-native-client/core/table.cc b/hbase-native-client/core/table.cc
index f20078d..b89c1a2 100644
--- a/hbase-native-client/core/table.cc
+++ b/hbase-native-client/core/table.cc
@@ -80,6 +80,13 @@ bool Table::CheckAndPut(const std::string &row, const std::string &family,
   return context.get(operation_timeout());
 }
 
+bool Table::CheckAndDelete(const std::string &row, const std::string &family,
+                           const std::string &qualifier, const std::string &value,
+                           const hbase::Delete &del, const pb::CompareType &compare_op) {
+  auto context = async_table_->CheckAndDelete(row, family, qualifier, value, del, compare_op);
+  return context.get(operation_timeout());
+}
+
 void Table::Delete(const hbase::Delete &del) {
   auto future = async_table_->Delete(del);
   future.get(operation_timeout());
diff --git a/hbase-native-client/core/table.h b/hbase-native-client/core/table.h
index 3c486af..cc37182 100644
--- a/hbase-native-client/core/table.h
+++ b/hbase-native-client/core/table.h
@@ -86,6 +86,29 @@ class Table {
   void Delete(const hbase::Delete &del);
 
   /**
+   * 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-existence)
+   *
+   * The expected value argument of this call is on the left and the current
+   * value of the cell is on the right side of the comparison operator.
+   *
+   * Ie. eg. GREATER operator means expected value > existing <=> add the delete.
+   *
+   * @param row to check
+   * @param family column family to check
+   * @param qualifier column qualifier to check
+   * @param compare_op comparison operator to use
+   * @param value the expected value
+   * @param del data to delete if check succeeds
+   * @return true if the new delete was executed, false otherwise
+   */
+  bool CheckAndDelete(const std::string &row, const std::string &family,
+                      const std::string &qualifier, const std::string &value,
+                      const hbase::Delete &del,
+                      const pb::CompareType &compare_op = pb::CompareType::EQUAL);
+
+  /**
    * @brief - Increments some data in the table.
    * @param - increment Increment object to perform HBase Increment operation.
    */