Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add (ReadOnly)Memory<byte> implicit conversions to RedisKey #2578

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/StackExchange.Redis/KeyspaceIsolation/KeyPrefixed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace StackExchange.Redis.KeyspaceIsolation
Expand Down Expand Up @@ -843,7 +844,8 @@ internal KeyPrefixed(TInner inner, byte[] keyPrefix)

protected RedisChannel ToInner(RedisChannel outer)
{
var combined = RedisKey.ConcatenateBytes(Prefix, null, (byte[]?)outer);
var combined = RedisKey.ConcatenateBytesArray(Prefix, null, (byte[]?)outer);

return new RedisChannel(combined, outer.IsPattern ? RedisChannel.PatternMode.Pattern : RedisChannel.PatternMode.Literal);
}

Expand Down
27 changes: 19 additions & 8 deletions src/StackExchange.Redis/PhysicalConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1148,19 +1148,30 @@ internal static byte ToHexNibble(int value)
return value < 10 ? (byte)('0' + value) : (byte)('a' - 10 + value);
}

internal static void WriteUnifiedPrefixedString(PipeWriter writer, byte[]? prefix, string? value)
internal static void WriteUnifiedPrefixedString(PipeWriter writer, ReadOnlyMemory<byte> prefix, string? value)
{
if (value == null)
if (prefix.IsEmpty && value == null)
{
// special case
writer.Write(NullBulkString.Span);
}
else if (value == null)
{
int totalLength = prefix.Length;

var span = writer.GetSpan(3 + Format.MaxInt32TextLen);
span[0] = (byte)'$';
int bytes = WriteRaw(span, totalLength, offset: 1);
writer.Advance(bytes);

writer.Write(prefix.Span);
}
else
{
// ${total-len}\r\n 3 + MaxInt32TextLen
// {prefix}{value}\r\n
int encodedLength = Encoding.UTF8.GetByteCount(value),
prefixLength = prefix?.Length ?? 0,
prefixLength = prefix.Length,
totalLength = prefixLength + encodedLength;

if (totalLength == 0)
Expand All @@ -1175,7 +1186,7 @@ internal static void WriteUnifiedPrefixedString(PipeWriter writer, byte[]? prefi
int bytes = WriteRaw(span, totalLength, offset: 1);
writer.Advance(bytes);

if (prefixLength != 0) writer.Write(prefix);
if (prefixLength != 0) writer.Write(prefix.Span);
if (encodedLength != 0) WriteRaw(writer, value, encodedLength);
WriteCrlf(writer);
}
Expand Down Expand Up @@ -1251,11 +1262,11 @@ internal static unsafe void WriteRaw(PipeWriter writer, string value, int expect
}
}

private static void WriteUnifiedPrefixedBlob(PipeWriter writer, byte[]? prefix, byte[]? value)
private static void WriteUnifiedPrefixedBlob(PipeWriter writer, ReadOnlyMemory<byte> prefix, byte[]? value)
{
// ${total-len}\r\n
// {prefix}{value}\r\n
if (prefix == null || prefix.Length == 0 || value == null)
if (prefix.Length == 0 || value == null)
{ // if no prefix, just use the non-prefixed version;
// even if prefixed, a null value writes as null, so can use the non-prefixed version
WriteUnifiedBlob(writer, value);
Expand All @@ -1264,10 +1275,10 @@ private static void WriteUnifiedPrefixedBlob(PipeWriter writer, byte[]? prefix,
{
var span = writer.GetSpan(3 + Format.MaxInt32TextLen); // note even with 2 max-len, we're still in same text range
span[0] = (byte)'$';
int bytes = WriteRaw(span, prefix.LongLength + value.LongLength, offset: 1);
int bytes = WriteRaw(span, prefix.Length + value.LongLength, offset: 1);
writer.Advance(bytes);

writer.Write(prefix);
writer.Write(prefix.Span);
writer.Write(value);

span = writer.GetSpan(2);
Expand Down
3 changes: 3 additions & 0 deletions src/StackExchange.Redis/PublicAPI/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ StackExchange.Redis.IServer.Protocol.get -> StackExchange.Redis.RedisProtocol
StackExchange.Redis.RedisFeatures.ClientId.get -> bool
StackExchange.Redis.RedisFeatures.Equals(StackExchange.Redis.RedisFeatures other) -> bool
StackExchange.Redis.RedisFeatures.Resp3.get -> bool
StackExchange.Redis.RedisKey.RedisKey(System.ReadOnlyMemory<byte> key) -> void
StackExchange.Redis.RedisProtocol
StackExchange.Redis.RedisProtocol.Resp2 = 20000 -> StackExchange.Redis.RedisProtocol
StackExchange.Redis.RedisProtocol.Resp3 = 30000 -> StackExchange.Redis.RedisProtocol
Expand All @@ -25,6 +26,8 @@ StackExchange.Redis.ResultType.Null = 8 -> StackExchange.Redis.ResultType
StackExchange.Redis.ResultType.Push = 37 -> StackExchange.Redis.ResultType
StackExchange.Redis.ResultType.Set = 21 -> StackExchange.Redis.ResultType
StackExchange.Redis.ResultType.VerbatimString = 12 -> StackExchange.Redis.ResultType
static StackExchange.Redis.RedisKey.implicit operator StackExchange.Redis.RedisKey(System.Memory<byte> key) -> StackExchange.Redis.RedisKey
static StackExchange.Redis.RedisKey.implicit operator StackExchange.Redis.RedisKey(System.ReadOnlyMemory<byte> key) -> StackExchange.Redis.RedisKey
static StackExchange.Redis.RedisResult.Create(StackExchange.Redis.RedisResult![]! values, StackExchange.Redis.ResultType resultType) -> StackExchange.Redis.RedisResult!
static StackExchange.Redis.RedisResult.Create(StackExchange.Redis.RedisValue[]! values, StackExchange.Redis.ResultType resultType) -> StackExchange.Redis.RedisResult!
virtual StackExchange.Redis.RedisResult.Length.get -> int
Expand Down