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])
+ })
}