From 559f6a8aef59bd7e55ff8c7900db4531d4f9743c Mon Sep 17 00:00:00 2001 From: ZhouSiLe Date: Sun, 8 Sep 2024 22:27:12 +0800 Subject: [PATCH 1/9] test: txn-context-enabled test cases --- tests/gocase/unit/config/config_test.go | 45 ++++++++++ tests/gocase/unit/geo/geo_test.go | 30 +++++-- tests/gocase/unit/pubsub/pubsub_test.go | 30 +++++-- tests/gocase/unit/scripting/function_test.go | 30 +++++-- tests/gocase/unit/type/bloom/bloom_test.go | 20 ++++- tests/gocase/unit/type/hash/hash_test.go | 30 +++++-- tests/gocase/unit/type/incr/incr_test.go | 19 +++- tests/gocase/unit/type/json/json_test.go | 18 +++- tests/gocase/unit/type/list/list_test.go | 62 ++++++++++++- tests/gocase/unit/type/set/set_test.go | 28 ++++-- tests/gocase/unit/type/sint/sint_test.go | 21 ++++- tests/gocase/unit/type/stream/stream_test.go | 30 +++++-- .../gocase/unit/type/strings/strings_test.go | 16 ++++ tests/gocase/unit/type/zset/zset_test.go | 32 ++++--- tests/gocase/util/configs.go | 88 +++++++++++++++++++ 15 files changed, 427 insertions(+), 72 deletions(-) create mode 100644 tests/gocase/util/configs.go diff --git a/tests/gocase/unit/config/config_test.go b/tests/gocase/unit/config/config_test.go index 0c434e72c55..c43b7da91d7 100644 --- a/tests/gocase/unit/config/config_test.go +++ b/tests/gocase/unit/config/config_test.go @@ -275,3 +275,48 @@ func TestChangeProtoMaxBulkLen(t *testing.T) { // Must be >= 1MB require.Error(t, rdb.ConfigSet(ctx, "proto-max-bulk-len", "1024").Err()) } + +func TestGetConfigTxnContext(t *testing.T) { + srv := util.StartServer(t, map[string]string{ + "txn-context-enabled": "yes", + }) + defer srv.Close() + + ctx := context.Background() + rdb := srv.NewClient() + defer func() { require.NoError(t, rdb.Close()) }() + val := rdb.ConfigGet(ctx, "txn-context-enabled").Val() + require.EqualValues(t, "yes", val["txn-context-enabled"]) + + // default value "no" + srv1 := util.StartServer(t, map[string]string{}) + defer srv1.Close() + + rdb = srv1.NewClient() + val = rdb.ConfigGet(ctx, "txn-context-enabled").Val() + require.EqualValues(t, "no", val["txn-context-enabled"]) +} + +func TestGenerateConfigsMatrix(t *testing.T) { + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + { + Name: "resp3-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + + require.NoError(t, err) + require.Equal(t, 4, len(configsMatrix)) + require.Contains(t, configsMatrix, util.KvrocksServerConfigs{"txn-context-enabled": "yes", "resp3-enabled": "yes"}) + require.Contains(t, configsMatrix, util.KvrocksServerConfigs{"txn-context-enabled": "yes", "resp3-enabled": "no"}) + require.Contains(t, configsMatrix, util.KvrocksServerConfigs{"txn-context-enabled": "no", "resp3-enabled": "yes"}) + require.Contains(t, configsMatrix, util.KvrocksServerConfigs{"txn-context-enabled": "no", "resp3-enabled": "no"}) +} diff --git a/tests/gocase/unit/geo/geo_test.go b/tests/gocase/unit/geo/geo_test.go index a920ddabbce..6d474d645ba 100644 --- a/tests/gocase/unit/geo/geo_test.go +++ b/tests/gocase/unit/geo/geo_test.go @@ -87,18 +87,30 @@ func compareLists(list1, list2 []string) []string { return result } -func TestGeoWithRESP2(t *testing.T) { - testGeo(t, "no") -} +func TestGeo(t *testing.T) { + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + { + Name: "resp3-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) -func TestGeoWithRESP3(t *testing.T) { - testGeo(t, "yes") + for _, configs := range configsMatrix { + testGeo(t, configs) + } } -var testGeo = func(t *testing.T, enabledRESP3 string) { - srv := util.StartServer(t, map[string]string{ - "resp3-enabled": enabledRESP3, - }) +var testGeo = func(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() diff --git a/tests/gocase/unit/pubsub/pubsub_test.go b/tests/gocase/unit/pubsub/pubsub_test.go index bf4d655a726..6c398757e75 100644 --- a/tests/gocase/unit/pubsub/pubsub_test.go +++ b/tests/gocase/unit/pubsub/pubsub_test.go @@ -36,18 +36,30 @@ func receiveType[T any](t *testing.T, pubsub *redis.PubSub, typ T) T { return msg.(T) } -func TestPubSubWithRESP2(t *testing.T) { - testPubSub(t, "no") -} +func TestPubSub(t *testing.T) { + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + { + Name: "resp3-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) -func TestPubSubWithRESP3(t *testing.T) { - testPubSub(t, "yes") + for _, configs := range configsMatrix { + testPubSub(t, configs) + } } -func testPubSub(t *testing.T, enabledRESP3 string) { - srv := util.StartServer(t, map[string]string{ - "resp3-enabled": enabledRESP3, - }) +func testPubSub(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() diff --git a/tests/gocase/unit/scripting/function_test.go b/tests/gocase/unit/scripting/function_test.go index 8d71158498a..9ab7eff04d4 100644 --- a/tests/gocase/unit/scripting/function_test.go +++ b/tests/gocase/unit/scripting/function_test.go @@ -97,18 +97,30 @@ func decodeListLibResult(t *testing.T, v interface{}) ListLibResult { return ListLibResult{} } -func TestFunctionsWithRESP3(t *testing.T) { - testFunctions(t, "yes") -} +func TestFunctions(t *testing.T) { + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + { + Name: "resp3-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) -func TestFunctionsWithoutRESP2(t *testing.T) { - testFunctions(t, "no") + for _, configs := range configsMatrix { + testFunctions(t, configs) + } } -var testFunctions = func(t *testing.T, enabledRESP3 string) { - srv := util.StartServer(t, map[string]string{ - "resp3-enabled": enabledRESP3, - }) +var testFunctions = func(t *testing.T, config util.KvrocksServerConfigs) { + srv := util.StartServer(t, config) defer srv.Close() ctx := context.Background() diff --git a/tests/gocase/unit/type/bloom/bloom_test.go b/tests/gocase/unit/type/bloom/bloom_test.go index ebfd952e08f..13009afd493 100644 --- a/tests/gocase/unit/type/bloom/bloom_test.go +++ b/tests/gocase/unit/type/bloom/bloom_test.go @@ -29,8 +29,24 @@ import ( "github.com/stretchr/testify/require" ) -func TestBloom(t *testing.T) { - srv := util.StartServer(t, map[string]string{}) +func TestBloomInfo(t *testing.T) { + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) + + for _, configs := range configsMatrix { + testBloom(t, configs) + } +} +func testBloom(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() diff --git a/tests/gocase/unit/type/hash/hash_test.go b/tests/gocase/unit/type/hash/hash_test.go index 3c769649295..caab802af77 100644 --- a/tests/gocase/unit/type/hash/hash_test.go +++ b/tests/gocase/unit/type/hash/hash_test.go @@ -50,18 +50,30 @@ func getVals(hash map[string]string) []string { return r } -func TestHashWithRESP2(t *testing.T) { - testHash(t, "no") -} +func TestHash(t *testing.T) { + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + { + Name: "resp3-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) -func TestHashWithRESP3(t *testing.T) { - testHash(t, "yes") + for _, configs := range configsMatrix { + testHash(t, configs) + } } -var testHash = func(t *testing.T, enabledRESP3 string) { - srv := util.StartServer(t, map[string]string{ - "resp3-enabled": enabledRESP3, - }) +var testHash = func(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() diff --git a/tests/gocase/unit/type/incr/incr_test.go b/tests/gocase/unit/type/incr/incr_test.go index a90f9e1d66d..f8a1785cfb1 100644 --- a/tests/gocase/unit/type/incr/incr_test.go +++ b/tests/gocase/unit/type/incr/incr_test.go @@ -28,7 +28,24 @@ import ( ) func TestIncr(t *testing.T) { - srv := util.StartServer(t, map[string]string{}) + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) + + for _, configs := range configsMatrix { + testIncr(t, configs) + } +} + +func testIncr(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() diff --git a/tests/gocase/unit/type/json/json_test.go b/tests/gocase/unit/type/json/json_test.go index a5e02dba80b..b943a32a714 100644 --- a/tests/gocase/unit/type/json/json_test.go +++ b/tests/gocase/unit/type/json/json_test.go @@ -30,7 +30,23 @@ import ( ) func TestJson(t *testing.T) { - srv := util.StartServer(t, map[string]string{}) + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) + + for _, configs := range configsMatrix { + testJSON(t, configs) + } +} +func testJSON(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() diff --git a/tests/gocase/unit/type/list/list_test.go b/tests/gocase/unit/type/list/list_test.go index 79f7b360bfa..8b7a2c58f4e 100644 --- a/tests/gocase/unit/type/list/list_test.go +++ b/tests/gocase/unit/type/list/list_test.go @@ -42,7 +42,24 @@ var largeValue = map[string]string{ } func TestLTRIM(t *testing.T) { - srv := util.StartServer(t, map[string]string{}) + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) + + for _, configs := range configsMatrix { + testLTRIM(t, configs) + } +} + +func testLTRIM(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() @@ -85,7 +102,24 @@ func TestLTRIM(t *testing.T) { } func TestZipList(t *testing.T) { - srv := util.StartServer(t, map[string]string{}) + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) + + for _, configs := range configsMatrix { + testZipList(t, configs) + } +} + +func testZipList(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClientWithOption(&redis.Options{ @@ -233,7 +267,29 @@ func TestZipList(t *testing.T) { } func TestList(t *testing.T) { - srv := util.StartServer(t, map[string]string{}) + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + { + Name: "resp3-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) + + for _, configs := range configsMatrix { + testList(t, configs) + } +} + +func testList(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() diff --git a/tests/gocase/unit/type/set/set_test.go b/tests/gocase/unit/type/set/set_test.go index 0d596620936..3c910513f02 100644 --- a/tests/gocase/unit/type/set/set_test.go +++ b/tests/gocase/unit/type/set/set_test.go @@ -57,17 +57,29 @@ func GetArrayUnion(arrays ...[]string) []string { } func TestSet(t *testing.T) { - setTests(t, "no") -} + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + { + Name: "resp3-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) -func TestSetWithRESP3(t *testing.T) { - setTests(t, "yes") + for _, configs := range configsMatrix { + setTests(t, configs) + } } -var setTests = func(t *testing.T, enabledRESP3 string) { - srv := util.StartServer(t, map[string]string{ - "resp3-enabled": enabledRESP3, - }) +var setTests = func(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() diff --git a/tests/gocase/unit/type/sint/sint_test.go b/tests/gocase/unit/type/sint/sint_test.go index aa45859f33c..4b4f0cb35bc 100644 --- a/tests/gocase/unit/type/sint/sint_test.go +++ b/tests/gocase/unit/type/sint/sint_test.go @@ -27,8 +27,25 @@ import ( "github.com/stretchr/testify/require" ) -func TestSint(t *testing.T) { - srv := util.StartServer(t, map[string]string{}) +func TestString(t *testing.T) { + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) + + for _, configs := range configsMatrix { + testSint(t, configs) + } +} + +func testSint(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() diff --git a/tests/gocase/unit/type/stream/stream_test.go b/tests/gocase/unit/type/stream/stream_test.go index 8ff7a503c3f..943127fcaaa 100644 --- a/tests/gocase/unit/type/stream/stream_test.go +++ b/tests/gocase/unit/type/stream/stream_test.go @@ -34,18 +34,30 @@ import ( "github.com/stretchr/testify/require" ) -func TestStreamWithRESP2(t *testing.T) { - streamTests(t, "no") -} +func TestStream(t *testing.T) { + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + { + Name: "resp3-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } -func TestStreamWithRESP3(t *testing.T) { - streamTests(t, "yes") + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) + + for _, configs := range configsMatrix { + streamTests(t, configs) + } } -var streamTests = func(t *testing.T, enabledRESP3 string) { - srv := util.StartServer(t, map[string]string{ - "resp3-enabled": enabledRESP3, - }) +var streamTests = func(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() diff --git a/tests/gocase/unit/type/strings/strings_test.go b/tests/gocase/unit/type/strings/strings_test.go index 49963d0b559..e5938182b8c 100644 --- a/tests/gocase/unit/type/strings/strings_test.go +++ b/tests/gocase/unit/type/strings/strings_test.go @@ -35,6 +35,22 @@ import ( ) func TestString(t *testing.T) { + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) + + for _, configs := range configsMatrix { + testString(t, configs) + } +} +func testString(t *testing.T, configs util.KvrocksServerConfigs) { srv := util.StartServer(t, map[string]string{}) defer srv.Close() ctx := context.Background() diff --git a/tests/gocase/unit/type/zset/zset_test.go b/tests/gocase/unit/type/zset/zset_test.go index 20441b5b17e..ad57defaa85 100644 --- a/tests/gocase/unit/type/zset/zset_test.go +++ b/tests/gocase/unit/type/zset/zset_test.go @@ -1907,24 +1907,36 @@ func stressTests(t *testing.T, rdb *redis.Client, ctx context.Context, encoding }) } -func TestZSetWithRESP2(t *testing.T) { - testZSet(t, "no") -} +func TestZSet(t *testing.T) { + configOptions := []util.ConfigOptions{ + { + Name: "txn-context-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + { + Name: "resp3-enabled", + Options: []string{"yes", "no"}, + ConfigType: util.YesNo, + }, + } + + configsMatrix, err := util.GenerateConfigsMatrix(configOptions) + require.NoError(t, err) -func TestZSetWithRESP3(t *testing.T) { - testZSet(t, "yes") + for _, configs := range configsMatrix { + testZSet(t, configs) + } } -var testZSet = func(t *testing.T, enabledRESP3 string) { - srv := util.StartServer(t, map[string]string{ - "resp3-enabled": enabledRESP3, - }) +var testZSet = func(t *testing.T, configs util.KvrocksServerConfigs) { + srv := util.StartServer(t, configs) defer srv.Close() ctx := context.Background() rdb := srv.NewClient() defer func() { require.NoError(t, rdb.Close()) }() - basicTests(t, rdb, ctx, enabledRESP3, "skiplist", srv) + basicTests(t, rdb, ctx, configs["resp3-enabled"], "skiplist", srv) t.Run("ZUNIONSTORE regression, should not create NaN in scores", func(t *testing.T) { rdb.ZAdd(ctx, "z", redis.Z{Score: math.Inf(-1), Member: "neginf"}) diff --git a/tests/gocase/util/configs.go b/tests/gocase/util/configs.go new file mode 100644 index 00000000000..c575f25a8cc --- /dev/null +++ b/tests/gocase/util/configs.go @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package util + +import "fmt" + +type FieldType int + +const ( + YesNo FieldType = iota +) + +type ConfigOptions struct { + Name string + Options []string + ConfigType FieldType +} + +type KvrocksServerConfigs map[string]string + +func verifyConfigOptions(configType FieldType, option string) error { + switch configType { + case YesNo: + if option == "yes" || option == "no" { + break + } + return fmt.Errorf("invalid option for yes/no config") + default: + return fmt.Errorf("unsupported config type") + } + return nil +} + +// / GenerateConfigsMatrix generates all possible combinations of config options +func GenerateConfigsMatrix(configOptions []ConfigOptions) ([]KvrocksServerConfigs, error) { + configsMatrix := make([]KvrocksServerConfigs, 0) + + var helper func(configs []ConfigOptions, index int, currentConfig map[string]string) error + + helper = func(configs []ConfigOptions, currentIndex int, currentConfig map[string]string) error { + if currentIndex == len(configOptions) { + configsMatrix = append(configsMatrix, currentConfig) + return nil + } + + currentConfigBackup := make(KvrocksServerConfigs, len(currentConfig)) + for k, v := range currentConfig { + currentConfigBackup[k] = v + } + + for _, option := range configs[currentIndex].Options { + err := verifyConfigOptions(configs[currentIndex].ConfigType, option) + if err != nil { + return err + } + + currentConfig[configs[currentIndex].Name] = option + err = helper(configs, currentIndex+1, currentConfig) + if err != nil { + return err + } + currentConfig = currentConfigBackup + } + + return nil + } + + err := helper(configOptions, 0, make(KvrocksServerConfigs, 0)) + + return configsMatrix, err +} From 3d067c66106b7a911cee446eae400fdaadea5ec2 Mon Sep 17 00:00:00 2001 From: ZhouSiLe Date: Mon, 7 Oct 2024 20:44:44 +0800 Subject: [PATCH 2/9] refactor: promote the engine::Context in the Execute --- src/commands/cmd_bit.cc | 24 +++---- src/commands/cmd_bloom_filter.cc | 32 +++++----- src/commands/cmd_cluster.cc | 13 ++-- src/commands/cmd_function.cc | 7 ++- src/commands/cmd_geo.cc | 30 +++++---- src/commands/cmd_hash.cc | 63 +++++++++---------- src/commands/cmd_hll.cc | 12 ++-- src/commands/cmd_json.cc | 91 +++++++++++++-------------- src/commands/cmd_key.cc | 76 +++++++++++----------- src/commands/cmd_list.cc | 63 +++++++++---------- src/commands/cmd_pubsub.cc | 27 ++++---- src/commands/cmd_replication.cc | 14 +++-- src/commands/cmd_script.cc | 6 +- src/commands/cmd_search.cc | 23 ++++--- src/commands/cmd_server.cc | 104 ++++++++++++++++-------------- src/commands/cmd_set.cc | 68 ++++++++++---------- src/commands/cmd_sortedint.cc | 24 +++---- src/commands/cmd_stream.cc | 79 +++++++++++------------ src/commands/cmd_string.cc | 90 +++++++++++++------------- src/commands/cmd_txn.cc | 11 ++-- src/commands/cmd_zset.cc | 105 +++++++++++++++---------------- src/commands/commander.h | 8 ++- src/search/index_manager.h | 17 +++-- src/server/redis_connection.cc | 16 ++--- src/server/redis_connection.h | 4 +- src/server/server.cc | 5 +- src/storage/scripting.cc | 4 +- 27 files changed, 514 insertions(+), 502 deletions(-) diff --git a/src/commands/cmd_bit.cc b/src/commands/cmd_bit.cc index 973c803e031..13be25f3134 100644 --- a/src/commands/cmd_bit.cc +++ b/src/commands/cmd_bit.cc @@ -46,10 +46,10 @@ class CommandGetBit : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { bool bit = false; redis::Bitmap bitmap_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = bitmap_db.GetBit(ctx, args_[1], offset_, &bit); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -78,10 +78,10 @@ class CommandSetBit : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { bool old_bit = false; redis::Bitmap bitmap_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = bitmap_db.SetBit(ctx, args_[1], offset_, bit_, &old_bit); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -134,10 +134,10 @@ class CommandBitCount : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint32_t cnt = 0; redis::Bitmap bitmap_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = bitmap_db.BitCount(ctx, args_[1], start_, stop_, is_bit_index_, &cnt); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -194,10 +194,10 @@ class CommandBitPos : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { int64_t pos = 0; redis::Bitmap bitmap_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = bitmap_db.BitPos(ctx, args_[1], bit_, start_, stop_, stop_given_, &pos, is_bit_index_); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -234,7 +234,7 @@ class CommandBitOp : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector op_keys; op_keys.reserve(args_.size() - 2); for (uint64_t i = 3; i < args_.size(); i++) { @@ -243,7 +243,7 @@ class CommandBitOp : public Commander { int64_t dest_key_len = 0; redis::Bitmap bitmap_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = bitmap_db.BitOp(ctx, op_flag_, args_[1], args_[2], op_keys, &dest_key_len); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -337,11 +337,11 @@ class CommandBitfield : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Bitmap bitmap_db(srv->storage, conn->GetNamespace()); std::vector> rets; rocksdb::Status s; - engine::Context ctx(srv->storage); + if (read_only_) { s = bitmap_db.BitfieldReadOnly(ctx, args_[1], cmds_, &rets); } else { diff --git a/src/commands/cmd_bloom_filter.cc b/src/commands/cmd_bloom_filter.cc index 1020954fef2..6fd422ff8eb 100644 --- a/src/commands/cmd_bloom_filter.cc +++ b/src/commands/cmd_bloom_filter.cc @@ -88,9 +88,9 @@ class CommandBFReserve : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::BloomChain bloomfilter_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = bloomfilter_db.Reserve(ctx, args_[1], capacity_, error_rate_, expansion_); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -106,10 +106,10 @@ class CommandBFReserve : public Commander { class CommandBFAdd : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::BloomChain bloom_db(srv->storage, conn->GetNamespace()); BloomFilterAddResult ret = BloomFilterAddResult::kOk; - engine::Context ctx(srv->storage); + auto s = bloom_db.Add(ctx, args_[1], args_[2], &ret); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -138,10 +138,10 @@ class CommandBFMAdd : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::BloomChain bloom_db(srv->storage, conn->GetNamespace()); std::vector rets(items_.size(), BloomFilterAddResult::kOk); - engine::Context ctx(srv->storage); + auto s = bloom_db.MAdd(ctx, args_[1], items_, &rets); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -234,10 +234,10 @@ class CommandBFInsert : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::BloomChain bloom_db(srv->storage, conn->GetNamespace()); std::vector rets(items_.size(), BloomFilterAddResult::kOk); - engine::Context ctx(srv->storage); + auto s = bloom_db.InsertCommon(ctx, args_[1], items_, insert_options_, &rets); if (s.IsNotFound()) return {Status::RedisExecErr, "key is not found"}; if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -266,10 +266,10 @@ class CommandBFInsert : public Commander { class CommandBFExists : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::BloomChain bloom_db(srv->storage, conn->GetNamespace()); bool exist = false; - engine::Context ctx(srv->storage); + auto s = bloom_db.Exists(ctx, args_[1], args_[2], &exist); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -288,10 +288,10 @@ class CommandBFMExists : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::BloomChain bloom_db(srv->storage, conn->GetNamespace()); std::vector exists(items_.size(), false); - engine::Context ctx(srv->storage); + auto s = bloom_db.MExists(ctx, args_[1], items_, &exists); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -332,10 +332,10 @@ class CommandBFInfo : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::BloomChain bloom_db(srv->storage, conn->GetNamespace()); BloomFilterInfo info; - engine::Context ctx(srv->storage); + auto s = bloom_db.Info(ctx, args_[1], &info); if (s.IsNotFound()) return {Status::RedisExecErr, "key is not found"}; if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -380,10 +380,10 @@ class CommandBFInfo : public Commander { class CommandBFCard : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::BloomChain bloom_db(srv->storage, conn->GetNamespace()); BloomFilterInfo info; - engine::Context ctx(srv->storage); + auto s = bloom_db.Info(ctx, args_[1], &info); if (!s.ok() && !s.IsNotFound()) return {Status::RedisExecErr, s.ToString()}; if (s.IsNotFound()) { diff --git a/src/commands/cmd_cluster.cc b/src/commands/cmd_cluster.cc index 9f4aa27d8dc..11f604690ab 100644 --- a/src/commands/cmd_cluster.cc +++ b/src/commands/cmd_cluster.cc @@ -65,7 +65,7 @@ class CommandCluster : public Commander { return {Status::RedisParseErr, "CLUSTER command, CLUSTER INFO|NODES|SLOTS|KEYSLOT|RESET|REPLICAS"}; } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (!srv->GetConfig()->cluster_enabled) { return {Status::RedisExecErr, "Cluster mode is not enabled"}; } @@ -244,7 +244,7 @@ class CommandClusterX : public Commander { return {Status::RedisParseErr, "CLUSTERX command, CLUSTERX VERSION|MYID|SETNODEID|SETNODES|SETSLOT|MIGRATE"}; } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (!srv->GetConfig()->cluster_enabled) { return {Status::RedisExecErr, "Cluster mode is not enabled"}; } @@ -329,7 +329,8 @@ static uint64_t GenerateClusterFlag(uint64_t flags, const std::vectorEnableFlag(redis::Connection::kReadOnly); return Status::OK(); @@ -338,7 +339,8 @@ class CommandReadOnly : public Commander { class CommandReadWrite : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { *output = redis::SimpleString("OK"); conn->DisableFlag(redis::Connection::kReadOnly); return Status::OK(); @@ -347,7 +349,8 @@ class CommandReadWrite : public Commander { class CommandAsking : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { conn->EnableFlag(redis::Connection::kAsking); *output = redis::SimpleString("OK"); return Status::OK(); diff --git a/src/commands/cmd_function.cc b/src/commands/cmd_function.cc index c28eed12fa6..53fbc0c03f4 100644 --- a/src/commands/cmd_function.cc +++ b/src/commands/cmd_function.cc @@ -29,9 +29,9 @@ namespace redis { struct CommandFunction : Commander { - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { CommandParser parser(args_, 1); - engine::Context ctx(srv->storage); + if (parser.EatEqICase("load")) { bool replace = false; if (parser.EatEqICase("replace")) { @@ -85,7 +85,8 @@ struct CommandFunction : Commander { template struct CommandFCall : Commander { - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { int64_t numkeys = GET_OR_RET(ParseInt(args_[2], 10)); if (numkeys > int64_t(args_.size() - 3)) { return {Status::NotOK, "Number of keys can't be greater than number of args"}; diff --git a/src/commands/cmd_geo.cc b/src/commands/cmd_geo.cc index 80dc62e8adf..3cf41c84e91 100644 --- a/src/commands/cmd_geo.cc +++ b/src/commands/cmd_geo.cc @@ -111,10 +111,10 @@ class CommandGeoAdd : public CommandGeoBase { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t ret = 0; redis::Geo geo_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = geo_db.Add(ctx, args_[1], &geo_points_, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -140,10 +140,10 @@ class CommandGeoDist : public CommandGeoBase { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { double distance = 0; redis::Geo geo_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = geo_db.Dist(ctx, args_[1], args_[2], args_[3], &distance); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -167,10 +167,10 @@ class CommandGeoHash : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector hashes; redis::Geo geo_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = geo_db.Hash(ctx, args_[1], members_, &hashes); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -197,10 +197,10 @@ class CommandGeoPos : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::map geo_points; redis::Geo geo_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = geo_db.Pos(ctx, args_[1], members_, &geo_points); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -305,10 +305,10 @@ class CommandGeoRadius : public CommandGeoBase { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector geo_points; redis::Geo geo_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = geo_db.Radius(ctx, args_[1], longitude_, latitude_, GetRadiusMeters(radius_), count_, sort_, store_key_, store_distance_, GetUnitConversion(), &geo_points); if (!s.ok()) { @@ -453,11 +453,10 @@ class CommandGeoSearch : public CommandGeoBase { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector geo_points; redis::Geo geo_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); auto s = geo_db.Search(ctx, args_[1], geo_shape_, origin_point_type_, member_, count_, sort_, false, GetUnitConversion(), &geo_points); @@ -616,11 +615,10 @@ class CommandGeoSearchStore : public CommandGeoSearch { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector geo_points; redis::Geo geo_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); auto s = geo_db.SearchStore(ctx, args_[2], geo_shape_, origin_point_type_, member_, count_, sort_, store_key_, store_distance_, GetUnitConversion(), &geo_points); @@ -660,10 +658,10 @@ class CommandGeoRadiusByMember : public CommandGeoRadius { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector geo_points; redis::Geo geo_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = geo_db.RadiusByMember(ctx, args_[1], args_[2], GetRadiusMeters(radius_), count_, sort_, store_key_, store_distance_, GetUnitConversion(), &geo_points); if (!s.ok()) { diff --git a/src/commands/cmd_hash.cc b/src/commands/cmd_hash.cc index a319ec23c3d..9b9847fbbe3 100644 --- a/src/commands/cmd_hash.cc +++ b/src/commands/cmd_hash.cc @@ -29,10 +29,10 @@ namespace redis { class CommandHGet : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Hash hash_db(srv->storage, conn->GetNamespace()); std::string value; - engine::Context ctx(srv->storage); + auto s = hash_db.Get(ctx, args_[1], args_[2], &value); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -55,10 +55,10 @@ class CommandHSetNX : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t ret = 0; redis::Hash hash_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = hash_db.MSet(ctx, args_[1], field_values_, true, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -74,10 +74,10 @@ class CommandHSetNX : public Commander { class CommandHStrlen : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Hash hash_db(srv->storage, conn->GetNamespace()); std::string value; - engine::Context ctx(srv->storage); + auto s = hash_db.Get(ctx, args_[1], args_[2], &value); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -90,7 +90,7 @@ class CommandHStrlen : public Commander { class CommandHDel : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector fields; for (size_t i = 2; i < args_.size(); i++) { fields.emplace_back(args_[i]); @@ -98,7 +98,7 @@ class CommandHDel : public Commander { uint64_t ret = 0; redis::Hash hash_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = hash_db.Delete(ctx, args_[1], fields, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -111,10 +111,10 @@ class CommandHDel : public Commander { class CommandHExists : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Hash hash_db(srv->storage, conn->GetNamespace()); std::string value; - engine::Context ctx(srv->storage); + auto s = hash_db.Get(ctx, args_[1], args_[2], &value); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -127,10 +127,10 @@ class CommandHExists : public Commander { class CommandHLen : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t count = 0; redis::Hash hash_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = hash_db.Size(ctx, args_[1], &count); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -153,10 +153,10 @@ class CommandHIncrBy : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { int64_t ret = 0; redis::Hash hash_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = hash_db.IncrBy(ctx, args_[1], args_[2], increment_, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -181,10 +181,10 @@ class CommandHIncrByFloat : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { double ret = 0; redis::Hash hash_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = hash_db.IncrByFloat(ctx, args_[1], args_[2], increment_, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -200,7 +200,7 @@ class CommandHIncrByFloat : public Commander { class CommandHMGet : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector fields; for (size_t i = 2; i < args_.size(); i++) { fields.emplace_back(args_[i]); @@ -209,7 +209,7 @@ class CommandHMGet : public Commander { std::vector values; std::vector statuses; redis::Hash hash_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = hash_db.MGet(ctx, args_[1], fields, &values, &statuses); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -237,10 +237,10 @@ class CommandHMSet : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t ret = 0; redis::Hash hash_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = hash_db.MSet(ctx, args_[1], field_values_, false, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -260,10 +260,10 @@ class CommandHMSet : public Commander { class CommandHKeys : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Hash hash_db(srv->storage, conn->GetNamespace()); std::vector field_values; - engine::Context ctx(srv->storage); + auto s = hash_db.GetAll(ctx, args_[1], &field_values, HashFetchType::kOnlyKey); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -282,10 +282,10 @@ class CommandHKeys : public Commander { class CommandHVals : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Hash hash_db(srv->storage, conn->GetNamespace()); std::vector field_values; - engine::Context ctx(srv->storage); + auto s = hash_db.GetAll(ctx, args_[1], &field_values, HashFetchType::kOnlyValue); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -304,10 +304,10 @@ class CommandHVals : public Commander { class CommandHGetAll : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Hash hash_db(srv->storage, conn->GetNamespace()); std::vector field_values; - engine::Context ctx(srv->storage); + auto s = hash_db.GetAll(ctx, args_[1], &field_values); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -346,10 +346,10 @@ class CommandHRangeByLex : public Commander { } } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Hash hash_db(srv->storage, conn->GetNamespace()); std::vector field_values; - engine::Context ctx(srv->storage); + rocksdb::Status s = hash_db.RangeByLex(ctx, args_[1], spec_, &field_values); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -371,12 +371,12 @@ class CommandHRangeByLex : public Commander { class CommandHScan : public CommandSubkeyScanBase { public: CommandHScan() = default; - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Hash hash_db(srv->storage, conn->GetNamespace()); std::vector fields; std::vector values; auto key_name = srv->GetKeyNameFromCursor(cursor_, CursorType::kTypeHash); - engine::Context ctx(srv->storage); + auto s = hash_db.Scan(ctx, key_, key_name, limit_, prefix_, &fields, &values); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -414,11 +414,10 @@ class CommandHRandField : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Hash hash_db(srv->storage, conn->GetNamespace()); std::vector field_values; - engine::Context ctx(srv->storage); auto s = hash_db.RandField(ctx, args_[1], command_count_, &field_values, withvalues_ ? HashFetchType::kAll : HashFetchType::kOnlyKey); if (!s.ok() && !s.IsNotFound()) { diff --git a/src/commands/cmd_hll.cc b/src/commands/cmd_hll.cc index 2e2c246254b..35f6889dd85 100644 --- a/src/commands/cmd_hll.cc +++ b/src/commands/cmd_hll.cc @@ -33,7 +33,7 @@ namespace redis { /// Complexity: O(1) for each element added. class CommandPfAdd final : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::HyperLogLog hll(srv->storage, conn->GetNamespace()); DCHECK_GE(args_.size(), 2u); std::vector hashes(args_.size() - 2); @@ -41,7 +41,7 @@ class CommandPfAdd final : public Commander { hashes[i - 2] = redis::HyperLogLog::HllHash(args_[i]); } uint64_t ret{}; - engine::Context ctx(srv->storage); + auto s = hll.Add(ctx, args_[1], hashes, &ret); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -56,13 +56,13 @@ class CommandPfAdd final : public Commander { /// O(N) with N being the number of keys, and much bigger constant times, /// when called with multiple keys. class CommandPfCount final : public Commander { - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::HyperLogLog hll(srv->storage, conn->GetNamespace()); uint64_t ret{}; rocksdb::Status s; // The first argument is the command name, so we need to skip it. DCHECK_GE(args_.size(), 2u); - engine::Context ctx(srv->storage); + if (args_.size() > 2) { std::vector keys(args_.begin() + 1, args_.end()); s = hll.CountMultiple(ctx, keys, &ret); @@ -84,11 +84,11 @@ class CommandPfCount final : public Commander { /// /// complexity: O(N) to merge N HyperLogLogs, but with high constant times. class CommandPfMerge final : public Commander { - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::HyperLogLog hll(srv->storage, conn->GetNamespace()); DCHECK_GT(args_.size(), 1u); std::vector src_user_keys(args_.begin() + 2, args_.end()); - engine::Context ctx(srv->storage); + auto s = hll.Merge(ctx, /*dest_user_key=*/args_[1], src_user_keys); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; diff --git a/src/commands/cmd_json.cc b/src/commands/cmd_json.cc index 1b9c1b32511..7f9de307ccd 100644 --- a/src/commands/cmd_json.cc +++ b/src/commands/cmd_json.cc @@ -55,9 +55,9 @@ std::string SizeToString(const std::vector &elems) { class CommandJsonSet : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Json json(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = json.Set(ctx, args_[1], args_[2], args_[3]); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -102,11 +102,11 @@ class CommandJsonGet : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Json json(srv->storage, conn->GetNamespace()); JsonValue result; - engine::Context ctx(srv->storage); + auto s = json.Get(ctx, args_[1], paths_, &result); if (s.IsNotFound()) { *output = conn->NilString(); @@ -128,11 +128,11 @@ class CommandJsonGet : public Commander { class CommandJsonInfo : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Json json(srv->storage, conn->GetNamespace()); auto storage_format = JsonStorageFormat::JSON; - engine::Context ctx(srv->storage); + auto s = json.Info(ctx, args_[1], &storage_format); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -146,12 +146,11 @@ class CommandJsonInfo : public Commander { class CommandJsonArrAppend : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Json json(srv->storage, conn->GetNamespace()); Optionals results; - engine::Context ctx(srv->storage); auto s = json.ArrAppend(ctx, args_[1], args_[2], {args_.begin() + 3, args_.end()}, &results); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -172,13 +171,12 @@ class CommandJsonArrInsert : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Json json(srv->storage, conn->GetNamespace()); Optionals results; auto parse_result = ParseInt(args_[3], 10); - engine::Context ctx(srv->storage); auto s = json.ArrInsert(ctx, args_[1], args_[2], index_, {args_.begin() + 4, args_.end()}, &results); if (s.IsNotFound()) { *output = conn->NilString(); @@ -196,7 +194,7 @@ class CommandJsonArrInsert : public Commander { class CommandJsonType : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Json json(srv->storage, conn->GetNamespace()); std::vector types; @@ -207,7 +205,7 @@ class CommandJsonType : public Commander { } else if (args_.size() > 3) { return {Status::RedisExecErr, "The number of arguments is more than expected"}; } - engine::Context ctx(srv->storage); + auto s = json.Type(ctx, args_[1], path, &types); if (!s.ok() && !s.IsNotFound()) return {Status::RedisExecErr, s.ToString()}; if (s.IsNotFound()) { @@ -222,14 +220,14 @@ class CommandJsonType : public Commander { class CommandJsonObjkeys : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Json json(srv->storage, conn->GetNamespace()); Optionals> results; // If path not specified set it to $ std::string path = (args_.size() > 2) ? args_[2] : "$"; - engine::Context ctx(srv->storage); + auto s = json.ObjKeys(ctx, args_[1], path, &results); if (!s.ok() && !s.IsNotFound()) return {Status::RedisExecErr, s.ToString()}; if (s.IsNotFound()) { @@ -252,14 +250,14 @@ class CommandJsonObjkeys : public Commander { class CommandJsonClear : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); size_t result = 0; // If path not specified set it to $ std::string path = (args_.size() > 2) ? args_[2] : "$"; - engine::Context ctx(svr->storage); + auto s = json.Clear(ctx, args_[1], path, &result); if (s.IsNotFound()) { @@ -276,12 +274,12 @@ class CommandJsonClear : public Commander { class CommandJsonToggle : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); std::string path = (args_.size() > 2) ? args_[2] : "$"; Optionals results; - engine::Context ctx(svr->storage); + auto s = json.Toggle(ctx, args_[1], path, &results); if (!s.ok() && !s.IsNotFound()) return {Status::RedisExecErr, s.ToString()}; if (s.IsNotFound()) { @@ -296,7 +294,7 @@ class CommandJsonToggle : public Commander { class CommandJsonArrLen : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); std::string path = "$"; @@ -307,7 +305,7 @@ class CommandJsonArrLen : public Commander { } Optionals results; - engine::Context ctx(svr->storage); + auto s = json.ArrLen(ctx, args_[1], path, &results); if (s.IsNotFound()) { *output = conn->NilString(); @@ -322,14 +320,14 @@ class CommandJsonArrLen : public Commander { class CommandJsonMerge : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); std::string key = args_[1]; std::string path = args_[2]; std::string value = args_[3]; bool result = false; - engine::Context ctx(svr->storage); + auto s = json.Merge(ctx, key, path, value, result); if (!s.ok()) { @@ -360,11 +358,11 @@ class CommandJsonArrPop : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Json json(srv->storage, conn->GetNamespace()); Optionals results; - engine::Context ctx(srv->storage); + auto s = json.ArrPop(ctx, args_[1], path_, index_, &results); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -387,7 +385,7 @@ class CommandJsonArrPop : public Commander { class CommandJsonObjLen : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); std::string path = "$"; @@ -398,7 +396,7 @@ class CommandJsonObjLen : public Commander { } Optionals results; - engine::Context ctx(svr->storage); + auto s = json.ObjLen(ctx, args_[1], path, &results); if (s.IsNotFound()) { if (args_.size() == 2) { @@ -425,12 +423,11 @@ class CommandJsonArrTrim : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Json json(srv->storage, conn->GetNamespace()); Optionals results; - engine::Context ctx(srv->storage); auto s = json.ArrTrim(ctx, args_[1], path_, start_, stop_, &results); if (s.IsNotFound()) { @@ -466,12 +463,11 @@ class CommanderJsonArrIndex : public Commander { return Status::OK(); } - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); Optionals results; - engine::Context ctx(svr->storage); auto s = json.ArrIndex(ctx, args_[1], args_[2], args_[3], start_, end_, &results); if (s.IsNotFound()) { @@ -492,7 +488,7 @@ class CommanderJsonArrIndex : public Commander { class CommandJsonDel : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); size_t result = 0; std::string path = "$"; @@ -501,7 +497,7 @@ class CommandJsonDel : public Commander { } else if (args_.size() > 3) { return {Status::RedisExecErr, "The number of arguments is more than expected"}; } - engine::Context ctx(svr->storage); + auto s = json.Del(ctx, args_[1], path, &result); if (s.IsNotFound()) { *output = conn->NilString(); @@ -515,11 +511,11 @@ class CommandJsonDel : public Commander { class CommandJsonNumIncrBy : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); JsonValue result = JsonValue::FromString("[]").GetValue(); - engine::Context ctx(svr->storage); + auto s = json.NumIncrBy(ctx, args_[1], args_[2], args_[3], &result); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -533,11 +529,11 @@ class CommandJsonNumIncrBy : public Commander { class CommandJsonNumMultBy : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); JsonValue result = JsonValue::FromString("[]").GetValue(); - engine::Context ctx(svr->storage); + auto s = json.NumMultBy(ctx, args_[1], args_[2], args_[3], &result); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -551,7 +547,7 @@ class CommandJsonNumMultBy : public Commander { class CommandJsonStrAppend : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); // path default, if not provided @@ -563,7 +559,7 @@ class CommandJsonStrAppend : public Commander { } Optionals results; - engine::Context ctx(svr->storage); + auto s = json.StrAppend(ctx, args_[1], path, args_[3], &results); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -574,7 +570,7 @@ class CommandJsonStrAppend : public Commander { class CommandJsonStrLen : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); std::string path = "$"; @@ -585,7 +581,7 @@ class CommandJsonStrLen : public Commander { } Optionals results; - engine::Context ctx(svr->storage); + auto s = json.StrLen(ctx, args_[1], path, &results); if (s.IsNotFound()) { if (args_.size() == 2) { @@ -605,7 +601,7 @@ class CommandJsonStrLen : public Commander { class CommandJsonMGet : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); std::string path = args_[args_.size() - 1]; @@ -615,7 +611,7 @@ class CommandJsonMGet : public Commander { } std::vector json_values; - engine::Context ctx(svr->storage); + auto statuses = json.MGet(ctx, user_keys, path, json_values); std::vector values; @@ -634,7 +630,7 @@ class CommandJsonMGet : public Commander { class CommandJsonMSet : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { if ((args_.size() - 1) % 3 != 0) { return {Status::RedisExecErr, errWrongNumOfArguments}; } @@ -650,7 +646,6 @@ class CommandJsonMSet : public Commander { values.emplace_back(args_[i * 3 + 3]); } - engine::Context ctx(svr->storage); if (auto s = json.MSet(ctx, user_keys, paths, values); !s.ok()) return {Status::RedisExecErr, s.ToString()}; *output = redis::SimpleString("OK"); @@ -660,7 +655,7 @@ class CommandJsonMSet : public Commander { class CommandJsonDebug : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); std::string path = "$"; @@ -676,7 +671,7 @@ class CommandJsonDebug : public Commander { } std::vector results; - engine::Context ctx(svr->storage); + auto s = json.DebugMemory(ctx, args_[2], path, &results); if (s.IsNotFound()) { @@ -696,7 +691,7 @@ class CommandJsonDebug : public Commander { class CommandJsonResp : public Commander { public: - Status Execute(Server *svr, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *svr, Connection *conn, std::string *output) override { redis::Json json(svr->storage, conn->GetNamespace()); std::string path = "$"; @@ -706,7 +701,7 @@ class CommandJsonResp : public Commander { return {Status::RedisExecErr, "The number of arguments is more than expected"}; } std::vector results; - engine::Context ctx(svr->storage); + auto s = json.Resp(ctx, args_[1], path, &results, conn->GetProtocolVersion()); if (s.IsNotFound()) { *output = conn->NilString(); diff --git a/src/commands/cmd_key.cc b/src/commands/cmd_key.cc index 634437539eb..023db7ca16c 100644 --- a/src/commands/cmd_key.cc +++ b/src/commands/cmd_key.cc @@ -32,10 +32,10 @@ namespace redis { class CommandType : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); RedisType type = kRedisNone; - engine::Context ctx(srv->storage); + auto s = redis.Type(ctx, args_[1], &type); if (s.ok()) { if (type >= RedisTypeNames.size()) return {Status::RedisExecErr, "Invalid type"}; @@ -54,10 +54,10 @@ class CommandMove : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { int count = 0; redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + rocksdb::Status s = redis.Exists(ctx, {args_[1]}, &count); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -68,7 +68,7 @@ class CommandMove : public Commander { class CommandMoveX : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::string &key = args_[1], &token = args_[2]; redis::Database redis(srv->storage, conn->GetNamespace()); @@ -88,7 +88,7 @@ class CommandMoveX : public Commander { Database::CopyResult res = Database::CopyResult::DONE; std::string ns_key = redis.AppendNamespacePrefix(key); std::string new_ns_key = ComposeNamespaceKey(ns, key, srv->storage->IsSlotIdEncoded()); - engine::Context ctx(srv->storage); + auto s = redis.Copy(ctx, ns_key, new_ns_key, true, true, &res); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -103,11 +103,11 @@ class CommandMoveX : public Commander { class CommandObject : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (util::ToLower(args_[1]) == "dump") { redis::Database redis(srv->storage, conn->GetNamespace()); std::vector infos; - engine::Context ctx(srv->storage); + auto s = redis.Dump(ctx, args_[2], &infos); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -126,10 +126,10 @@ class CommandObject : public Commander { class CommandTTL : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); int64_t ttl = 0; - engine::Context ctx(srv->storage); + auto s = redis.TTL(ctx, args_[1], &ttl); if (s.ok()) { *output = redis::Integer(ttl > 0 ? ttl / 1000 : ttl); @@ -142,10 +142,10 @@ class CommandTTL : public Commander { class CommandPTTL : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); int64_t ttl = 0; - engine::Context ctx(srv->storage); + auto s = redis.TTL(ctx, args_[1], &ttl); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -156,7 +156,7 @@ class CommandPTTL : public Commander { class CommandExists : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector keys; keys.reserve(args_.size() - 1); for (size_t i = 1; i < args_.size(); i++) { @@ -165,7 +165,7 @@ class CommandExists : public Commander { int cnt = 0; redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = redis.Exists(ctx, keys, &cnt); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; *output = redis::Integer(cnt); @@ -181,9 +181,9 @@ class CommandExpire : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = redis.Expire(ctx, args_[1], ttl_ * 1000 + util::GetTimeStampMS()); if (s.ok()) { *output = redis::Integer(1); @@ -204,9 +204,9 @@ class CommandPExpire : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = redis.Expire(ctx, args_[1], seconds_); if (s.ok()) { *output = redis::Integer(1); @@ -233,9 +233,9 @@ class CommandExpireAt : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = redis.Expire(ctx, args_[1], timestamp_ * 1000); if (s.ok()) { *output = redis::Integer(1); @@ -262,9 +262,9 @@ class CommandPExpireAt : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = redis.Expire(ctx, args_[1], timestamp_); if (s.ok()) { *output = redis::Integer(1); @@ -280,10 +280,10 @@ class CommandPExpireAt : public Commander { class CommandExpireTime : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); uint64_t timestamp = 0; - engine::Context ctx(srv->storage); + auto s = redis.GetExpireTime(ctx, args_[1], ×tamp); if (s.ok()) { *output = timestamp > 0 ? redis::Integer(timestamp / 1000) : redis::Integer(-1); @@ -298,10 +298,10 @@ class CommandExpireTime : public Commander { class CommandPExpireTime : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); uint64_t timestamp = 0; - engine::Context ctx(srv->storage); + auto s = redis.GetExpireTime(ctx, args_[1], ×tamp); if (s.ok()) { *output = timestamp > 0 ? redis::Integer(timestamp) : redis::Integer(-1); @@ -316,10 +316,10 @@ class CommandPExpireTime : public Commander { class CommandPersist : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { int64_t ttl = 0; redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = redis.TTL(ctx, args_[1], &ttl); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -338,7 +338,7 @@ class CommandPersist : public Commander { class CommandDel : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector keys; keys.reserve(args_.size() - 1); for (size_t i = 1; i < args_.size(); i++) { @@ -347,7 +347,7 @@ class CommandDel : public Commander { uint64_t cnt = 0; redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = redis.MDel(ctx, keys, &cnt); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -358,12 +358,12 @@ class CommandDel : public Commander { class CommandRename : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); Database::CopyResult res = Database::CopyResult::DONE; std::string ns_key = redis.AppendNamespacePrefix(args_[1]); std::string new_ns_key = redis.AppendNamespacePrefix(args_[2]); - engine::Context ctx(srv->storage); + auto s = redis.Copy(ctx, ns_key, new_ns_key, false, true, &res); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; if (res == Database::CopyResult::KEY_NOT_EXIST) return {Status::RedisExecErr, "no such key"}; @@ -374,12 +374,12 @@ class CommandRename : public Commander { class CommandRenameNX : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); Database::CopyResult res = Database::CopyResult::DONE; std::string ns_key = redis.AppendNamespacePrefix(args_[1]); std::string new_ns_key = redis.AppendNamespacePrefix(args_[2]); - engine::Context ctx(srv->storage); + auto s = redis.Copy(ctx, ns_key, new_ns_key, true, true, &res); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; switch (res) { @@ -417,12 +417,12 @@ class CommandCopy : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); Database::CopyResult res = Database::CopyResult::DONE; std::string ns_key = redis.AppendNamespacePrefix(args_[1]); std::string new_ns_key = redis.AppendNamespacePrefix(args_[2]); - engine::Context ctx(srv->storage); + auto s = redis.Copy(ctx, ns_key, new_ns_key, !replace_, false, &res); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; switch (res) { @@ -490,9 +490,9 @@ class CommandSort : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + RedisType type = kRedisNone; if (auto s = redis.Type(ctx, args_[1], &type); !s.ok()) { return {Status::RedisExecErr, s.ToString()}; diff --git a/src/commands/cmd_list.cc b/src/commands/cmd_list.cc index 132ffcc5c57..0cc2f1210fd 100644 --- a/src/commands/cmd_list.cc +++ b/src/commands/cmd_list.cc @@ -33,7 +33,7 @@ class CommandPush : public Commander { public: CommandPush(bool create_if_missing, bool left) : left_(left), create_if_missing_(create_if_missing) {} - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector elems; for (size_t i = 2; i < args_.size(); i++) { elems.emplace_back(args_[i]); @@ -42,7 +42,7 @@ class CommandPush : public Commander { uint64_t ret = 0; rocksdb::Status s; redis::List list_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + if (create_if_missing_) { s = list_db.Push(ctx, args_[1], elems, left_, &ret); } else { @@ -110,9 +110,9 @@ class CommandPop : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::List list_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + if (with_count_) { std::vector elems; auto s = list_db.PopMulti(ctx, args_[1], left_, count_, &elems); @@ -194,12 +194,12 @@ class CommandLMPop : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::List list_db(srv->storage, conn->GetNamespace()); std::vector elems; std::string chosen_key; - engine::Context ctx(srv->storage); + for (auto &key : keys_) { auto s = list_db.PopMulti(ctx, key, left_, count_, &elems); if (!s.ok() && !s.IsNotFound()) { @@ -262,10 +262,10 @@ class CommandBPop : public BlockingCommander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { srv_ = srv; InitConnection(conn); - engine::Context ctx(srv->storage); + auto s = TryPopFromList(ctx); if (s.ok() || !s.IsNotFound()) { return Status::OK(); // error has already output in TryPopFromList @@ -383,10 +383,10 @@ class CommandBLMPop : public BlockingCommander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { srv_ = srv; InitConnection(conn); - engine::Context ctx(srv->storage); + auto s = ExecuteUnblocked(ctx); if (s.ok() || !s.IsNotFound()) { return Status::OK(); // error has already been output @@ -474,10 +474,10 @@ class CommandLRem : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t ret = 0; redis::List list_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = list_db.Rem(ctx, args_[1], count_, args_[3], &ret); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -504,10 +504,10 @@ class CommandLInsert : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { int ret = 0; redis::List list_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = list_db.Insert(ctx, args_[1], args_[3], args_[4], before_, &ret); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -535,10 +535,10 @@ class CommandLRange : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::List list_db(srv->storage, conn->GetNamespace()); std::vector elems; - engine::Context ctx(srv->storage); + auto s = list_db.Range(ctx, args_[1], start_, stop_, &elems); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -554,10 +554,9 @@ class CommandLRange : public Commander { class CommandLLen : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::List list_db(srv->storage, conn->GetNamespace()); uint64_t count = 0; - engine::Context ctx(srv->storage); auto s = list_db.Size(ctx, args_[1], &count); if (!s.ok() && !s.IsNotFound()) { @@ -581,10 +580,10 @@ class CommandLIndex : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::List list_db(srv->storage, conn->GetNamespace()); std::string elem; - engine::Context ctx(srv->storage); + auto s = list_db.Index(ctx, args_[1], index_, &elem); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -614,9 +613,9 @@ class CommandLSet : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::List list_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = list_db.Set(ctx, args_[1], index_, args_[3]); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -649,9 +648,9 @@ class CommandLTrim : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::List list_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = list_db.Trim(ctx, args_[1], start_, stop_); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -668,10 +667,10 @@ class CommandLTrim : public Commander { class CommandRPopLPUSH : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::List list_db(srv->storage, conn->GetNamespace()); std::string elem; - engine::Context ctx(srv->storage); + auto s = list_db.LMove(ctx, args_[1], args_[2], /*src_left=*/false, /*dst_left=*/true, &elem); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -700,10 +699,10 @@ class CommandLMove : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::List list_db(srv->storage, conn->GetNamespace()); std::string elem; - engine::Context ctx(srv->storage); + auto s = list_db.LMove(ctx, args_[1], args_[2], src_left_, dst_left_, &elem); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -745,13 +744,13 @@ class CommandBLMove : public BlockingCommander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { srv_ = srv; InitConnection(conn); redis::List list_db(srv->storage, conn->GetNamespace()); std::string elem; - engine::Context ctx(srv->storage); + auto s = list_db.LMove(ctx, args_[1], args_[2], src_left_, dst_left_, &elem); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -832,10 +831,10 @@ class CommandLPos : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::List list_db(srv->storage, conn->GetNamespace()); std::vector indexes; - engine::Context ctx(srv->storage); + auto s = list_db.Pos(ctx, args_[1], args_[2], spec_, &indexes); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; diff --git a/src/commands/cmd_pubsub.cc b/src/commands/cmd_pubsub.cc index f8c8ca01605..346dfebdd8a 100644 --- a/src/commands/cmd_pubsub.cc +++ b/src/commands/cmd_pubsub.cc @@ -27,13 +27,14 @@ namespace redis { class CommandPublish : public Commander { public: - Status Execute(Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, [[maybe_unused]] Connection *conn, + std::string *output) override { if (!srv->IsSlave()) { // Compromise: can't replicate a message to sub-replicas in a cascading-like structure. // Replication relies on WAL seq; increasing the seq on a replica will break the replication process, // hence the compromise solution redis::PubSub pubsub_db(srv->storage); - engine::Context ctx(srv->storage); + auto s = pubsub_db.Publish(ctx, args_[1], args_[2]); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -50,9 +51,9 @@ class CommandPublish : public Commander { class CommandMPublish : public Commander { public: - Status Execute(Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { int total_receivers = 0; - engine::Context ctx(srv->storage); + for (size_t i = 2; i < args_.size(); i++) { if (!srv->IsSlave()) { redis::PubSub pubsub_db(srv->storage); @@ -83,7 +84,8 @@ void SubscribeCommandReply(const Connection *conn, std::string *output, const st class CommandSubscribe : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { for (unsigned i = 1; i < args_.size(); i++) { conn->SubscribeChannel(args_[i]); SubscribeCommandReply(conn, output, "subscribe", args_[i], @@ -95,7 +97,8 @@ class CommandSubscribe : public Commander { class CommandUnSubscribe : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { if (args_.size() == 1) { conn->UnsubscribeAll([conn, output](const std::string &sub_name, int num) { SubscribeCommandReply(conn, output, "unsubscribe", sub_name, num); @@ -113,7 +116,8 @@ class CommandUnSubscribe : public Commander { class CommandPSubscribe : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { for (size_t i = 1; i < args_.size(); i++) { conn->PSubscribeChannel(args_[i]); SubscribeCommandReply(conn, output, "psubscribe", args_[i], @@ -125,7 +129,8 @@ class CommandPSubscribe : public Commander { class CommandPUnSubscribe : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { if (args_.size() == 1) { conn->PUnsubscribeAll([conn, output](const std::string &sub_name, int num) { SubscribeCommandReply(conn, output, "punsubscribe", sub_name, num); @@ -143,7 +148,7 @@ class CommandPUnSubscribe : public Commander { class CommandSSubscribe : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint16_t slot = 0; if (srv->GetConfig()->cluster_enabled) { slot = GetSlotIdFromKey(args_[1]); @@ -164,7 +169,7 @@ class CommandSSubscribe : public Commander { class CommandSUnSubscribe : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (args_.size() == 1) { conn->SUnsubscribeAll([conn, output](const std::string &sub_name, int num) { SubscribeCommandReply(conn, output, "sunsubscribe", sub_name, num); @@ -204,7 +209,7 @@ class CommandPubSub : public Commander { return {Status::RedisInvalidCmd, errUnknownSubcommandOrWrongArguments}; } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (subcommand_ == "numpat") { *output = redis::Integer(srv->GetPubSubPatternSize()); return Status::OK(); diff --git a/src/commands/cmd_replication.cc b/src/commands/cmd_replication.cc index cb2869e3426..387b212741a 100644 --- a/src/commands/cmd_replication.cc +++ b/src/commands/cmd_replication.cc @@ -56,7 +56,7 @@ class CommandPSync : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { LOG(INFO) << "Slave " << conn->GetAddr() << ", listening port: " << conn->GetListeningPort() << ", announce ip: " << conn->GetAnnounceIP() << " asks for synchronization" << " with next sequence: " << next_repl_seq_ @@ -186,7 +186,8 @@ class CommandReplConf : public Commander { return Status::OK(); } - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { if (port_ != 0) { conn->SetListeningPort(port_); } @@ -206,7 +207,8 @@ class CommandFetchMeta : public Commander { public: Status Parse([[maybe_unused]] const std::vector &args) override { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, [[maybe_unused]] std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, + [[maybe_unused]] std::string *output) override { int repl_fd = conn->GetFD(); std::string ip = conn->GetAnnounceIP(); @@ -262,7 +264,8 @@ class CommandFetchFile : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, [[maybe_unused]] std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, + [[maybe_unused]] std::string *output) override { std::vector files = util::Split(files_str_, ","); int repl_fd = conn->GetFD(); @@ -334,7 +337,8 @@ class CommandDBName : public Commander { public: Status Parse([[maybe_unused]] const std::vector &args) override { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, [[maybe_unused]] std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, + [[maybe_unused]] std::string *output) override { conn->Reply(srv->storage->GetName() + CRLF); return Status::OK(); } diff --git a/src/commands/cmd_script.cc b/src/commands/cmd_script.cc index ec440ba29f4..1eb85705ee4 100644 --- a/src/commands/cmd_script.cc +++ b/src/commands/cmd_script.cc @@ -29,7 +29,8 @@ namespace redis { template class CommandEvalImpl : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { if (evalsha && args_[1].size() != 40) { return {Status::RedisNoScript, errNoMatchingScript}; } @@ -62,7 +63,8 @@ class CommandScript : public Commander { return Status::OK(); } - Status Execute(Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, [[maybe_unused]] Connection *conn, + std::string *output) override { // There's a little tricky here since the script command was the write type // command but some subcommands like `exists` were readonly, so we want to allow // executing on slave here. Maybe we should find other way to do this. diff --git a/src/commands/cmd_search.cc b/src/commands/cmd_search.cc index b697e10c399..5d9e220e738 100644 --- a/src/commands/cmd_search.cc +++ b/src/commands/cmd_search.cc @@ -180,9 +180,9 @@ class CommandFTCreate : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { index_info_->ns = conn->GetNamespace(); - engine::Context ctx(srv->storage); + GET_OR_RET(srv->index_mgr.Create(ctx, std::move(index_info_))); output->append(redis::SimpleString("OK")); @@ -276,7 +276,7 @@ class CommandFTExplainSQL : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { auto plan = GET_OR_RET(srv->index_mgr.GeneratePlan(std::move(ir_), conn->GetNamespace())); if (format_ == SIMPLE) { @@ -307,7 +307,7 @@ class CommandFTSearchSQL : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { auto results = GET_OR_RET(srv->index_mgr.Search(std::move(ir_), conn->GetNamespace())); DumpQueryResult(results, output); @@ -385,7 +385,7 @@ class CommandFTExplain : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { CHECK(ir_); auto plan = GET_OR_RET(srv->index_mgr.GeneratePlan(std::move(ir_), conn->GetNamespace())); @@ -404,7 +404,7 @@ class CommandFTSearch : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { CHECK(ir_); auto results = GET_OR_RET(srv->index_mgr.Search(std::move(ir_), conn->GetNamespace())); @@ -418,7 +418,7 @@ class CommandFTSearch : public Commander { }; class CommandFTInfo : public Commander { - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { const auto &index_map = srv->index_mgr.index_map; const auto &index_name = args_[1]; @@ -466,7 +466,7 @@ class CommandFTInfo : public Commander { }; class CommandFTList : public Commander { - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { const auto &index_map = srv->index_mgr.index_map; std::vector results; @@ -483,10 +483,10 @@ class CommandFTList : public Commander { }; class CommandFTDrop : public Commander { - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { const auto &index_name = args_[1]; - GET_OR_RET(srv->index_mgr.Drop(index_name, conn->GetNamespace())); + GET_OR_RET(srv->index_mgr.Drop(ctx, index_name, conn->GetNamespace())); output->append(SimpleString("OK")); @@ -495,10 +495,9 @@ class CommandFTDrop : public Commander { }; class CommandFTTagVals : public Commander { - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { const auto &index_name = args_[1]; const auto &tag_field_name = args_[2]; - engine::Context ctx(srv->storage); auto field_values = GET_OR_RET(srv->index_mgr.FieldValues(ctx, index_name, tag_field_name, conn->GetNamespace())); std::vector result_vec(field_values.begin(), field_values.end()); diff --git a/src/commands/cmd_server.cc b/src/commands/cmd_server.cc index ded447ef9e7..c9529d76002 100644 --- a/src/commands/cmd_server.cc +++ b/src/commands/cmd_server.cc @@ -37,7 +37,7 @@ namespace redis { class CommandAuth : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { auto &user_password = args_[1]; std::string ns; AuthResult result = srv->AuthenticateUser(user_password, &ns); @@ -61,7 +61,7 @@ class CommandAuth : public Commander { class CommandNamespace : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (!conn->IsAdmin()) { return {Status::RedisExecErr, errAdminPermissionRequired}; } @@ -113,11 +113,11 @@ class CommandNamespace : public Commander { class CommandKeys : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::string prefix = args_[1]; std::vector keys; redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + rocksdb::Status s; if (prefix == "*") { s = redis.Keys(ctx, std::string(), &keys); @@ -138,7 +138,7 @@ class CommandKeys : public Commander { class CommandFlushDB : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (srv->GetConfig()->cluster_enabled) { if (srv->slot_migrator->IsMigrationInProgress()) { srv->slot_migrator->SetStopMigrationFlag(true); @@ -146,7 +146,7 @@ class CommandFlushDB : public Commander { } } redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = redis.FlushDB(ctx); LOG(WARNING) << "DB keys in namespace: " << conn->GetNamespace() << " was flushed, addr: " << conn->GetAddr(); if (s.ok()) { @@ -160,7 +160,7 @@ class CommandFlushDB : public Commander { class CommandFlushAll : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (!conn->IsAdmin()) { return {Status::RedisExecErr, errAdminPermissionRequired}; } @@ -173,7 +173,7 @@ class CommandFlushAll : public Commander { } redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = redis.FlushAll(ctx); if (s.ok()) { LOG(WARNING) << "All DB keys was flushed, addr: " << conn->GetAddr(); @@ -187,7 +187,8 @@ class CommandFlushAll : public Commander { class CommandPing : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, [[maybe_unused]] Connection *conn, + std::string *output) override { if (args_.size() == 1) { *output = redis::SimpleString("PONG"); } else if (args_.size() == 2) { @@ -201,7 +202,8 @@ class CommandPing : public Commander { class CommandSelect : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, [[maybe_unused]] Connection *conn, + std::string *output) override { *output = redis::SimpleString("OK"); return Status::OK(); } @@ -209,7 +211,7 @@ class CommandSelect : public Commander { class CommandConfig : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (!conn->IsAdmin()) { return {Status::RedisExecErr, errAdminPermissionRequired}; } @@ -247,7 +249,7 @@ class CommandConfig : public Commander { class CommandInfo : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::string section = "all"; if (args_.size() == 2) { section = util::ToLower(args_[1]); @@ -269,10 +271,10 @@ class CommandDisk : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { RedisType type = kRedisNone; redis::Disk disk_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = disk_db.Type(ctx, args_[2], &type); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -296,7 +298,8 @@ class CommandMemory : public CommandDisk {}; class CommandRole : public Commander { public: - Status Execute(Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, [[maybe_unused]] Connection *conn, + std::string *output) override { srv->GetRoleInfo(output); return Status::OK(); } @@ -304,7 +307,7 @@ class CommandRole : public Commander { class CommandDBSize : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::string ns = conn->GetNamespace(); if (args_.size() == 1) { KeyNumStats stats; @@ -343,7 +346,8 @@ class CommandPerfLog : public Commander { return Status::OK(); } - Status Execute(Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, [[maybe_unused]] Connection *conn, + std::string *output) override { auto perf_log = srv->GetPerfLog(); if (subcommand_ == "len") { *output = redis::Integer(static_cast(perf_log->Size())); @@ -380,7 +384,8 @@ class CommandSlowlog : public Commander { return Status::OK(); } - Status Execute(Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, [[maybe_unused]] Connection *conn, + std::string *output) override { auto slowlog = srv->GetSlowLog(); if (subcommand_ == "reset") { slowlog->Reset(); @@ -480,7 +485,7 @@ class CommandClient : public Commander { return {Status::RedisInvalidCmd, "Syntax error, try CLIENT LIST|INFO|KILL ip:port|GETNAME|SETNAME"}; } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (subcommand_ == "list") { *output = conn->VerbatimString("txt", srv->GetClientsStr()); return Status::OK(); @@ -527,7 +532,8 @@ class CommandClient : public Commander { class CommandMonitor : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { conn->Owner()->BecomeMonitorConn(conn); *output = redis::SimpleString("OK"); return Status::OK(); @@ -536,7 +542,8 @@ class CommandMonitor : public Commander { class CommandShutdown : public Commander { public: - Status Execute(Server *srv, Connection *conn, [[maybe_unused]] std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, + [[maybe_unused]] std::string *output) override { if (!conn->IsAdmin()) { return {Status::RedisExecErr, errAdminPermissionRequired}; } @@ -551,7 +558,8 @@ class CommandShutdown : public Commander { class CommandQuit : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { conn->EnableFlag(redis::Connection::kCloseAfterReply); *output = redis::SimpleString("OK"); return Status::OK(); @@ -585,7 +593,7 @@ class CommandDebug : public Commander { return {Status::RedisInvalidCmd, "Syntax error, DEBUG SLEEP |PROTOCOL |DBSIZE-LIMIT <0|1>"}; } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (subcommand_ == "sleep") { usleep(microsecond_); *output = redis::SimpleString("OK"); @@ -652,7 +660,8 @@ class CommandDebug : public Commander { class CommandCommand : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { if (args_.size() == 1) { CommandTable::GetAllCommandsInfo(output); } else { @@ -697,7 +706,8 @@ class CommandCommand : public Commander { class CommandEcho : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, [[maybe_unused]] Connection *conn, + std::string *output) override { *output = redis::BulkString(args_[1]); return Status::OK(); } @@ -705,7 +715,8 @@ class CommandEcho : public Commander { class CommandTime : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, [[maybe_unused]] Connection *conn, + std::string *output) override { uint64_t now = util::GetTimeStampUS(); uint64_t s = now / 1000 / 1000; // unix time in seconds. uint64_t us = now - (s * 1000 * 1000); // microseconds. @@ -725,7 +736,7 @@ class CommandTime : public Commander { */ class CommandHello final : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { size_t next_arg = 1; int protocol = 2; // default protocol version is 2 if (args_.size() >= 2) { @@ -835,13 +846,13 @@ class CommandScan : public CommandScanBase { return redis::Array(list); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Database redis_db(srv->storage, conn->GetNamespace()); auto key_name = srv->GetKeyNameFromCursor(cursor_, CursorType::kTypeBase); std::vector keys; std::string end_key; - engine::Context ctx(srv->storage); + auto s = redis_db.Scan(ctx, key_name, limit_, prefix_, &keys, &end_key, type_); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -853,11 +864,11 @@ class CommandScan : public CommandScanBase { class CommandRandomKey : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::string key; auto cursor = srv->GetLastRandomKeyCursor(); redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = redis.RandomKey(ctx, cursor, &key); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -870,7 +881,7 @@ class CommandRandomKey : public Commander { class CommandCompact : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::string begin_key, end_key; auto ns = conn->GetNamespace(); if (ns != kDefaultNamespace) { @@ -889,7 +900,7 @@ class CommandCompact : public Commander { class CommandBGSave : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (!conn->IsAdmin()) { return {Status::RedisExecErr, errAdminPermissionRequired}; } @@ -905,7 +916,7 @@ class CommandBGSave : public Commander { class CommandFlushBackup : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (!conn->IsAdmin()) { return {Status::RedisExecErr, errAdminPermissionRequired}; } @@ -956,7 +967,7 @@ class CommandSlaveOf : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (srv->GetConfig()->cluster_enabled) { return {Status::RedisExecErr, "can't change to slave in cluster mode"}; } @@ -1011,7 +1022,8 @@ class CommandSlaveOf : public Commander { class CommandStats : public Commander { public: - Status Execute(Server *srv, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, [[maybe_unused]] Connection *conn, + std::string *output) override { std::string stats_json = srv->GetRocksDBStatsJson(); *output = redis::BulkString(stats_json); return Status::OK(); @@ -1028,7 +1040,7 @@ static uint64_t GenerateConfigFlag(uint64_t flags, const std::vectorIsAdmin()) { return {Status::RedisExecErr, errAdminPermissionRequired}; } @@ -1068,10 +1080,10 @@ class CommandRestore : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { rocksdb::Status db_status; redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + if (!replace_) { int count = 0; db_status = redis.Exists(ctx, {args_[1]}, &count); @@ -1136,13 +1148,12 @@ class CommandRdb : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (!conn->IsAdmin()) { return {Status::RedisExecErr, errAdminPermissionRequired}; } redis::Database redis(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); auto stream_ptr = std::make_unique(path_); GET_OR_RET(stream_ptr->Open()); @@ -1163,7 +1174,7 @@ class CommandRdb : public Commander { class CommandReset : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { // 1. Discards the current MULTI transaction block, if one exists. if (conn->IsFlagEnabled(Connection::kMultiExec)) { conn->ResetMultiExec(); @@ -1210,7 +1221,8 @@ class CommandApplyBatch : public Commander { return Commander::Parse(args); } - Status Execute(Server *svr, [[maybe_unused]] Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *svr, [[maybe_unused]] Connection *conn, + std::string *output) override { size_t size = raw_batch_.size(); auto options = svr->storage->DefaultWriteOptions(); options.low_pri = low_pri_; @@ -1235,12 +1247,12 @@ class CommandDump : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { rocksdb::Status db_status; std::string &key = args_[1]; redis::Database redis(srv->storage, conn->GetNamespace()); int count = 0; - engine::Context ctx(srv->storage); + db_status = redis.Exists(ctx, {key}, &count); if (!db_status.ok()) { if (db_status.IsNotFound()) { @@ -1294,7 +1306,7 @@ class CommandPollUpdates : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t next_sequence = sequence_; // sequence + 1 is for excluding the current sequence to avoid getting duplicate updates auto batches = GET_OR_RET(srv->PollUpdates(sequence_ + 1, max_, is_strict_)); diff --git a/src/commands/cmd_set.cc b/src/commands/cmd_set.cc index b2ed58e6657..e80dcfe117e 100644 --- a/src/commands/cmd_set.cc +++ b/src/commands/cmd_set.cc @@ -30,7 +30,7 @@ namespace redis { class CommandSAdd : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector members; for (unsigned int i = 2; i < args_.size(); i++) { members.emplace_back(args_[i]); @@ -38,7 +38,7 @@ class CommandSAdd : public Commander { uint64_t ret = 0; redis::Set set_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = set_db.Add(ctx, args_[1], members, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -51,7 +51,7 @@ class CommandSAdd : public Commander { class CommandSRem : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector members; for (size_t i = 2; i < args_.size(); i++) { members.emplace_back(args_[i]); @@ -59,7 +59,7 @@ class CommandSRem : public Commander { uint64_t ret = 0; redis::Set set_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = set_db.Remove(ctx, args_[1], members, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -72,10 +72,10 @@ class CommandSRem : public Commander { class CommandSCard : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Set set_db(srv->storage, conn->GetNamespace()); uint64_t ret = 0; - engine::Context ctx(srv->storage); + auto s = set_db.Card(ctx, args_[1], &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -88,10 +88,10 @@ class CommandSCard : public Commander { class CommandSMembers : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Set set_db(srv->storage, conn->GetNamespace()); std::vector members; - engine::Context ctx(srv->storage); + auto s = set_db.Members(ctx, args_[1], &members); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -104,10 +104,10 @@ class CommandSMembers : public Commander { class CommandSIsMember : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Set set_db(srv->storage, conn->GetNamespace()); bool ret = false; - engine::Context ctx(srv->storage); + auto s = set_db.IsMember(ctx, args_[1], args_[2], &ret); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -120,7 +120,7 @@ class CommandSIsMember : public Commander { class CommandSMIsMember : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Set set_db(srv->storage, conn->GetNamespace()); std::vector members; for (size_t i = 2; i < args_.size(); i++) { @@ -128,7 +128,7 @@ class CommandSMIsMember : public Commander { } std::vector exists; - engine::Context ctx(srv->storage); + auto s = set_db.MIsMember(ctx, args_[1], members, &exists); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -168,10 +168,10 @@ class CommandSPop : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Set set_db(srv->storage, conn->GetNamespace()); std::vector members; - engine::Context ctx(srv->storage); + auto s = set_db.Take(ctx, args_[1], &members, count_, true); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -211,10 +211,10 @@ class CommandSRandMember : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Set set_db(srv->storage, conn->GetNamespace()); std::vector members; - engine::Context ctx(srv->storage); + auto s = set_db.Take(ctx, args_[1], &members, count_, false); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -229,10 +229,10 @@ class CommandSRandMember : public Commander { class CommandSMove : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Set set_db(srv->storage, conn->GetNamespace()); bool ret = false; - engine::Context ctx(srv->storage); + auto s = set_db.Move(ctx, args_[1], args_[2], args_[3], &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -245,7 +245,7 @@ class CommandSMove : public Commander { class CommandSDiff : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector keys; for (size_t i = 1; i < args_.size(); i++) { keys.emplace_back(args_[i]); @@ -253,7 +253,7 @@ class CommandSDiff : public Commander { std::vector members; redis::Set set_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = set_db.Diff(ctx, keys, &members); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -266,7 +266,7 @@ class CommandSDiff : public Commander { class CommandSUnion : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector keys; for (size_t i = 1; i < args_.size(); i++) { keys.emplace_back(args_[i]); @@ -274,7 +274,7 @@ class CommandSUnion : public Commander { std::vector members; redis::Set set_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = set_db.Union(ctx, keys, &members); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -287,7 +287,7 @@ class CommandSUnion : public Commander { class CommandSInter : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector keys; for (size_t i = 1; i < args_.size(); i++) { keys.emplace_back(args_[i]); @@ -295,7 +295,7 @@ class CommandSInter : public Commander { std::vector members; redis::Set set_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = set_db.Inter(ctx, keys, &members); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -345,7 +345,7 @@ class CommandSInterCard : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector keys; for (size_t i = 2; i < numkeys_ + 2; i++) { keys.emplace_back(args_[i]); @@ -353,7 +353,7 @@ class CommandSInterCard : public Commander { redis::Set set_db(srv->storage, conn->GetNamespace()); uint64_t ret = 0; - engine::Context ctx(srv->storage); + auto s = set_db.InterCard(ctx, keys, limit_, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -375,7 +375,7 @@ class CommandSInterCard : public Commander { class CommandSDiffStore : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector keys; for (size_t i = 2; i < args_.size(); i++) { keys.emplace_back(args_[i]); @@ -383,7 +383,7 @@ class CommandSDiffStore : public Commander { uint64_t ret = 0; redis::Set set_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = set_db.DiffStore(ctx, args_[1], keys, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -396,7 +396,7 @@ class CommandSDiffStore : public Commander { class CommandSUnionStore : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector keys; for (size_t i = 2; i < args_.size(); i++) { keys.emplace_back(args_[i]); @@ -404,7 +404,7 @@ class CommandSUnionStore : public Commander { uint64_t ret = 0; redis::Set set_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = set_db.UnionStore(ctx, args_[1], keys, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -417,7 +417,7 @@ class CommandSUnionStore : public Commander { class CommandSInterStore : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector keys; for (size_t i = 2; i < args_.size(); i++) { keys.emplace_back(args_[i]); @@ -425,7 +425,7 @@ class CommandSInterStore : public Commander { uint64_t ret = 0; redis::Set set_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = set_db.InterStore(ctx, args_[1], keys, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -439,11 +439,11 @@ class CommandSInterStore : public Commander { class CommandSScan : public CommandSubkeyScanBase { public: CommandSScan() = default; - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Set set_db(srv->storage, conn->GetNamespace()); std::vector members; auto key_name = srv->GetKeyNameFromCursor(cursor_, CursorType::kTypeSet); - engine::Context ctx(srv->storage); + auto s = set_db.Scan(ctx, key_, key_name, limit_, prefix_, &members); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; diff --git a/src/commands/cmd_sortedint.cc b/src/commands/cmd_sortedint.cc index ae8cea9377d..3aad69f95fe 100644 --- a/src/commands/cmd_sortedint.cc +++ b/src/commands/cmd_sortedint.cc @@ -39,10 +39,10 @@ class CommandSortedintAdd : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Sortedint sortedint_db(srv->storage, conn->GetNamespace()); uint64_t ret = 0; - engine::Context ctx(srv->storage); + auto s = sortedint_db.Add(ctx, args_[1], ids_, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -70,10 +70,10 @@ class CommandSortedintRem : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Sortedint sortedint_db(srv->storage, conn->GetNamespace()); uint64_t ret = 0; - engine::Context ctx(srv->storage); + auto s = sortedint_db.Remove(ctx, args_[1], ids_, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -89,10 +89,10 @@ class CommandSortedintRem : public Commander { class CommandSortedintCard : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Sortedint sortedint_db(srv->storage, conn->GetNamespace()); uint64_t ret = 0; - engine::Context ctx(srv->storage); + auto s = sortedint_db.Card(ctx, args_[1], &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -105,7 +105,7 @@ class CommandSortedintCard : public Commander { class CommandSortedintExists : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Sortedint sortedint_db(srv->storage, conn->GetNamespace()); std::vector ids; for (size_t i = 2; i < args_.size(); i++) { @@ -118,7 +118,7 @@ class CommandSortedintExists : public Commander { } std::vector exists; - engine::Context ctx(srv->storage); + auto s = sortedint_db.MExist(ctx, args_[1], ids, &exists); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -166,10 +166,10 @@ class CommandSortedintRange : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Sortedint sortedint_db(srv->storage, conn->GetNamespace()); std::vector ids; - engine::Context ctx(srv->storage); + auto s = sortedint_db.Range(ctx, args_[1], cursor_id_, offset_, limit_, reversed_, &ids); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -228,11 +228,11 @@ class CommandSortedintRangeByValue : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector ids; int size = 0; redis::Sortedint sortedint_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = sortedint_db.RangeByValue(ctx, args_[1], spec_, &ids, &size); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; diff --git a/src/commands/cmd_stream.cc b/src/commands/cmd_stream.cc index 9a9c02a64c7..3345c3b8461 100644 --- a/src/commands/cmd_stream.cc +++ b/src/commands/cmd_stream.cc @@ -49,10 +49,10 @@ class CommandXAck : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); uint64_t acknowledged = 0; - engine::Context ctx(srv->storage); + auto s = stream_db.DeletePelEntries(ctx, stream_name_, group_name_, entry_ids_, &acknowledged); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -165,7 +165,7 @@ class CommandXAdd : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::StreamAddOptions options; options.nomkstream = nomkstream_; if (with_max_len_) { @@ -180,7 +180,7 @@ class CommandXAdd : public Commander { redis::Stream stream_db(srv->storage, conn->GetNamespace()); StreamEntryID entry_id; - engine::Context ctx(srv->storage); + auto s = stream_db.Add(ctx, stream_name_, options, name_value_pairs_, &entry_id); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -224,10 +224,10 @@ class CommandXDel : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); uint64_t deleted = 0; - engine::Context ctx(srv->storage); + auto s = stream_db.DeleteEntries(ctx, args_[1], ids_, &deleted); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -319,10 +319,10 @@ class CommandXClaim : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); StreamClaimResult result; - engine::Context ctx(srv->storage); + auto s = stream_db.ClaimPelEntries(ctx, stream_name_, group_name_, consumer_name_, min_idle_time_ms_, entry_ids_, stream_claim_options_, &result); if (!s.ok()) { @@ -409,10 +409,10 @@ class CommandAutoClaim : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); StreamAutoClaimResult result; - engine::Context ctx(srv->storage); + auto s = stream_db.AutoClaim(ctx, key_name_, group_name_, consumer_name_, options_, &result); if (!s.ok()) { if (s.IsNotFound()) { @@ -535,11 +535,9 @@ class CommandXGroup : public Commander { return {Status::RedisParseErr, "unknown subcommand"}; } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); - if (subcommand_ == "create") { auto s = stream_db.CreateGroup(ctx, stream_name_, xgroup_create_options_, group_name_); if (!s.ok()) { @@ -638,10 +636,10 @@ class CommandXLen : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); uint64_t len = 0; - engine::Context ctx(srv->storage); + auto s = stream_db.Len(ctx, args_[1], options_, &len); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -686,17 +684,17 @@ class CommandXInfo : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (subcommand_ == "stream") { - return getStreamInfo(srv, conn, output); + return getStreamInfo(ctx, srv, conn, output); } if (subcommand_ == "groups") { - return getGroupInfo(srv, conn, output); + return getGroupInfo(ctx, srv, conn, output); } if (subcommand_ == "consumers") { - return getConsumerInfo(srv, conn, output); + return getConsumerInfo(ctx, srv, conn, output); } return Status::OK(); } @@ -706,10 +704,10 @@ class CommandXInfo : public Commander { std::string subcommand_; bool full_ = false; - Status getStreamInfo(Server *srv, Connection *conn, std::string *output) { + Status getStreamInfo(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) { redis::Stream stream_db(srv->storage, conn->GetNamespace()); redis::StreamInfo info; - engine::Context ctx(srv->storage); + auto s = stream_db.GetStreamInfo(ctx, args_[2], full_, count_, &info); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -764,10 +762,10 @@ class CommandXInfo : public Commander { return Status::OK(); } - Status getGroupInfo(Server *srv, Connection *conn, std::string *output) { + Status getGroupInfo(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) { redis::Stream stream_db(srv->storage, conn->GetNamespace()); std::vector> result_vector; - engine::Context ctx(srv->storage); + auto s = stream_db.GetGroupInfo(ctx, args_[2], result_vector); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -805,10 +803,10 @@ class CommandXInfo : public Commander { return Status::OK(); } - Status getConsumerInfo(Server *srv, Connection *conn, std::string *output) { + Status getConsumerInfo(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) { redis::Stream stream_db(srv->storage, conn->GetNamespace()); std::vector> result_vector; - engine::Context ctx(srv->storage); + auto s = stream_db.GetConsumerInfo(ctx, args_[2], args_[3], result_vector); if (!s.ok() && !s.IsNotFound()) { @@ -876,14 +874,14 @@ class CommandXPending : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); std::vector> pending_infos; StreamGetPendingEntryResult results; options_.stream_name = stream_name_; options_.group_name = group_name_; std::vector ext_results; - engine::Context ctx(srv->storage); + auto s = stream_db.GetPendingEntries(ctx, options_, results, ext_results); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -992,7 +990,7 @@ class CommandXRange : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (with_count_ && count_ == 0) { *output = conn->NilString(); return Status::OK(); @@ -1010,7 +1008,7 @@ class CommandXRange : public Commander { options.exclude_end = exclude_end_; std::vector result; - engine::Context ctx(srv->storage); + auto s = stream_db.Range(ctx, stream_name_, options, &result); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1086,7 +1084,7 @@ class CommandXRevRange : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (with_count_ && count_ == 0) { *output = conn->NilString(); return Status::OK(); @@ -1104,7 +1102,7 @@ class CommandXRevRange : public Commander { options.exclude_end = exclude_end_; std::vector result; - engine::Context ctx(srv->storage); + auto s = stream_db.Range(ctx, stream_name_, options, &result); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1215,11 +1213,10 @@ class CommandXRead : public Commander, return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); std::vector results; - engine::Context ctx(srv->storage); for (size_t i = 0; i < streams_.size(); ++i) { if (latest_marks_[i]) { @@ -1252,7 +1249,7 @@ class CommandXRead : public Commander, return Status::OK(); // No blocking in multi-exec } - return BlockingRead(ctx, srv, conn, &stream_db); + return BlockingRead(srv, conn, &stream_db); } if (!block_ && results.empty()) { @@ -1280,8 +1277,7 @@ class CommandXRead : public Commander, return Status::OK(); } - Status BlockingRead([[maybe_unused]] const engine::Context &ctx, Server *srv, Connection *conn, - redis::Stream *stream_db) { + Status BlockingRead(Server *srv, Connection *conn, redis::Stream *stream_db) { if (!with_count_) { with_count_ = true; count_ = blocked_default_count_; @@ -1520,9 +1516,9 @@ class CommandXReadGroup : public Commander, return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + std::vector results; for (size_t i = 0; i < streams_.size(); ++i) { @@ -1799,7 +1795,7 @@ class CommandXTrim : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); StreamTrimOptions options; @@ -1808,7 +1804,7 @@ class CommandXTrim : public Commander { options.min_id = min_id_; uint64_t removed = 0; - engine::Context ctx(srv->storage); + auto s = stream_db.Trim(ctx, args_[1], options, &removed); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1861,10 +1857,9 @@ class CommandXSetId : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::Stream stream_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); auto s = stream_db.SetId(ctx, stream_name_, last_id_, entries_added_, max_deleted_id_); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; diff --git a/src/commands/cmd_string.cc b/src/commands/cmd_string.cc index 612fe5e1fc1..1322c74b7b9 100644 --- a/src/commands/cmd_string.cc +++ b/src/commands/cmd_string.cc @@ -38,10 +38,10 @@ namespace redis { class CommandGet : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::string value; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.Get(ctx, args_[1], &value); // The IsInvalidArgument error means the key type maybe a bitmap // which we need to fall back to the bitmap's GetString according @@ -78,9 +78,9 @@ class CommandGetEx : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::string value; - engine::Context ctx(srv->storage); + redis::String string_db(srv->storage, conn->GetNamespace()); auto s = string_db.GetEx(ctx, args_[1], &value, expire_); @@ -110,10 +110,10 @@ class CommandGetEx : public Commander { class CommandStrlen : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::string value; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.Get(ctx, args_[1], &value); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -130,10 +130,10 @@ class CommandStrlen : public Commander { class CommandGetSet : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::String string_db(srv->storage, conn->GetNamespace()); std::optional old_value; - engine::Context ctx(srv->storage); + auto s = string_db.GetSet(ctx, args_[1], args_[2], old_value); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -150,10 +150,10 @@ class CommandGetSet : public Commander { class CommandGetDel : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::String string_db(srv->storage, conn->GetNamespace()); std::string value; - engine::Context ctx(srv->storage); + auto s = string_db.GetDel(ctx, args_[1], &value); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -182,10 +182,10 @@ class CommandGetRange : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::string value; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.Get(ctx, args_[1], &value); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -230,10 +230,10 @@ class CommandSetRange : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t ret = 0; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.SetRange(ctx, args_[1], offset_, args_[3], &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -249,7 +249,7 @@ class CommandSetRange : public Commander { class CommandMGet : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::String string_db(srv->storage, conn->GetNamespace()); std::vector keys; for (size_t i = 1; i < args_.size(); i++) { @@ -257,7 +257,7 @@ class CommandMGet : public Commander { } std::vector values; // always return OK - engine::Context ctx(srv->storage); + auto statuses = string_db.MGet(ctx, keys, &values); *output = conn->MultiBulkString(values, statuses); return Status::OK(); @@ -266,10 +266,10 @@ class CommandMGet : public Commander { class CommandAppend : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t ret = 0; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.Append(ctx, args_[1], args_[2], &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -304,11 +304,10 @@ class CommandSet : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::optional ret; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); rocksdb::Status s = string_db.Set(ctx, args_[1], args_[2], {expire_, set_flag_, get_, keep_ttl_}, ret); if (!s.ok()) { @@ -353,9 +352,9 @@ class CommandSetEX : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.SetEX(ctx, args_[1], args_[3], expire_); *output = redis::SimpleString("OK"); return Status::OK(); @@ -380,9 +379,9 @@ class CommandPSetEX : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.SetEX(ctx, args_[1], args_[3], expire_); *output = redis::SimpleString("OK"); return Status::OK(); @@ -402,13 +401,13 @@ class CommandMSet : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::String string_db(srv->storage, conn->GetNamespace()); std::vector kvs; for (size_t i = 1; i < args_.size(); i += 2) { kvs.emplace_back(StringPair{args_[i], args_[i + 1]}); } - engine::Context ctx(srv->storage); + auto s = string_db.MSet(ctx, kvs, 0); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -421,10 +420,10 @@ class CommandMSet : public Commander { class CommandSetNX : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { bool ret = false; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.SetNX(ctx, args_[1], args_[2], 0, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -445,7 +444,7 @@ class CommandMSetNX : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { bool ret = false; std::vector kvs; redis::String string_db(srv->storage, conn->GetNamespace()); @@ -453,7 +452,6 @@ class CommandMSetNX : public Commander { kvs.emplace_back(StringPair{args_[i], args_[i + 1]}); } - engine::Context ctx(srv->storage); auto s = string_db.MSetNX(ctx, kvs, 0, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -466,10 +464,10 @@ class CommandMSetNX : public Commander { class CommandIncr : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { int64_t ret = 0; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.IncrBy(ctx, args_[1], 1, &ret); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -480,10 +478,10 @@ class CommandIncr : public Commander { class CommandDecr : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { int64_t ret = 0; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.IncrBy(ctx, args_[1], -1, &ret); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -504,10 +502,10 @@ class CommandIncrBy : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { int64_t ret = 0; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.IncrBy(ctx, args_[1], increment_, &ret); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -531,10 +529,10 @@ class CommandIncrByFloat : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { double ret = 0; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.IncrByFloat(ctx, args_[1], increment_, &ret); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -564,10 +562,10 @@ class CommandDecrBy : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { int64_t ret = 0; redis::String string_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = string_db.IncrBy(ctx, args_[1], -1 * increment_, &ret); if (!s.ok()) return {Status::RedisExecErr, s.ToString()}; @@ -594,10 +592,10 @@ class CommandCAS : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::String string_db(srv->storage, conn->GetNamespace()); int ret = 0; - engine::Context ctx(srv->storage); + auto s = string_db.CAS(ctx, args_[1], args_[2], args_[3], expire_, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -613,10 +611,10 @@ class CommandCAS : public Commander { class CommandCAD : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::String string_db(srv->storage, conn->GetNamespace()); int ret = 0; - engine::Context ctx(srv->storage); + auto s = string_db.CAD(ctx, args_[1], args_[2], &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -666,11 +664,11 @@ class CommandLCS : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::String string_db(srv->storage, conn->GetNamespace()); StringLCSResult rst; - engine::Context ctx(srv->storage); + auto s = string_db.LCS(ctx, args_[1], args_[2], {type_, min_match_len_}, &rst); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; diff --git a/src/commands/cmd_txn.cc b/src/commands/cmd_txn.cc index 41bc823f056..2984d621c14 100644 --- a/src/commands/cmd_txn.cc +++ b/src/commands/cmd_txn.cc @@ -29,7 +29,8 @@ namespace redis { class CommandMulti : public Commander { public: - Status Execute([[maybe_unused]] Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, Connection *conn, + std::string *output) override { if (conn->IsFlagEnabled(Connection::kMultiExec)) { return {Status::RedisExecErr, "MULTI calls can not be nested"}; } @@ -43,7 +44,7 @@ class CommandMulti : public Commander { class CommandDiscard : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (!conn->IsFlagEnabled(Connection::kMultiExec)) { return {Status::RedisExecErr, "DISCARD without MULTI"}; } @@ -59,7 +60,7 @@ class CommandDiscard : public Commander { class CommandExec : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (!conn->IsFlagEnabled(Connection::kMultiExec)) { return {Status::RedisExecErr, "EXEC without MULTI"}; } @@ -92,7 +93,7 @@ class CommandExec : public Commander { class CommandWatch : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { if (conn->IsFlagEnabled(Connection::kMultiExec)) { return {Status::RedisExecErr, "WATCH inside MULTI is not allowed"}; } @@ -111,7 +112,7 @@ class CommandWatch : public Commander { class CommandUnwatch : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute([[maybe_unused]] engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { srv->ResetWatchedKeys(conn); *output = redis::SimpleString("OK"); return Status::OK(); diff --git a/src/commands/cmd_zset.cc b/src/commands/cmd_zset.cc index 51f1c6e0967..d26abb54b91 100644 --- a/src/commands/cmd_zset.cc +++ b/src/commands/cmd_zset.cc @@ -68,11 +68,11 @@ class CommandZAdd : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t ret = 0; double old_score = member_scores_[0].score; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.Add(ctx, args_[1], flags_, &member_scores_, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -141,10 +141,10 @@ class CommandZCount : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t ret = 0; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.Count(ctx, args_[1], spec_, &ret); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -160,10 +160,10 @@ class CommandZCount : public Commander { class CommandZCard : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t ret = 0; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.Card(ctx, args_[1], &ret); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -185,10 +185,10 @@ class CommandZIncrBy : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { double score = 0; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.IncrBy(ctx, args_[1], args_[3], incr_, &score); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -211,10 +211,10 @@ class CommandZLexCount : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t size = 0; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.RangeByLex(ctx, args_[1], spec_, nullptr, &size); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -248,10 +248,10 @@ class CommandZPop : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); std::vector member_scores; - engine::Context ctx(srv->storage); + auto s = zset_db.Pop(ctx, args_[1], count_, min_, &member_scores); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -318,7 +318,7 @@ class CommandBZPop : public BlockingCommander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { srv_ = srv; InitConnection(conn); @@ -326,7 +326,7 @@ class CommandBZPop : public BlockingCommander { std::vector member_scores; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = PopFromMultipleZsets(ctx, &zset_db, keys_, min_, 1, &user_key, &member_scores); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -445,9 +445,9 @@ class CommandZMPop : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + for (auto &user_key : keys_) { std::vector member_scores; auto s = zset_db.Pop(ctx, user_key, count_, flag_ == ZSET_MIN, &member_scores); @@ -512,7 +512,7 @@ class CommandBZMPop : public BlockingCommander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { srv_ = srv; InitConnection(conn); @@ -520,7 +520,7 @@ class CommandBZMPop : public BlockingCommander { std::vector member_scores; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = PopFromMultipleZsets(ctx, &zset_db, keys_, flag_ == ZSET_MIN, count_, &user_key, &member_scores); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -657,13 +657,13 @@ class CommandZRangeStore : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); std::vector member_scores; rocksdb::Status s; - engine::Context ctx(srv->storage); + switch (range_type_) { case kZRangeAuto: case kZRangeRank: @@ -795,12 +795,12 @@ class CommandZRangeGeneric : public Commander { return Status::OK(); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); std::vector member_scores; rocksdb::Status s; - engine::Context ctx(srv->storage); + switch (range_type_) { case kZRangeAuto: case kZRangeRank: @@ -900,11 +900,11 @@ class CommandZRank : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { int rank = 0; double score = 0.0; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.Rank(ctx, args_[1], args_[2], reversed_, &rank, &score); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -940,7 +940,7 @@ class CommandZRevRank : public CommandZRank { class CommandZRem : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector members; for (size_t i = 2; i < args_.size(); i++) { members.emplace_back(args_[i]); @@ -948,7 +948,7 @@ class CommandZRem : public Commander { uint64_t size = 0; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.Remove(ctx, args_[1], members, &size); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -974,13 +974,12 @@ class CommandZRemRangeByRank : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); uint64_t cnt = 0; spec_.with_deletion = true; - engine::Context ctx(srv->storage); auto s = zset_db.RangeByRank(ctx, args_[1], spec_, nullptr, &cnt); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1002,13 +1001,12 @@ class CommandZRemRangeByScore : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); uint64_t cnt = 0; spec_.with_deletion = true; - engine::Context ctx(srv->storage); auto s = zset_db.RangeByScore(ctx, args_[1], spec_, nullptr, &cnt); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1030,13 +1028,12 @@ class CommandZRemRangeByLex : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); uint64_t cnt = 0; spec_.with_deletion = true; - engine::Context ctx(srv->storage); auto s = zset_db.RangeByLex(ctx, args_[1], spec_, nullptr, &cnt); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1052,10 +1049,10 @@ class CommandZRemRangeByLex : public Commander { class CommandZScore : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { double score = 0; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.Score(ctx, args_[1], args_[2], &score); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -1072,14 +1069,14 @@ class CommandZScore : public Commander { class CommandZMScore : public Commander { public: - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { std::vector members; for (size_t i = 2; i < args_.size(); i++) { members.emplace_back(args_[i]); } std::map mscores; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.MGet(ctx, args_[1], members, &mscores); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -1143,10 +1140,10 @@ class CommandZUnion : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); std::vector member_scores; - engine::Context ctx(srv->storage); + auto s = zset_db.Union(ctx, keys_weights_, aggregate_method_, &member_scores); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1229,10 +1226,10 @@ class CommandZUnionStore : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t size = 0; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.UnionStore(ctx, args_[1], keys_weights_, aggregate_method_, &size); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1257,10 +1254,10 @@ class CommandZInterStore : public CommandZUnionStore { public: CommandZInterStore() : CommandZUnionStore() {} - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { uint64_t size = 0; redis::ZSet zset_db(srv->storage, conn->GetNamespace()); - engine::Context ctx(srv->storage); + auto s = zset_db.InterStore(ctx, args_[1], keys_weights_, aggregate_method_, &size); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1280,10 +1277,10 @@ class CommandZInter : public CommandZUnion { public: CommandZInter() : CommandZUnion() {} - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); std::vector member_scores; - engine::Context ctx(srv->storage); + auto s = zset_db.Inter(ctx, keys_weights_, aggregate_method_, &member_scores); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1336,10 +1333,10 @@ class CommandZInterCard : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); uint64_t count = 0; - engine::Context ctx(srv->storage); + auto s = zset_db.InterCard(ctx, keys_, limit_, &count); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1363,12 +1360,12 @@ class CommandZScan : public CommandSubkeyScanBase { public: CommandZScan() = default; - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); std::vector members; std::vector scores; auto key_name = srv->GetKeyNameFromCursor(cursor_, CursorType::kTypeZSet); - engine::Context ctx(srv->storage); + auto s = zset_db.Scan(ctx, key_, key_name, limit_, prefix_, &members, &scores); if (!s.ok() && !s.IsNotFound()) { return {Status::RedisExecErr, s.ToString()}; @@ -1415,10 +1412,10 @@ class CommandZRandMember : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); std::vector member_scores; - engine::Context ctx(srv->storage); + auto s = zset_db.RandMember(ctx, args_[1], count_, &member_scores); if (!s.ok() && !s.IsNotFound()) { @@ -1471,11 +1468,11 @@ class CommandZDiff : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); std::vector members_with_scores; - engine::Context ctx(srv->storage); + auto s = zset_db.Diff(ctx, keys_, &members_with_scores); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; @@ -1519,11 +1516,11 @@ class CommandZDiffStore : public Commander { return Commander::Parse(args); } - Status Execute(Server *srv, Connection *conn, std::string *output) override { + Status Execute(engine::Context &ctx, Server *srv, Connection *conn, std::string *output) override { redis::ZSet zset_db(srv->storage, conn->GetNamespace()); uint64_t stored_count = 0; - engine::Context ctx(srv->storage); + auto s = zset_db.DiffStore(ctx, args_[1], keys_, &stored_count); if (!s.ok()) { return {Status::RedisExecErr, s.ToString()}; diff --git a/src/commands/commander.h b/src/commands/commander.h index 9d8dd23932d..b0389d44eb0 100644 --- a/src/commands/commander.h +++ b/src/commands/commander.h @@ -46,6 +46,10 @@ class Server; +namespace engine { +struct Context; +} + namespace redis { class Connection; @@ -100,8 +104,8 @@ class Commander { void SetArgs(const std::vector &args) { args_ = args; } virtual Status Parse() { return Parse(args_); } virtual Status Parse([[maybe_unused]] const std::vector &args) { return Status::OK(); } - virtual Status Execute([[maybe_unused]] Server *srv, [[maybe_unused]] Connection *conn, - [[maybe_unused]] std::string *output) { + virtual Status Execute([[maybe_unused]] engine::Context &ctx, [[maybe_unused]] Server *srv, + [[maybe_unused]] Connection *conn, [[maybe_unused]] std::string *output) { return {Status::RedisExecErr, errNotImplemented}; } diff --git a/src/search/index_manager.h b/src/search/index_manager.h index aae3489ba11..eb5d5dcc30d 100644 --- a/src/search/index_manager.h +++ b/src/search/index_manager.h @@ -43,13 +43,12 @@ struct IndexManager { IndexManager(GlobalIndexer *indexer, engine::Storage *storage) : indexer(indexer), storage(storage) {} - Status Load(const std::string &ns) { + Status Load(engine::Context &ctx, const std::string &ns) { // currently index cannot work in cluster mode if (storage->GetConfig()->cluster_enabled) { return Status::OK(); } - auto no_txn_ctx = engine::Context::NoTransactionContext(storage); - util::UniqueIterator iter(no_txn_ctx, no_txn_ctx.DefaultScanOptions(), ColumnFamilyID::Search); + util::UniqueIterator iter(ctx, ctx.DefaultScanOptions(), ColumnFamilyID::Search); auto begin = SearchKey{ns, ""}.ConstructIndexMeta(); for (iter->Seek(begin); iter->Valid(); iter->Next()) { @@ -76,9 +75,8 @@ struct IndexManager { auto index_key = SearchKey(ns, index_name.ToStringView()); std::string prefix_value; - if (auto s = storage->Get(no_txn_ctx, no_txn_ctx.DefaultMultiGetOptions(), - storage->GetCFHandle(ColumnFamilyID::Search), index_key.ConstructIndexPrefixes(), - &prefix_value); + if (auto s = storage->Get(ctx, ctx.DefaultMultiGetOptions(), storage->GetCFHandle(ColumnFamilyID::Search), + index_key.ConstructIndexPrefixes(), &prefix_value); !s.ok()) { return {Status::NotOK, fmt::format("fail to find index prefixes for index {}: {}", index_name, s.ToString())}; } @@ -92,7 +90,7 @@ struct IndexManager { auto info = std::make_unique(index_name.ToString(), metadata, ns); info->prefixes = prefixes; - util::UniqueIterator field_iter(no_txn_ctx, no_txn_ctx.DefaultScanOptions(), ColumnFamilyID::Search); + util::UniqueIterator field_iter(ctx, ctx.DefaultScanOptions(), ColumnFamilyID::Search); auto field_begin = index_key.ConstructFieldMeta(); for (field_iter->Seek(field_begin); field_iter->Valid(); field_iter->Next()) { @@ -227,7 +225,7 @@ struct IndexManager { return results; } - Status Drop(std::string_view index_name, const std::string &ns) { + Status Drop(engine::Context &ctx, std::string_view index_name, const std::string &ns) { auto iter = index_map.Find(index_name, ns); if (iter == index_map.end()) { return {Status::NotOK, "index not found"}; @@ -264,8 +262,7 @@ struct IndexManager { return {Status::NotOK, s.ToString()}; } - auto no_txn_ctx = engine::Context::NoTransactionContext(storage); - if (auto s = storage->Write(no_txn_ctx, storage->DefaultWriteOptions(), batch->GetWriteBatch()); !s.ok()) { + if (auto s = storage->Write(ctx, storage->DefaultWriteOptions(), batch->GetWriteBatch()); !s.ok()) { return {Status::NotOK, fmt::format("failed to delete index metadata and data: {}", s.ToString())}; } diff --git a/src/server/redis_connection.cc b/src/server/redis_connection.cc index f7276249e4c..e742b1683c4 100644 --- a/src/server/redis_connection.cc +++ b/src/server/redis_connection.cc @@ -344,13 +344,14 @@ void Connection::RecordProfilingSampleIfNeed(const std::string &cmd, uint64_t du srv_->GetPerfLog()->PushEntry(std::move(entry)); } -Status Connection::ExecuteCommand(const std::string &cmd_name, const std::vector &cmd_tokens, - Commander *current_cmd, std::string *reply) { +Status Connection::ExecuteCommand(engine::Context &ctx, const std::string &cmd_name, + const std::vector &cmd_tokens, Commander *current_cmd, + std::string *reply) { srv_->stats.IncrCalls(cmd_name); auto start = std::chrono::high_resolution_clock::now(); bool is_profiling = IsProfilingEnabled(cmd_name); - auto s = current_cmd->Execute(srv_, this, reply); + auto s = current_cmd->Execute(ctx, srv_, this, reply); auto end = std::chrono::high_resolution_clock::now(); uint64_t duration = std::chrono::duration_cast(end - start).count(); if (is_profiling) RecordProfilingSampleIfNeed(cmd_name, duration); @@ -497,7 +498,7 @@ void Connection::ExecuteCommands(std::deque *to_process_cmds) { continue; } - auto no_txn_ctx = engine::Context::NoTransactionContext(srv_->storage); + engine::Context ctx(srv_->storage); // TODO: transaction support for index recording std::vector index_records; if (!srv_->index_mgr.index_map.empty() && IsCmdForIndexing(attributes) && !config->cluster_enabled) { @@ -505,7 +506,7 @@ void Connection::ExecuteCommands(std::deque *to_process_cmds) { [&, this](const std::vector &args, const CommandKeyRange &key_range) { key_range.ForEachKey( [&, this](const std::string &key) { - auto res = srv_->indexer.Record(no_txn_ctx, key, ns_); + auto res = srv_->indexer.Record(ctx, key, ns_); if (res.IsOK()) { index_records.push_back(*res); } else if (!res.Is() && !res.Is()) { @@ -518,11 +519,10 @@ void Connection::ExecuteCommands(std::deque *to_process_cmds) { } SetLastCmd(cmd_name); - s = ExecuteCommand(cmd_name, cmd_tokens, current_cmd.get(), &reply); - + s = ExecuteCommand(ctx, cmd_name, cmd_tokens, current_cmd.get(), &reply); // TODO: transaction support for index updating for (const auto &record : index_records) { - auto s = GlobalIndexer::Update(no_txn_ctx, record); + auto s = GlobalIndexer::Update(ctx, record); if (!s.IsOK() && !s.Is()) { LOG(WARNING) << "index updating failed for key: " << record.key; } diff --git a/src/server/redis_connection.h b/src/server/redis_connection.h index 83c57c013b4..e7d277f6e8b 100644 --- a/src/server/redis_connection.h +++ b/src/server/redis_connection.h @@ -160,8 +160,8 @@ class Connection : public EvbufCallbackBase { evbuffer *Output() { return bufferevent_get_output(bev_); } bufferevent *GetBufferEvent() { return bev_; } void ExecuteCommands(std::deque *to_process_cmds); - Status ExecuteCommand(const std::string &cmd_name, const std::vector &cmd_tokens, Commander *current_cmd, - std::string *reply); + Status ExecuteCommand(engine::Context &ctx, const std::string &cmd_name, const std::vector &cmd_tokens, + Commander *current_cmd, std::string *reply); bool IsProfilingEnabled(const std::string &cmd); void RecordProfilingSampleIfNeed(const std::string &cmd, uint64_t duration); void SetImporting() { importing_ = true; } diff --git a/src/server/server.cc b/src/server/server.cc index c6c4b8510ab..4d6eab26a45 100644 --- a/src/server/server.cc +++ b/src/server/server.cc @@ -158,9 +158,10 @@ Status Server::Start() { } if (!config_->cluster_enabled) { - GET_OR_RET(index_mgr.Load(kDefaultNamespace)); + engine::Context no_txn_ctx = engine::Context::NoTransactionContext(storage); + GET_OR_RET(index_mgr.Load(no_txn_ctx, kDefaultNamespace)); for (auto [_, ns] : namespace_.List()) { - GET_OR_RET(index_mgr.Load(ns)); + GET_OR_RET(index_mgr.Load(no_txn_ctx, ns)); } } diff --git a/src/storage/scripting.cc b/src/storage/scripting.cc index 9d728f74d7d..6e05e05db6d 100644 --- a/src/storage/scripting.cc +++ b/src/storage/scripting.cc @@ -813,7 +813,9 @@ int RedisGenericCommand(lua_State *lua, int raise_error) { } std::string output; - s = conn->ExecuteCommand(cmd_name, args, cmd.get(), &output); + // TODO: make it possible for multiple redis commands in lua script to use the same txn context. + engine::Context ctx(srv->storage); + s = conn->ExecuteCommand(ctx, cmd_name, args, cmd.get(), &output); if (!s) { PushError(lua, s.Msg().data()); return raise_error ? RaiseError(lua) : 1; From f439dbeda9e894f21cd6ff31ae8a08030610b47b Mon Sep 17 00:00:00 2001 From: ZhouSiLe Date: Thu, 24 Oct 2024 00:16:04 +0800 Subject: [PATCH 3/9] refactor: Hoist key mutexes --- src/server/redis_connection.cc | 18 +++++++++++++++-- src/storage/redis_db.cc | 20 ++++++++----------- src/storage/storage.cc | 1 + src/types/redis_bitmap.cc | 10 +--------- src/types/redis_bloom_chain.cc | 2 -- src/types/redis_hash.cc | 5 +---- src/types/redis_hyperloglog.cc | 2 -- src/types/redis_json.cc | 21 +------------------- src/types/redis_list.cc | 10 +--------- src/types/redis_set.cc | 30 ---------------------------- src/types/redis_sortedint.cc | 2 -- src/types/redis_stream.cc | 20 ++++--------------- src/types/redis_string.cc | 36 ++++------------------------------ src/types/redis_string.h | 3 +-- src/types/redis_zset.cc | 36 ---------------------------------- 15 files changed, 38 insertions(+), 178 deletions(-) diff --git a/src/server/redis_connection.cc b/src/server/redis_connection.cc index 6647c308528..9e9fb88bc3c 100644 --- a/src/server/redis_connection.cc +++ b/src/server/redis_connection.cc @@ -499,9 +499,24 @@ void Connection::ExecuteCommands(std::deque *to_process_cmds) { SetLastCmd(cmd_name); { + std::optional guard; + if (cmd_flags & kCmdWrite) { + std::vector lock_keys; + attributes->ForEachKeyRange( + [&, this](const std::vector &args, const CommandKeyRange &key_range) { + key_range.ForEachKey( + [&, this](const std::string &key) { + auto ns_key = ComposeNamespaceKey(ns_, key, srv_->storage->IsSlotIdEncoded()); + lock_keys.emplace_back(std::move(ns_key)); + }, + args); + }, + cmd_tokens); + + guard.emplace(srv_->storage->GetLockManager(), lock_keys); + } engine::Context ctx(srv_->storage); - // TODO: transaction support for index recording std::vector index_records; if (!srv_->index_mgr.index_map.empty() && IsCmdForIndexing(attributes) && !config->cluster_enabled) { attributes->ForEachKeyRange( @@ -521,7 +536,6 @@ void Connection::ExecuteCommands(std::deque *to_process_cmds) { } s = ExecuteCommand(ctx, cmd_name, cmd_tokens, current_cmd.get(), &reply); - // TODO: transaction support for index updating for (const auto &record : index_records) { auto s = GlobalIndexer::Update(ctx, record); if (!s.IsOK() && !s.Is()) { diff --git a/src/storage/redis_db.cc b/src/storage/redis_db.cc index 7fe83477e9a..6557a67b4ff 100644 --- a/src/storage/redis_db.cc +++ b/src/storage/redis_db.cc @@ -113,7 +113,7 @@ rocksdb::Status Database::Expire(engine::Context &ctx, const Slice &user_key, ui std::string value; Metadata metadata(kRedisNone, false); - LockGuard guard(storage_->GetLockManager(), ns_key); + rocksdb::Status s = storage_->Get(ctx, ctx.GetReadOptions(), metadata_cf_handle_, ns_key, &value); if (!s.ok()) return s; @@ -151,7 +151,7 @@ rocksdb::Status Database::Del(engine::Context &ctx, const Slice &user_key) { std::string ns_key = AppendNamespacePrefix(user_key); std::string value; - LockGuard guard(storage_->GetLockManager(), ns_key); + rocksdb::Status s = storage_->Get(ctx, ctx.GetReadOptions(), metadata_cf_handle_, ns_key, &value); if (!s.ok()) return s; Metadata metadata(kRedisNone, false); @@ -166,13 +166,12 @@ rocksdb::Status Database::Del(engine::Context &ctx, const Slice &user_key) { rocksdb::Status Database::MDel(engine::Context &ctx, const std::vector &keys, uint64_t *deleted_cnt) { *deleted_cnt = 0; - std::vector lock_keys; - lock_keys.reserve(keys.size()); + std::vector ns_keys; + ns_keys.reserve(keys.size()); for (const auto &key : keys) { std::string ns_key = AppendNamespacePrefix(key); - lock_keys.emplace_back(std::move(ns_key)); + ns_keys.emplace_back(std::move(ns_key)); } - MultiLockGuard guard(storage_->GetLockManager(), lock_keys); auto batch = storage_->GetWriteBatchBase(); WriteBatchLogData log_data(kRedisNone); @@ -182,8 +181,8 @@ rocksdb::Status Database::MDel(engine::Context &ctx, const std::vector &k } std::vector slice_keys; - slice_keys.reserve(lock_keys.size()); - for (const auto &ns_key : lock_keys) { + slice_keys.reserve(ns_keys.size()); + for (const auto &ns_key : ns_keys) { slice_keys.emplace_back(ns_key); } @@ -203,7 +202,7 @@ rocksdb::Status Database::MDel(engine::Context &ctx, const std::vector &k if (!s.ok()) continue; if (metadata.Expired()) continue; - s = batch->Delete(metadata_cf_handle_, lock_keys[i]); + s = batch->Delete(metadata_cf_handle_, ns_keys[i]); if (!s.ok()) return s; *deleted_cnt += 1; } @@ -646,9 +645,6 @@ rocksdb::Status Database::typeInternal(engine::Context &ctx, const Slice &key, R rocksdb::Status Database::Copy(engine::Context &ctx, const std::string &key, const std::string &new_key, bool nx, bool delete_old, CopyResult *res) { - std::vector lock_keys = {key, new_key}; - MultiLockGuard guard(storage_->GetLockManager(), lock_keys); - RedisType type = kRedisNone; auto s = typeInternal(ctx, key, &type); if (!s.ok()) return s; diff --git a/src/storage/storage.cc b/src/storage/storage.cc index 2eead08ace6..ce09705608f 100644 --- a/src/storage/storage.cc +++ b/src/storage/storage.cc @@ -878,6 +878,7 @@ Status Storage::CommitTxn() { if (!is_txn_mode_) { return Status{Status::NotOK, "cannot commit while not in transaction mode"}; } + // TODO: fix engine::Context ctx(this); auto s = writeToDB(ctx, default_write_opts_, txn_write_batch_->GetWriteBatch()); diff --git a/src/types/redis_bitmap.cc b/src/types/redis_bitmap.cc index ae9fefcd315..e75deea3644 100644 --- a/src/types/redis_bitmap.cc +++ b/src/types/redis_bitmap.cc @@ -184,7 +184,6 @@ rocksdb::Status Bitmap::SetBit(engine::Context &ctx, const Slice &user_key, uint std::string raw_value; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); BitmapMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata, &raw_value); if (!s.ok() && !s.IsNotFound()) return s; @@ -461,7 +460,6 @@ rocksdb::Status Bitmap::BitOp(engine::Context &ctx, BitOpFlags op_flag, const st const Slice &user_key, const std::vector &op_keys, int64_t *len) { std::string raw_value; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); std::vector> meta_pairs; uint64_t max_bitmap_size = 0; @@ -824,15 +822,9 @@ template rocksdb::Status Bitmap::bitfield(engine::Context &ctx, const Slice &user_key, const std::vector &ops, std::vector> *rets) { std::string ns_key = AppendNamespacePrefix(user_key); - - std::optional guard; - if constexpr (!ReadOnly) { - guard = LockGuard(storage_->GetLockManager(), ns_key); - } - BitmapMetadata metadata; std::string raw_value; - // TODO(mwish): maintain snapshot for read-only bitfield. + auto s = GetMetadata(ctx, ns_key, &metadata, &raw_value); if (!s.ok() && !s.IsNotFound()) { return s; diff --git a/src/types/redis_bloom_chain.cc b/src/types/redis_bloom_chain.cc index 30c07fe338c..7dea8189b16 100644 --- a/src/types/redis_bloom_chain.cc +++ b/src/types/redis_bloom_chain.cc @@ -126,7 +126,6 @@ rocksdb::Status BloomChain::Reserve(engine::Context &ctx, const Slice &user_key, uint16_t expansion) { std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); BloomChainMetadata bloom_chain_metadata; rocksdb::Status s = getBloomChainMetadata(ctx, ns_key, &bloom_chain_metadata); if (!s.ok() && !s.IsNotFound()) return s; @@ -156,7 +155,6 @@ rocksdb::Status BloomChain::InsertCommon(engine::Context &ctx, const Slice &user const BloomFilterInsertOptions &insert_options, std::vector *rets) { std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); BloomChainMetadata metadata; rocksdb::Status s = getBloomChainMetadata(ctx, ns_key, &metadata); diff --git a/src/types/redis_hash.cc b/src/types/redis_hash.cc index 8930c9fce64..905efdadd37 100644 --- a/src/types/redis_hash.cc +++ b/src/types/redis_hash.cc @@ -66,7 +66,6 @@ rocksdb::Status Hash::IncrBy(engine::Context &ctx, const Slice &user_key, const std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); HashMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) return s; @@ -117,7 +116,6 @@ rocksdb::Status Hash::IncrByFloat(engine::Context &ctx, const Slice &user_key, c std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); HashMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) return s; @@ -211,7 +209,7 @@ rocksdb::Status Hash::Delete(engine::Context &ctx, const Slice &user_key, const WriteBatchLogData log_data(kRedisHash); auto s = batch->PutLogData(log_data.Encode()); if (!s.ok()) return s; - LockGuard guard(storage_->GetLockManager(), ns_key); + s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s; @@ -245,7 +243,6 @@ rocksdb::Status Hash::MSet(engine::Context &ctx, const Slice &user_key, const st *added_cnt = 0; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); HashMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) return s; diff --git a/src/types/redis_hyperloglog.cc b/src/types/redis_hyperloglog.cc index 562a7d6b1f6..b7b2197f208 100644 --- a/src/types/redis_hyperloglog.cc +++ b/src/types/redis_hyperloglog.cc @@ -112,7 +112,6 @@ rocksdb::Status HyperLogLog::Add(engine::Context &ctx, const Slice &user_key, *ret = 0; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); HyperLogLogMetadata metadata{}; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) { @@ -238,7 +237,6 @@ rocksdb::Status HyperLogLog::Merge(engine::Context &ctx, const Slice &dest_user_ } std::string dest_key = AppendNamespacePrefix(dest_user_key); - LockGuard guard(storage_->GetLockManager(), dest_key); std::vector registers; HyperLogLogMetadata metadata; diff --git a/src/types/redis_json.cc b/src/types/redis_json.cc index 5120573e7ce..ba331ef96ff 100644 --- a/src/types/redis_json.cc +++ b/src/types/redis_json.cc @@ -124,8 +124,6 @@ rocksdb::Status Json::Set(engine::Context &ctx, const std::string &user_key, con const std::string &value) { auto ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); - JsonMetadata metadata; JsonValue origin; auto s = read(ctx, ns_key, &metadata, &origin); @@ -190,8 +188,6 @@ rocksdb::Status Json::ArrAppend(engine::Context &ctx, const std::string &user_ke append_values.emplace_back(std::move(value.value)); } - LockGuard guard(storage_->GetLockManager(), ns_key); - JsonMetadata metadata; JsonValue value; auto s = read(ctx, ns_key, &metadata, &value); @@ -248,8 +244,6 @@ rocksdb::Status Json::Merge(engine::Context &ctx, const std::string &user_key, c const std::string &merge_value, bool &result) { auto ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); - JsonMetadata metadata; JsonValue json_val; @@ -279,8 +273,6 @@ rocksdb::Status Json::Clear(engine::Context &ctx, const std::string &user_key, c size_t *result) { auto ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); - JsonValue json_val; JsonMetadata metadata; auto s = read(ctx, ns_key, &metadata, &json_val); @@ -327,8 +319,6 @@ rocksdb::Status Json::ArrInsert(engine::Context &ctx, const std::string &user_ke insert_values.emplace_back(std::move(value.value)); } - LockGuard guard(storage_->GetLockManager(), ns_key); - JsonMetadata metadata; JsonValue value; auto s = read(ctx, ns_key, &metadata, &value); @@ -349,8 +339,6 @@ rocksdb::Status Json::Toggle(engine::Context &ctx, const std::string &user_key, Optionals *results) { auto ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); - JsonMetadata metadata; JsonValue origin; auto s = read(ctx, ns_key, &metadata, &origin); @@ -367,8 +355,6 @@ rocksdb::Status Json::ArrPop(engine::Context &ctx, const std::string &user_key, std::vector> *results) { auto ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); - JsonMetadata metadata; JsonValue json_val; auto s = read(ctx, ns_key, &metadata, &json_val); @@ -403,8 +389,6 @@ rocksdb::Status Json::ArrTrim(engine::Context &ctx, const std::string &user_key, int64_t stop, Optionals *results) { auto ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); - JsonMetadata metadata; JsonValue json_val; auto s = read(ctx, ns_key, &metadata, &json_val); @@ -424,7 +408,7 @@ rocksdb::Status Json::Del(engine::Context &ctx, const std::string &user_key, con *result = 0; auto ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); + JsonValue json_val; JsonMetadata metadata; auto s = read(ctx, ns_key, &metadata, &json_val); @@ -473,8 +457,6 @@ rocksdb::Status Json::numop(engine::Context &ctx, JsonValue::NumOpEnum op, const auto s = read(ctx, ns_key, &metadata, &json_val); if (!s.ok()) return s; - LockGuard guard(storage_->GetLockManager(), ns_key); - auto res = json_val.NumOp(path, number, op, result); if (!res) { return rocksdb::Status::InvalidArgument(res.Msg()); @@ -571,7 +553,6 @@ rocksdb::Status Json::MSet(engine::Context &ctx, const std::vector std::string ns_key = AppendNamespacePrefix(user_key); ns_keys.emplace_back(std::move(ns_key)); } - MultiLockGuard guard(storage_->GetLockManager(), ns_keys); auto batch = storage_->GetWriteBatchBase(); WriteBatchLogData log_data(kRedisJson); diff --git a/src/types/redis_list.cc b/src/types/redis_list.cc index e640ffb6005..acef1ed9cc6 100644 --- a/src/types/redis_list.cc +++ b/src/types/redis_list.cc @@ -63,7 +63,7 @@ rocksdb::Status List::push(engine::Context &ctx, const Slice &user_key, const st WriteBatchLogData log_data(kRedisList, {std::to_string(cmd)}); auto s = batch->PutLogData(log_data.Encode()); if (!s.ok()) return s; - LockGuard guard(storage_->GetLockManager(), ns_key); + s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !(create_if_missing && s.IsNotFound())) { return s.IsNotFound() ? rocksdb::Status::OK() : s; @@ -108,7 +108,6 @@ rocksdb::Status List::PopMulti(engine::Context &ctx, const rocksdb::Slice &user_ std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); ListMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s; @@ -177,7 +176,6 @@ rocksdb::Status List::Rem(engine::Context &ctx, const Slice &user_key, int count std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); ListMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s; @@ -271,7 +269,6 @@ rocksdb::Status List::Insert(engine::Context &ctx, const Slice &user_key, const *new_size = 0; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); ListMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s; @@ -462,7 +459,6 @@ rocksdb::Status List::Pos(engine::Context &ctx, const Slice &user_key, const Sli rocksdb::Status List::Set(engine::Context &ctx, const Slice &user_key, int index, Slice elem) { std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); ListMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s; @@ -501,7 +497,6 @@ rocksdb::Status List::lmoveOnSingleList(engine::Context &ctx, const rocksdb::Sli std::string *elem) { std::string ns_key = AppendNamespacePrefix(src); - LockGuard guard(storage_->GetLockManager(), ns_key); ListMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) { @@ -567,8 +562,6 @@ rocksdb::Status List::lmoveOnTwoLists(engine::Context &ctx, const rocksdb::Slice std::string src_ns_key = AppendNamespacePrefix(src); std::string dst_ns_key = AppendNamespacePrefix(dst); - std::vector lock_keys{src_ns_key, dst_ns_key}; - MultiLockGuard guard(storage_->GetLockManager(), lock_keys); ListMetadata src_metadata(false); auto s = GetMetadata(ctx, src_ns_key, &src_metadata); if (!s.ok()) { @@ -636,7 +629,6 @@ rocksdb::Status List::Trim(engine::Context &ctx, const Slice &user_key, int star uint32_t trim_cnt = 0; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); ListMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s; diff --git a/src/types/redis_set.cc b/src/types/redis_set.cc index 043e0d36cea..01849328c60 100644 --- a/src/types/redis_set.cc +++ b/src/types/redis_set.cc @@ -37,7 +37,6 @@ rocksdb::Status Set::GetMetadata(engine::Context &ctx, const Slice &ns_key, SetM rocksdb::Status Set::Overwrite(engine::Context &ctx, Slice user_key, const std::vector &members) { std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); SetMetadata metadata; auto batch = storage_->GetWriteBatchBase(); WriteBatchLogData log_data(kRedisSet); @@ -62,7 +61,6 @@ rocksdb::Status Set::Add(engine::Context &ctx, const Slice &user_key, const std: std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); SetMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) return s; @@ -100,7 +98,6 @@ rocksdb::Status Set::Remove(engine::Context &ctx, const Slice &user_key, const s std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); SetMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s; @@ -218,9 +215,6 @@ rocksdb::Status Set::Take(engine::Context &ctx, const Slice &user_key, std::vect std::string ns_key = AppendNamespacePrefix(user_key); - std::optional lock_guard; - if (pop) lock_guard.emplace(storage_->GetLockManager(), ns_key); - SetMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s; @@ -290,14 +284,6 @@ rocksdb::Status Set::Scan(engine::Context &ctx, const Slice &user_key, const std * DIFF key1 key2 key3 = {b,d} */ rocksdb::Status Set::Diff(engine::Context &ctx, const std::vector &keys, std::vector *members) { - std::vector lock_keys; - lock_keys.reserve(keys.size()); - for (const auto key : keys) { - std::string ns_key = AppendNamespacePrefix(key); - lock_keys.emplace_back(std::move(ns_key)); - } - MultiLockGuard guard(storage_->GetLockManager(), lock_keys); - members->clear(); std::vector source_members; auto s = Members(ctx, keys[0], &source_members); @@ -329,14 +315,6 @@ rocksdb::Status Set::Diff(engine::Context &ctx, const std::vector &keys, * UNION key1 key2 key3 = {a,b,c,d,e} */ rocksdb::Status Set::Union(engine::Context &ctx, const std::vector &keys, std::vector *members) { - std::vector lock_keys; - lock_keys.reserve(keys.size()); - for (const auto key : keys) { - std::string ns_key = AppendNamespacePrefix(key); - lock_keys.emplace_back(std::move(ns_key)); - } - MultiLockGuard guard(storage_->GetLockManager(), lock_keys); - members->clear(); std::map union_members; @@ -363,14 +341,6 @@ rocksdb::Status Set::Union(engine::Context &ctx, const std::vector &keys, * INTER key1 key2 key3 = {c} */ rocksdb::Status Set::Inter(engine::Context &ctx, const std::vector &keys, std::vector *members) { - std::vector lock_keys; - lock_keys.reserve(keys.size()); - for (const auto key : keys) { - std::string ns_key = AppendNamespacePrefix(key); - lock_keys.emplace_back(std::move(ns_key)); - } - MultiLockGuard guard(storage_->GetLockManager(), lock_keys); - members->clear(); std::map member_counters; diff --git a/src/types/redis_sortedint.cc b/src/types/redis_sortedint.cc index 98e1f7a5133..f29ca7de616 100644 --- a/src/types/redis_sortedint.cc +++ b/src/types/redis_sortedint.cc @@ -38,7 +38,6 @@ rocksdb::Status Sortedint::Add(engine::Context &ctx, const Slice &user_key, cons std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); SortedintMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) return s; @@ -75,7 +74,6 @@ rocksdb::Status Sortedint::Remove(engine::Context &ctx, const Slice &user_key, c std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); SortedintMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s; diff --git a/src/types/redis_stream.cc b/src/types/redis_stream.cc index 009a98c0a8d..df9284c2db5 100644 --- a/src/types/redis_stream.cc +++ b/src/types/redis_stream.cc @@ -96,7 +96,6 @@ rocksdb::Status Stream::Add(engine::Context &ctx, const Slice &stream_name, cons std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); StreamMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) return s; @@ -333,7 +332,6 @@ rocksdb::Status Stream::DeletePelEntries(engine::Context &ctx, const Slice &stre std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); StreamMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) { @@ -400,7 +398,7 @@ rocksdb::Status Stream::ClaimPelEntries(engine::Context &ctx, const Slice &strea const std::vector &entry_ids, const StreamClaimOptions &options, StreamClaimResult *result) { std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); + StreamMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s; @@ -536,7 +534,6 @@ rocksdb::Status Stream::AutoClaim(engine::Context &ctx, const Slice &stream_name std::string ns_key = AppendNamespacePrefix(stream_name); StreamMetadata metadata(false); - LockGuard guard(storage_->GetLockManager(), ns_key); auto s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) { // not found will be caught by outside with no such key or consumer group return s; @@ -692,7 +689,6 @@ rocksdb::Status Stream::CreateGroup(engine::Context &ctx, const Slice &stream_na } std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); StreamMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) { @@ -745,7 +741,6 @@ rocksdb::Status Stream::DestroyGroup(engine::Context &ctx, const Slice &stream_n *delete_cnt = 0; std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); StreamMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) { @@ -849,14 +844,14 @@ rocksdb::Status Stream::createConsumerWithoutLock(engine::Context &ctx, const Sl rocksdb::Status Stream::CreateConsumer(engine::Context &ctx, const Slice &stream_name, const std::string &group_name, const std::string &consumer_name, int *created_number) { std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); + return createConsumerWithoutLock(ctx, stream_name, group_name, consumer_name, created_number); } rocksdb::Status Stream::DestroyConsumer(engine::Context &ctx, const Slice &stream_name, const std::string &group_name, const std::string &consumer_name, uint64_t &deleted_pel) { std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); + StreamMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) { @@ -923,7 +918,7 @@ rocksdb::Status Stream::DestroyConsumer(engine::Context &ctx, const Slice &strea rocksdb::Status Stream::GroupSetId(engine::Context &ctx, const Slice &stream_name, const std::string &group_name, const StreamXGroupCreateOptions &options) { std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); + StreamMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) { @@ -965,7 +960,6 @@ rocksdb::Status Stream::DeleteEntries(engine::Context &ctx, const Slice &stream_ std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); StreamMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) { @@ -1211,7 +1205,6 @@ rocksdb::Status Stream::GetStreamInfo(engine::Context &ctx, const rocksdb::Slice uint64_t count, StreamInfo *info) { std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); StreamMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s; @@ -1452,7 +1445,6 @@ rocksdb::Status Stream::RangeWithPending(engine::Context &ctx, const Slice &stre } std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); StreamMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); @@ -1582,8 +1574,6 @@ rocksdb::Status Stream::Trim(engine::Context &ctx, const Slice &stream_name, con std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); - StreamMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) { @@ -1696,8 +1686,6 @@ rocksdb::Status Stream::SetId(engine::Context &ctx, const Slice &stream_name, co std::string ns_key = AppendNamespacePrefix(stream_name); - LockGuard guard(storage_->GetLockManager(), ns_key); - StreamMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) { diff --git a/src/types/redis_string.cc b/src/types/redis_string.cc index 7d78534256a..210fb697b91 100644 --- a/src/types/redis_string.cc +++ b/src/types/redis_string.cc @@ -118,7 +118,6 @@ rocksdb::Status String::Append(engine::Context &ctx, const std::string &user_key *new_size = 0; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); std::string raw_value; rocksdb::Status s = getRawValue(ctx, ns_key, &raw_value); if (!s.ok() && !s.IsNotFound()) return s; @@ -156,7 +155,6 @@ rocksdb::Status String::GetEx(engine::Context &ctx, const std::string &user_key, std::optional expire) { std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); rocksdb::Status s = getValue(ctx, ns_key, value); if (!s.ok()) return s; @@ -190,7 +188,6 @@ rocksdb::Status String::GetSet(engine::Context &ctx, const std::string &user_key rocksdb::Status String::GetDel(engine::Context &ctx, const std::string &user_key, std::string *value) { std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); rocksdb::Status s = getValue(ctx, ns_key, value); if (!s.ok()) return s; @@ -199,7 +196,7 @@ rocksdb::Status String::GetDel(engine::Context &ctx, const std::string &user_key rocksdb::Status String::Set(engine::Context &ctx, const std::string &user_key, const std::string &value) { std::vector pairs{StringPair{user_key, value}}; - return MSet(ctx, pairs, /*expire=*/0, /*lock=*/true); + return MSet(ctx, pairs, /*expire=*/0); } rocksdb::Status String::Set(engine::Context &ctx, const std::string &user_key, const std::string &value, @@ -207,7 +204,6 @@ rocksdb::Status String::Set(engine::Context &ctx, const std::string &user_key, c uint64_t expire = 0; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); bool need_old_value = args.type != StringSetType::NONE || args.get || args.keep_ttl; if (need_old_value) { std::string old_value; @@ -289,7 +285,6 @@ rocksdb::Status String::SetRange(engine::Context &ctx, const std::string &user_k const std::string &value, uint64_t *new_size) { std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); std::string raw_value; rocksdb::Status s = getRawValue(ctx, ns_key, &raw_value); if (!s.ok() && !s.IsNotFound()) return s; @@ -329,7 +324,6 @@ rocksdb::Status String::IncrBy(engine::Context &ctx, const std::string &user_key int64_t *new_value) { std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); std::string raw_value; rocksdb::Status s = getRawValue(ctx, ns_key, &raw_value); if (!s.ok() && !s.IsNotFound()) return s; @@ -366,7 +360,7 @@ rocksdb::Status String::IncrBy(engine::Context &ctx, const std::string &user_key rocksdb::Status String::IncrByFloat(engine::Context &ctx, const std::string &user_key, double increment, double *new_value) { std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); + std::string raw_value; rocksdb::Status s = getRawValue(ctx, ns_key, &raw_value); if (!s.ok() && !s.IsNotFound()) return s; @@ -397,21 +391,7 @@ rocksdb::Status String::IncrByFloat(engine::Context &ctx, const std::string &use return updateRawValue(ctx, ns_key, raw_value); } -rocksdb::Status String::MSet(engine::Context &ctx, const std::vector &pairs, uint64_t expire_ms, - bool lock) { - // Data race, key string maybe overwrite by other key while didn't lock the keys here, - // to improve the set performance - std::optional guard; - if (lock) { - std::vector lock_keys; - lock_keys.reserve(pairs.size()); - for (const StringPair &pair : pairs) { - std::string ns_key = AppendNamespacePrefix(pair.key); - lock_keys.emplace_back(std::move(ns_key)); - } - guard.emplace(storage_->GetLockManager(), lock_keys); - } - +rocksdb::Status String::MSet(engine::Context &ctx, const std::vector &pairs, uint64_t expire_ms) { auto batch = storage_->GetWriteBatchBase(); WriteBatchLogData log_data(kRedisString); auto s = batch->PutLogData(log_data.Encode()); @@ -434,25 +414,19 @@ rocksdb::Status String::MSetNX(engine::Context &ctx, const std::vector lock_keys; - lock_keys.reserve(pairs.size()); std::vector keys; keys.reserve(pairs.size()); for (StringPair pair : pairs) { std::string ns_key = AppendNamespacePrefix(pair.key); - lock_keys.emplace_back(std::move(ns_key)); keys.emplace_back(pair.key); } - // Lock these keys before doing anything. - MultiLockGuard guard(storage_->GetLockManager(), lock_keys); - if (Exists(ctx, keys, &exists).ok() && exists > 0) { return rocksdb::Status::OK(); } - rocksdb::Status s = MSet(ctx, pairs, /*expire_ms=*/expire_ms, /*lock=*/false); + rocksdb::Status s = MSet(ctx, pairs, /*expire_ms=*/expire_ms); if (!s.ok()) return s; *flag = true; @@ -471,7 +445,6 @@ rocksdb::Status String::CAS(engine::Context &ctx, const std::string &user_key, c std::string current_value; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); rocksdb::Status s = getValue(ctx, ns_key, ¤t_value); if (!s.ok() && !s.IsNotFound()) { @@ -507,7 +480,6 @@ rocksdb::Status String::CAD(engine::Context &ctx, const std::string &user_key, c std::string current_value; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); rocksdb::Status s = getValue(ctx, ns_key, ¤t_value); if (!s.ok() && !s.IsNotFound()) { diff --git a/src/types/redis_string.h b/src/types/redis_string.h index b218bae346a..e5025d64fc6 100644 --- a/src/types/redis_string.h +++ b/src/types/redis_string.h @@ -100,8 +100,7 @@ class String : public Database { rocksdb::Status IncrByFloat(engine::Context &ctx, const std::string &user_key, double increment, double *new_value); std::vector MGet(engine::Context &ctx, const std::vector &keys, std::vector *values); - rocksdb::Status MSet(engine::Context &ctx, const std::vector &pairs, uint64_t expire_ms, - bool lock = true); + rocksdb::Status MSet(engine::Context &ctx, const std::vector &pairs, uint64_t expire_ms); rocksdb::Status MSetNX(engine::Context &ctx, const std::vector &pairs, uint64_t expire_ms, bool *flag); rocksdb::Status CAS(engine::Context &ctx, const std::string &user_key, const std::string &old_value, const std::string &new_value, uint64_t expire_ms, int *flag); diff --git a/src/types/redis_zset.cc b/src/types/redis_zset.cc index 4474b348e5b..5fa586d6160 100644 --- a/src/types/redis_zset.cc +++ b/src/types/redis_zset.cc @@ -42,7 +42,6 @@ rocksdb::Status ZSet::Add(engine::Context &ctx, const Slice &user_key, ZAddFlags std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); ZSetMetadata metadata; rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok() && !s.IsNotFound()) return s; @@ -159,7 +158,6 @@ rocksdb::Status ZSet::Pop(engine::Context &ctx, const Slice &user_key, int count std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); ZSetMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s; @@ -224,8 +222,6 @@ rocksdb::Status ZSet::RangeByRank(engine::Context &ctx, const Slice &user_key, c std::string ns_key = AppendNamespacePrefix(user_key); - std::optional lock_guard; - if (spec.with_deletion) lock_guard.emplace(storage_->GetLockManager(), ns_key); ZSetMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); @@ -306,8 +302,6 @@ rocksdb::Status ZSet::RangeByScore(engine::Context &ctx, const Slice &user_key, std::string ns_key = AppendNamespacePrefix(user_key); - std::optional lock_guard; - if (spec.with_deletion) lock_guard.emplace(storage_->GetLockManager(), ns_key); ZSetMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s; @@ -429,10 +423,6 @@ rocksdb::Status ZSet::RangeByLex(engine::Context &ctx, const Slice &user_key, co std::string ns_key = AppendNamespacePrefix(user_key); - std::optional lock_guard; - if (spec.with_deletion) { - lock_guard.emplace(storage_->GetLockManager(), ns_key); - } ZSetMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s; @@ -526,7 +516,6 @@ rocksdb::Status ZSet::Remove(engine::Context &ctx, const Slice &user_key, const *removed_cnt = 0; std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); ZSetMetadata metadata(false); rocksdb::Status s = GetMetadata(ctx, ns_key, &metadata); if (!s.ok()) return s.IsNotFound() ? rocksdb::Status::OK() : s; @@ -621,7 +610,6 @@ rocksdb::Status ZSet::Rank(engine::Context &ctx, const Slice &user_key, const Sl rocksdb::Status ZSet::Overwrite(engine::Context &ctx, const Slice &user_key, const MemberScores &mscores) { std::string ns_key = AppendNamespacePrefix(user_key); - LockGuard guard(storage_->GetLockManager(), ns_key); ZSetMetadata metadata; auto batch = storage_->GetWriteBatchBase(); WriteBatchLogData log_data(kRedisZSet); @@ -658,14 +646,6 @@ rocksdb::Status ZSet::InterStore(engine::Context &ctx, const Slice &dst, const s rocksdb::Status ZSet::Inter(engine::Context &ctx, const std::vector &keys_weights, AggregateMethod aggregate_method, std::vector *members) { - std::vector lock_keys; - lock_keys.reserve(keys_weights.size()); - for (const auto &key_weight : keys_weights) { - std::string ns_key = AppendNamespacePrefix(key_weight.key); - lock_keys.emplace_back(std::move(ns_key)); - } - MultiLockGuard guard(storage_->GetLockManager(), lock_keys); - std::map dst_zset; std::map member_counters; std::vector target_mscores; @@ -723,14 +703,6 @@ rocksdb::Status ZSet::Inter(engine::Context &ctx, const std::vector & rocksdb::Status ZSet::InterCard(engine::Context &ctx, const std::vector &user_keys, uint64_t limit, uint64_t *inter_cnt) { - std::vector lock_keys; - lock_keys.reserve(user_keys.size()); - for (const auto &user_key : user_keys) { - std::string ns_key = AppendNamespacePrefix(user_key); - lock_keys.emplace_back(std::move(ns_key)); - } - MultiLockGuard guard(storage_->GetLockManager(), lock_keys); - std::vector mscores_list; mscores_list.reserve(user_keys.size()); RangeScoreSpec spec; @@ -780,14 +752,6 @@ rocksdb::Status ZSet::UnionStore(engine::Context &ctx, const Slice &dst, const s rocksdb::Status ZSet::Union(engine::Context &ctx, const std::vector &keys_weights, AggregateMethod aggregate_method, std::vector *members) { - std::vector lock_keys; - lock_keys.reserve(keys_weights.size()); - for (const auto &key_weight : keys_weights) { - std::string ns_key = AppendNamespacePrefix(key_weight.key); - lock_keys.emplace_back(std::move(ns_key)); - } - MultiLockGuard guard(storage_->GetLockManager(), lock_keys); - std::map dst_zset; std::vector target_mscores; uint64_t target_size = 0; From ccf757d46c171634f7ff67467238787cd1e4d445 Mon Sep 17 00:00:00 2001 From: ZhouSiLe Date: Thu, 24 Oct 2024 11:31:51 +0800 Subject: [PATCH 4/9] chore: remove temporary comments --- src/storage/storage.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/storage/storage.cc b/src/storage/storage.cc index ce09705608f..2eead08ace6 100644 --- a/src/storage/storage.cc +++ b/src/storage/storage.cc @@ -878,7 +878,6 @@ Status Storage::CommitTxn() { if (!is_txn_mode_) { return Status{Status::NotOK, "cannot commit while not in transaction mode"}; } - // TODO: fix engine::Context ctx(this); auto s = writeToDB(ctx, default_write_opts_, txn_write_batch_->GetWriteBatch()); From 1177698ed4307053bdf2ece8a0b86dcf4931df20 Mon Sep 17 00:00:00 2001 From: ZhouSiLe Date: Wed, 30 Oct 2024 23:44:20 +0800 Subject: [PATCH 5/9] fix: add MultiLockGuard of OnWrite --- src/commands/blocking_commander.h | 8 ++++++++ src/commands/cmd_list.cc | 29 +++++++++++++++++++++++++++++ src/commands/cmd_stream.cc | 8 ++++++++ src/commands/cmd_zset.cc | 19 +++++++++++++++++++ src/server/redis_connection.cc | 2 +- 5 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/commands/blocking_commander.h b/src/commands/blocking_commander.h index 05883a8ac04..4217b24966f 100644 --- a/src/commands/blocking_commander.h +++ b/src/commands/blocking_commander.h @@ -23,6 +23,9 @@ #include "commander.h" #include "event_util.h" #include "server/redis_connection.h" +#include "server/server.h" + +class MultiLockGuard; namespace redis { @@ -44,6 +47,10 @@ class BlockingCommander : public Commander, // in other words, returning true indicates ending the blocking virtual bool OnBlockingWrite() = 0; + // method to get keys to be locked + // when OnWrite is triggered, BlockingCommander needs to relock the keys + virtual std::vector GetLockKeys() = 0; + // to start the blocking process // usually put to the end of the Execute method Status StartBlocking(int64_t timeout, std::string *output) { @@ -63,6 +70,7 @@ class BlockingCommander : public Commander, } void OnWrite(bufferevent *bev) { + MultiLockGuard guard(conn_->GetServer()->storage->GetLockManager(), GetLockKeys()); bool done = OnBlockingWrite(); if (!done) { diff --git a/src/commands/cmd_list.cc b/src/commands/cmd_list.cc index 0cc2f1210fd..bd962cf1625 100644 --- a/src/commands/cmd_list.cc +++ b/src/commands/cmd_list.cc @@ -313,6 +313,16 @@ class CommandBPop : public BlockingCommander { return s; } + std::vector GetLockKeys() override { + std::vector lock_keys; + lock_keys.reserve(keys_.size()); + for (const auto &key : keys_) { + auto ns_key = ComposeNamespaceKey(conn_->GetNamespace(), key, srv_->storage->IsSlotIdEncoded()); + lock_keys.emplace_back(std::move(ns_key)); + } + return lock_keys; + } + bool OnBlockingWrite() override { engine::Context ctx(srv_->storage); auto s = TryPopFromList(ctx); @@ -436,6 +446,16 @@ class CommandBLMPop : public BlockingCommander { } } + std::vector GetLockKeys() override { + std::vector lock_keys; + lock_keys.reserve(keys_.size()); + for (const auto &key : keys_) { + auto ns_key = ComposeNamespaceKey(conn_->GetNamespace(), key, srv_->storage->IsSlotIdEncoded()); + lock_keys.emplace_back(std::move(ns_key)); + } + return lock_keys; + } + bool OnBlockingWrite() override { engine::Context ctx(srv_->storage); auto s = ExecuteUnblocked(ctx); @@ -767,6 +787,15 @@ class CommandBLMove : public BlockingCommander { void UnblockKeys() override { srv_->UnblockOnKey(args_[1], conn_); } + std::vector GetLockKeys() override { + std::vector lock_keys{ + ComposeNamespaceKey(conn_->GetNamespace(), args_[1], srv_->storage->IsSlotIdEncoded())}; + if (args_[1] != args_[2]) { + lock_keys.emplace_back(ComposeNamespaceKey(conn_->GetNamespace(), args_[2], srv_->storage->IsSlotIdEncoded())); + } + return lock_keys; + } + bool OnBlockingWrite() override { redis::List list_db(srv_->storage, conn_->GetNamespace()); std::string elem; diff --git a/src/commands/cmd_stream.cc b/src/commands/cmd_stream.cc index 903b0031c5d..a9d058ad46f 100644 --- a/src/commands/cmd_stream.cc +++ b/src/commands/cmd_stream.cc @@ -1635,6 +1635,14 @@ class CommandXReadGroup : public Commander, redis::Stream stream_db(srv_->storage, conn_->GetNamespace()); std::vector results; + + std::vector lock_keys; + lock_keys.reserve(streams_.size()); + for (auto &stream_name : streams_) { + auto ns_key = stream_db.AppendNamespacePrefix(stream_name); + lock_keys.emplace_back(std::move(ns_key)); + } + MultiLockGuard guard(srv_->storage->GetLockManager(), lock_keys); engine::Context ctx(srv_->storage); for (size_t i = 0; i < streams_.size(); ++i) { redis::StreamRangeOptions options; diff --git a/src/commands/cmd_zset.cc b/src/commands/cmd_zset.cc index d26abb54b91..1c71afa5217 100644 --- a/src/commands/cmd_zset.cc +++ b/src/commands/cmd_zset.cc @@ -366,6 +366,15 @@ class CommandBZPop : public BlockingCommander { conn_->Reply(output); } + std::vector GetLockKeys() override { + std::vector lock_keys{ + ComposeNamespaceKey(conn_->GetNamespace(), args_[1], srv_->storage->IsSlotIdEncoded())}; + if (args_[1] != args_[2]) { + lock_keys.emplace_back(ComposeNamespaceKey(conn_->GetNamespace(), args_[2], srv_->storage->IsSlotIdEncoded())); + } + return lock_keys; + } + bool OnBlockingWrite() override { std::string user_key; std::vector member_scores; @@ -548,6 +557,16 @@ class CommandBZMPop : public BlockingCommander { std::string NoopReply(const Connection *conn) override { return conn->NilString(); } + std::vector GetLockKeys() override { + std::vector lock_keys; + lock_keys.reserve(keys_.size()); + for (const auto &key : keys_) { + auto ns_key = ComposeNamespaceKey(conn_->GetNamespace(), key, srv_->storage->IsSlotIdEncoded()); + lock_keys.emplace_back(std::move(ns_key)); + } + return lock_keys; + } + bool OnBlockingWrite() override { std::string user_key; std::vector member_scores; diff --git a/src/server/redis_connection.cc b/src/server/redis_connection.cc index 1504df039c6..cfa3fd642ae 100644 --- a/src/server/redis_connection.cc +++ b/src/server/redis_connection.cc @@ -502,7 +502,7 @@ void Connection::ExecuteCommands(std::deque *to_process_cmds) { if (cmd_flags & kCmdWrite) { std::vector lock_keys; attributes->ForEachKeyRange( - [&, this](const std::vector &args, const CommandKeyRange &key_range) { + [&lock_keys, this](const std::vector &args, const CommandKeyRange &key_range) { key_range.ForEachKey( [&, this](const std::string &key) { auto ns_key = ComposeNamespaceKey(ns_, key, srv_->storage->IsSlotIdEncoded()); From 765366f39f9992312a7f4475183febd6002d73b4 Mon Sep 17 00:00:00 2001 From: ZhouSiLe Date: Thu, 31 Oct 2024 11:39:22 +0800 Subject: [PATCH 6/9] fix: try to fix issue 2473 --- src/commands/cmd_zset.cc | 2 +- tests/gocase/unit/protocol/regression_test.go | 3 - tests/gocase/unit/type/list/list_test.go | 65 ------------------- tests/gocase/unit/type/zset/zset_test.go | 7 -- 4 files changed, 1 insertion(+), 76 deletions(-) diff --git a/src/commands/cmd_zset.cc b/src/commands/cmd_zset.cc index 1c71afa5217..fc140b435e4 100644 --- a/src/commands/cmd_zset.cc +++ b/src/commands/cmd_zset.cc @@ -557,7 +557,7 @@ class CommandBZMPop : public BlockingCommander { std::string NoopReply(const Connection *conn) override { return conn->NilString(); } - std::vector GetLockKeys() override { + std::vector GetLockKeys() override { std::vector lock_keys; lock_keys.reserve(keys_.size()); for (const auto &key : keys_) { diff --git a/tests/gocase/unit/protocol/regression_test.go b/tests/gocase/unit/protocol/regression_test.go index 7dd4ea22b41..091bed26c29 100644 --- a/tests/gocase/unit/protocol/regression_test.go +++ b/tests/gocase/unit/protocol/regression_test.go @@ -23,7 +23,6 @@ import ( "context" "fmt" "testing" - "time" "github.com/apache/kvrocks/tests/gocase/util" "github.com/stretchr/testify/require" @@ -42,8 +41,6 @@ func TestRegression(t *testing.T) { proto := "*3\r\n$5\r\nBLPOP\r\n$6\r\nhandle\r\n$1\r\n0\r\n" require.NoError(t, c.Write(fmt.Sprintf("%s%s", proto, proto))) - // TODO: Remove time.Sleep after fix issue #2473 - time.Sleep(100 * time.Millisecond) resList := []string{"*2", "$6", "handle", "$1", "a"} v := rdb.RPush(ctx, "handle", "a") diff --git a/tests/gocase/unit/type/list/list_test.go b/tests/gocase/unit/type/list/list_test.go index 8b7a2c58f4e..1f55e9116a4 100644 --- a/tests/gocase/unit/type/list/list_test.go +++ b/tests/gocase/unit/type/list/list_test.go @@ -376,22 +376,13 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() createList("blist", []string{"a", "b", large, "c", "d"}) - // TODO: Remove time.Sleep after fix issue #2473 - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blpop", "blist", "1")) - time.Sleep(100 * time.Millisecond) rd.MustReadStrings(t, []string{"blist", "a"}) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("brpop", "blist", "1")) - time.Sleep(100 * time.Millisecond) rd.MustReadStrings(t, []string{"blist", "d"}) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blpop", "blist", "1")) - time.Sleep(100 * time.Millisecond) rd.MustReadStrings(t, []string{"blist", "b"}) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("brpop", "blist", "1")) - time.Sleep(100 * time.Millisecond) rd.MustReadStrings(t, []string{"blist", "c"}) }) @@ -400,23 +391,15 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { defer func() { require.NoError(t, rd.Close()) }() createList("blist1", []string{"a", large, "c"}) createList("blist2", []string{"d", large, "f"}) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blpop", "blist1", "blist2", "1")) - time.Sleep(100 * time.Millisecond) rd.MustReadStrings(t, []string{"blist1", "a"}) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("brpop", "blist1", "blist2", "1")) - time.Sleep(100 * time.Millisecond) rd.MustReadStrings(t, []string{"blist1", "c"}) require.EqualValues(t, 1, rdb.LLen(ctx, "blist1").Val()) require.EqualValues(t, 3, rdb.LLen(ctx, "blist2").Val()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blpop", "blist2", "blist2", "1")) - time.Sleep(100 * time.Millisecond) rd.MustReadStrings(t, []string{"blist2", "d"}) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("brpop", "blist2", "blist2", "1")) - time.Sleep(100 * time.Millisecond) rd.MustReadStrings(t, []string{"blist2", "f"}) require.EqualValues(t, 1, rdb.LLen(ctx, "blist1").Val()) require.EqualValues(t, 1, rdb.LLen(ctx, "blist2").Val()) @@ -427,13 +410,9 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, "blist1").Err()) createList("blist2", []string{"d", large, "f"}) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blpop", "blist1", "blist2", "1")) - time.Sleep(100 * time.Millisecond) rd.MustReadStrings(t, []string{"blist2", "d"}) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("brpop", "blist1", "blist2", "1")) - time.Sleep(100 * time.Millisecond) rd.MustReadStrings(t, []string{"blist2", "f"}) require.EqualValues(t, 0, rdb.LLen(ctx, "blist1").Val()) require.EqualValues(t, 1, rdb.LLen(ctx, "blist2").Val()) @@ -444,25 +423,17 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, "list1", "list2").Err()) - time.Sleep(time.Millisecond * 100) require.NoError(t, rd.WriteArgs("blpop", "list1", "list2", "list2", "list1", "0")) - time.Sleep(time.Millisecond * 100) require.NoError(t, rdb.LPush(ctx, "list1", "a").Err()) rd.MustReadStrings(t, []string{"list1", "a"}) - time.Sleep(time.Millisecond * 100) require.NoError(t, rd.WriteArgs("blpop", "list1", "list2", "list2", "list1", "0")) - time.Sleep(time.Millisecond * 100) require.NoError(t, rdb.LPush(ctx, "list2", "b").Err()) rd.MustReadStrings(t, []string{"list2", "b"}) require.NoError(t, rdb.LPush(ctx, "list1", "a").Err()) require.NoError(t, rdb.LPush(ctx, "list2", "b").Err()) - time.Sleep(time.Millisecond * 100) require.NoError(t, rd.WriteArgs("blpop", "list1", "list2", "list2", "list1", "0")) - time.Sleep(time.Millisecond * 100) rd.MustReadStrings(t, []string{"list1", "a"}) - time.Sleep(time.Millisecond * 100) require.NoError(t, rd.WriteArgs("blpop", "list1", "list2", "list2", "list1", "0")) - time.Sleep(time.Millisecond * 100) rd.MustReadStrings(t, []string{"list2", "b"}) }) @@ -470,9 +441,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, "blist", "target").Err()) - time.Sleep(time.Millisecond * 100) require.NoError(t, rd.WriteArgs("blpop", "blist", "0")) - time.Sleep(time.Millisecond * 100) require.EqualValues(t, 2, rdb.LPush(ctx, "blist", "foo", "bar").Val()) rd.MustReadStrings(t, []string{"blist", "bar"}) require.Equal(t, "foo", rdb.LRange(ctx, "blist", 0, -1).Val()[0]) @@ -483,9 +452,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, "blist1").Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs(popType, "blist1", "0")) - time.Sleep(100 * time.Millisecond) require.NoError(t, rdb.RPush(ctx, "blist1", "foo").Err()) rd.MustReadStrings(t, []string{"blist1", "foo"}) require.EqualValues(t, 0, rdb.Exists(ctx, "blist1").Val()) @@ -495,7 +462,6 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rd.WriteArgs(popType, "blist1", "-1")) - time.Sleep(100 * time.Millisecond) rd.MustMatch(t, ".*negative.*") }) @@ -505,7 +471,6 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rd.WriteArgs(popType, "blist1", "0")) - time.Sleep(time.Millisecond * 1000) require.NoError(t, rdb.RPush(ctx, "blist1", "foo").Err()) rd.MustReadStrings(t, []string{"blist1", "foo"}) }) @@ -515,7 +480,6 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, "blist1", "blist2").Err()) require.NoError(t, rdb.Set(ctx, "blist2", "nolist", 0).Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs(popType, "blist1", "blist2", "1")) rd.MustMatch(t, ".*WRONGTYPE.*") }) @@ -524,7 +488,6 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, "blist1", "blist2").Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs(popType, "blist1", "blist2", "1")) rd.MustMatch(t, "") }) @@ -533,16 +496,12 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, "blist1", "blist2").Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs(popType, "blist1", "blist2", "4")) - time.Sleep(100 * time.Millisecond) require.NoError(t, rdb.RPush(ctx, "blist1", "foo").Err()) rd.MustReadStrings(t, []string{"blist1", "foo"}) require.EqualValues(t, 0, rdb.Exists(ctx, "blist1").Val()) require.EqualValues(t, 0, rdb.Exists(ctx, "blist2").Val()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs(popType, "blist1", "blist2", "1")) - time.Sleep(100 * time.Millisecond) require.NoError(t, rdb.RPush(ctx, "blist2", "foo").Err()) rd.MustReadStrings(t, []string{"blist2", "foo"}) require.EqualValues(t, 0, rdb.Exists(ctx, "blist1").Val()) @@ -950,9 +909,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { require.NoError(t, rdb.Del(ctx, "target_key{t}").Err()) require.NoError(t, rdb.RPush(ctx, "target_key{t}", 1).Err()) createList("list{t}", []string{"a", "b", "c", "d"}) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("lmove", "list{t}", "target_key{t}", from, to)) - time.Sleep(100 * time.Millisecond) r, err1 := rd.ReadLine() require.Equal(t, "$1", r) require.NoError(t, err1) @@ -998,9 +955,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { require.NoError(t, rdb.Del(ctx, "target_key{t}").Err()) require.NoError(t, rdb.RPush(ctx, "target_key{t}", 1).Err()) createList("list{t}", []string{"a", "b", "c", "d"}) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmove", "list{t}", "target_key{t}", from, to, "1")) - time.Sleep(100 * time.Millisecond) r, err1 := rd.ReadLine() require.Equal(t, "$1", r) require.NoError(t, err1) @@ -1026,9 +981,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, "blist", "target").Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmove", "blist", "target", "left", "right", "0")) - time.Sleep(100 * time.Millisecond) require.EqualValues(t, 2, rdb.LPush(ctx, "blist", "foo", "bar").Val()) rd.MustRead(t, "$3") require.Equal(t, "bar", rdb.LRange(ctx, "target", 0, -1).Val()[0]) @@ -1436,9 +1389,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, key1, key2).Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmpop", "1", "1", key1, direction, "count", "1")) - time.Sleep(time.Millisecond * 100) require.NoError(t, rdb.RPush(ctx, key1, "ONE", "TWO").Err()) if direction == "LEFT" { rd.MustReadStringsWithKey(t, key1, []string{"ONE"}) @@ -1452,9 +1403,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, key1, key2).Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmpop", "1", "1", key1, direction, "count", "2")) - time.Sleep(time.Millisecond * 100) require.NoError(t, rdb.RPush(ctx, key1, "ONE", "TWO").Err()) if direction == "LEFT" { rd.MustReadStringsWithKey(t, key1, []string{"ONE", "TWO"}) @@ -1468,9 +1417,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, key1, key2).Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmpop", "1", "1", key1, direction, "count", "10")) - time.Sleep(time.Millisecond * 100) require.NoError(t, rdb.RPush(ctx, key1, "ONE", "TWO").Err()) if direction == "LEFT" { rd.MustReadStringsWithKey(t, key1, []string{"ONE", "TWO"}) @@ -1484,9 +1431,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, key1, key2).Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmpop", "1", "2", key1, key2, direction, "count", "2")) - time.Sleep(time.Millisecond * 100) require.NoError(t, rdb.RPush(ctx, key1, "ONE", "TWO").Err()) if direction == "LEFT" { rd.MustReadStringsWithKey(t, key1, []string{"ONE", "TWO"}) @@ -1500,9 +1445,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, key1, key2).Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmpop", "1", "2", key1, key2, direction, "count", "2")) - time.Sleep(time.Millisecond * 100) require.NoError(t, rdb.RPush(ctx, key2, "one", "two").Err()) if direction == "LEFT" { rd.MustReadStringsWithKey(t, key2, []string{"one", "two"}) @@ -1516,9 +1459,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, key1, key2).Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmpop", "1", "2", key1, key2, direction, "count", "2")) - time.Sleep(time.Millisecond * 100) require.NoError(t, rdb.RPush(ctx, key2, "one", "two").Err()) require.NoError(t, rdb.RPush(ctx, key1, "ONE", "TWO").Err()) if direction == "LEFT" { @@ -1534,9 +1475,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, key1, key2).Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmpop", "1", "2", key1, key2, direction)) - time.Sleep(time.Millisecond * 100) require.NoError(t, rdb.RPush(ctx, key2, "one", "two").Err()) if direction == "LEFT" { rd.MustReadStringsWithKey(t, key2, []string{"one"}) @@ -1551,9 +1490,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, key1, key2).Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmpop", "1", "2", key1, key2, direction)) - time.Sleep(time.Millisecond * 1200) rd.MustMatch(t, "") }) @@ -1562,9 +1499,7 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, key1, key2).Err()) - time.Sleep(100 * time.Millisecond) require.NoError(t, rd.WriteArgs("blmpop", "0", "2", key1, key2, direction, "count", "2")) - time.Sleep(time.Millisecond * 1200) require.NoError(t, rdb.RPush(ctx, key2, "one", "two").Err()) if direction == "LEFT" { rd.MustReadStringsWithKey(t, key2, []string{"one", "two"}) diff --git a/tests/gocase/unit/type/zset/zset_test.go b/tests/gocase/unit/type/zset/zset_test.go index ad57defaa85..fce7e96a652 100644 --- a/tests/gocase/unit/type/zset/zset_test.go +++ b/tests/gocase/unit/type/zset/zset_test.go @@ -332,8 +332,6 @@ func basicTests(t *testing.T, rdb *redis.Client, ctx context.Context, enabledRES rdb.ZAdd(ctx, "zsetb", redis.Z{Score: 1, Member: "d"}, redis.Z{Score: 2, Member: "e"}) require.EqualValues(t, 3, rdb.ZCard(ctx, "zseta").Val()) require.EqualValues(t, 2, rdb.ZCard(ctx, "zsetb").Val()) - // TODO: Remove time.Sleep after fix issue #2473 - time.Sleep(time.Millisecond * 100) resultz := rdb.BZPopMin(ctx, 0, "zseta", "zsetb").Val().Z require.Equal(t, redis.Z{Score: 1, Member: "a"}, resultz) resultz = rdb.BZPopMin(ctx, 0, "zseta", "zsetb").Val().Z @@ -349,9 +347,7 @@ func basicTests(t *testing.T, rdb *redis.Client, ctx context.Context, enabledRES rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() - time.Sleep(time.Millisecond * 100) require.NoError(t, rd.WriteArgs("bzpopmin", "zseta", "0")) - time.Sleep(time.Millisecond * 100) rdb.ZAdd(ctx, "zseta", redis.Z{Score: 1, Member: "a"}) rd.MustReadStrings(t, []string{"zseta", "a", "1"}) }) @@ -363,7 +359,6 @@ func basicTests(t *testing.T, rdb *redis.Client, ctx context.Context, enabledRES rdb.ZAdd(ctx, "zsetb", redis.Z{Score: 1, Member: "d"}, redis.Z{Score: 2, Member: "e"}) require.EqualValues(t, 3, rdb.ZCard(ctx, "zseta").Val()) require.EqualValues(t, 2, rdb.ZCard(ctx, "zsetb").Val()) - time.Sleep(time.Millisecond * 100) resultz := rdb.BZPopMax(ctx, 0, "zseta", "zsetb").Val().Z require.Equal(t, redis.Z{Score: 3, Member: "c"}, resultz) resultz = rdb.BZPopMax(ctx, 0, "zseta", "zsetb").Val().Z @@ -379,9 +374,7 @@ func basicTests(t *testing.T, rdb *redis.Client, ctx context.Context, enabledRES rd := srv.NewTCPClient() defer func() { require.NoError(t, rd.Close()) }() - time.Sleep(time.Millisecond * 100) require.NoError(t, rd.WriteArgs("bzpopmax", "zseta", "0")) - time.Sleep(time.Millisecond * 100) rdb.ZAdd(ctx, "zseta", redis.Z{Score: 1, Member: "a"}) rd.MustReadStrings(t, []string{"zseta", "a", "1"}) }) From 37156265c6edaa5b138baa393bfa27d21f14a8b9 Mon Sep 17 00:00:00 2001 From: ZhouSiLe Date: Thu, 31 Oct 2024 18:04:37 +0800 Subject: [PATCH 7/9] refactor: GetLockKeys=>GetLocks --- src/commands/blocking_commander.h | 10 ++++------ src/commands/cmd_list.cc | 12 ++++++------ src/commands/cmd_zset.cc | 17 +++++++++-------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/commands/blocking_commander.h b/src/commands/blocking_commander.h index 4217b24966f..fd955085cb5 100644 --- a/src/commands/blocking_commander.h +++ b/src/commands/blocking_commander.h @@ -21,11 +21,9 @@ #pragma once #include "commander.h" +#include "common/lock_manager.h" #include "event_util.h" #include "server/redis_connection.h" -#include "server/server.h" - -class MultiLockGuard; namespace redis { @@ -47,9 +45,9 @@ class BlockingCommander : public Commander, // in other words, returning true indicates ending the blocking virtual bool OnBlockingWrite() = 0; - // method to get keys to be locked + // method to lock the keys of the BlockingCommander with MultiLockGuard // when OnWrite is triggered, BlockingCommander needs to relock the keys - virtual std::vector GetLockKeys() = 0; + virtual MultiLockGuard GetLocks() = 0; // to start the blocking process // usually put to the end of the Execute method @@ -70,7 +68,7 @@ class BlockingCommander : public Commander, } void OnWrite(bufferevent *bev) { - MultiLockGuard guard(conn_->GetServer()->storage->GetLockManager(), GetLockKeys()); + auto guard = GetLocks(); bool done = OnBlockingWrite(); if (!done) { diff --git a/src/commands/cmd_list.cc b/src/commands/cmd_list.cc index bd962cf1625..aed14c6c6d0 100644 --- a/src/commands/cmd_list.cc +++ b/src/commands/cmd_list.cc @@ -313,14 +313,14 @@ class CommandBPop : public BlockingCommander { return s; } - std::vector GetLockKeys() override { + MultiLockGuard GetLocks() override { std::vector lock_keys; lock_keys.reserve(keys_.size()); for (const auto &key : keys_) { auto ns_key = ComposeNamespaceKey(conn_->GetNamespace(), key, srv_->storage->IsSlotIdEncoded()); lock_keys.emplace_back(std::move(ns_key)); } - return lock_keys; + return MultiLockGuard(srv_->storage->GetLockManager(), lock_keys); } bool OnBlockingWrite() override { @@ -446,14 +446,14 @@ class CommandBLMPop : public BlockingCommander { } } - std::vector GetLockKeys() override { + MultiLockGuard GetLocks() override { std::vector lock_keys; lock_keys.reserve(keys_.size()); for (const auto &key : keys_) { auto ns_key = ComposeNamespaceKey(conn_->GetNamespace(), key, srv_->storage->IsSlotIdEncoded()); lock_keys.emplace_back(std::move(ns_key)); } - return lock_keys; + return MultiLockGuard(srv_->storage->GetLockManager(), lock_keys); } bool OnBlockingWrite() override { @@ -787,13 +787,13 @@ class CommandBLMove : public BlockingCommander { void UnblockKeys() override { srv_->UnblockOnKey(args_[1], conn_); } - std::vector GetLockKeys() override { + MultiLockGuard GetLocks() override { std::vector lock_keys{ ComposeNamespaceKey(conn_->GetNamespace(), args_[1], srv_->storage->IsSlotIdEncoded())}; if (args_[1] != args_[2]) { lock_keys.emplace_back(ComposeNamespaceKey(conn_->GetNamespace(), args_[2], srv_->storage->IsSlotIdEncoded())); } - return lock_keys; + return MultiLockGuard(srv_->storage->GetLockManager(), lock_keys); } bool OnBlockingWrite() override { diff --git a/src/commands/cmd_zset.cc b/src/commands/cmd_zset.cc index fc140b435e4..5245b8fca15 100644 --- a/src/commands/cmd_zset.cc +++ b/src/commands/cmd_zset.cc @@ -366,13 +366,14 @@ class CommandBZPop : public BlockingCommander { conn_->Reply(output); } - std::vector GetLockKeys() override { - std::vector lock_keys{ - ComposeNamespaceKey(conn_->GetNamespace(), args_[1], srv_->storage->IsSlotIdEncoded())}; - if (args_[1] != args_[2]) { - lock_keys.emplace_back(ComposeNamespaceKey(conn_->GetNamespace(), args_[2], srv_->storage->IsSlotIdEncoded())); + MultiLockGuard GetLocks() override { + std::vector lock_keys; + lock_keys.reserve(keys_.size()); + for (const auto &key : keys_) { + auto ns_key = ComposeNamespaceKey(conn_->GetNamespace(), key, srv_->storage->IsSlotIdEncoded()); + lock_keys.emplace_back(std::move(ns_key)); } - return lock_keys; + return MultiLockGuard(srv_->storage->GetLockManager(), lock_keys); } bool OnBlockingWrite() override { @@ -557,14 +558,14 @@ class CommandBZMPop : public BlockingCommander { std::string NoopReply(const Connection *conn) override { return conn->NilString(); } - std::vector GetLockKeys() override { + MultiLockGuard GetLocks() override { std::vector lock_keys; lock_keys.reserve(keys_.size()); for (const auto &key : keys_) { auto ns_key = ComposeNamespaceKey(conn_->GetNamespace(), key, srv_->storage->IsSlotIdEncoded()); lock_keys.emplace_back(std::move(ns_key)); } - return lock_keys; + return MultiLockGuard(srv_->storage->GetLockManager(), lock_keys); } bool OnBlockingWrite() override { From abd3826236501786c5f367733f2003704fc42313 Mon Sep 17 00:00:00 2001 From: ZhouSiLe Date: Thu, 31 Oct 2024 18:05:58 +0800 Subject: [PATCH 8/9] fix: issues 2617 --- tests/gocase/unit/type/list/list_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/gocase/unit/type/list/list_test.go b/tests/gocase/unit/type/list/list_test.go index 1f55e9116a4..f7509300236 100644 --- a/tests/gocase/unit/type/list/list_test.go +++ b/tests/gocase/unit/type/list/list_test.go @@ -1460,6 +1460,9 @@ func testList(t *testing.T, configs util.KvrocksServerConfigs) { defer func() { require.NoError(t, rd.Close()) }() require.NoError(t, rdb.Del(ctx, key1, key2).Err()) require.NoError(t, rd.WriteArgs("blmpop", "1", "2", key1, key2, direction, "count", "2")) + // https://github.com/apache/kvrocks/issues/2617 + // WriteArgs are required to be executed first + time.Sleep(100 * time.Millisecond) require.NoError(t, rdb.RPush(ctx, key2, "one", "two").Err()) require.NoError(t, rdb.RPush(ctx, key1, "ONE", "TWO").Err()) if direction == "LEFT" { From 23501dafb295ccdf4a1b2b27f0de81924508e791 Mon Sep 17 00:00:00 2001 From: ZhouSiLe Date: Thu, 31 Oct 2024 22:14:15 +0800 Subject: [PATCH 9/9] chore: comments & guard --- src/commands/blocking_commander.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/commands/blocking_commander.h b/src/commands/blocking_commander.h index fd955085cb5..2749681984f 100644 --- a/src/commands/blocking_commander.h +++ b/src/commands/blocking_commander.h @@ -45,8 +45,8 @@ class BlockingCommander : public Commander, // in other words, returning true indicates ending the blocking virtual bool OnBlockingWrite() = 0; - // method to lock the keys of the BlockingCommander with MultiLockGuard - // when OnWrite is triggered, BlockingCommander needs to relock the keys + // GetLocks() locks the keys of the BlockingCommander with MultiLockGuard. + // When OnWrite() is triggered, BlockingCommander needs to relock the keys. virtual MultiLockGuard GetLocks() = 0; // to start the blocking process @@ -68,8 +68,11 @@ class BlockingCommander : public Commander, } void OnWrite(bufferevent *bev) { - auto guard = GetLocks(); - bool done = OnBlockingWrite(); + bool done{false}; + { + auto guard = GetLocks(); + done = OnBlockingWrite(); + } if (!done) { // The connection may be waked up but can't pop from the datatype.