Commit 36f5a354 authored by Nick Craver's avatar Nick Craver

Property cleanup

parent e3493310
......@@ -51,7 +51,7 @@ public RedisChannel GetChannel(int index, RedisChannel.PatternMode mode)
internal bool TryGetCommandBytes(int i, out CommandBytes command)
{
var payload = _inner[i].DirecyPayload;
var payload = _inner[i].Payload;
if (payload.Length > CommandBytes.MaxLength)
{
command = default;
......
......@@ -11,20 +11,18 @@ namespace StackExchange.Redis
{
get
{
if (index >= _itemsCount) throw new IndexOutOfRangeException();
if (index >= ItemsCount) throw new IndexOutOfRangeException();
return _itemsOversized[index];
}
}
internal int ItemsCount => _itemsCount;
internal int ItemsCount { get; }
internal ReadOnlySequence<byte> Payload { get; }
internal static readonly RawResult NullMultiBulk = new RawResult(null, 0);
internal static readonly RawResult EmptyMultiBulk = new RawResult(Array.Empty<RawResult>(), 0);
internal static readonly RawResult Nil = default;
private readonly ReadOnlySequence<byte> _payload;
internal ReadOnlySequence<byte> DirecyPayload => _payload;
// note: can't use Memory<RawResult> here - struct recursion breaks runtimr
private readonly RawResult[] _itemsOversized;
private readonly int _itemsCount;
private readonly ResultType _type;
private const ResultType NonNullFlag = (ResultType)128;
......@@ -43,18 +41,18 @@ public RawResult(ResultType resultType, ReadOnlySequence<byte> payload, bool isN
}
if (!isNull) resultType |= NonNullFlag;
_type = resultType;
_payload = payload;
Payload = payload;
_itemsOversized = default;
_itemsCount = default;
ItemsCount = default;
}
public RawResult(RawResult[] itemsOversized, int itemCount)
{
_type = ResultType.MultiBulk;
if (itemsOversized != null) _type |= NonNullFlag;
_payload = default;
Payload = default;
_itemsOversized = itemsOversized;
_itemsCount = itemCount;
ItemsCount = itemCount;
}
public bool IsError => Type == ResultType.Error;
......@@ -74,15 +72,15 @@ public override string ToString()
case ResultType.Error:
return $"{Type}: {GetString()}";
case ResultType.BulkString:
return $"{Type}: {_payload.Length} bytes";
return $"{Type}: {Payload.Length} bytes";
case ResultType.MultiBulk:
return $"{Type}: {_itemsCount} items";
return $"{Type}: {ItemsCount} items";
default:
return $"(unknown: {Type})";
}
}
public Tokenizer GetInlineTokenizer() => new Tokenizer(_payload);
public Tokenizer GetInlineTokenizer() => new Tokenizer(Payload);
internal ref struct Tokenizer
{
......@@ -144,7 +142,7 @@ internal RedisChannel AsRedisChannel(byte[] channelPrefix, RedisChannel.PatternM
}
if (StartsWith(channelPrefix))
{
byte[] copy = _payload.Slice(channelPrefix.Length).ToArray();
byte[] copy = Payload.Slice(channelPrefix.Length).ToArray();
return new RedisChannel(copy, mode);
}
return default(RedisChannel);
......@@ -186,7 +184,7 @@ internal void Recycle(int limit = -1)
var arr = _itemsOversized;
if (arr != null)
{
if (limit < 0) limit = _itemsCount;
if (limit < 0) limit = ItemsCount;
for (int i = 0; i < limit; i++)
{
arr[i].Recycle();
......@@ -197,15 +195,15 @@ internal void Recycle(int limit = -1)
internal bool IsEqual(CommandBytes expected)
{
if (expected.Length != _payload.Length) return false;
return new CommandBytes(_payload).Equals(expected);
if (expected.Length != Payload.Length) return false;
return new CommandBytes(Payload).Equals(expected);
}
internal unsafe bool IsEqual(byte[] expected)
{
if (expected == null) throw new ArgumentNullException(nameof(expected));
var rangeToCheck = _payload;
var rangeToCheck = Payload;
if (expected.Length != rangeToCheck.Length) return false;
if (rangeToCheck.IsSingleSegment) return rangeToCheck.First.Span.SequenceEqual(expected);
......@@ -225,17 +223,17 @@ internal unsafe bool IsEqual(byte[] expected)
internal bool StartsWith(CommandBytes expected)
{
var len = expected.Length;
if (len > _payload.Length) return false;
if (len > Payload.Length) return false;
var rangeToCheck = _payload.Slice(0, len);
var rangeToCheck = Payload.Slice(0, len);
return new CommandBytes(rangeToCheck).Equals(expected);
}
internal bool StartsWith(byte[] expected)
{
if (expected == null) throw new ArgumentNullException(nameof(expected));
if (expected.Length > _payload.Length) return false;
if (expected.Length > Payload.Length) return false;
var rangeToCheck = _payload.Slice(0, expected.Length);
var rangeToCheck = Payload.Slice(0, expected.Length);
if (rangeToCheck.IsSingleSegment) return rangeToCheck.First.Span.SequenceEqual(expected);
int offset = 0;
......@@ -254,15 +252,15 @@ internal byte[] GetBlob()
{
if (IsNull) return null;
if (_payload.IsEmpty) return Array.Empty<byte>();
if (Payload.IsEmpty) return Array.Empty<byte>();
return _payload.ToArray();
return Payload.ToArray();
}
internal bool GetBoolean()
{
if (_payload.Length != 1) throw new InvalidCastException();
switch (_payload.First.Span[0])
if (Payload.Length != 1) throw new InvalidCastException();
switch (Payload.First.Span[0])
{
case (byte)'1': return true;
case (byte)'0': return false;
......@@ -273,13 +271,13 @@ internal bool GetBoolean()
internal ReadOnlySpan<RawResult> GetItems()
{
if (Type == ResultType.MultiBulk)
return new ReadOnlySpan<RawResult>(_itemsOversized, 0, _itemsCount);
return new ReadOnlySpan<RawResult>(_itemsOversized, 0, ItemsCount);
throw new InvalidOperationException();
}
internal ReadOnlyMemory<RawResult> GetItemsMemory()
{
if (Type == ResultType.MultiBulk)
return new ReadOnlyMemory<RawResult>(_itemsOversized, 0, _itemsCount);
return new ReadOnlyMemory<RawResult>(_itemsOversized, 0, ItemsCount);
throw new InvalidOperationException();
}
......@@ -396,11 +394,11 @@ internal string[] GetItemsAsStrings()
internal unsafe string GetString()
{
if (IsNull) return null;
if (_payload.IsEmpty) return "";
if (Payload.IsEmpty) return "";
if (_payload.IsSingleSegment)
if (Payload.IsSingleSegment)
{
var span = _payload.First.Span;
var span = Payload.First.Span;
fixed (byte* ptr = &MemoryMarshal.GetReference(span))
{
return Encoding.UTF8.GetString(ptr, span.Length);
......@@ -408,7 +406,7 @@ internal unsafe string GetString()
}
var decoder = Encoding.UTF8.GetDecoder();
int charCount = 0;
foreach(var segment in _payload)
foreach(var segment in Payload)
{
var span = segment.Span;
if (span.IsEmpty) continue;
......@@ -425,7 +423,7 @@ internal unsafe string GetString()
fixed (char* sPtr = s)
{
char* cPtr = sPtr;
foreach (var segment in _payload)
foreach (var segment in Payload)
{
var span = segment.Span;
if (span.IsEmpty) continue;
......@@ -458,16 +456,16 @@ internal bool TryGetDouble(out double val)
internal bool TryGetInt64(out long value)
{
if(IsNull || _payload.IsEmpty || _payload.Length > PhysicalConnection.MaxInt64TextLen)
if(IsNull || Payload.IsEmpty || Payload.Length > PhysicalConnection.MaxInt64TextLen)
{
value = 0;
return false;
}
if (_payload.IsSingleSegment) return RedisValue.TryParseInt64(_payload.First.Span, out value);
if (Payload.IsSingleSegment) return RedisValue.TryParseInt64(Payload.First.Span, out value);
Span<byte> span = stackalloc byte[(int)_payload.Length]; // we already checked the length was <= MaxInt64TextLen
_payload.CopyTo(span);
Span<byte> span = stackalloc byte[(int)Payload.Length]; // we already checked the length was <= MaxInt64TextLen
Payload.CopyTo(span);
return RedisValue.TryParseInt64(span, out value);
}
}
......
......@@ -3231,24 +3231,23 @@ protected override bool SetResultCore(PhysicalConnection connection, Message mes
internal sealed class ExecuteMessage : Message
{
private readonly CommandBytes _command;
private readonly ICollection<object> _args;
public new CommandBytes Command { get; }
public new CommandBytes Command => _command;
public ExecuteMessage(CommandMap map, int db, CommandFlags flags, string command, ICollection<object> args) : base(db, flags, RedisCommand.UNKNOWN)
{
if (args != null && args.Count >= PhysicalConnection.REDIS_MAX_ARGS) // using >= here because we will be adding 1 for the command itself (which is an arg for the purposes of the multi-bulk protocol)
{
throw ExceptionFactory.TooManyArgs(command, args.Count);
}
_command = map?.GetBytes(command) ?? default;
if (_command.IsEmpty) throw ExceptionFactory.CommandDisabled(command);
Command = map?.GetBytes(command) ?? default;
if (Command.IsEmpty) throw ExceptionFactory.CommandDisabled(command);
_args = args ?? Array.Empty<object>();
}
protected override void WriteImpl(PhysicalConnection physical)
{
physical.WriteHeader(RedisCommand.UNKNOWN, _args.Count, _command);
physical.WriteHeader(RedisCommand.UNKNOWN, _args.Count, Command);
foreach (object arg in _args)
{
if (arg is RedisKey key)
......@@ -3268,7 +3267,7 @@ protected override void WriteImpl(PhysicalConnection physical)
}
}
public override string CommandAndKey => _command.ToString();
public override string CommandAndKey => Command.ToString();
public override int GetHashSlot(ServerSelectionStrategy serverSelectionStrategy)
{
......
......@@ -8,31 +8,29 @@ namespace StackExchange.Redis
/// </summary>
public readonly struct RedisKey : IEquatable<RedisKey>
{
private readonly byte[] keyPrefix;
private readonly object keyValue; // always either a string or a byte[]
internal RedisKey(byte[] keyPrefix, object keyValue)
{
this.keyPrefix = keyPrefix?.Length == 0 ? null : keyPrefix;
this.keyValue = keyValue;
KeyPrefix = keyPrefix?.Length == 0 ? null : keyPrefix;
KeyValue = keyValue;
}
internal RedisKey AsPrefix() => new RedisKey((byte[])this, null);
internal bool IsNull => keyPrefix == null && keyValue == null;
internal bool IsNull => KeyPrefix == null && KeyValue == null;
internal bool IsEmpty
{
get
{
if (keyPrefix != null) return false;
if (keyValue == null) return true;
if (keyValue is string) return ((string)keyValue).Length == 0;
return ((byte[])keyValue).Length == 0;
if (KeyPrefix != null) return false;
if (KeyValue == null) return true;
if (KeyValue is string s) return s.Length == 0;
return ((byte[])KeyValue).Length == 0;
}
}
internal byte[] KeyPrefix => keyPrefix;
internal object KeyValue => keyValue;
internal byte[] KeyPrefix { get; }
internal object KeyValue { get; }
/// <summary>
/// Indicate whether two keys are not equal
......@@ -74,35 +72,35 @@ internal bool IsEmpty
/// </summary>
/// <param name="x">The first <see cref="RedisChannel"/> to compare.</param>
/// <param name="y">The second <see cref="RedisChannel"/> to compare.</param>
public static bool operator ==(RedisKey x, RedisKey y) => CompositeEquals(x.keyPrefix, x.keyValue, y.keyPrefix, y.keyValue);
public static bool operator ==(RedisKey x, RedisKey y) => CompositeEquals(x.KeyPrefix, x.KeyValue, y.KeyPrefix, y.KeyValue);
/// <summary>
/// Indicate whether two keys are equal
/// </summary>
/// <param name="x">The first <see cref="RedisChannel"/> to compare.</param>
/// <param name="y">The second <see cref="RedisChannel"/> to compare.</param>
public static bool operator ==(string x, RedisKey y) => CompositeEquals(null, x, y.keyPrefix, y.keyValue);
public static bool operator ==(string x, RedisKey y) => CompositeEquals(null, x, y.KeyPrefix, y.KeyValue);
/// <summary>
/// Indicate whether two keys are equal
/// </summary>
/// <param name="x">The first <see cref="RedisChannel"/> to compare.</param>
/// <param name="y">The second <see cref="RedisChannel"/> to compare.</param>
public static bool operator ==(byte[] x, RedisKey y) => CompositeEquals(null, x, y.keyPrefix, y.keyValue);
public static bool operator ==(byte[] x, RedisKey y) => CompositeEquals(null, x, y.KeyPrefix, y.KeyValue);
/// <summary>
/// Indicate whether two keys are equal
/// </summary>
/// <param name="x">The first <see cref="RedisChannel"/> to compare.</param>
/// <param name="y">The second <see cref="RedisChannel"/> to compare.</param>
public static bool operator ==(RedisKey x, string y) => CompositeEquals(x.keyPrefix, x.keyValue, null, y);
public static bool operator ==(RedisKey x, string y) => CompositeEquals(x.KeyPrefix, x.KeyValue, null, y);
/// <summary>
/// Indicate whether two keys are equal
/// </summary>
/// <param name="x">The first <see cref="RedisChannel"/> to compare.</param>
/// <param name="y">The second <see cref="RedisChannel"/> to compare.</param>
public static bool operator ==(RedisKey x, byte[] y) => CompositeEquals(x.keyPrefix, x.keyValue, null, y);
public static bool operator ==(RedisKey x, byte[] y) => CompositeEquals(x.KeyPrefix, x.KeyValue, null, y);
/// <summary>
/// See Object.Equals
......@@ -112,11 +110,11 @@ public override bool Equals(object obj)
{
if (obj is RedisKey other)
{
return CompositeEquals(keyPrefix, keyValue, other.keyPrefix, other.keyValue);
return CompositeEquals(KeyPrefix, KeyValue, other.KeyPrefix, other.KeyValue);
}
if (obj is string || obj is byte[])
{
return CompositeEquals(keyPrefix, keyValue, null, obj);
return CompositeEquals(KeyPrefix, KeyValue, null, obj);
}
return false;
}
......@@ -125,7 +123,7 @@ public override bool Equals(object obj)
/// Indicate whether two keys are equal
/// </summary>
/// <param name="other">The <see cref="RedisKey"/> to compare to.</param>
public bool Equals(RedisKey other) => CompositeEquals(keyPrefix, keyValue, other.keyPrefix, other.keyValue);
public bool Equals(RedisKey other) => CompositeEquals(KeyPrefix, KeyValue, other.KeyPrefix, other.KeyValue);
private static bool CompositeEquals(byte[] keyPrefix0, object keyValue0, byte[] keyPrefix1, object keyValue1)
{
......@@ -146,8 +144,8 @@ private static bool CompositeEquals(byte[] keyPrefix0, object keyValue0, byte[]
/// </summary>
public override int GetHashCode()
{
int chk0 = keyPrefix == null ? 0 : RedisValue.GetHashCode(keyPrefix),
chk1 = keyValue is string ? keyValue.GetHashCode() : RedisValue.GetHashCode((byte[])keyValue);
int chk0 = KeyPrefix == null ? 0 : RedisValue.GetHashCode(KeyPrefix),
chk1 = KeyValue is string ? KeyValue.GetHashCode() : RedisValue.GetHashCode((byte[])KeyValue);
return unchecked((17 * chk0) + chk1);
}
......@@ -159,7 +157,7 @@ public override int GetHashCode()
internal RedisValue AsRedisValue()
{
if (keyPrefix == null && keyValue is string) return (string)keyValue;
if (KeyPrefix == null && KeyValue is string) return (string)KeyValue;
return (byte[])this;
}
......@@ -191,7 +189,7 @@ internal void AssertNotNull()
/// Obtain the <see cref="RedisKey"/> as a <see cref="T:byte[]"/>.
/// </summary>
/// <param name="key">The key to get a byte array for.</param>
public static implicit operator byte[] (RedisKey key) => ConcatenateBytes(key.keyPrefix, key.keyValue, null);
public static implicit operator byte[] (RedisKey key) => ConcatenateBytes(key.KeyPrefix, key.KeyValue, null);
/// <summary>
/// Obtain the key as a <see cref="string"/>.
......@@ -200,13 +198,13 @@ internal void AssertNotNull()
public static implicit operator string(RedisKey key)
{
byte[] arr;
if (key.keyPrefix == null)
if (key.KeyPrefix == null)
{
if (key.keyValue == null) return null;
if (key.KeyValue == null) return null;
if (key.keyValue is string) return (string)key.keyValue;
if (key.KeyValue is string) return (string)key.KeyValue;
arr = (byte[])key.keyValue;
arr = (byte[])key.KeyValue;
}
else
{
......@@ -231,20 +229,20 @@ internal void AssertNotNull()
[Obsolete]
public static RedisKey operator +(RedisKey x, RedisKey y)
{
return new RedisKey(ConcatenateBytes(x.keyPrefix, x.keyValue, y.keyPrefix), y.keyValue);
return new RedisKey(ConcatenateBytes(x.KeyPrefix, x.KeyValue, y.KeyPrefix), y.KeyValue);
}
internal static RedisKey WithPrefix(byte[] prefix, RedisKey value)
{
if (prefix == null || prefix.Length == 0) return value;
if (value.keyPrefix == null) return new RedisKey(prefix, value.keyValue);
if (value.keyValue == null) return new RedisKey(prefix, value.keyPrefix);
if (value.KeyPrefix == null) return new RedisKey(prefix, value.KeyValue);
if (value.KeyValue == null) return new RedisKey(prefix, value.KeyPrefix);
// two prefixes; darn
byte[] copy = new byte[prefix.Length + value.keyPrefix.Length];
byte[] copy = new byte[prefix.Length + value.KeyPrefix.Length];
Buffer.BlockCopy(prefix, 0, copy, 0, prefix.Length);
Buffer.BlockCopy(value.keyPrefix, 0, copy, prefix.Length, value.keyPrefix.Length);
return new RedisKey(copy, value.keyValue);
Buffer.BlockCopy(value.KeyPrefix, 0, copy, prefix.Length, value.KeyPrefix.Length);
return new RedisKey(copy, value.KeyValue);
}
internal static byte[] ConcatenateBytes(byte[] a, object b, byte[] c)
......@@ -252,7 +250,7 @@ internal static byte[] ConcatenateBytes(byte[] a, object b, byte[] c)
if ((a == null || a.Length == 0) && (c == null || c.Length == 0))
{
if (b == null) return null;
if (b is string) return Encoding.UTF8.GetBytes((string)b);
if (b is string s) return Encoding.UTF8.GetBytes(s);
return (byte[])b;
}
......
......@@ -394,12 +394,12 @@ public ErrorRedisResult(string value)
private sealed class SingleRedisResult : RedisResult
{
private readonly RedisValue _value;
private readonly ResultType _resultType;
public override ResultType Type => _resultType;
public override ResultType Type { get; }
public SingleRedisResult(RedisValue value, ResultType? resultType)
{
_value = value;
_resultType = resultType ?? (value.IsInteger ? ResultType.Integer : ResultType.BulkString);
Type = resultType ?? (value.IsInteger ? ResultType.Integer : ResultType.BulkString);
}
public override bool IsNull => _value.IsNull;
......
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