perf: keep parser state in bytes until materialization
This commit is contained in:
@@ -37,7 +37,7 @@ public readonly struct ParsedCommand
|
||||
|
||||
public sealed class NatsParser
|
||||
{
|
||||
private static readonly byte[] CrLfBytes = "\r\n"u8.ToArray();
|
||||
private static ReadOnlySpan<byte> CrLfBytes => "\r\n"u8;
|
||||
private ILogger? _logger;
|
||||
public ILogger? Logger { set => _logger = value; }
|
||||
|
||||
@@ -85,7 +85,7 @@ public sealed class NatsParser
|
||||
|
||||
// Look for \r\n to find control line
|
||||
var reader = new SequenceReader<byte>(buffer);
|
||||
if (!reader.TryReadTo(out ReadOnlySequence<byte> line, CrLfBytes.AsSpan()))
|
||||
if (!reader.TryReadTo(out ReadOnlySequence<byte> line, CrLfBytes))
|
||||
return false;
|
||||
|
||||
// Control line size check
|
||||
@@ -177,7 +177,7 @@ public sealed class NatsParser
|
||||
case (byte)'c':
|
||||
if (b1 == (byte)'o') // CONNECT
|
||||
{
|
||||
command = ParseConnect(lineSpan);
|
||||
command = ParseConnect(line);
|
||||
buffer = buffer.Slice(reader.Position);
|
||||
TraceInOp("CONNECT");
|
||||
return true;
|
||||
@@ -188,7 +188,7 @@ public sealed class NatsParser
|
||||
case (byte)'i':
|
||||
if (b1 == (byte)'n') // INFO
|
||||
{
|
||||
command = ParseInfo(lineSpan);
|
||||
command = ParseInfo(line);
|
||||
buffer = buffer.Slice(reader.Position);
|
||||
TraceInOp("INFO");
|
||||
return true;
|
||||
@@ -430,36 +430,34 @@ public sealed class NatsParser
|
||||
};
|
||||
}
|
||||
|
||||
private static ParsedCommandView ParseConnect(Span<byte> line)
|
||||
private static ParsedCommandView ParseConnect(ReadOnlySequence<byte> line)
|
||||
{
|
||||
// CONNECT {json} -- find first space after command
|
||||
int spaceIdx = line.IndexOf((byte)' ');
|
||||
if (spaceIdx < 0)
|
||||
var reader = new SequenceReader<byte>(line);
|
||||
if (!reader.TryAdvanceTo((byte)' ', advancePastDelimiter: true))
|
||||
throw new ProtocolViolationException("Invalid CONNECT");
|
||||
|
||||
var json = line[(spaceIdx + 1)..];
|
||||
var json = line.Slice(reader.Position);
|
||||
return new ParsedCommandView
|
||||
{
|
||||
Type = CommandType.Connect,
|
||||
Operation = "CONNECT",
|
||||
Payload = new ReadOnlySequence<byte>(json.ToArray()),
|
||||
Payload = json,
|
||||
MaxMessages = -1,
|
||||
};
|
||||
}
|
||||
|
||||
private static ParsedCommandView ParseInfo(Span<byte> line)
|
||||
private static ParsedCommandView ParseInfo(ReadOnlySequence<byte> line)
|
||||
{
|
||||
// INFO {json} -- find first space after command
|
||||
int spaceIdx = line.IndexOf((byte)' ');
|
||||
if (spaceIdx < 0)
|
||||
var reader = new SequenceReader<byte>(line);
|
||||
if (!reader.TryAdvanceTo((byte)' ', advancePastDelimiter: true))
|
||||
throw new ProtocolViolationException("Invalid INFO");
|
||||
|
||||
var json = line[(spaceIdx + 1)..];
|
||||
var json = line.Slice(reader.Position);
|
||||
return new ParsedCommandView
|
||||
{
|
||||
Type = CommandType.Info,
|
||||
Operation = "INFO",
|
||||
Payload = new ReadOnlySequence<byte>(json.ToArray()),
|
||||
Payload = json,
|
||||
MaxMessages = -1,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user