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

hulk pushed a commit to branch unstable
in repository https://gitbox.apache.org/repos/asf/incubator-kvrocks.git


The following commit(s) were added to refs/heads/unstable by this push:
     new 8ffdfaf  Add GETDEL command (#771)
8ffdfaf is described below

commit 8ffdfaf2d5caf73977a9855066d7e06ecc93c76f
Author: ran <[email protected]>
AuthorDate: Sun Aug 7 23:45:07 2022 +0800

    Add GETDEL command (#771)
---
 README.md                            |  2 +-
 src/redis_cmd.cc                     | 19 +++++++++++++++++++
 src/redis_string.cc                  | 10 ++++++++++
 src/redis_string.h                   |  1 +
 tests/cppunit/t_string_test.cc       | 14 ++++++++++++++
 tests/tcl/tests/unit/command.tcl     |  4 ++--
 tests/tcl/tests/unit/type/string.tcl | 12 ++++++------
 7 files changed, 53 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index ace584b..d2f75b6 100644
--- a/README.md
+++ b/README.md
@@ -114,7 +114,7 @@ $ redis-cli -p 6666
 ### Running test cases
 
 ```shell
-$ ./build.sh build --unittest
+$ ./x.py build --unittest
 $ cd build
 $ ./unittest
 ```
diff --git a/src/redis_cmd.cc b/src/redis_cmd.cc
index 886613b..aa8f84e 100644
--- a/src/redis_cmd.cc
+++ b/src/redis_cmd.cc
@@ -325,6 +325,24 @@ class CommandGetSet : public Commander {
   }
 };
 
+class CommandGetDel : public Commander {
+ public:
+  Status Execute(Server *svr, Connection *conn, std::string *output) override {
+    Redis::String string_db(svr->storage_, conn->GetNamespace());
+    std::string value;
+    rocksdb::Status s = string_db.GetDel(args_[1], &value);
+    if (!s.ok() && !s.IsNotFound()) {
+      return Status(Status::RedisExecErr, s.ToString());
+    }
+    if (s.IsNotFound()) {
+      *output = Redis::NilString();
+    } else {
+      *output = Redis::BulkString(value);
+    }
+    return Status::OK();
+  }
+};
+
 class CommandGetRange: public Commander {
  public:
   Status Parse(const std::vector<std::string> &args) override {
@@ -4778,6 +4796,7 @@ CommandAttributes redisCommandTable[] = {
     ADD_CMD("strlen", 2, "read-only", 1, 1, 1, CommandStrlen),
     ADD_CMD("getset", 3, "write", 1, 1, 1, CommandGetSet),
     ADD_CMD("getrange", 4, "read-only", 1, 1, 1, CommandGetRange),
+    ADD_CMD("getdel", 2, "write", 1, 1, 1, CommandGetDel),
     ADD_CMD("setrange", 4, "write", 1, 1, 1, CommandSetRange),
     ADD_CMD("mget", -2, "read-only", 1, -1, 1, CommandMGet),
     ADD_CMD("append", 3, "write", 1, 1, 1, CommandAppend),
diff --git a/src/redis_string.cc b/src/redis_string.cc
index 1a288d5..20ea14c 100644
--- a/src/redis_string.cc
+++ b/src/redis_string.cc
@@ -165,6 +165,16 @@ rocksdb::Status String::GetSet(const std::string 
&user_key, const std::string &n
   // prev status was used to tell whether old value was empty or not
   return !write_status.ok() ? write_status : s;
 }
+rocksdb::Status String::GetDel(const std::string &user_key, std::string 
*value)  {
+  std::string ns_key;
+  AppendNamespacePrefix(user_key, &ns_key);
+
+  LockGuard guard(storage_->GetLockManager(), ns_key);
+  rocksdb::Status s = getValue(ns_key, value);
+  if (!s.ok()) return s;
+
+  return storage_->Delete(rocksdb::WriteOptions(), metadata_cf_handle_, 
ns_key);
+}
 
 rocksdb::Status String::Set(const std::string &user_key, const std::string 
&value) {
   std::vector<StringPair> pairs{StringPair{user_key, value}};
diff --git a/src/redis_string.h b/src/redis_string.h
index 0403070..37d66d2 100644
--- a/src/redis_string.h
+++ b/src/redis_string.h
@@ -41,6 +41,7 @@ class String : public Database {
   rocksdb::Status Append(const std::string &user_key, const std::string 
&value, int *ret);
   rocksdb::Status Get(const std::string &user_key, std::string *value);
   rocksdb::Status GetSet(const std::string &user_key, const std::string 
&new_value, std::string *old_value);
+  rocksdb::Status GetDel(const std::string &user_key, std::string *value);
   rocksdb::Status Set(const std::string &user_key, const std::string &value);
   rocksdb::Status SetEX(const std::string &user_key, const std::string &value, 
int ttl);
   rocksdb::Status SetNX(const std::string &user_key, const std::string &value, 
int ttl, int *ret);
diff --git a/tests/cppunit/t_string_test.cc b/tests/cppunit/t_string_test.cc
index c612bfa..5d01f0b 100644
--- a/tests/cppunit/t_string_test.cc
+++ b/tests/cppunit/t_string_test.cc
@@ -157,6 +157,20 @@ TEST_F(RedisStringTest, GetSet) {
   }
   string->Del(key_);
 }
+TEST_F(RedisStringTest, GetDel) {
+  for (size_t i = 0; i < pairs_.size(); i++) {
+    string->Set(pairs_[i].key.ToString(), pairs_[i].value.ToString());
+  }
+  for (size_t i = 0; i < pairs_.size(); i++) {
+    std::string got_value;
+    string->GetDel(pairs_[i].key.ToString(), &got_value);
+    EXPECT_EQ(pairs_[i].value, got_value);
+
+    std::string second_got_value;
+    auto s = string->GetDel(pairs_[i].key.ToString(), &second_got_value);
+    EXPECT_TRUE(!s.ok() && s.IsNotFound());
+  }
+}
 
 TEST_F(RedisStringTest, MSetXX) {
   int ret;
diff --git a/tests/tcl/tests/unit/command.tcl b/tests/tcl/tests/unit/command.tcl
index d6aba67..70f20e0 100644
--- a/tests/tcl/tests/unit/command.tcl
+++ b/tests/tcl/tests/unit/command.tcl
@@ -16,9 +16,9 @@
 # under the License.
 
 start_server {tags {"command"}} {
-    test {kvrocks has 170 commands currently} {
+    test {kvrocks has 171 commands currently} {
         r command count
-    } {170}
+    } {171}
 
     test {acquire GET command info by COMMAND INFO} {
         set e [lindex [r command info get] 0]
diff --git a/tests/tcl/tests/unit/type/string.tcl 
b/tests/tcl/tests/unit/type/string.tcl
index b1ab480..7db12af 100644
--- a/tests/tcl/tests/unit/type/string.tcl
+++ b/tests/tcl/tests/unit/type/string.tcl
@@ -180,12 +180,12 @@ start_server {tags {"string"}} {
     #      set ex
     #  } {*wrong number of arguments*}
 
-    # test "GETDEL command" {
-    #     r del foo
-    #     r set foo bar
-    #     assert_equal bar [r getdel foo ]
-    #     assert_equal {} [r getdel foo ]
-    # }
+    test "GETDEL command" {
+        r del foo
+        r set foo bar
+        assert_equal bar [r getdel foo ]
+        assert_equal {} [r getdel foo ]
+    }
 
     # test {GETDEL propagate as DEL command to replica} {
     #     set repl [attach_to_replication_stream]

Reply via email to