Skip to content

Commit 1996224

Browse files
committed
Shifting inline code to function improves BDN performance.
1 parent 0437f67 commit 1996224

File tree

1 file changed

+60
-47
lines changed

1 file changed

+60
-47
lines changed

libs/server/Resp/Parser/RespCommand.cs

Lines changed: 60 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2628,32 +2628,35 @@ internal bool FuzzParseCommandBuffer(ReadOnlySpan<byte> buffer, out RespCommand
26282628
[MethodImpl(MethodImplOptions.AggressiveInlining)]
26292629
private RespCommand ParseCommand(bool writeErrorOnFailure, out bool commandReceived)
26302630
{
2631-
var cmd = RespCommand.INVALID;
2631+
RespCommand cmd;
26322632

26332633
// Initialize count as -1 (i.e., read head has not been advanced)
26342634
var count = -1;
26352635
commandReceived = true;
26362636
endReadHead = readHead;
26372637

2638-
var remainingBytes = bytesRead - readHead;
26392638
var ptr = recvBufferPtr + readHead;
2640-
var end = ptr + remainingBytes;
2639+
var end = recvBufferPtr + bytesRead;
2640+
var remainingBytes = bytesRead - readHead;
26412641

26422642
// Attempt parsing using fast parse pass for most common operations
26432643
cmd = FastParseCommand(out count, ptr, remainingBytes);
26442644

2645-
// See if input command is all upper-case. If not, convert and try fast parse pass again.
2646-
if ((cmd == RespCommand.NONE) && MakeUpperCase(ptr, remainingBytes))
2645+
if (cmd == RespCommand.NONE)
26472646
{
2648-
cmd = FastParseCommand(out count, ptr, remainingBytes);
2649-
}
2647+
// See if input command is all upper-case. If not, convert and try fast parse pass again.
2648+
if (MakeUpperCase(ptr, remainingBytes))
2649+
{
2650+
cmd = FastParseCommand(out count, ptr, remainingBytes);
2651+
}
26502652

2651-
// If we have not found a command, continue parsing on slow path.
2652-
// But first ensure we are attempting to read a RESP array header.
2653-
if ((cmd == RespCommand.NONE) && (*ptr == '*'))
2654-
{
2655-
cmd = ArrayParseCommand(writeErrorOnFailure, ptr, end, out count, out commandReceived);
2656-
if (!commandReceived) return cmd;
2653+
// If we have not found a command, continue parsing on slow path.
2654+
// But first ensure we are attempting to read a RESP array header.
2655+
if ((cmd == RespCommand.NONE) && (*ptr == '*'))
2656+
{
2657+
cmd = ArrayParseCommand(writeErrorOnFailure, ptr, end, out count, out commandReceived);
2658+
if (!commandReceived) return cmd;
2659+
}
26572660
}
26582661

26592662
if (cmd != RespCommand.NONE)
@@ -2674,42 +2677,11 @@ private RespCommand ParseCommand(bool writeErrorOnFailure, out bool commandRecei
26742677

26752678
readHead = (int)(ptr - recvBufferPtr);
26762679
}
2677-
else if (CanRunInlineCommands())
2680+
else if (CanRunInlineCommands() && (*ptr != '*'))
26782681
{
2679-
// This may be an inline command string. We'll parse it and convert a part to a RESP command string,
2680-
// which is then parsed to get the command.
2681-
SpanByteAndMemory spam = new(null);
2682-
if (!ParseInlineCommandline(ref spam, writeErrorOnFailure, ref ptr, out commandReceived, out var nbytes, out var result))
2683-
{
2684-
if (commandReceived)
2685-
endReadHead = readHead;
2682+
cmd = TryParseInlineCommandline(writeErrorOnFailure, ref ptr, out commandReceived, ref count);
2683+
if (!commandReceived)
26862684
return RespCommand.INVALID;
2687-
}
2688-
2689-
// If we're here, commandReceived is true, and we've reached end-of-line.
2690-
endReadHead = readHead;
2691-
2692-
fixed (byte* nptr = spam.Memory.Memory.Span)
2693-
{
2694-
var nend = nptr + nbytes;
2695-
2696-
cmd = FastParseCommand(out count, nptr, nbytes);
2697-
2698-
// Since we're operating on a temporary buffer and not the actual receive buffer,
2699-
// we don't care for its commandReceived, and we reset readHead afterwards.
2700-
if (cmd == RespCommand.NONE)
2701-
{
2702-
cmd = ArrayParseCommand(writeErrorOnFailure, nptr, nend, out count, out _,
2703-
result[0].ReadOnlySpan, result.Length > 1 ? result[1] : default);
2704-
}
2705-
readHead = endReadHead;
2706-
2707-
if (cmd == RespCommand.INVALID)
2708-
logger?.LogWarning("Received malformed input message. Line is skipped.");
2709-
}
2710-
2711-
// Note that arguments are initialized from the actual command string, and not our made-up RESP string.
2712-
parseState.InitializeWithArguments(result[(result.Length - count)..]);
27132685
}
27142686
else
27152687
{
@@ -2725,6 +2697,47 @@ private RespCommand ParseCommand(bool writeErrorOnFailure, out bool commandRecei
27252697
return cmd;
27262698
}
27272699

2700+
private RespCommand TryParseInlineCommandline(bool writeErrorOnFailure, ref byte* ptr,
2701+
out bool commandReceived, ref int count)
2702+
{
2703+
// This may be an inline command string. We'll parse it and convert a part to a RESP command string,
2704+
// which is then parsed to get the command.
2705+
SpanByteAndMemory spam = new(null);
2706+
if (!ParseInlineCommandline(ref spam, writeErrorOnFailure, ref ptr, out commandReceived, out var nbytes, out var result))
2707+
{
2708+
if (commandReceived)
2709+
endReadHead = readHead;
2710+
return RespCommand.INVALID;
2711+
}
2712+
2713+
// If we're here, commandReceived is true, and we've reached end-of-line.
2714+
endReadHead = readHead;
2715+
2716+
fixed (byte* nptr = spam.Memory.Memory.Span)
2717+
{
2718+
var nend = nptr + nbytes;
2719+
2720+
var cmd = FastParseCommand(out count, nptr, nbytes);
2721+
2722+
// Since we're operating on a temporary buffer and not the actual receive buffer,
2723+
// we don't care for its commandReceived, and we reset readHead afterwards.
2724+
if (cmd == RespCommand.NONE)
2725+
{
2726+
cmd = ArrayParseCommand(writeErrorOnFailure, nptr, nend, out count, out _,
2727+
result[0].ReadOnlySpan, result.Length > 1 ? result[1] : default);
2728+
}
2729+
readHead = endReadHead;
2730+
2731+
if (cmd == RespCommand.INVALID)
2732+
logger?.LogWarning("Received malformed input message. Line is skipped.");
2733+
else
2734+
// Note that arguments are initialized from the actual command string, and not our made-up RESP string.
2735+
parseState.InitializeWithArguments(result[(result.Length - count)..]);
2736+
2737+
return cmd;
2738+
}
2739+
}
2740+
27282741
private bool ParseInlineCommandline(ref SpanByteAndMemory spam,
27292742
bool writeErrorOnFailure, ref byte* ptr, out bool commandReceived,
27302743
out int nbytes, out ArgSlice[] result)

0 commit comments

Comments
 (0)