Skip to content

Commit 34580dc

Browse files
author
aserebriyskiy
committed
feat userver: support redis bitop
Testing: new tests bf83aa8928cdc3f7e2f7cecb77c8e2f8c9e77944
1 parent ebb6908 commit 34580dc

20 files changed

+208
-1
lines changed

.mapping.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2449,6 +2449,7 @@
24492449
"redis/functional_tests/pytest_redis_cluster_topology_plugin/package/ya.make":"taxi/uservices/userver/redis/functional_tests/pytest_redis_cluster_topology_plugin/package/ya.make",
24502450
"redis/functional_tests/pytest_redis_cluster_topology_plugin/pytest_plugin.py":"taxi/uservices/userver/redis/functional_tests/pytest_redis_cluster_topology_plugin/pytest_plugin.py",
24512451
"redis/functional_tests/pytest_redis_cluster_topology_plugin/ya.make":"taxi/uservices/userver/redis/functional_tests/pytest_redis_cluster_topology_plugin/ya.make",
2452+
"redis/include/userver/storages/redis/bit_operation.hpp":"taxi/uservices/userver/redis/include/userver/storages/redis/bit_operation.hpp",
24522453
"redis/include/userver/storages/redis/client.hpp":"taxi/uservices/userver/redis/include/userver/storages/redis/client.hpp",
24532454
"redis/include/userver/storages/redis/client_fwd.hpp":"taxi/uservices/userver/redis/include/userver/storages/redis/client_fwd.hpp",
24542455
"redis/include/userver/storages/redis/command_control.hpp":"taxi/uservices/userver/redis/include/userver/storages/redis/command_control.hpp",
@@ -2485,6 +2486,7 @@
24852486
"redis/include/userver/storages/redis/subscription_token.hpp":"taxi/uservices/userver/redis/include/userver/storages/redis/subscription_token.hpp",
24862487
"redis/include/userver/storages/redis/transaction.hpp":"taxi/uservices/userver/redis/include/userver/storages/redis/transaction.hpp",
24872488
"redis/library.yaml":"taxi/uservices/userver/redis/library.yaml",
2489+
"redis/src/storages/redis/bit_operation.cpp":"taxi/uservices/userver/redis/src/storages/redis/bit_operation.cpp",
24882490
"redis/src/storages/redis/client.cpp":"taxi/uservices/userver/redis/src/storages/redis/client.cpp",
24892491
"redis/src/storages/redis/client_cluster_redistest.cpp":"taxi/uservices/userver/redis/src/storages/redis/client_cluster_redistest.cpp",
24902492
"redis/src/storages/redis/client_cluster_redistest.hpp":"taxi/uservices/userver/redis/src/storages/redis/client_cluster_redistest.hpp",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
#include <string>
4+
5+
USERVER_NAMESPACE_BEGIN
6+
7+
namespace storages::redis {
8+
9+
enum class BitOperation { kAnd, kOr, kXor, kNot };
10+
11+
std::string ToString(BitOperation bitop);
12+
13+
} // namespace storages::redis
14+
15+
USERVER_NAMESPACE_END

redis/include/userver/storages/redis/client.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <userver/storages/redis/impl/base.hpp>
1111
#include <userver/storages/redis/impl/wait_connected_mode.hpp>
1212

13+
#include <userver/storages/redis/bit_operation.hpp>
1314
#include <userver/storages/redis/client_fwd.hpp>
1415
#include <userver/storages/redis/command_options.hpp>
1516
#include <userver/storages/redis/request.hpp>
@@ -62,6 +63,10 @@ class Client {
6263
virtual RequestAppend Append(std::string key, std::string value,
6364
const CommandControl& command_control) = 0;
6465

66+
virtual RequestBitop Bitop(BitOperation op, std::string dest_key,
67+
std::vector<std::string> src_keys,
68+
const CommandControl& command_control) = 0;
69+
6570
virtual RequestDbsize Dbsize(size_t shard,
6671
const CommandControl& command_control) = 0;
6772

redis/include/userver/storages/redis/request.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ class ScanRequest final {
151151
};
152152

153153
using RequestAppend = Request<size_t>;
154+
using RequestBitop = Request<size_t>;
154155
using RequestDbsize = Request<size_t>;
155156
using RequestDel = Request<size_t>;
156157
using RequestUnlink = Request<size_t>;

redis/include/userver/storages/redis/transaction.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <memory>
77
#include <string>
88

9+
#include <userver/storages/redis/bit_operation.hpp>
910
#include <userver/storages/redis/command_options.hpp>
1011
#include <userver/storages/redis/request.hpp>
1112

@@ -43,6 +44,9 @@ class Transaction {
4344

4445
virtual RequestAppend Append(std::string key, std::string value) = 0;
4546

47+
virtual RequestBitop Bitop(BitOperation op, std::string dest,
48+
std::vector<std::string> srcs) = 0;
49+
4650
virtual RequestDbsize Dbsize(size_t shard) = 0;
4751

4852
virtual RequestDel Del(std::string key) = 0;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <userver/storages/redis/bit_operation.hpp>
2+
3+
USERVER_NAMESPACE_BEGIN
4+
5+
namespace storages::redis {
6+
7+
std::string ToString(BitOperation bitop) {
8+
std::string operation{"ERR"};
9+
switch (bitop) {
10+
case BitOperation::kOr:
11+
operation = "OR";
12+
break;
13+
case BitOperation::kXor:
14+
operation = "XOR";
15+
break;
16+
case BitOperation::kAnd:
17+
operation = "AND";
18+
break;
19+
case BitOperation::kNot:
20+
operation = "NOT";
21+
break;
22+
}
23+
24+
return operation;
25+
}
26+
27+
} // namespace storages::redis
28+
29+
USERVER_NAMESPACE_END

redis/src/storages/redis/client_impl.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,18 @@ RequestAppend ClientImpl::Append(std::string key, std::string value,
9999
true, GetCommandControl(command_control)));
100100
}
101101

102+
RequestBitop ClientImpl::Bitop(BitOperation op, std::string dest_key,
103+
std::vector<std::string> src_keys,
104+
const CommandControl& command_control) {
105+
auto shard = ShardByKey(dest_key, command_control);
106+
const auto operation = ToString(op);
107+
108+
return CreateRequest<RequestBitop>(
109+
MakeRequest(CmdArgs{"bitop", std::move(operation), std::move(dest_key),
110+
std::move(src_keys)},
111+
shard, true, GetCommandControl(command_control)));
112+
}
113+
102114
RequestDbsize ClientImpl::Dbsize(size_t shard,
103115
const CommandControl& command_control) {
104116
CheckShard(shard, command_control);

redis/src/storages/redis/client_impl.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ class ClientImpl final : public Client,
6262
RequestAppend Append(std::string key, std::string value,
6363
const CommandControl& command_control) override;
6464

65+
RequestBitop Bitop(BitOperation op, std::string dest_key,
66+
std::vector<std::string> src_keys,
67+
const CommandControl& command_control) override;
68+
6569
RequestDbsize Dbsize(size_t shard,
6670
const CommandControl& command_control) override;
6771

redis/src/storages/redis/client_redistest.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,52 @@ UTEST_F(RedisClientTest, Append) {
171171
EXPECT_EQ(client->Get("key", {}).Get(), "Hello World");
172172
}
173173

174+
UTEST_F(RedisClientTest, BitopAnd) {
175+
auto client = GetClient();
176+
client->Set("bit1", "acbd", {}).Get();
177+
client->Set("bit2", "def8", {}).Get();
178+
EXPECT_EQ(client
179+
->Bitop(storages::redis::BitOperation::kAnd, "dest",
180+
{"bit1", "bit2"}, {})
181+
.Get(),
182+
4);
183+
EXPECT_EQ(client->Get("dest", {}).Get(), "`ab ");
184+
}
185+
186+
UTEST_F(RedisClientTest, BitopOr) {
187+
auto client = GetClient();
188+
client->Set("bit1", "acbd", {}).Get();
189+
client->Set("bit2", "def8", {}).Get();
190+
EXPECT_EQ(client
191+
->Bitop(storages::redis::BitOperation::kOr, "dest",
192+
{"bit1", "bit2"}, {})
193+
.Get(),
194+
4);
195+
EXPECT_EQ(client->Get("dest", {}).Get(), "egf|");
196+
}
197+
198+
UTEST_F(RedisClientTest, BitopXor) {
199+
auto client = GetClient();
200+
client->Set("bit1", "acbd", {}).Get();
201+
client->Set("bit2", "def8", {}).Get();
202+
EXPECT_EQ(client
203+
->Bitop(storages::redis::BitOperation::kXor, "dest",
204+
{"bit1", "bit2"}, {})
205+
.Get(),
206+
4);
207+
EXPECT_EQ(client->Get("dest", {}).Get(), "\x5\x6\x4\\");
208+
}
209+
210+
UTEST_F(RedisClientTest, BitopNot) {
211+
auto client = GetClient();
212+
client->Set("bit1", "acbd", {}).Get();
213+
EXPECT_EQ(
214+
client->Bitop(storages::redis::BitOperation::kNot, "dest", {"bit1"}, {})
215+
.Get(),
216+
4);
217+
EXPECT_EQ(client->Get("dest", {}).Get(), "\x9E\x9C\x9D\x9B");
218+
}
219+
174220
UTEST_F(RedisClientTest, Dbsize) {
175221
auto client = GetClient();
176222
EXPECT_EQ(client->Dbsize(0, {}).Get(), 0);

redis/src/storages/redis/impl/redis_stats.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace {
2020
const std::string_view kCommandTypes[] = {
2121
"append",
2222
"auth",
23+
"bitop",
2324
"cluster",
2425
"dbsize",
2526
"del",
@@ -178,7 +179,9 @@ void Statistics::AccountReplyReceived(const ReplyPtr& reply,
178179
} else {
179180
LOG_LIMITED_WARNING() << "Cannot account timings for unknown command '"
180181
<< cmd->GetName() << '\'';
181-
UASSERT_MSG(false, "Cannot account timings for unknown command");
182+
UASSERT_MSG(false,
183+
fmt::format("Cannot account timings for unknown command {}",
184+
cmd->GetName()));
182185
}
183186

184187
AccountError(reply->status);

0 commit comments

Comments
 (0)