Skip to content

Commit 0920147

Browse files
atakavcimgravell
authored andcommitted
new operations with BITOP command (#2900)
1 parent 551f744 commit 0920147

File tree

7 files changed

+384
-1
lines changed

7 files changed

+384
-1
lines changed

src/StackExchange.Redis/Enums/Bitwise.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,30 @@ public enum Bitwise
2424
/// <a href="https://en.wikipedia.org/wiki/Bitwise_operation#NOT">Not</a>
2525
/// </summary>
2626
Not,
27+
28+
/// <summary>
29+
/// DIFF operation: members of X that are not members of any of Y1, Y2, ...
30+
/// Equivalent to X ∧ ¬(Y1 ∨ Y2 ∨ ...)
31+
/// </summary>
32+
Diff,
33+
34+
/// <summary>
35+
/// DIFF1 operation: members of one or more of Y1, Y2, ... that are not members of X
36+
/// Equivalent to ¬X ∧ (Y1 ∨ Y2 ∨ ...)
37+
/// </summary>
38+
Diff1,
39+
40+
/// <summary>
41+
/// ANDOR operation: members of X that are also members of one or more of Y1, Y2, ...
42+
/// Equivalent to X ∧ (Y1 ∨ Y2 ∨ ...)
43+
/// </summary>
44+
AndOr,
45+
46+
/// <summary>
47+
/// ONE operation: members of exactly one of X1, X2, ...
48+
/// For two bitmaps this is equivalent to XOR. For more than two bitmaps,
49+
/// this returns bits that are set in exactly one of the input bitmaps.
50+
/// </summary>
51+
One,
2752
}
2853
}

src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,3 +1899,7 @@ static StackExchange.Redis.RedisChannel.Sharded(byte[]? value) -> StackExchange.
18991899
static StackExchange.Redis.RedisChannel.Sharded(string! value) -> StackExchange.Redis.RedisChannel
19001900
StackExchange.Redis.ClientInfo.ShardedSubscriptionCount.get -> int
19011901
StackExchange.Redis.ConfigurationOptions.SetUserPfxCertificate(string! userCertificatePath, string? password = null) -> void
1902+
StackExchange.Redis.Bitwise.AndOr = 6 -> StackExchange.Redis.Bitwise
1903+
StackExchange.Redis.Bitwise.Diff = 4 -> StackExchange.Redis.Bitwise
1904+
StackExchange.Redis.Bitwise.Diff1 = 5 -> StackExchange.Redis.Bitwise
1905+
StackExchange.Redis.Bitwise.One = 7 -> StackExchange.Redis.Bitwise

src/StackExchange.Redis/RedisFeatures.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ namespace StackExchange.Redis
4444
v7_0_0_rc1 = new Version(6, 9, 240), // 7.0 RC1 is version 6.9.240
4545
v7_2_0_rc1 = new Version(7, 1, 240), // 7.2 RC1 is version 7.1.240
4646
v7_4_0_rc1 = new Version(7, 3, 240), // 7.4 RC1 is version 7.3.240
47-
v7_4_0_rc2 = new Version(7, 3, 241); // 7.4 RC2 is version 7.3.241
47+
v7_4_0_rc2 = new Version(7, 3, 241), // 7.4 RC2 is version 7.3.241
48+
v8_2_0_rc1 = new Version(8, 1, 240); // 8.2 RC1 is version 8.1.240
4849
#pragma warning restore SA1310 // Field names should not contain underscore
4950
#pragma warning restore SA1311 // Static readonly fields should begin with upper-case letter
5051

src/StackExchange.Redis/RedisLiterals.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public static readonly RedisValue
5757
AGGREGATE = "AGGREGATE",
5858
ALPHA = "ALPHA",
5959
AND = "AND",
60+
ANDOR = "ANDOR",
6061
ANY = "ANY",
6162
ASC = "ASC",
6263
AUTH = "AUTH",
@@ -73,6 +74,8 @@ public static readonly RedisValue
7374
DB = "DB",
7475
@default = "default",
7576
DESC = "DESC",
77+
DIFF = "DIFF",
78+
DIFF1 = "DIFF1",
7679
DOCTOR = "DOCTOR",
7780
ENCODING = "ENCODING",
7881
EX = "EX",
@@ -118,6 +121,7 @@ public static readonly RedisValue
118121
NUMSUB = "NUMSUB",
119122
NX = "NX",
120123
OBJECT = "OBJECT",
124+
ONE = "ONE",
121125
OR = "OR",
122126
PATTERN = "PATTERN",
123127
PAUSE = "PAUSE",
@@ -216,6 +220,10 @@ public static readonly RedisValue
216220
Bitwise.Or => OR,
217221
Bitwise.Xor => XOR,
218222
Bitwise.Not => NOT,
223+
Bitwise.Diff => DIFF,
224+
Bitwise.Diff1 => DIFF1,
225+
Bitwise.AndOr => ANDOR,
226+
Bitwise.One => ONE,
219227
_ => throw new ArgumentOutOfRangeException(nameof(operation)),
220228
};
221229
}

tests/StackExchange.Redis.Tests/KeyPrefixedDatabaseTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,42 @@ public void StringBitOperation_2()
12601260
mock.Received().StringBitOperation(Bitwise.Xor, "prefix:destination", Arg.Is(valid), CommandFlags.None);
12611261
}
12621262

1263+
[Fact]
1264+
public void StringBitOperation_Diff()
1265+
{
1266+
RedisKey[] keys = new RedisKey[] { "x", "y1", "y2" };
1267+
Expression<Predicate<RedisKey[]>> valid = _ => _.Length == 3 && _[0] == "prefix:x" && _[1] == "prefix:y1" && _[2] == "prefix:y2";
1268+
prefixed.StringBitOperation(Bitwise.Diff, "destination", keys, CommandFlags.None);
1269+
mock.Received().StringBitOperation(Bitwise.Diff, "prefix:destination", Arg.Is(valid), CommandFlags.None);
1270+
}
1271+
1272+
[Fact]
1273+
public void StringBitOperation_Diff1()
1274+
{
1275+
RedisKey[] keys = new RedisKey[] { "x", "y1", "y2" };
1276+
Expression<Predicate<RedisKey[]>> valid = _ => _.Length == 3 && _[0] == "prefix:x" && _[1] == "prefix:y1" && _[2] == "prefix:y2";
1277+
prefixed.StringBitOperation(Bitwise.Diff1, "destination", keys, CommandFlags.None);
1278+
mock.Received().StringBitOperation(Bitwise.Diff1, "prefix:destination", Arg.Is(valid), CommandFlags.None);
1279+
}
1280+
1281+
[Fact]
1282+
public void StringBitOperation_AndOr()
1283+
{
1284+
RedisKey[] keys = new RedisKey[] { "x", "y1", "y2" };
1285+
Expression<Predicate<RedisKey[]>> valid = _ => _.Length == 3 && _[0] == "prefix:x" && _[1] == "prefix:y1" && _[2] == "prefix:y2";
1286+
prefixed.StringBitOperation(Bitwise.AndOr, "destination", keys, CommandFlags.None);
1287+
mock.Received().StringBitOperation(Bitwise.AndOr, "prefix:destination", Arg.Is(valid), CommandFlags.None);
1288+
}
1289+
1290+
[Fact]
1291+
public void StringBitOperation_One()
1292+
{
1293+
RedisKey[] keys = new RedisKey[] { "a", "b", "c" };
1294+
Expression<Predicate<RedisKey[]>> valid = _ => _.Length == 3 && _[0] == "prefix:a" && _[1] == "prefix:b" && _[2] == "prefix:c";
1295+
prefixed.StringBitOperation(Bitwise.One, "destination", keys, CommandFlags.None);
1296+
mock.Received().StringBitOperation(Bitwise.One, "prefix:destination", Arg.Is(valid), CommandFlags.None);
1297+
}
1298+
12631299
[Fact]
12641300
public void StringBitPosition()
12651301
{

tests/StackExchange.Redis.Tests/KeyPrefixedTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,42 @@ public async Task StringBitOperationAsync_2()
11761176
await mock.Received().StringBitOperationAsync(Bitwise.Xor, "prefix:destination", Arg.Is(valid), CommandFlags.None);
11771177
}
11781178

1179+
[Fact]
1180+
public async Task StringBitOperationAsync_Diff()
1181+
{
1182+
RedisKey[] keys = new RedisKey[] { "x", "y1", "y2" };
1183+
Expression<Predicate<RedisKey[]>> valid = _ => _.Length == 3 && _[0] == "prefix:x" && _[1] == "prefix:y1" && _[2] == "prefix:y2";
1184+
await prefixed.StringBitOperationAsync(Bitwise.Diff, "destination", keys, CommandFlags.None);
1185+
await mock.Received().StringBitOperationAsync(Bitwise.Diff, "prefix:destination", Arg.Is(valid), CommandFlags.None);
1186+
}
1187+
1188+
[Fact]
1189+
public async Task StringBitOperationAsync_Diff1()
1190+
{
1191+
RedisKey[] keys = new RedisKey[] { "x", "y1", "y2" };
1192+
Expression<Predicate<RedisKey[]>> valid = _ => _.Length == 3 && _[0] == "prefix:x" && _[1] == "prefix:y1" && _[2] == "prefix:y2";
1193+
await prefixed.StringBitOperationAsync(Bitwise.Diff1, "destination", keys, CommandFlags.None);
1194+
await mock.Received().StringBitOperationAsync(Bitwise.Diff1, "prefix:destination", Arg.Is(valid), CommandFlags.None);
1195+
}
1196+
1197+
[Fact]
1198+
public async Task StringBitOperationAsync_AndOr()
1199+
{
1200+
RedisKey[] keys = new RedisKey[] { "x", "y1", "y2" };
1201+
Expression<Predicate<RedisKey[]>> valid = _ => _.Length == 3 && _[0] == "prefix:x" && _[1] == "prefix:y1" && _[2] == "prefix:y2";
1202+
await prefixed.StringBitOperationAsync(Bitwise.AndOr, "destination", keys, CommandFlags.None);
1203+
await mock.Received().StringBitOperationAsync(Bitwise.AndOr, "prefix:destination", Arg.Is(valid), CommandFlags.None);
1204+
}
1205+
1206+
[Fact]
1207+
public async Task StringBitOperationAsync_One()
1208+
{
1209+
RedisKey[] keys = new RedisKey[] { "a", "b", "c" };
1210+
Expression<Predicate<RedisKey[]>> valid = _ => _.Length == 3 && _[0] == "prefix:a" && _[1] == "prefix:b" && _[2] == "prefix:c";
1211+
await prefixed.StringBitOperationAsync(Bitwise.One, "destination", keys, CommandFlags.None);
1212+
await mock.Received().StringBitOperationAsync(Bitwise.One, "prefix:destination", Arg.Is(valid), CommandFlags.None);
1213+
}
1214+
11791215
[Fact]
11801216
public async Task StringBitPositionAsync()
11811217
{

0 commit comments

Comments
 (0)