Skip to content

Commit

Permalink
Improve FastParseCommand readability
Browse files Browse the repository at this point in the history
  • Loading branch information
aromaa committed Apr 3, 2024
1 parent a3eb1b2 commit 7b60511
Showing 1 changed file with 59 additions and 227 deletions.
286 changes: 59 additions & 227 deletions libs/server/Resp/RespCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,12 @@ private RespCommand FastParseCommand(out int count)
count = ptr[1] - '1';
Debug.Assert(count is >= 0 and < 9);

var oldReadHead = readHead;

// Extract length of the first string header
var length = ptr[5] - '0';
Debug.Assert(length is > 0 and <= 9);

var oldReadHead = readHead;

// Ensure that the complete command string is contained in the package. Otherwise exit early.
// Include 10 bytes to account for array and command string headers, and terminator
// 10 bytes = "*_\r\n$_\r\n" (8 bytes) + "\r\n" (2 bytes) at end of command name
Expand All @@ -226,235 +226,67 @@ private RespCommand FastParseCommand(out int count)
//

// Only check against commands with the correct count and length.
// Note: Cases are encoded as 0x{count}{length} for readability.
byte hash = (byte)((count << 4) | length);
switch (hash)
{
case 0x04:
if (lastWord == MemoryMarshal.Read<ulong>("\r\nPING\r\n"u8))
{
return RespCommand.PING;
}
else if (lastWord == MemoryMarshal.Read<ulong>("\r\nEXEC\r\n"u8))
{
return RespCommand.EXEC;
}
break;
case 0x05:
if (lastWord == MemoryMarshal.Read<ulong>("\nMULTI\r\n"u8))
{
return RespCommand.MULTI;
}
break;
case 0x06:
if (lastWord == MemoryMarshal.Read<ulong>("ASKING\r\n"u8))
{
return RespCommand.ASKING;
}
break;

case 0x07:
if (lastWord == MemoryMarshal.Read<ulong>("ISCARD\r\n"u8) && ptr[8] == 'D')
{
return RespCommand.DISCARD;
}
else if (lastWord == MemoryMarshal.Read<ulong>("NWATCH\r\n"u8) && ptr[8] == 'U')
{
return RespCommand.UNWATCH;
}
break;

case 0x08:
if (lastWord == MemoryMarshal.Read<ulong>("ADONLY\r\n"u8) && *(ushort*)(ptr + 8) == MemoryMarshal.Read<ushort>("RE"u8))
{
return RespCommand.READONLY;
}
break;

case 0x09:
if (lastWord == MemoryMarshal.Read<ulong>("DWRITE\r\n"u8) && *(uint*)(ptr + 8) == MemoryMarshal.Read<uint>("READ"u8))
{
return RespCommand.READWRITE;
}
break;

case 0x13:
if (lastWord == MemoryMarshal.Read<ulong>("3\r\nGET\r\n"u8))
{
return RespCommand.GET;
}
else if (lastWord == MemoryMarshal.Read<ulong>("3\r\nDEL\r\n"u8))
{
return RespCommand.DEL;
}
else if (lastWord == MemoryMarshal.Read<ulong>("3\r\nTTL\r\n"u8))
{
return RespCommand.TTL;
}
break;

case 0x14:
if (lastWord == MemoryMarshal.Read<ulong>("\r\nINCR\r\n"u8))
{
return RespCommand.INCR;
}
else if (lastWord == MemoryMarshal.Read<ulong>("\r\nPTTL\r\n"u8))
{
return RespCommand.PTTL;
}
else if (lastWord == MemoryMarshal.Read<ulong>("\r\nDECR\r\n"u8))
{
return RespCommand.DECR;
}
break;

case 0x16:
if (lastWord == MemoryMarshal.Read<ulong>("EXISTS\r\n"u8))
{
return RespCommand.EXISTS;
}
else if (lastWord == MemoryMarshal.Read<ulong>("GETDEL\r\n"u8))
{
return RespCommand.GETDEL;
}
break;

case 0x17:
if (lastWord == MemoryMarshal.Read<ulong>("ERSIST\r\n"u8) && ptr[8] == 'P')
{
return RespCommand.PERSIST;
}
else if (lastWord == MemoryMarshal.Read<ulong>("FCOUNT\r\n"u8) && ptr[8] == 'P')
{
return RespCommand.PFCOUNT;
}
break;

case 0x23:
if (lastWord == MemoryMarshal.Read<ulong>("3\r\nSET\r\n"u8))
{
return RespCommand.SET;
}
break;

case 0x25:
if (lastWord == MemoryMarshal.Read<ulong>("\nPFADD\r\n"u8))
{
return RespCommand.PFADD;
}
break;

case 0x26:
if (lastWord == MemoryMarshal.Read<ulong>("INCRBY\r\n"u8))
{
return RespCommand.INCRBY;
}
else if (lastWord == MemoryMarshal.Read<ulong>("DECRBY\r\n"u8))
{
return RespCommand.DECRBY;
}
else if (lastWord == MemoryMarshal.Read<ulong>("RENAME\r\n"u8))
{
return RespCommand.RENAME;
}
else if (lastWord == MemoryMarshal.Read<ulong>("GETBIT\r\n"u8))
{
return RespCommand.GETBIT;
}
else if (lastWord == MemoryMarshal.Read<ulong>("APPEND\r\n"u8))
{
return RespCommand.APPEND;
}
break;

case 0x27:
if (lastWord == MemoryMarshal.Read<ulong>("UBLISH\r\n"u8) && ptr[8] == 'P')
{
return RespCommand.PUBLISH;
}

else if (lastWord == MemoryMarshal.Read<ulong>("FMERGE\r\n"u8) && ptr[8] == 'P')
{
return RespCommand.PFMERGE;
}
break;

case 0x35:
if (lastWord == MemoryMarshal.Read<ulong>("\nSETEX\r\n"u8))
{
return RespCommand.SETEX;
}
break;

case 0x36:
if (lastWord == MemoryMarshal.Read<ulong>("PSETEX\r\n"u8))
{
return RespCommand.PSETEX;
}
else if (lastWord == MemoryMarshal.Read<ulong>("SETBIT\r\n"u8))
{
return RespCommand.SETBIT;
}
break;

case 0x38:
if (lastWord == MemoryMarshal.Read<ulong>("TRANGE\r\n"u8) && *(ushort*)(ptr + 8) == MemoryMarshal.Read<ushort>("SE"u8))
{
return RespCommand.SETRANGE;
}
else if (lastWord == MemoryMarshal.Read<ulong>("TRANGE\r\n"u8) && *(ushort*)(ptr + 8) == MemoryMarshal.Read<ushort>("GE"u8))
{
return RespCommand.GETRANGE;
}
break;
}

//
// Fast path for commands with few, but variable, #arguments (command array size < 10)
//
return ((count << 4) | length) switch
{
// Commands without arguments
4 when lastWord == MemoryMarshal.Read<ulong>("\r\nPING\r\n"u8) => RespCommand.PING,
4 when lastWord == MemoryMarshal.Read<ulong>("\r\nEXEC\r\n"u8) => RespCommand.EXEC,
5 when lastWord == MemoryMarshal.Read<ulong>("\nMULTI\r\n"u8) => RespCommand.MULTI,
6 when lastWord == MemoryMarshal.Read<ulong>("ASKING\r\n"u8) => RespCommand.ASKING,
7 when lastWord == MemoryMarshal.Read<ulong>("ISCARD\r\n"u8) && ptr[8] == 'D' => RespCommand.DISCARD,
7 when lastWord == MemoryMarshal.Read<ulong>("NWATCH\r\n"u8) && ptr[8] == 'U' => RespCommand.UNWATCH,
8 when lastWord == MemoryMarshal.Read<ulong>("ADONLY\r\n"u8) && *(ushort*)(ptr + 8) == MemoryMarshal.Read<ushort>("RE"u8) => RespCommand.READONLY,
9 when lastWord == MemoryMarshal.Read<ulong>("DWRITE\r\n"u8) && *(uint*)(ptr + 8) == MemoryMarshal.Read<uint>("READ"u8) => RespCommand.READWRITE,

// Commands with fixed amount of arguments
(1 << 4) | 3 when lastWord == MemoryMarshal.Read<ulong>("3\r\nGET\r\n"u8) => RespCommand.GET,
(1 << 4) | 3 when lastWord == MemoryMarshal.Read<ulong>("3\r\nDEL\r\n"u8) => RespCommand.DEL,
(1 << 4) | 3 when lastWord == MemoryMarshal.Read<ulong>("3\r\nTTL\r\n"u8) => RespCommand.TTL,
(1 << 4) | 4 when lastWord == MemoryMarshal.Read<ulong>("\r\nINCR\r\n"u8) => RespCommand.INCR,
(1 << 4) | 4 when lastWord == MemoryMarshal.Read<ulong>("\r\nPTTL\r\n"u8) => RespCommand.PTTL,
(1 << 4) | 4 when lastWord == MemoryMarshal.Read<ulong>("\r\nDECR\r\n"u8) => RespCommand.DECR,
(1 << 4) | 4 when lastWord == MemoryMarshal.Read<ulong>("EXISTS\r\n"u8) => RespCommand.EXISTS,
(1 << 4) | 6 when lastWord == MemoryMarshal.Read<ulong>("GETDEL\r\n"u8) => RespCommand.GETDEL,
(1 << 4) | 7 when lastWord == MemoryMarshal.Read<ulong>("ERSIST\r\n"u8) && ptr[8] == 'P' => RespCommand.PERSIST,
(1 << 4) | 7 when lastWord == MemoryMarshal.Read<ulong>("PFCOUNT\r\n"u8) && ptr[8] == 'P' => RespCommand.PFCOUNT,
(2 << 4) | 3 when lastWord == MemoryMarshal.Read<ulong>("3\r\nSET\r\n"u8) => RespCommand.SET,
(2 << 4) | 5 when lastWord == MemoryMarshal.Read<ulong>("\nPFADD\r\n"u8) => RespCommand.PFADD,
(2 << 4) | 6 when lastWord == MemoryMarshal.Read<ulong>("INCRBY\r\n"u8) => RespCommand.INCRBY,
(2 << 4) | 6 when lastWord == MemoryMarshal.Read<ulong>("DECRBY\r\n"u8) => RespCommand.DECRBY,
(2 << 4) | 6 when lastWord == MemoryMarshal.Read<ulong>("RENAME\r\n"u8) => RespCommand.RENAME,
(2 << 4) | 6 when lastWord == MemoryMarshal.Read<ulong>("GETBIT\r\n"u8) => RespCommand.GETBIT,
(2 << 4) | 6 when lastWord == MemoryMarshal.Read<ulong>("APPEND\r\n"u8) => RespCommand.APPEND,
(2 << 4) | 7 when lastWord == MemoryMarshal.Read<ulong>("UBLISH\r\n"u8) && ptr[8] == 'P' => RespCommand.PUBLISH,
(2 << 4) | 7 when lastWord == MemoryMarshal.Read<ulong>("FMERGE\r\n"u8) && ptr[8] == 'P' => RespCommand.PFMERGE,
(3 << 4) | 5 when lastWord == MemoryMarshal.Read<ulong>("\nSETEX\r\n"u8) => RespCommand.SETEX,
(3 << 4) | 6 when lastWord == MemoryMarshal.Read<ulong>("PSETEX\r\n"u8) => RespCommand.PSETEX,
(3 << 4) | 6 when lastWord == MemoryMarshal.Read<ulong>("SETBIT\r\n"u8) => RespCommand.SETBIT,
(3 << 4) | 8 when lastWord == MemoryMarshal.Read<ulong>("TRANGE\r\n"u8) && *(ushort*)(ptr + 8) == MemoryMarshal.Read<ushort>("SE"u8) => RespCommand.SETRANGE,
(3 << 4) | 8 when lastWord == MemoryMarshal.Read<ulong>("TRANGE\r\n"u8) && *(ushort*)(ptr + 8) == MemoryMarshal.Read<ushort>("GE"u8) => RespCommand.GETRANGE,

_ => ((length << 4) | count) switch
{
// Commands with dynamic amount of arguments
>= ((3 << 4) | 3) and <= ((3 << 4) | 6) when lastWord == MemoryMarshal.Read<ulong>("3\r\nSET\r\n"u8) => RespCommand.SETEXNX,
>= ((6 << 4) | 0) and <= ((6 << 4) | 9) when lastWord == MemoryMarshal.Read<ulong>("RUNTXP\r\n"u8) => RespCommand.RUNTXP,
>= ((6 << 4) | 2) and <= ((6 << 4) | 3) when lastWord == MemoryMarshal.Read<ulong>("EXPIRE\r\n"u8) => RespCommand.EXPIRE,
>= ((6 << 4) | 2) and <= ((6 << 4) | 5) when lastWord == MemoryMarshal.Read<ulong>("BITPOS\r\n"u8) => RespCommand.BITPOS,
>= ((7 << 4) | 2) and <= ((7 << 4) | 3) when lastWord == MemoryMarshal.Read<ulong>("EXPIRE\r\n"u8) && ptr[8] == 'P' => RespCommand.PEXPIRE,
>= ((8 << 4) | 1) and <= ((8 << 4) | 4) when lastWord == MemoryMarshal.Read<ulong>("TCOUNT\r\n"u8) && *(ushort*)(ptr + 8) == MemoryMarshal.Read<ushort>("BI"u8) => RespCommand.BITCOUNT,

_ => MatchedNone(this, oldReadHead)
}
};

switch (length)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static RespCommand MatchedNone(RespServerSession session, int oldReadHead)
{
case 3:
if (((count >= 3) && (count <= 6)) && lastWord == MemoryMarshal.Read<ulong>("3\r\nSET\r\n"u8))
{
return RespCommand.SETEXNX;
}
break;

case 6:
if (lastWord == MemoryMarshal.Read<ulong>("RUNTXP\r\n"u8))
{
return RespCommand.RUNTXP;
}
else if (((count == 2) || (count == 3)) && lastWord == MemoryMarshal.Read<ulong>("EXPIRE\r\n"u8))
{
return RespCommand.EXPIRE;
}
else if ((count > 1 && count < 6) && lastWord == MemoryMarshal.Read<ulong>("BITPOS\r\n"u8))
{
return RespCommand.BITPOS;
}
break;

case 7:

if (((count == 2) || (count == 3)) && lastWord == MemoryMarshal.Read<ulong>("EXPIRE\r\n"u8) && ptr[8] == 'P')
{
return RespCommand.PEXPIRE;
}
break;

case 8:
if ((count > 0 && count < 5) && lastWord == MemoryMarshal.Read<ulong>("TCOUNT\r\n"u8) /* "BITCOUNT" */ && *(ushort*)(ptr + 8) == MemoryMarshal.Read<ushort>("BI"u8))
{
return RespCommand.BITCOUNT;
}
break;
}
// Backup the read head, if we didn't find a command and need to continue in the more expensive parsing loop
session.readHead = oldReadHead;

// Backup the read head, if we didn't find a command and need to continue in the more expensive parsing loop
readHead = oldReadHead;
return RespCommand.NONE;
}
}
}
else
Expand Down

0 comments on commit 7b60511

Please sign in to comment.