Commit 102039d5 authored by Marc Gravell's avatar Marc Gravell

Make SetPopMultiple available on RedisFeatures; use in test; test for explicit...

Make SetPopMultiple available on RedisFeatures; use in test; test for explicit single SPOP; add fast zero SPOP
parent c8025c22
...@@ -57,13 +57,16 @@ public async Task SetRemoveArgTests() ...@@ -57,13 +57,16 @@ public async Task SetRemoveArgTests()
} }
[Fact] [Fact]
public void SetPop() public void SetPopMulti_Multi()
{ {
using (var conn = Create()) using (var conn = Create())
{ {
Skip.IfMissingFeature(conn, nameof(RedisFeatures.SetPopMultiple), r => r.SetPopMultiple);
var db = conn.GetDatabase(); var db = conn.GetDatabase();
var key = Me(); var key = Me();
db.KeyDelete(key);
for (int i = 1; i < 11; i++) for (int i = 1; i < 11; i++)
{ {
db.SetAdd(key, i); db.SetAdd(key, i);
...@@ -81,15 +84,44 @@ public void SetPop() ...@@ -81,15 +84,44 @@ public void SetPop()
Assert.Equal(7, db.SetLength(key)); Assert.Equal(7, db.SetLength(key));
} }
} }
[Fact]
public void SetPopMulti_Single()
{
using (var conn = Create())
{
var db = conn.GetDatabase();
var key = Me();
db.KeyDelete(key);
for (int i = 1; i < 11; i++)
{
db.SetAdd(key, i);
}
var random = db.SetPop(key);
Assert.False(random.IsNull);
Assert.True((int)random > 0);
Assert.True((int)random < 10);
Assert.Equal(9, db.SetLength(key));
var moreRandoms = db.SetPop(key, 1);
Assert.Single(moreRandoms);
Assert.False(moreRandoms[0].IsNull);
Assert.Equal(8, db.SetLength(key));
}
}
[Fact] [Fact]
public async Task SetPopAsync() public async Task SetPopMulti_Multi_Async()
{ {
using (var conn = Create()) using (var conn = Create())
{ {
Skip.IfMissingFeature(conn, nameof(RedisFeatures.SetPopMultiple), r => r.SetPopMultiple);
var db = conn.GetDatabase(); var db = conn.GetDatabase();
var key = Me(); var key = Me();
db.KeyDelete(key);
for (int i = 1; i < 11; i++) for (int i = 1; i < 11; i++)
{ {
db.SetAdd(key, i); db.SetAdd(key, i);
...@@ -107,5 +139,55 @@ public async Task SetPopAsync() ...@@ -107,5 +139,55 @@ public async Task SetPopAsync()
Assert.Equal(7, db.SetLength(key)); Assert.Equal(7, db.SetLength(key));
} }
} }
[Fact]
public async Task SetPopMulti_Single_Async()
{
using (var conn = Create())
{
var db = conn.GetDatabase();
var key = Me();
db.KeyDelete(key);
for (int i = 1; i < 11; i++)
{
db.SetAdd(key, i);
}
var random = await db.SetPopAsync(key).ForAwait();
Assert.False(random.IsNull);
Assert.True((int)random > 0);
Assert.True((int)random < 10);
Assert.Equal(9, db.SetLength(key));
var moreRandoms = db.SetPop(key, 1);
Assert.Single(moreRandoms);
Assert.False(moreRandoms[0].IsNull);
Assert.Equal(8, db.SetLength(key));
}
}
[Fact]
public async Task SetPopMulti_Zero_Async()
{
using (var conn = Create())
{
var db = conn.GetDatabase();
var key = Me();
db.KeyDelete(key);
for (int i = 1; i < 11; i++)
{
db.SetAdd(key, i);
}
var t = db.SetPopAsync(key, count: 0);
Assert.True(t.IsCompleted); // sync
var arr = await t;
Assert.Empty(arr);
Assert.Equal(10, db.SetLength(key));
}
}
} }
} }
...@@ -1253,13 +1253,19 @@ public Task<RedisValue> SetPopAsync(RedisKey key, CommandFlags flags = CommandFl ...@@ -1253,13 +1253,19 @@ public Task<RedisValue> SetPopAsync(RedisKey key, CommandFlags flags = CommandFl
public RedisValue[] SetPop(RedisKey key, long count, CommandFlags flags = CommandFlags.None) public RedisValue[] SetPop(RedisKey key, long count, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Database, flags, RedisCommand.SPOP, key, count); if (count == 0) return Array.Empty<RedisValue>();
var msg = count == 1
? Message.Create(Database, flags, RedisCommand.SPOP, key)
: Message.Create(Database, flags, RedisCommand.SPOP, key, count);
return ExecuteSync(msg, ResultProcessor.RedisValueArray); return ExecuteSync(msg, ResultProcessor.RedisValueArray);
} }
public Task<RedisValue[]> SetPopAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None) public Task<RedisValue[]> SetPopAsync(RedisKey key, long count, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Database, flags, RedisCommand.SPOP, key, count); if(count == 0) return Task.FromResult(Array.Empty<RedisValue>());
var msg = count == 1
? Message.Create(Database, flags, RedisCommand.SPOP, key)
: Message.Create(Database, flags, RedisCommand.SPOP, key, count);
return ExecuteAsync(msg, ResultProcessor.RedisValueArray); return ExecuteAsync(msg, ResultProcessor.RedisValueArray);
} }
......
...@@ -150,6 +150,11 @@ public RedisFeatures(Version version) ...@@ -150,6 +150,11 @@ public RedisFeatures(Version version)
/// </summary> /// </summary>
public bool Geo => Version >= v3_2_0; public bool Geo => Version >= v3_2_0;
/// <summary>
/// Does SetPop support popping multiple items?
/// </summary>
public bool SetPopMultiple => Version >= v3_2_0;
/// <summary> /// <summary>
/// The Redis version of the server /// The Redis version of the server
/// </summary> /// </summary>
......
...@@ -1119,9 +1119,13 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes ...@@ -1119,9 +1119,13 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
{ {
switch (result.Type) switch (result.Type)
{ {
// allow a single item to pass explicitly pretending to be an array; example: SPOP {key} 1
case ResultType.BulkString:
var arr = new[] { result.AsRedisValue() };
SetResult(message, arr);
return true;
case ResultType.MultiBulk: case ResultType.MultiBulk:
var arr = result.GetItemsAsValues(); arr = result.GetItemsAsValues();
SetResult(message, arr); SetResult(message, arr);
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment