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

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


The following commit(s) were added to refs/heads/unstable by this push:
     new 3b554e27 Use CommandKeyRangeVecGen to support retrieving store keys 
(#2055)
3b554e27 is described below

commit 3b554e27acc25f01873f4b86e422aa79bd21374f
Author: Binbin <[email protected]>
AuthorDate: Sat Jan 27 10:11:29 2024 +0800

    Use CommandKeyRangeVecGen to support retrieving store keys (#2055)
---
 src/commands/cmd_geo.cc                   | 49 +++++++++++++++-
 src/commands/cmd_zset.cc                  | 12 ++--
 tests/gocase/unit/command/command_test.go | 96 ++++++++++++++++++++++++++++---
 3 files changed, 139 insertions(+), 18 deletions(-)

diff --git a/src/commands/cmd_geo.cc b/src/commands/cmd_geo.cc
index 2342e3df..3ed2237d 100644
--- a/src/commands/cmd_geo.cc
+++ b/src/commands/cmd_geo.cc
@@ -344,6 +344,26 @@ class CommandGeoRadius : public CommandGeoBase {
     return redis::Array(list);
   }
 
+  static std::vector<CommandKeyRange> Range(const std::vector<std::string> 
&args) {
+    int store_key = 0;
+
+    // Check for the presence of the stored key in the command args.
+    for (size_t i = 6; i < args.size(); i++) {
+      // For the case when a user specifies both "store" and "storedist" 
options,
+      // the second key will override the first key. The behavior is kept the 
same
+      // as in ParseRadiusExtraOption method.
+      if ((util::ToLower(args[i]) == "store" || util::ToLower(args[i]) == 
"storedist") && i + 1 < args.size()) {
+        store_key = (int)i + 1;
+        i++;
+      }
+    }
+
+    if (store_key > 0) {
+      return {{1, 1, 1}, {store_key, store_key, 1}};
+    }
+    return {{1, 1, 1}};
+  }
+
  protected:
   double radius_ = 0;
   bool with_coord_ = false;
@@ -604,6 +624,8 @@ class CommandGeoSearchStore : public CommandGeoSearch {
     return Status::OK();
   }
 
+  static std::vector<CommandKeyRange> Range(const std::vector<std::string> 
&args) { return {{1, 1, 1}, {2, 2, 1}}; }
+
  private:
   bool store_distance_ = false;
   std::string store_key_;
@@ -646,6 +668,26 @@ class CommandGeoRadiusByMember : public CommandGeoRadius {
 
     return Status::OK();
   }
+
+  static std::vector<CommandKeyRange> Range(const std::vector<std::string> 
&args) {
+    int store_key = 0;
+
+    // Check for the presence of the stored key in the command args.
+    for (size_t i = 5; i < args.size(); i++) {
+      // For the case when a user specifies both "store" and "storedist" 
options,
+      // the second key will override the first key. The behavior is kept the 
same
+      // as in ParseRadiusExtraOption method.
+      if ((util::ToLower(args[i]) == "store" || util::ToLower(args[i]) == 
"storedist") && i + 1 < args.size()) {
+        store_key = (int)i + 1;
+        i++;
+      }
+    }
+
+    if (store_key > 0) {
+      return {{1, 1, 1}, {store_key, store_key, 1}};
+    }
+    return {{1, 1, 1}};
+  }
 };
 
 class CommandGeoRadiusReadonly : public CommandGeoRadius {
@@ -662,11 +704,12 @@ 
REDIS_REGISTER_COMMANDS(MakeCmdAttr<CommandGeoAdd>("geoadd", -5, "write", 1, 1,
                         MakeCmdAttr<CommandGeoDist>("geodist", -4, 
"read-only", 1, 1, 1),
                         MakeCmdAttr<CommandGeoHash>("geohash", -3, 
"read-only", 1, 1, 1),
                         MakeCmdAttr<CommandGeoPos>("geopos", -3, "read-only", 
1, 1, 1),
-                        MakeCmdAttr<CommandGeoRadius>("georadius", -6, 
"write", 1, 1, 1),
-                        
MakeCmdAttr<CommandGeoRadiusByMember>("georadiusbymember", -5, "write", 1, 1, 
1),
+                        MakeCmdAttr<CommandGeoRadius>("georadius", -6, 
"write", CommandGeoRadius::Range),
+                        
MakeCmdAttr<CommandGeoRadiusByMember>("georadiusbymember", -5, "write",
+                                                              
CommandGeoRadiusByMember::Range),
                         MakeCmdAttr<CommandGeoRadiusReadonly>("georadius_ro", 
-6, "read-only", 1, 1, 1),
                         
MakeCmdAttr<CommandGeoRadiusByMemberReadonly>("georadiusbymember_ro", -5, 
"read-only", 1, 1, 1),
                         MakeCmdAttr<CommandGeoSearch>("geosearch", -7, 
"read-only", 1, 1, 1),
-                        MakeCmdAttr<CommandGeoSearchStore>("geosearchstore", 
-8, "write", 1, 1, 1))
+                        MakeCmdAttr<CommandGeoSearchStore>("geosearchstore", 
-8, "write", CommandGeoSearchStore::Range))
 
 }  // namespace redis
diff --git a/src/commands/cmd_zset.cc b/src/commands/cmd_zset.cc
index 17ec5548..d78fe54e 100644
--- a/src/commands/cmd_zset.cc
+++ b/src/commands/cmd_zset.cc
@@ -1223,9 +1223,9 @@ class CommandZUnionStore : public Commander {
     return Status::OK();
   }
 
-  static CommandKeyRange Range(const std::vector<std::string> &args) {
+  static std::vector<CommandKeyRange> Range(const std::vector<std::string> 
&args) {
     int num_key = *ParseInt<int>(args[2], 10);
-    return {3, 2 + num_key, 1};
+    return {{1, 1, 1}, {3, 2 + num_key, 1}};
   }
 
  protected:
@@ -1250,9 +1250,9 @@ class CommandZInterStore : public CommandZUnionStore {
     return Status::OK();
   }
 
-  static CommandKeyRange Range(const std::vector<std::string> &args) {
+  static std::vector<CommandKeyRange> Range(const std::vector<std::string> 
&args) {
     int num_key = *ParseInt<int>(args[2], 10);
-    return {3, 2 + num_key, 1};
+    return {{1, 1, 1}, {3, 2 + num_key, 1}};
   }
 };
 
@@ -1506,9 +1506,9 @@ class CommandZDiffStore : public Commander {
     return Status::OK();
   }
 
-  static CommandKeyRange Range(const std::vector<std::string> &args) {
+  static std::vector<CommandKeyRange> Range(const std::vector<std::string> 
&args) {
     int num_key = *ParseInt<int>(args[2], 10);
-    return {3, 2 + num_key, 1};
+    return {{1, 1, 1}, {3, 2 + num_key, 1}};
   }
 
  protected:
diff --git a/tests/gocase/unit/command/command_test.go 
b/tests/gocase/unit/command/command_test.go
index 89d87a58..51be1347 100644
--- a/tests/gocase/unit/command/command_test.go
+++ b/tests/gocase/unit/command/command_test.go
@@ -88,9 +88,10 @@ func TestCommand(t *testing.T) {
                r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZINTERSTORE", "dst", 
"2", "src1", "src2")
                vs, err := r.Slice()
                require.NoError(t, err)
-               require.Len(t, vs, 2)
-               require.Equal(t, "src1", vs[0])
-               require.Equal(t, "src2", vs[1])
+               require.Len(t, vs, 3)
+               require.Equal(t, "dst", vs[0])
+               require.Equal(t, "src1", vs[1])
+               require.Equal(t, "src2", vs[2])
        })
 
        t.Run("COMMAND GETKEYS ZINTERCARD", func(t *testing.T) {
@@ -115,9 +116,10 @@ func TestCommand(t *testing.T) {
                r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZUNIONSTORE", "dst", 
"2", "src1", "src2")
                vs, err := r.Slice()
                require.NoError(t, err)
-               require.Len(t, vs, 2)
-               require.Equal(t, "src1", vs[0])
-               require.Equal(t, "src2", vs[1])
+               require.Len(t, vs, 3)
+               require.Equal(t, "dst", vs[0])
+               require.Equal(t, "src1", vs[1])
+               require.Equal(t, "src2", vs[2])
        })
 
        t.Run("COMMAND GETKEYS ZDIFF", func(t *testing.T) {
@@ -133,9 +135,10 @@ func TestCommand(t *testing.T) {
                r := rdb.Do(ctx, "COMMAND", "GETKEYS", "ZDIFFSTORE", "dst", 
"2", "src1", "src2")
                vs, err := r.Slice()
                require.NoError(t, err)
-               require.Len(t, vs, 2)
-               require.Equal(t, "src1", vs[0])
-               require.Equal(t, "src2", vs[1])
+               require.Len(t, vs, 3)
+               require.Equal(t, "dst", vs[0])
+               require.Equal(t, "src1", vs[1])
+               require.Equal(t, "src2", vs[2])
        })
 
        t.Run("COMMAND GETKEYS ZMPOP", func(t *testing.T) {
@@ -173,4 +176,79 @@ func TestCommand(t *testing.T) {
                require.Equal(t, "key1", vs[0])
                require.Equal(t, "key2", vs[1])
        })
+
+       t.Run("COMMAND GETKEYS GEORADIUS", func(t *testing.T) {
+               // non-store
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "GEORADIUS", "src", "1", 
"1", "1", "km")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 1)
+               require.Equal(t, "src", vs[0])
+
+               // store
+               r = rdb.Do(ctx, "COMMAND", "GETKEYS", "GEORADIUS", "src", "1", 
"1", "1", "km", "store", "dst")
+               vs, err = r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "src", vs[0])
+               require.Equal(t, "dst", vs[1])
+
+               // storedist
+               r = rdb.Do(ctx, "COMMAND", "GETKEYS", "GEORADIUS", "src", "1", 
"1", "1", "km", "storedist", "dst")
+               vs, err = r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "src", vs[0])
+               require.Equal(t, "dst", vs[1])
+
+               // store + storedist
+               r = rdb.Do(ctx, "COMMAND", "GETKEYS", "GEORADIUS", "src", "1", 
"1", "1", "km", "store", "dst1", "storedist", "dst2")
+               vs, err = r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "src", vs[0])
+               require.Equal(t, "dst2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS GEORADIUSBYMEMBER", func(t *testing.T) {
+               // non-store
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "GEORADIUSBYMEMBER", 
"src", "member", "radius", "m")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 1)
+               require.Equal(t, "src", vs[0])
+
+               // store
+               r = rdb.Do(ctx, "COMMAND", "GETKEYS", "GEORADIUSBYMEMBER", 
"src", "member", "radius", "m", "store", "dst")
+               vs, err = r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "src", vs[0])
+               require.Equal(t, "dst", vs[1])
+
+               // storedist
+               r = rdb.Do(ctx, "COMMAND", "GETKEYS", "GEORADIUSBYMEMBER", 
"src", "member", "radius", "m", "storedist", "dst")
+               vs, err = r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "src", vs[0])
+               require.Equal(t, "dst", vs[1])
+
+               // store + storedist
+               r = rdb.Do(ctx, "COMMAND", "GETKEYS", "GEORADIUSBYMEMBER", 
"src", "member", "radius", "m", "store", "dst1", "storedist", "dst2")
+               vs, err = r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "src", vs[0])
+               require.Equal(t, "dst2", vs[1])
+       })
+
+       t.Run("COMMAND GETKEYS GEOSEARCHSTORE", func(t *testing.T) {
+               r := rdb.Do(ctx, "COMMAND", "GETKEYS", "GEOSEARCHSTORE", "dst", 
"src", "frommember", "member", "byradius", "10", "m")
+               vs, err := r.Slice()
+               require.NoError(t, err)
+               require.Len(t, vs, 2)
+               require.Equal(t, "dst", vs[0])
+               require.Equal(t, "src", vs[1])
+       })
 }

Reply via email to