Skip to content

Commit 74a1fe0

Browse files
shacharPashchayim
andauthored
Add bloom (BF) commands (#3)
Co-authored-by: Chayim <chayim@users.noreply.github.com>
1 parent ae9715a commit 74a1fe0

File tree

7 files changed

+423
-70
lines changed

7 files changed

+423
-70
lines changed

src/NRedisStack.Core/Bloom/BloomCommands.cs

Lines changed: 147 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using NRedisStack.Core.Bloom.DataTypes;
12
using NRedisStack.Core.Literals;
23
using StackExchange.Redis;
34
namespace NRedisStack.Core
@@ -11,24 +12,62 @@ public BloomCommands(IDatabase db)
1112
_db = db;
1213
}
1314

14-
public RedisResult Add(RedisKey key, string item)
15+
/// <summary>
16+
/// Adds an item to a Bloom Filter.
17+
/// </summary>
18+
/// <param name="key">The key under which the filter is found.</param>
19+
/// <param name="item">The item to add.</param>
20+
/// <returns><see langword="true"/> if the item did not exist in the filter, <see langword="false"/> otherwise.</returns>
21+
/// <remarks><seealso href="https://redis.io/commands/bf.add"/></remarks>
22+
public bool Add(RedisKey key, RedisValue item)
1523
{
16-
return _db.Execute(BF.ADD, key, item);
24+
return _db.Execute(BF.ADD, key, item).ToString() == "1";
1725
}
1826

19-
public bool Exists(RedisKey key, string item)
27+
/// <summary>
28+
/// Checks whether an item exist in the Bloom Filter or not.
29+
/// </summary>
30+
/// <param name="key">The name of the filter.</param>
31+
/// <param name="item">The item to check for.</param>
32+
/// <returns><see langword="true"/> means the item may exist in the filter,
33+
/// and <see langword="false"/> means the item may exist in the filter.</returns>
34+
/// <remarks><seealso href="https://redis.io/commands/bf.exists"/></remarks>
35+
public bool Exists(RedisKey key, RedisValue item)
2036
{
2137
return _db.Execute(BF.EXISTS, key, item).ToString() == "1";
2238
}
2339

24-
public RedisResult Info(RedisKey key)
40+
/// <summary>
41+
/// Return information about a bloom filter.
42+
/// </summary>
43+
/// <param name="key">Name of the key to return information about.</param>
44+
/// <returns>Array with information of the filter.</returns>
45+
/// <remarks><seealso href="https://redis.io/commands/bf.info"/></remarks>
46+
public BloomInformation? Info(RedisKey key)
2547
{
26-
return _db.Execute(BF.INFO, key);
48+
var info = _db.Execute(BF.INFO, key);
49+
return ResponseParser.ToBloomInfo(info);
2750
}
2851

29-
public RedisResult Insert(RedisKey key, RedisValue[] items, int? capacity = null,
52+
/// <summary>
53+
/// Adds one or more items to a Bloom Filter. A filter will be created if it does not exist.
54+
/// </summary>
55+
/// <param name="key">The name of the filter.</param>
56+
/// <param name="items">One or more items to add.</param>
57+
/// <param name="capacity">(Optional) Specifies the desired capacity for the filter to be created.</param>
58+
/// <param name="error">(Optional) Specifies the error ratio of the newly created filter if it does not yet exist.</param>
59+
/// <param name="expansion">(Optional) When capacity is reached, an additional sub-filter is
60+
/// created in size of the last sub-filter multiplied by expansion.</param>
61+
/// <param name="nocreate">(Optional) <see langword="true"/> to indicates that the
62+
/// filter should not be created if it does not already exist.</param>
63+
/// <param name="nonscaling">(Optional) <see langword="true"/> toprevent the filter
64+
/// from creating additional sub-filters if initial capacity is reached.</param>
65+
/// <returns>An array of booleans. Each element is either true or false depending on whether the
66+
/// corresponding input element was newly added to the filter or may have previously existed.</returns>
67+
/// <remarks><seealso href="https://redis.io/commands/bf.insert"/></remarks>
68+
public bool[] Insert(RedisKey key, RedisValue[] items, int? capacity = null,
3069
double? error = null, int? expansion = null,
31-
bool nocreate = false, bool nonscaling = false) //NOT DONE
70+
bool nocreate = false, bool nonscaling = false)
3271
{
3372
if (items == null)
3473
throw new ArgumentNullException(nameof(items));
@@ -54,29 +93,125 @@ public RedisResult Insert(RedisKey key, RedisValue[] items, int? capacity = null
5493
}
5594

5695
if (nocreate)
96+
{
5797
args.Add(BloomArgs.NOCREATE);
5898

99+
}
100+
59101
if (nonscaling)
102+
{
60103
args.Add(BloomArgs.NONSCALING);
104+
}
61105

62106
args.Add(BloomArgs.ITEMS);
63107
foreach (var item in items)
64108
{
65109
args.Add(item);
66110
}
67111

68-
return _db.Execute(BF.INSERT, args);
112+
return ResponseParser.ToBooleanArray(_db.Execute(BF.INSERT, args));
69113
}
70114

71-
public RedisResult ScanDump(RedisKey key, int iterator)
115+
/// <summary>
116+
/// Restores a filter previosly saved using SCANDUMP.
117+
/// </summary>
118+
/// <param name="key">Name of the key to restore.</param>
119+
/// <param name="iterator">Iterator value associated with data (returned by SCANDUMP).</param>
120+
/// <param name="data">Current data chunk (returned by SCANDUMP).</param>
121+
/// <returns>Array with information of the filter.</returns>
122+
/// <remarks><seealso href="https://redis.io/commands/bf.loadchunk"/></remarks>
123+
public bool LoadChunk(RedisKey key, long iterator, Byte[] data)
72124
{
73-
return _db.Execute(BF.SCANDUMP, key, iterator);
125+
return ResponseParser.ParseOKtoBoolean(_db.Execute(BF.LOADCHUNK, key, iterator, data));
74126
}
75127

76-
public RedisResult LoadChunk(RedisKey key, int iterator, RedisValue data)
128+
/// <summary>
129+
/// Adds one or more items to the Bloom Filter. A filter will be created if it does not exist yet.
130+
/// </summary>
131+
/// <param name="key">The name of the filter.</param>
132+
/// <param name="items">One or more items to add.</param>
133+
/// <returns>An array of booleans. Each element is either true or false depending on whether the
134+
/// corresponding input element was newly added to the filter or may have previously existed.</returns>
135+
/// <remarks><seealso href="https://redis.io/commands/bf.madd"/></remarks>
136+
public bool[] MAdd(RedisKey key, RedisValue[] items)
77137
{
78-
return _db.Execute(BF.LOADCHUNK, key, iterator, data);
138+
if (items == null)
139+
throw new ArgumentNullException(nameof(items));
140+
141+
List<object> args = new List<object> { key };
142+
143+
foreach (var item in items)
144+
{
145+
args.Add(item);
146+
}
147+
148+
return ResponseParser.ToBooleanArray(_db.Execute(BF.MADD, args));
79149
}
80150

151+
/// <summary>
152+
/// Checks whether one or more items may exist in the filter or not.
153+
/// </summary>
154+
/// <param name="key">The name of the filter.</param>
155+
/// <param name="items">One or more items to check.</param>
156+
/// <returns>An array of booleans, for each item <see langword="true"/> means the item may exist in the filter,
157+
/// and <see langword="false"/> means the item may exist in the filter.</returns>
158+
/// <remarks><seealso href="https://redis.io/commands/bf.mexists"/></remarks>
159+
public bool[] MExists(RedisKey key, RedisValue[] items)
160+
{
161+
if (items == null)
162+
throw new ArgumentNullException(nameof(items));
163+
164+
List<object> args = new List<object> { key };
165+
166+
foreach (var item in items)
167+
{
168+
args.Add(item);
169+
}
170+
171+
return ResponseParser.ToBooleanArray(_db.Execute(BF.MEXISTS, args));
172+
173+
}
174+
175+
/// <summary>
176+
/// Creates a new Bloom Filter.
177+
/// </summary>
178+
/// <param name="key">The key under which the filter is found.</param>
179+
/// <param name="errorRate">The desired probability for false positives (value between 0 to 1).</param>
180+
/// <param name="capacity">The number of entries intended to be added to the filter.</param>
181+
/// <param name="expansion">(Optional) When capacity is reached, an additional sub-filter is
182+
/// created in size of the last sub-filter multiplied by expansion.</param>
183+
/// <param name="nonscaling">(Optional) <see langword="true"/> toprevent the filter
184+
/// from creating additional sub-filters if initial capacity is reached.</param>
185+
/// <returns><see langword="true"/> if executed correctly, <see langword="false"/> otherwise.</returns>
186+
/// <remarks><seealso href="https://redis.io/commands/bf.reserve"/></remarks>
187+
public bool Reserve(RedisKey key, double errorRate, long capacity,
188+
int? expansion = null, bool nonscaling = false)
189+
{
190+
List<object> args = new List<object> { key, errorRate, capacity };
191+
192+
if (expansion != null)
193+
{
194+
args.Add(expansion);
195+
}
196+
197+
if (nonscaling)
198+
{
199+
args.Add(BloomArgs.NONSCALING);
200+
}
201+
202+
return ResponseParser.ParseOKtoBoolean(_db.Execute(BF.RESERVE, args));
203+
}
204+
205+
/// <summary>
206+
/// Restores a filter previosly saved using SCANDUMP.
207+
/// </summary>
208+
/// <param name="key">Name of the filter.</param>
209+
/// <param name="iterator">Iterator value; either 0 or the iterator from a previous invocation of this command.</param>
210+
/// <returns>Tuple of iterator and data.</returns>
211+
/// <remarks><seealso href="https://redis.io/commands/bf.scandump"/></remarks>
212+
public Tuple<long,Byte[]>? ScanDump(RedisKey key, long iterator)
213+
{
214+
return ResponseParser.ToScanDumpTuple(_db.Execute(BF.SCANDUMP, key, iterator));
215+
}
81216
}
82217
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
namespace NRedisStack.Core.Bloom.DataTypes
2+
{
3+
/// <summary>
4+
/// This class represents the response for BF.INFO command.
5+
/// This object has Read-only properties and cannot be generated outside a BF.INFO response.
6+
/// </summary>
7+
public class BloomInformation
8+
{
9+
public long Capacity { get; private set; }
10+
public long Size { get; private set; }
11+
public long NumberOfFilters { get; private set; }
12+
public long NumberOfItemsInserted { get; private set; }
13+
public long ExpansionRate { get; private set; }
14+
15+
internal BloomInformation(long capacity, long size, long numberOfFilters, long numberOfItemsInserted, long expansionRate)
16+
{
17+
Capacity = capacity;
18+
Size = size;
19+
NumberOfFilters = numberOfFilters;
20+
NumberOfItemsInserted = numberOfItemsInserted;
21+
ExpansionRate = expansionRate;
22+
}
23+
}
24+
}

src/NRedisStack.Core/Json/JsonCommands.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,15 @@ public RedisResult Set(RedisKey key, RedisValue path, RedisValue json, When when
3535
}
3636
}
3737

38-
public RedisResult Get(RedisKey key, RedisValue? indent = null,
39-
RedisValue? newLine = null, RedisValue? space = null, RedisValue? path = null)
38+
public RedisResult Get(RedisKey key,
39+
RedisValue? indent = null,
40+
RedisValue? newLine = null,
41+
RedisValue? space = null,
42+
RedisValue? path = null)
4043
{
41-
List<object> args = new List<object>();
42-
args.Add(key);
44+
45+
List<object> args = new List<object>(){key};
46+
4347
if (indent != null)
4448
{
4549
args.Add(JsonArgs.INDENT);

0 commit comments

Comments
 (0)