Commit c70bc5d4 authored by Marc Gravell's avatar Marc Gravell

BREAKING CHANGE: KeyValuePair<,> is really confusing for talking about hashes...

BREAKING CHANGE: KeyValuePair<,> is really confusing for talking about hashes and sorted sets; this fixes that, but changes the API
parent 82a112c8
using System; using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework; using NUnit.Framework;
namespace StackExchange.Redis.Tests namespace StackExchange.Redis.Tests
...@@ -56,9 +52,19 @@ public void SortedSetScan(bool supported) ...@@ -56,9 +52,19 @@ public void SortedSetScan(bool supported)
var arr = db.SortedSetScan(key).ToArray(); var arr = db.SortedSetScan(key).ToArray();
Assert.AreEqual(3, arr.Length); Assert.AreEqual(3, arr.Length);
Assert.IsTrue(arr.Any(x => x.Key == "a" && x.Value == 1), "a"); Assert.IsTrue(arr.Any(x => x.Element == "a" && x.Score == 1), "a");
Assert.IsTrue(arr.Any(x => x.Key == "b" && x.Value == 2), "b"); Assert.IsTrue(arr.Any(x => x.Element == "b" && x.Score == 2), "b");
Assert.IsTrue(arr.Any(x => x.Key == "c" && x.Value == 3), "c"); Assert.IsTrue(arr.Any(x => x.Element == "c" && x.Score == 3), "c");
var dictionary = arr.ToDictionary();
Assert.AreEqual(1, dictionary["a"]);
Assert.AreEqual(2, dictionary["b"]);
Assert.AreEqual(3, dictionary["c"]);
var sDictionary = arr.ToStringDictionary();
Assert.AreEqual(1, sDictionary["a"]);
Assert.AreEqual(2, sDictionary["b"]);
Assert.AreEqual(3, sDictionary["c"]);
} }
} }
...@@ -80,9 +86,19 @@ public void HashScan(bool supported) ...@@ -80,9 +86,19 @@ public void HashScan(bool supported)
var arr = db.HashScan(key).ToArray(); var arr = db.HashScan(key).ToArray();
Assert.AreEqual(3, arr.Length); Assert.AreEqual(3, arr.Length);
Assert.IsTrue(arr.Any(x => x.Key == "a" && x.Value == "1"), "a"); Assert.IsTrue(arr.Any(x => x.Name == "a" && x.Value == "1"), "a");
Assert.IsTrue(arr.Any(x => x.Key == "b" && x.Value == "2"), "b"); Assert.IsTrue(arr.Any(x => x.Name == "b" && x.Value == "2"), "b");
Assert.IsTrue(arr.Any(x => x.Key == "c" && x.Value == "3"), "c"); Assert.IsTrue(arr.Any(x => x.Name == "c" && x.Value == "3"), "c");
var dictionary = arr.ToDictionary();
Assert.AreEqual(1, (long)dictionary["a"]);
Assert.AreEqual(2, (long)dictionary["b"]);
Assert.AreEqual(3, (long)dictionary["c"]);
var sDictionary = arr.ToStringDictionary();
Assert.AreEqual("1", sDictionary["a"]);
Assert.AreEqual("2", sDictionary["b"]);
Assert.AreEqual("3", sDictionary["c"]);
} }
} }
......
...@@ -64,6 +64,8 @@ ...@@ -64,6 +64,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="StackExchange\Redis\Aggregate.cs" /> <Compile Include="StackExchange\Redis\Aggregate.cs" />
<Compile Include="StackExchange\Redis\ExtensionMethods.cs" />
<Compile Include="StackExchange\Redis\HashEntry.cs" />
<Compile Include="StackExchange\Redis\InternalErrorEventArgs.cs" /> <Compile Include="StackExchange\Redis\InternalErrorEventArgs.cs" />
<Compile Include="StackExchange\Redis\RedisChannel.cs" /> <Compile Include="StackExchange\Redis\RedisChannel.cs" />
<Compile Include="StackExchange\Redis\Bitwise.cs" /> <Compile Include="StackExchange\Redis\Bitwise.cs" />
...@@ -139,6 +141,7 @@ ...@@ -139,6 +141,7 @@
<Compile Include="StackExchange\Redis\SocketManager.NoPoll.cs"> <Compile Include="StackExchange\Redis\SocketManager.NoPoll.cs">
<DependentUpon>SocketManager.cs</DependentUpon> <DependentUpon>SocketManager.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="StackExchange\Redis\SortedSetEntry.cs" />
<Compile Include="StackExchange\Redis\SortType.cs" /> <Compile Include="StackExchange\Redis\SortType.cs" />
<Compile Include="StackExchange\Redis\StringSplits.cs" /> <Compile Include="StackExchange\Redis\StringSplits.cs" />
<Compile Include="StackExchange\Redis\TaskSource.cs" /> <Compile Include="StackExchange\Redis\TaskSource.cs" />
......
using System;
using System.Collections.Generic;
namespace StackExchange.Redis
{
/// <summary>
/// Utility methods
/// </summary>
public static class ExtensionMethods
{
/// <summary>
/// Create a dictionary from an array of HashEntry values
/// </summary>
public static Dictionary<string,string> ToStringDictionary(this HashEntry[] hash)
{
if (hash == null) return null;
var result = new Dictionary<string, string>(hash.Length, StringComparer.Ordinal);
for(int i = 0; i < hash.Length; i++)
{
result.Add(hash[i].name, hash[i].value);
}
return result;
}
/// <summary>
/// Create a dictionary from an array of HashEntry values
/// </summary>
public static Dictionary<RedisValue, RedisValue> ToDictionary(this HashEntry[] hash)
{
if (hash == null) return null;
var result = new Dictionary<RedisValue, RedisValue>(hash.Length);
for (int i = 0; i < hash.Length; i++)
{
result.Add(hash[i].name, hash[i].value);
}
return result;
}
/// <summary>
/// Create a dictionary from an array of SortedSetEntry values
/// </summary>
public static Dictionary<string, double> ToStringDictionary(this SortedSetEntry[] sortedSet)
{
if (sortedSet == null) return null;
var result = new Dictionary<string, double>(sortedSet.Length, StringComparer.Ordinal);
for (int i = 0; i < sortedSet.Length; i++)
{
result.Add(sortedSet[i].element, sortedSet[i].score);
}
return result;
}
/// <summary>
/// Create a dictionary from an array of SortedSetEntry values
/// </summary>
public static Dictionary<RedisValue, double> ToDictionary(this SortedSetEntry[] sortedSet)
{
if (sortedSet == null) return null;
var result = new Dictionary<RedisValue, double>(sortedSet.Length);
for (int i = 0; i < sortedSet.Length; i++)
{
result.Add(sortedSet[i].element, sortedSet[i].score);
}
return result;
}
/// <summary>
/// Create a dictionary from an array of key/value pairs
/// </summary>
public static Dictionary<string, string> ToStringDictionary(this KeyValuePair<RedisKey, RedisValue>[] pairs)
{
if (pairs == null) return null;
var result = new Dictionary<string, string>(pairs.Length, StringComparer.Ordinal);
for (int i = 0; i < pairs.Length; i++)
{
result.Add(pairs[i].Key, pairs[i].Value);
}
return result;
}
/// <summary>
/// Create a dictionary from an array of key/value pairs
/// </summary>
public static Dictionary<RedisKey, RedisValue> ToDictionary(this KeyValuePair<RedisKey, RedisValue>[] pairs)
{
if (pairs == null) return null;
var result = new Dictionary<RedisKey, RedisValue>(pairs.Length);
for (int i = 0; i < pairs.Length; i++)
{
result.Add(pairs[i].Key, pairs[i].Value);
}
return result;
}
/// <summary>
/// Create a dictionary from an array of string pairs
/// </summary>
public static Dictionary<string, string> ToDictionary(this KeyValuePair<string, string>[] pairs)
{
if (pairs == null) return null;
var result = new Dictionary<string, string>(pairs.Length, StringComparer.Ordinal);
for (int i = 0; i < pairs.Length; i++)
{
result.Add(pairs[i].Key, pairs[i].Value);
}
return result;
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace StackExchange.Redis
{
/// <summary>
/// Describes a hash-field (a name/value pair)
/// </summary>
public struct HashEntry : IEquatable<HashEntry>
{
internal readonly RedisValue name, value;
/// <summary>
/// Initializes a HashEntry value
/// </summary>
public HashEntry(RedisValue name, RedisValue value)
{
this.name = name;
this.value = value;
}
/// <summary>
/// The name of the hash field
/// </summary>
public RedisValue Name { get { return name; } }
/// <summary>
/// The value of the hash field
/// </summary>
public RedisValue Value{ get { return value; } }
/// <summary>
/// The name of the hash field
/// </summary>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Name", false)]
public RedisValue Key { get { return name; } }
/// <summary>
/// Converts to a key/value pair
/// </summary>
public static implicit operator KeyValuePair<RedisValue, RedisValue>(HashEntry value)
{
return new KeyValuePair<RedisValue, RedisValue>(value.name, value.value);
}
/// <summary>
/// Converts from a key/value pair
/// </summary>
public static implicit operator HashEntry(KeyValuePair<RedisValue, RedisValue> value)
{
return new HashEntry(value.Key, value.Value);
}
/// <summary>
/// See Object.ToString()
/// </summary>
public override string ToString()
{
return name + ": " + value;
}
/// <summary>
/// See Object.GetHashCode()
/// </summary>
public override int GetHashCode()
{
return name.GetHashCode() ^ value.GetHashCode();
}
/// <summary>
/// Compares two values for equality
/// </summary>
public override bool Equals(object obj)
{
return obj is HashEntry && Equals((HashEntry)obj);
}
/// <summary>
/// Compares two values for equality
/// </summary>
public bool Equals(HashEntry value)
{
return this.name == value.name && this.value == value.value;
}
}
}
...@@ -93,7 +93,7 @@ public interface IDatabase : IRedis, IDatabaseAsync ...@@ -93,7 +93,7 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// </summary> /// </summary>
/// <returns>list of fields and their values stored in the hash, or an empty list when key does not exist.</returns> /// <returns>list of fields and their values stored in the hash, or an empty list when key does not exist.</returns>
/// <remarks>http://redis.io/commands/hgetall</remarks> /// <remarks>http://redis.io/commands/hgetall</remarks>
KeyValuePair<RedisValue, RedisValue>[] HashGetAll(RedisKey key, CommandFlags flags = CommandFlags.None); HashEntry[] HashGetAll(RedisKey key, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Increments the number stored at field in the hash stored at key by increment. If key does not exist, a new key holding a hash is created. If field does not exist or holds a string that cannot be interpreted as integer, the value is set to 0 before the operation is performed. /// Increments the number stored at field in the hash stored at key by increment. If key does not exist, a new key holding a hash is created. If field does not exist or holds a string that cannot be interpreted as integer, the value is set to 0 before the operation is performed.
...@@ -130,13 +130,13 @@ public interface IDatabase : IRedis, IDatabaseAsync ...@@ -130,13 +130,13 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// </summary> /// </summary>
/// <returns>yields all elements of the hash.</returns> /// <returns>yields all elements of the hash.</returns>
/// <remarks>http://redis.io/commands/hscan</remarks> /// <remarks>http://redis.io/commands/hscan</remarks>
IEnumerable<KeyValuePair<RedisValue, RedisValue>> HashScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisDatabase.ScanUtils.DefaultPageSize, CommandFlags flags = CommandFlags.None); IEnumerable<HashEntry> HashScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisDatabase.ScanUtils.DefaultPageSize, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Sets the specified fields to their respective values in the hash stored at key. This command overwrites any existing fields in the hash. If key does not exist, a new key holding a hash is created. /// Sets the specified fields to their respective values in the hash stored at key. This command overwrites any existing fields in the hash. If key does not exist, a new key holding a hash is created.
/// </summary> /// </summary>
/// <remarks>http://redis.io/commands/hmset</remarks> /// <remarks>http://redis.io/commands/hmset</remarks>
void HashSet(RedisKey key, KeyValuePair<RedisValue, RedisValue>[] hashFields, CommandFlags flags = CommandFlags.None); void HashSet(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Sets field in the hash stored at key to value. If key does not exist, a new key holding a hash is created. If field already exists in the hash, it is overwritten. /// Sets field in the hash stored at key to value. If key does not exist, a new key holding a hash is created. If field already exists in the hash, it is overwritten.
...@@ -555,7 +555,7 @@ public interface IDatabase : IRedis, IDatabaseAsync ...@@ -555,7 +555,7 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// </summary> /// </summary>
/// <returns>The number of elements added to the sorted sets, not including elements already existing for which the score was updated.</returns> /// <returns>The number of elements added to the sorted sets, not including elements already existing for which the score was updated.</returns>
/// <remarks>http://redis.io/commands/zadd</remarks> /// <remarks>http://redis.io/commands/zadd</remarks>
long SortedSetAdd(RedisKey key, KeyValuePair<RedisValue, double>[] values, CommandFlags flags = CommandFlags.None); long SortedSetAdd(RedisKey key, SortedSetEntry[] values, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Computes a set operation over two sorted sets, and stores the result in destination, optionally performing /// Computes a set operation over two sorted sets, and stores the result in destination, optionally performing
...@@ -612,7 +612,7 @@ public interface IDatabase : IRedis, IDatabaseAsync ...@@ -612,7 +612,7 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// <returns>list of elements in the specified range</returns> /// <returns>list of elements in the specified range</returns>
/// <remarks>http://redis.io/commands/zrange</remarks> /// <remarks>http://redis.io/commands/zrange</remarks>
/// <remarks>http://redis.io/commands/zrevrange</remarks> /// <remarks>http://redis.io/commands/zrevrange</remarks>
KeyValuePair<RedisValue, double>[] SortedSetRangeByRankWithScores(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None); SortedSetEntry[] SortedSetRangeByRankWithScores(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score. /// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score.
...@@ -633,7 +633,7 @@ public interface IDatabase : IRedis, IDatabaseAsync ...@@ -633,7 +633,7 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// <returns>list of elements in the specified score range</returns> /// <returns>list of elements in the specified score range</returns>
/// <remarks>http://redis.io/commands/zrangebyscore</remarks> /// <remarks>http://redis.io/commands/zrangebyscore</remarks>
/// <remarks>http://redis.io/commands/zrevrangebyscore</remarks> /// <remarks>http://redis.io/commands/zrevrangebyscore</remarks>
KeyValuePair<RedisValue, double>[] SortedSetRangeByScoreWithScores(RedisKey key, SortedSetEntry[] SortedSetRangeByScoreWithScores(RedisKey key,
double start = double.NegativeInfinity, double stop = double.PositiveInfinity, double start = double.NegativeInfinity, double stop = double.PositiveInfinity,
Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1,
CommandFlags flags = CommandFlags.None); CommandFlags flags = CommandFlags.None);
...@@ -679,7 +679,7 @@ public interface IDatabase : IRedis, IDatabaseAsync ...@@ -679,7 +679,7 @@ public interface IDatabase : IRedis, IDatabaseAsync
/// </summary> /// </summary>
/// <returns>yields all elements of the sorted set.</returns> /// <returns>yields all elements of the sorted set.</returns>
/// <remarks>http://redis.io/commands/zscan</remarks> /// <remarks>http://redis.io/commands/zscan</remarks>
IEnumerable<KeyValuePair<RedisValue, double>> SortedSetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisDatabase.ScanUtils.DefaultPageSize, CommandFlags flags = CommandFlags.None); IEnumerable<SortedSetEntry> SortedSetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisDatabase.ScanUtils.DefaultPageSize, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Returns the score of member in the sorted set at key; If member does not exist in the sorted set, or key does not exist, nil is returned. /// Returns the score of member in the sorted set at key; If member does not exist in the sorted set, or key does not exist, nil is returned.
/// </summary> /// </summary>
......
...@@ -58,7 +58,7 @@ public interface IDatabaseAsync : IRedisAsync ...@@ -58,7 +58,7 @@ public interface IDatabaseAsync : IRedisAsync
/// </summary> /// </summary>
/// <returns>list of fields and their values stored in the hash, or an empty list when key does not exist.</returns> /// <returns>list of fields and their values stored in the hash, or an empty list when key does not exist.</returns>
/// <remarks>http://redis.io/commands/hgetall</remarks> /// <remarks>http://redis.io/commands/hgetall</remarks>
Task<KeyValuePair<RedisValue, RedisValue>[]> HashGetAllAsync(RedisKey key, CommandFlags flags = CommandFlags.None); Task<HashEntry[]> HashGetAllAsync(RedisKey key, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Returns the value associated with field in the hash stored at key. /// Returns the value associated with field in the hash stored at key.
...@@ -109,7 +109,7 @@ public interface IDatabaseAsync : IRedisAsync ...@@ -109,7 +109,7 @@ public interface IDatabaseAsync : IRedisAsync
/// Sets the specified fields to their respective values in the hash stored at key. This command overwrites any existing fields in the hash. If key does not exist, a new key holding a hash is created. /// Sets the specified fields to their respective values in the hash stored at key. This command overwrites any existing fields in the hash. If key does not exist, a new key holding a hash is created.
/// </summary> /// </summary>
/// <remarks>http://redis.io/commands/hmset</remarks> /// <remarks>http://redis.io/commands/hmset</remarks>
Task HashSetAsync(RedisKey key, KeyValuePair<RedisValue, RedisValue>[] hashFields, CommandFlags flags = CommandFlags.None); Task HashSetAsync(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Sets field in the hash stored at key to value. If key does not exist, a new key holding a hash is created. If field already exists in the hash, it is overwritten. /// Sets field in the hash stored at key to value. If key does not exist, a new key holding a hash is created. If field already exists in the hash, it is overwritten.
...@@ -527,7 +527,7 @@ public interface IDatabaseAsync : IRedisAsync ...@@ -527,7 +527,7 @@ public interface IDatabaseAsync : IRedisAsync
/// </summary> /// </summary>
/// <returns>The number of elements added to the sorted sets, not including elements already existing for which the score was updated.</returns> /// <returns>The number of elements added to the sorted sets, not including elements already existing for which the score was updated.</returns>
/// <remarks>http://redis.io/commands/zadd</remarks> /// <remarks>http://redis.io/commands/zadd</remarks>
Task<long> SortedSetAddAsync(RedisKey key, KeyValuePair<RedisValue, double>[] values, CommandFlags flags = CommandFlags.None); Task<long> SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Computes a set operation over two sorted sets, and stores the result in destination, optionally performing /// Computes a set operation over two sorted sets, and stores the result in destination, optionally performing
...@@ -584,7 +584,7 @@ public interface IDatabaseAsync : IRedisAsync ...@@ -584,7 +584,7 @@ public interface IDatabaseAsync : IRedisAsync
/// <returns>list of elements in the specified range</returns> /// <returns>list of elements in the specified range</returns>
/// <remarks>http://redis.io/commands/zrange</remarks> /// <remarks>http://redis.io/commands/zrange</remarks>
/// <remarks>http://redis.io/commands/zrevrange</remarks> /// <remarks>http://redis.io/commands/zrevrange</remarks>
Task<KeyValuePair<RedisValue, double>[]> SortedSetRangeByRankWithScoresAsync(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None); Task<SortedSetEntry[]> SortedSetRangeByRankWithScoresAsync(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None);
/// <summary> /// <summary>
/// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score. /// Returns the specified range of elements in the sorted set stored at key. By default the elements are considered to be ordered from the lowest to the highest score. Lexicographical order is used for elements with equal score.
...@@ -605,7 +605,7 @@ public interface IDatabaseAsync : IRedisAsync ...@@ -605,7 +605,7 @@ public interface IDatabaseAsync : IRedisAsync
/// <returns>list of elements in the specified score range</returns> /// <returns>list of elements in the specified score range</returns>
/// <remarks>http://redis.io/commands/zrangebyscore</remarks> /// <remarks>http://redis.io/commands/zrangebyscore</remarks>
/// <remarks>http://redis.io/commands/zrevrangebyscore</remarks> /// <remarks>http://redis.io/commands/zrevrangebyscore</remarks>
Task<KeyValuePair<RedisValue, double>[]> SortedSetRangeByScoreWithScoresAsync(RedisKey key, Task<SortedSetEntry[]> SortedSetRangeByScoreWithScoresAsync(RedisKey key,
double start = double.NegativeInfinity, double stop = double.PositiveInfinity, double start = double.NegativeInfinity, double stop = double.PositiveInfinity,
Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1,
CommandFlags flags = CommandFlags.None); CommandFlags flags = CommandFlags.None);
......
...@@ -115,16 +115,16 @@ public RedisValue[] HashGet(RedisKey key, RedisValue[] hashFields, CommandFlags ...@@ -115,16 +115,16 @@ public RedisValue[] HashGet(RedisKey key, RedisValue[] hashFields, CommandFlags
return ExecuteSync(msg, ResultProcessor.RedisValueArray); return ExecuteSync(msg, ResultProcessor.RedisValueArray);
} }
public KeyValuePair<RedisValue, RedisValue>[] HashGetAll(RedisKey key, CommandFlags flags = CommandFlags.None) public HashEntry[] HashGetAll(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Db, flags, RedisCommand.HGETALL, key); var msg = Message.Create(Db, flags, RedisCommand.HGETALL, key);
return ExecuteSync(msg, ResultProcessor.ValuePairInterleaved); return ExecuteSync(msg, ResultProcessor.HashEntryArray);
} }
public Task<KeyValuePair<RedisValue, RedisValue>[]> HashGetAllAsync(RedisKey key, CommandFlags flags = CommandFlags.None) public Task<HashEntry[]> HashGetAllAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Db, flags, RedisCommand.HGETALL, key); var msg = Message.Create(Db, flags, RedisCommand.HGETALL, key);
return ExecuteAsync(msg, ResultProcessor.ValuePairInterleaved); return ExecuteAsync(msg, ResultProcessor.HashEntryArray);
} }
public Task<RedisValue> HashGetAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None) public Task<RedisValue> HashGetAsync(RedisKey key, RedisValue hashField, CommandFlags flags = CommandFlags.None)
...@@ -193,9 +193,9 @@ public Task<long> HashLengthAsync(RedisKey key, CommandFlags flags = CommandFlag ...@@ -193,9 +193,9 @@ public Task<long> HashLengthAsync(RedisKey key, CommandFlags flags = CommandFlag
return ExecuteAsync(msg, ResultProcessor.Int64); return ExecuteAsync(msg, ResultProcessor.Int64);
} }
public IEnumerable<KeyValuePair<RedisValue, RedisValue>> HashScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisDatabase.ScanUtils.DefaultPageSize, CommandFlags flags = CommandFlags.None) public IEnumerable<HashEntry> HashScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisDatabase.ScanUtils.DefaultPageSize, CommandFlags flags = CommandFlags.None)
{ {
var scan = TryScan<KeyValuePair<RedisValue, RedisValue>>(key, pattern, pageSize, flags, RedisCommand.HSCAN, HashScanResultProcessor.Default); var scan = TryScan<HashEntry>(key, pattern, pageSize, flags, RedisCommand.HSCAN, HashScanResultProcessor.Default);
if (scan != null) return scan; if (scan != null) return scan;
if (pattern.IsNull) return HashGetAll(key, flags); if (pattern.IsNull) return HashGetAll(key, flags);
...@@ -211,7 +211,7 @@ public bool HashSet(RedisKey key, RedisValue hashField, RedisValue value, When w ...@@ -211,7 +211,7 @@ public bool HashSet(RedisKey key, RedisValue hashField, RedisValue value, When w
return ExecuteSync(msg, ResultProcessor.Boolean); return ExecuteSync(msg, ResultProcessor.Boolean);
} }
public void HashSet(RedisKey key, KeyValuePair<RedisValue, RedisValue>[] hashFields, CommandFlags flags = CommandFlags.None) public void HashSet(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetHashSetMessage(key, hashFields, flags); var msg = GetHashSetMessage(key, hashFields, flags);
if (msg == null) return; if (msg == null) return;
...@@ -227,7 +227,7 @@ public Task<bool> HashSetAsync(RedisKey key, RedisValue hashField, RedisValue va ...@@ -227,7 +227,7 @@ public Task<bool> HashSetAsync(RedisKey key, RedisValue hashField, RedisValue va
return ExecuteAsync(msg, ResultProcessor.Boolean); return ExecuteAsync(msg, ResultProcessor.Boolean);
} }
public Task HashSetAsync(RedisKey key, KeyValuePair<RedisValue, RedisValue>[] hashFields, CommandFlags flags = CommandFlags.None) public Task HashSetAsync(RedisKey key, HashEntry[] hashFields, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetHashSetMessage(key, hashFields, flags); var msg = GetHashSetMessage(key, hashFields, flags);
return ExecuteAsync(msg, ResultProcessor.DemandOK); return ExecuteAsync(msg, ResultProcessor.DemandOK);
...@@ -912,7 +912,7 @@ public bool SortedSetAdd(RedisKey key, RedisValue member, double score, CommandF ...@@ -912,7 +912,7 @@ public bool SortedSetAdd(RedisKey key, RedisValue member, double score, CommandF
return ExecuteSync(msg, ResultProcessor.Boolean); return ExecuteSync(msg, ResultProcessor.Boolean);
} }
public long SortedSetAdd(RedisKey key, KeyValuePair<RedisValue, double>[] values, CommandFlags flags = CommandFlags.None) public long SortedSetAdd(RedisKey key, SortedSetEntry[] values, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetSortedSetAddMessage(key, values, flags); var msg = GetSortedSetAddMessage(key, values, flags);
return ExecuteSync(msg, ResultProcessor.Int64); return ExecuteSync(msg, ResultProcessor.Int64);
...@@ -924,7 +924,7 @@ public Task<bool> SortedSetAddAsync(RedisKey key, RedisValue member, double scor ...@@ -924,7 +924,7 @@ public Task<bool> SortedSetAddAsync(RedisKey key, RedisValue member, double scor
return ExecuteAsync(msg, ResultProcessor.Boolean); return ExecuteAsync(msg, ResultProcessor.Boolean);
} }
public Task<long> SortedSetAddAsync(RedisKey key, KeyValuePair<RedisValue, double>[] values, CommandFlags flags = CommandFlags.None) public Task<long> SortedSetAddAsync(RedisKey key, SortedSetEntry[] values, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetSortedSetAddMessage(key, values, flags); var msg = GetSortedSetAddMessage(key, values, flags);
return ExecuteAsync(msg, ResultProcessor.Int64); return ExecuteAsync(msg, ResultProcessor.Int64);
...@@ -1000,13 +1000,13 @@ public Task<RedisValue[]> SortedSetRangeByRankAsync(RedisKey key, long start = 0 ...@@ -1000,13 +1000,13 @@ public Task<RedisValue[]> SortedSetRangeByRankAsync(RedisKey key, long start = 0
return ExecuteAsync(msg, ResultProcessor.RedisValueArray); return ExecuteAsync(msg, ResultProcessor.RedisValueArray);
} }
public KeyValuePair<RedisValue, double>[] SortedSetRangeByRankWithScores(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) public SortedSetEntry[] SortedSetRangeByRankWithScores(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Db, flags, order == Order.Descending ? RedisCommand.ZREVRANGE : RedisCommand.ZRANGE, key, start, stop, RedisLiterals.WITHSCORES); var msg = Message.Create(Db, flags, order == Order.Descending ? RedisCommand.ZREVRANGE : RedisCommand.ZRANGE, key, start, stop, RedisLiterals.WITHSCORES);
return ExecuteSync(msg, ResultProcessor.SortedSetWithScores); return ExecuteSync(msg, ResultProcessor.SortedSetWithScores);
} }
public Task<KeyValuePair<RedisValue, double>[]> SortedSetRangeByRankWithScoresAsync(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None) public Task<SortedSetEntry[]> SortedSetRangeByRankWithScoresAsync(RedisKey key, long start = 0, long stop = -1, Order order = Order.Ascending, CommandFlags flags = CommandFlags.None)
{ {
var msg = Message.Create(Db, flags, order == Order.Descending ? RedisCommand.ZREVRANGE : RedisCommand.ZRANGE, key, start, stop, RedisLiterals.WITHSCORES); var msg = Message.Create(Db, flags, order == Order.Descending ? RedisCommand.ZREVRANGE : RedisCommand.ZRANGE, key, start, stop, RedisLiterals.WITHSCORES);
return ExecuteAsync(msg, ResultProcessor.SortedSetWithScores); return ExecuteAsync(msg, ResultProcessor.SortedSetWithScores);
...@@ -1024,13 +1024,13 @@ public Task<RedisValue[]> SortedSetRangeByScoreAsync(RedisKey key, double start ...@@ -1024,13 +1024,13 @@ public Task<RedisValue[]> SortedSetRangeByScoreAsync(RedisKey key, double start
return ExecuteAsync(msg, ResultProcessor.RedisValueArray); return ExecuteAsync(msg, ResultProcessor.RedisValueArray);
} }
public KeyValuePair<RedisValue, double>[] SortedSetRangeByScoreWithScores(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) public SortedSetEntry[] SortedSetRangeByScoreWithScores(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetSortedSetRangeByScoreMessage(key, start, stop, exclude, order, skip, take, flags, true); var msg = GetSortedSetRangeByScoreMessage(key, start, stop, exclude, order, skip, take, flags, true);
return ExecuteSync(msg, ResultProcessor.SortedSetWithScores); return ExecuteSync(msg, ResultProcessor.SortedSetWithScores);
} }
public Task<KeyValuePair<RedisValue, double>[]> SortedSetRangeByScoreWithScoresAsync(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None) public Task<SortedSetEntry[]> SortedSetRangeByScoreWithScoresAsync(RedisKey key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Exclude exclude = Exclude.None, Order order = Order.Ascending, long skip = 0, long take = -1, CommandFlags flags = CommandFlags.None)
{ {
var msg = GetSortedSetRangeByScoreMessage(key, start, stop, exclude, order, skip, take, flags, true); var msg = GetSortedSetRangeByScoreMessage(key, start, stop, exclude, order, skip, take, flags, true);
return ExecuteAsync(msg, ResultProcessor.SortedSetWithScores); return ExecuteAsync(msg, ResultProcessor.SortedSetWithScores);
...@@ -1096,9 +1096,9 @@ public Task<long> SortedSetRemoveRangeByScoreAsync(RedisKey key, double start, d ...@@ -1096,9 +1096,9 @@ public Task<long> SortedSetRemoveRangeByScoreAsync(RedisKey key, double start, d
return ExecuteAsync(msg, ResultProcessor.Int64); return ExecuteAsync(msg, ResultProcessor.Int64);
} }
public IEnumerable<KeyValuePair<RedisValue, double>> SortedSetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisDatabase.ScanUtils.DefaultPageSize, CommandFlags flags = CommandFlags.None) public IEnumerable<SortedSetEntry> SortedSetScan(RedisKey key, RedisValue pattern = default(RedisValue), int pageSize = RedisDatabase.ScanUtils.DefaultPageSize, CommandFlags flags = CommandFlags.None)
{ {
var scan = TryScan<KeyValuePair<RedisValue, double>>(key, pattern, pageSize, flags, RedisCommand.ZSCAN, SortedSetScanResultProcessor.Default); var scan = TryScan<SortedSetEntry>(key, pattern, pageSize, flags, RedisCommand.ZSCAN, SortedSetScanResultProcessor.Default);
if (scan != null) return scan; if (scan != null) return scan;
if (pattern.IsNull) return SortedSetRangeByRankWithScores(key, flags: flags); if (pattern.IsNull) return SortedSetRangeByRankWithScores(key, flags: flags);
...@@ -1412,20 +1412,25 @@ Message GetExpiryMessage(RedisKey key, CommandFlags flags, DateTime? expiry, out ...@@ -1412,20 +1412,25 @@ Message GetExpiryMessage(RedisKey key, CommandFlags flags, DateTime? expiry, out
return Message.Create(Db, flags, RedisCommand.EXPIREAT, key, seconds); return Message.Create(Db, flags, RedisCommand.EXPIREAT, key, seconds);
} }
private Message GetHashSetMessage(RedisKey key, KeyValuePair<RedisValue, RedisValue>[] hashFields, CommandFlags flags) private Message GetHashSetMessage(RedisKey key, HashEntry[] hashFields, CommandFlags flags)
{ {
if (hashFields == null) throw new ArgumentNullException("hashFields"); if (hashFields == null) throw new ArgumentNullException("hashFields");
switch (hashFields.Length) switch (hashFields.Length)
{ {
case 0: return null; case 0: return null;
case 1: return Message.Create(Db, flags, RedisCommand.HMSET, key, hashFields[0].Key, hashFields[0].Value); case 1: return Message.Create(Db, flags, RedisCommand.HMSET, key,
hashFields[0].name, hashFields[0].value);
case 2:
return Message.Create(Db, flags, RedisCommand.HMSET, key,
hashFields[0].name, hashFields[0].value,
hashFields[1].name, hashFields[1].value);
default: default:
var arr = new RedisValue[hashFields.Length * 2]; var arr = new RedisValue[hashFields.Length * 2];
int offset = 0; int offset = 0;
for (int i = 0; i < hashFields.Length; i++) for (int i = 0; i < hashFields.Length; i++)
{ {
arr[offset++] = hashFields[i].Key; arr[offset++] = hashFields[i].name;
arr[offset++] = hashFields[i].Value; arr[offset++] = hashFields[i].value;
} }
return Message.Create(Db, flags, RedisCommand.HMSET, key, arr); return Message.Create(Db, flags, RedisCommand.HMSET, key, arr);
} }
...@@ -1466,7 +1471,7 @@ Message GetRestoreMessage(RedisKey key, byte[] value, TimeSpan? expiry, CommandF ...@@ -1466,7 +1471,7 @@ Message GetRestoreMessage(RedisKey key, byte[] value, TimeSpan? expiry, CommandF
return Message.Create(Db, flags, RedisCommand.RESTORE, key, pttl, value); return Message.Create(Db, flags, RedisCommand.RESTORE, key, pttl, value);
} }
private Message GetSortedSetAddMessage(RedisKey key, KeyValuePair<RedisValue, double>[] values, CommandFlags flags) private Message GetSortedSetAddMessage(RedisKey key, SortedSetEntry[] values, CommandFlags flags)
{ {
if (values == null) throw new ArgumentNullException("values"); if (values == null) throw new ArgumentNullException("values");
switch (values.Length) switch (values.Length)
...@@ -1474,18 +1479,18 @@ private Message GetSortedSetAddMessage(RedisKey key, KeyValuePair<RedisValue, do ...@@ -1474,18 +1479,18 @@ private Message GetSortedSetAddMessage(RedisKey key, KeyValuePair<RedisValue, do
case 0: return null; case 0: return null;
case 1: case 1:
return Message.Create(Db, flags, RedisCommand.ZADD, key, return Message.Create(Db, flags, RedisCommand.ZADD, key,
values[0].Value, values[0].Key); values[0].element, values[0].score);
case 2: case 2:
return Message.Create(Db, flags, RedisCommand.ZADD, key, return Message.Create(Db, flags, RedisCommand.ZADD, key,
values[0].Value, values[0].Key, values[0].element, values[0].score,
values[1].Value, values[1].Key); values[1].element, values[1].score);
default: default:
var arr = new RedisValue[values.Length * 2]; var arr = new RedisValue[values.Length * 2];
int index = 0; int index = 0;
for (int i = 0; i < values.Length; i++) for (int i = 0; i < values.Length; i++)
{ {
arr[index++] = values[i].Value; arr[index++] = values[i].element;
arr[index++] = values[i].Key; arr[index++] = values[i].score;
} }
return Message.Create(Db, flags, RedisCommand.ZADD, key, arr); return Message.Create(Db, flags, RedisCommand.ZADD, key, arr);
} }
...@@ -1913,14 +1918,14 @@ internal override void WriteImpl(PhysicalConnection physical) ...@@ -1913,14 +1918,14 @@ internal override void WriteImpl(PhysicalConnection physical)
physical.Write((RedisValue)Script); physical.Write((RedisValue)Script);
} }
} }
sealed class HashScanResultProcessor : ScanResultProcessor<KeyValuePair<RedisValue, RedisValue>> sealed class HashScanResultProcessor : ScanResultProcessor<HashEntry>
{ {
public static readonly ResultProcessor<ScanIterator<KeyValuePair<RedisValue, RedisValue>>.ScanResult> Default = new HashScanResultProcessor(); public static readonly ResultProcessor<ScanIterator<HashEntry>.ScanResult> Default = new HashScanResultProcessor();
private HashScanResultProcessor() { } private HashScanResultProcessor() { }
protected override KeyValuePair<RedisValue, RedisValue>[] Parse(RawResult result) protected override HashEntry[] Parse(RawResult result)
{ {
KeyValuePair<RedisValue, RedisValue>[] pairs; HashEntry[] pairs;
if (!ValuePairInterleaved.TryParse(result, out pairs)) pairs = null; if (!HashEntryArray.TryParse(result, out pairs)) pairs = null;
return pairs; return pairs;
} }
} }
...@@ -2046,13 +2051,13 @@ internal override void WriteImpl(PhysicalConnection physical) ...@@ -2046,13 +2051,13 @@ internal override void WriteImpl(PhysicalConnection physical)
} }
} }
sealed class SortedSetScanResultProcessor : ScanResultProcessor<KeyValuePair<RedisValue, double>> sealed class SortedSetScanResultProcessor : ScanResultProcessor<SortedSetEntry>
{ {
public static readonly ResultProcessor<ScanIterator<KeyValuePair<RedisValue, double>>.ScanResult> Default = new SortedSetScanResultProcessor(); public static readonly ResultProcessor<ScanIterator<SortedSetEntry>.ScanResult> Default = new SortedSetScanResultProcessor();
private SortedSetScanResultProcessor() { } private SortedSetScanResultProcessor() { }
protected override KeyValuePair<RedisValue, double>[] Parse(RawResult result) protected override SortedSetEntry[] Parse(RawResult result)
{ {
KeyValuePair<RedisValue, double>[] pairs; SortedSetEntry[] pairs;
if (!SortedSetWithScores.TryParse(result, out pairs)) pairs = null; if (!SortedSetWithScores.TryParse(result, out pairs)) pairs = null;
return pairs; return pairs;
} }
......
...@@ -69,8 +69,8 @@ abstract class ResultProcessor ...@@ -69,8 +69,8 @@ abstract class ResultProcessor
public static readonly ResultProcessor<RedisResult> public static readonly ResultProcessor<RedisResult>
ScriptResult = new ScriptResultProcessor(); ScriptResult = new ScriptResultProcessor();
public static readonly SortedSetWithScoresProcessor public static readonly SortedSetEntryArrayProcessor
SortedSetWithScores = new SortedSetWithScoresProcessor(); SortedSetWithScores = new SortedSetEntryArrayProcessor();
public static readonly ResultProcessor<string> public static readonly ResultProcessor<string>
String = new StringProcessor(), String = new StringProcessor(),
...@@ -80,8 +80,8 @@ public static readonly SortedSetWithScoresProcessor ...@@ -80,8 +80,8 @@ public static readonly SortedSetWithScoresProcessor
public static readonly TimeSpanProcessor public static readonly TimeSpanProcessor
TimeSpanFromMilliseconds = new TimeSpanProcessor(true), TimeSpanFromMilliseconds = new TimeSpanProcessor(true),
TimeSpanFromSeconds = new TimeSpanProcessor(false); TimeSpanFromSeconds = new TimeSpanProcessor(false);
public static readonly ValuePairInterleavedProcessor public static readonly HashEntryArrayProcessor
ValuePairInterleaved = new ValuePairInterleavedProcessor(); HashEntryArray = new HashEntryArrayProcessor();
static readonly byte[] MOVED = Encoding.UTF8.GetBytes("MOVED "), ASK = Encoding.UTF8.GetBytes("ASK "); static readonly byte[] MOVED = Encoding.UTF8.GetBytes("MOVED "), ASK = Encoding.UTF8.GetBytes("ASK ");
public void ConnectionFail(Message message, ConnectionFailureType fail, Exception innerException) public void ConnectionFail(Message message, ConnectionFailureType fail, Exception innerException)
...@@ -342,27 +342,28 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes ...@@ -342,27 +342,28 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
} }
} }
internal sealed class SortedSetWithScoresProcessor : ValuePairInterleavedProcessorBase<RedisValue, double> internal sealed class SortedSetEntryArrayProcessor : ValuePairInterleavedProcessorBase<SortedSetEntry>
{ {
protected override RedisValue ParseKey(RawResult key) { return key.AsRedisValue(); } protected override SortedSetEntry Parse(RawResult first, RawResult second)
protected override double ParseValue(RawResult value)
{ {
double val; double val;
return value.TryGetDouble(out val) ? val : double.NaN; return new SortedSetEntry(first.AsRedisValue(), second.TryGetDouble(out val) ? val : double.NaN);
} }
} }
internal sealed class ValuePairInterleavedProcessor : ValuePairInterleavedProcessorBase<RedisValue, RedisValue> internal sealed class HashEntryArrayProcessor : ValuePairInterleavedProcessorBase<HashEntry>
{ {
protected override RedisValue ParseKey(RawResult key) { return key.AsRedisValue(); } protected override HashEntry Parse(RawResult first, RawResult second)
protected override RedisValue ParseValue(RawResult key) { return key.AsRedisValue(); } {
return new HashEntry(first.AsRedisValue(), second.AsRedisValue());
}
} }
internal abstract class ValuePairInterleavedProcessorBase<TKey, TValue> : ResultProcessor<KeyValuePair<TKey, TValue>[]> internal abstract class ValuePairInterleavedProcessorBase<T> : ResultProcessor<T[]>
{ {
static readonly KeyValuePair<TKey, TValue>[] nix = new KeyValuePair<TKey, TValue>[0]; static readonly T[] nix = new T[0];
public bool TryParse(RawResult result, out KeyValuePair<TKey, TValue>[] pairs) public bool TryParse(RawResult result, out T[] pairs)
{ {
switch (result.Type) switch (result.Type)
{ {
...@@ -381,13 +382,11 @@ public bool TryParse(RawResult result, out KeyValuePair<TKey, TValue>[] pairs) ...@@ -381,13 +382,11 @@ public bool TryParse(RawResult result, out KeyValuePair<TKey, TValue>[] pairs)
} }
else else
{ {
pairs = new KeyValuePair<TKey, TValue>[count]; pairs = new T[count];
int offset = 0; int offset = 0;
for (int i = 0; i < pairs.Length; i++) for (int i = 0; i < pairs.Length; i++)
{ {
var setting = ParseKey(arr[offset++]); pairs[i] = Parse(arr[offset++], arr[offset++]);
var value = ParseValue(arr[offset++]);
pairs[i] = new KeyValuePair<TKey, TValue>(setting, value);
} }
} }
} }
...@@ -397,11 +396,10 @@ public bool TryParse(RawResult result, out KeyValuePair<TKey, TValue>[] pairs) ...@@ -397,11 +396,10 @@ public bool TryParse(RawResult result, out KeyValuePair<TKey, TValue>[] pairs)
return false; return false;
} }
} }
protected abstract TKey ParseKey(RawResult key); protected abstract T Parse(RawResult first, RawResult second);
protected abstract TValue ParseValue(RawResult value);
protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result) protected override bool SetResultCore(PhysicalConnection connection, Message message, RawResult result)
{ {
KeyValuePair<TKey, TValue>[] arr; T[] arr;
if (TryParse(result, out arr)) if (TryParse(result, out arr))
{ {
SetResult(message, arr); SetResult(message, arr);
...@@ -1004,10 +1002,12 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes ...@@ -1004,10 +1002,12 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
} }
} }
sealed class StringPairInterleavedProcessor : ValuePairInterleavedProcessorBase<string, string> sealed class StringPairInterleavedProcessor : ValuePairInterleavedProcessorBase<KeyValuePair<string, string>>
{ {
protected override string ParseKey(RawResult key) { return key.GetString(); } protected override KeyValuePair<string, string> Parse(RawResult first, RawResult second)
protected override string ParseValue(RawResult key) { return key.GetString(); } {
return new KeyValuePair<string, string>(first.GetString(), second.GetString());
}
} }
sealed class StringProcessor : ResultProcessor<string> sealed class StringProcessor : ResultProcessor<string>
......
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace StackExchange.Redis
{
/// <summary>
/// Describes a sorted-set element with the corresponding value
/// </summary>
public struct SortedSetEntry : IEquatable<SortedSetEntry>, IComparable, IComparable<SortedSetEntry>
{
internal readonly RedisValue element;
internal readonly double score;
/// <summary>
/// Initializes a SortedSetEntry value
/// </summary>
public SortedSetEntry(RedisValue element, double score)
{
this.element = element;
this.score = score;
}
/// <summary>
/// The unique element stored in the sorted set
/// </summary>
public RedisValue Element { get { return element; } }
/// <summary>
/// The score against the element
/// </summary>
public double Score { get { return score; } }
/// <summary>
/// The score against the element
/// </summary>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Score", false)]
public double Value { get { return score; } }
/// <summary>
/// The unique element stored in the sorted set
/// </summary>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), Obsolete("Please use Element", false)]
public RedisValue Key { get { return element; } }
/// <summary>
/// Converts to a key/value pair
/// </summary>
public static implicit operator KeyValuePair<RedisValue,double>(SortedSetEntry value)
{
return new KeyValuePair<RedisValue, double>(value.element, value.score);
}
/// <summary>
/// Converts from a key/value pair
/// </summary>
public static implicit operator SortedSetEntry(KeyValuePair<RedisValue, double> value)
{
return new SortedSetEntry(value.Key, value.Value);
}
/// <summary>
/// See Object.ToString()
/// </summary>
public override string ToString()
{
return element + ": " + score;
}
/// <summary>
/// See Object.GetHashCode()
/// </summary>
public override int GetHashCode()
{
return element.GetHashCode() ^ score.GetHashCode();
}
/// <summary>
/// Compares two values for equality
/// </summary>
public override bool Equals(object obj)
{
return obj is SortedSetEntry && Equals((SortedSetEntry)obj);
}
/// <summary>
/// Compares two values for equality
/// </summary>
public bool Equals(SortedSetEntry value)
{
return this.element == value.element && this.score == value.score;
}
/// <summary>
/// Compares two values by score
/// </summary>
public int CompareTo(SortedSetEntry value)
{
return this.score.CompareTo(value.score);
}
/// <summary>
/// Compares two values by score
/// </summary>
public int CompareTo(object value)
{
return value is SortedSetEntry ? CompareTo((SortedSetEntry)value) : -1;
}
}
}
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