Commit 18d14db3 authored by Marc Gravell's avatar Marc Gravell

Fix #859 - add RedisValue.StartsWith

parent bea5dbfe
...@@ -150,5 +150,40 @@ private static void CheckString(RedisValue value, string expected) ...@@ -150,5 +150,40 @@ private static void CheckString(RedisValue value, string expected)
} }
private static byte[] Bytes(string s) => s == null ? null : Encoding.UTF8.GetBytes(s); private static byte[] Bytes(string s) => s == null ? null : Encoding.UTF8.GetBytes(s);
[Fact]
public void RedisValueStartsWith()
{
// test strings
RedisValue x = "abc";
Assert.True(x.StartsWith("a"));
Assert.True(x.StartsWith("ab"));
Assert.True(x.StartsWith("abc"));
Assert.False(x.StartsWith("abd"));
Assert.False(x.StartsWith("abcd"));
Assert.False(x.StartsWith(123));
Assert.False(x.StartsWith(false));
// test binary
x = Encoding.ASCII.GetBytes("abc");
Assert.True(x.StartsWith("a"));
Assert.True(x.StartsWith("ab"));
Assert.True(x.StartsWith("abc"));
Assert.False(x.StartsWith("abd"));
Assert.False(x.StartsWith("abcd"));
Assert.False(x.StartsWith(123));
Assert.False(x.StartsWith(false));
Assert.True(x.StartsWith(Encoding.ASCII.GetBytes("a")));
Assert.True(x.StartsWith(Encoding.ASCII.GetBytes("ab")));
Assert.True(x.StartsWith(Encoding.ASCII.GetBytes("abc")));
Assert.False(x.StartsWith(Encoding.ASCII.GetBytes("abd")));
Assert.False(x.StartsWith(Encoding.ASCII.GetBytes("abcd")));
x = 10; // integers are effectively strings in this context
Assert.True(x.StartsWith(1));
Assert.True(x.StartsWith(10));
Assert.False(x.StartsWith(100));
}
} }
} }
...@@ -60,7 +60,7 @@ internal static RedisResult TryCreate(PhysicalConnection connection, RawResult r ...@@ -60,7 +60,7 @@ internal static RedisResult TryCreate(PhysicalConnection connection, RawResult r
/// <summary> /// <summary>
/// Indicate the type of result that was received from redis /// Indicate the type of result that was received from redis
/// </summary> /// </summary>
public abstract ResultType ResultType { get; } public abstract ResultType Type { get; }
/// <summary> /// <summary>
/// Indicates whether this result was a null result /// Indicates whether this result was a null result
...@@ -199,7 +199,7 @@ private sealed class ArrayRedisResult : RedisResult ...@@ -199,7 +199,7 @@ private sealed class ArrayRedisResult : RedisResult
public override bool IsNull => value == null; public override bool IsNull => value == null;
private readonly RedisResult[] value; private readonly RedisResult[] value;
public override ResultType ResultType => ResultType.MultiBulk; public override ResultType Type => ResultType.MultiBulk;
public ArrayRedisResult(RedisResult[] value) public ArrayRedisResult(RedisResult[] value)
{ {
this.value = value ?? throw new ArgumentNullException(nameof(value)); this.value = value ?? throw new ArgumentNullException(nameof(value));
...@@ -302,7 +302,7 @@ private sealed class ErrorRedisResult : RedisResult ...@@ -302,7 +302,7 @@ private sealed class ErrorRedisResult : RedisResult
{ {
private readonly string value; private readonly string value;
public override ResultType ResultType => ResultType.Error; public override ResultType Type => ResultType.Error;
public ErrorRedisResult(string value) public ErrorRedisResult(string value)
{ {
this.value = value ?? throw new ArgumentNullException(nameof(value)); this.value = value ?? throw new ArgumentNullException(nameof(value));
...@@ -337,7 +337,7 @@ private sealed class SingleRedisResult : RedisResult ...@@ -337,7 +337,7 @@ private sealed class SingleRedisResult : RedisResult
{ {
private readonly RedisValue _value; private readonly RedisValue _value;
private readonly ResultType _resultType; private readonly ResultType _resultType;
public override ResultType ResultType => _resultType; public override ResultType Type => _resultType;
public SingleRedisResult(RedisValue value, ResultType? resultType) public SingleRedisResult(RedisValue value, ResultType? resultType)
{ {
_value = value; _value = value;
......
...@@ -762,5 +762,33 @@ public static RedisValue CreateFrom(MemoryStream stream) ...@@ -762,5 +762,33 @@ public static RedisValue CreateFrom(MemoryStream stream)
return stream.ToArray(); return stream.ToArray();
} }
} }
/// <summary>
/// Indicates whether the current value has the supplied value as a prefix
/// </summary>
public bool StartsWith(RedisValue value)
{
ReadOnlyMemory<byte> rawThis, rawOther;
var thisType = this.Type;
if (thisType == value.Type) // same? can often optimize
{
switch(thisType)
{
case StorageType.String:
var sThis = ((string)this._objectOrSentinel);
var sOther = ((string)value._objectOrSentinel);
return sThis.StartsWith(sOther, StringComparison.Ordinal);
case StorageType.Raw:
rawThis = this._memory;
rawOther = value._memory;
return rawThis.Span.StartsWith(rawOther.Span);
}
}
rawThis = (ReadOnlyMemory<byte>)this;
rawOther = (ReadOnlyMemory<byte>)value;
return rawThis.Span.StartsWith(rawOther.Span);
}
} }
} }
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