Skip to content

Commit

Permalink
Avoid allocating an unused OkPayload.
Browse files Browse the repository at this point in the history
  • Loading branch information
bgrainger committed Aug 13, 2023
1 parent e8d5878 commit 640f955
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 20 deletions.
18 changes: 9 additions & 9 deletions src/MySqlConnector/Core/ServerSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ public void FinishQuerying()
SendAsync(payload, IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
payload = ReceiveReplyAsync(IOBehavior.Synchronous, CancellationToken.None).GetAwaiter().GetResult();
#pragma warning restore CA2012
OkPayload.Create(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
OkPayload.Verify(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
}

lock (m_lock)
Expand Down Expand Up @@ -582,7 +582,7 @@ public async Task DisposeAsync(IOBehavior ioBehavior, CancellationToken cancella
// set 'collation_connection' to the server default
await SendAsync(m_setNamesPayload, ioBehavior, cancellationToken).ConfigureAwait(false);
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
OkPayload.Create(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
OkPayload.Verify(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);

if (ShouldGetRealServerDetails(cs))
await GetRealServerDetailsAsync(ioBehavior, CancellationToken.None).ConfigureAwait(false);
Expand Down Expand Up @@ -627,19 +627,19 @@ public async Task<bool> TryResetConnectionAsync(ConnectionSettings cs, MySqlConn
// read two OK replies
m_payloadHandler.SetNextSequenceNumber(1);
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
OkPayload.Create(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
OkPayload.Verify(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);

m_payloadHandler.SetNextSequenceNumber(1);
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
OkPayload.Create(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
OkPayload.Verify(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);

return true;
}

Log.SendingResetConnectionRequest(m_logger, Id, ServerVersion.OriginalString);
await SendAsync(ResetConnectionPayload.Instance, ioBehavior, cancellationToken).ConfigureAwait(false);
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
OkPayload.Create(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
OkPayload.Verify(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
}
else
{
Expand All @@ -663,13 +663,13 @@ public async Task<bool> TryResetConnectionAsync(ConnectionSettings cs, MySqlConn
Log.OptimisticReauthenticationFailed(m_logger, Id);
payload = await SwitchAuthenticationAsync(cs, password, payload, ioBehavior, cancellationToken).ConfigureAwait(false);
}
OkPayload.Create(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
OkPayload.Verify(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
}

// set 'collation_connection' to the server default
await SendAsync(m_setNamesPayload, ioBehavior, cancellationToken).ConfigureAwait(false);
payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
OkPayload.Create(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
OkPayload.Verify(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);

return true;
}
Expand Down Expand Up @@ -870,7 +870,7 @@ public async ValueTask<bool> TryPingAsync(bool logInfo, IOBehavior ioBehavior, C
Log.PingingServer(m_logger, Id);
await SendAsync(PingPayload.Instance, ioBehavior, cancellationToken).ConfigureAwait(false);
var payload = await ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
OkPayload.Create(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
OkPayload.Verify(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
Log.SuccessfullyPingedServer(m_logger, logInfo ? LogLevel.Information : LogLevel.Trace, Id);
return true;
}
Expand Down Expand Up @@ -1710,7 +1710,7 @@ static void ReadRow(ReadOnlySpan<byte> span, out int? connectionId, out ServerVe
// OK/EOF payload
payload = await ReceiveReplyAsync(ioBehavior, CancellationToken.None).ConfigureAwait(false);
if (OkPayload.IsOk(payload.Span, SupportsDeprecateEof))
OkPayload.Create(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
OkPayload.Verify(payload.Span, SupportsDeprecateEof, SupportsSessionTrack);
else
EofPayload.Create(payload.Span);

Expand Down
4 changes: 2 additions & 2 deletions src/MySqlConnector/MySqlConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ private async Task ChangeDatabaseAsync(IOBehavior ioBehavior, string databaseNam
using (var initDatabasePayload = InitDatabasePayload.Create(databaseName))
await m_session!.SendAsync(initDatabasePayload, ioBehavior, cancellationToken).ConfigureAwait(false);
var payload = await m_session.ReceiveReplyAsync(ioBehavior, cancellationToken).ConfigureAwait(false);
OkPayload.Create(payload.Span, m_session.SupportsDeprecateEof, m_session.SupportsSessionTrack);
OkPayload.Verify(payload.Span, m_session.SupportsDeprecateEof, m_session.SupportsSessionTrack);
m_session.DatabaseOverride = databaseName;
}

Expand Down Expand Up @@ -472,7 +472,7 @@ public async ValueTask ResetConnectionAsync(CancellationToken cancellationToken
Log.ResettingConnection(m_logger, session.Id);
await session.SendAsync(ResetConnectionPayload.Instance, AsyncIOBehavior, cancellationToken).ConfigureAwait(false);
var payload = await session.ReceiveReplyAsync(AsyncIOBehavior, cancellationToken).ConfigureAwait(false);
OkPayload.Create(payload.Span, session.SupportsDeprecateEof, session.SupportsSessionTrack);
OkPayload.Verify(payload.Span, session.SupportsDeprecateEof, session.SupportsSessionTrack);
}

[AllowNull]
Expand Down
48 changes: 39 additions & 9 deletions src/MySqlConnector/Protocol/Payloads/OkPayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,30 @@ public static bool IsOk(ReadOnlySpan<byte> span, bool deprecateEof) =>
(span.Length > 6 && span[0] == Signature ||
deprecateEof && span.Length < 0xFF_FFFF && span[0] == EofPayload.Signature);

public static OkPayload Create(ReadOnlySpan<byte> span, bool deprecateEof, bool clientSessionTrack)
/// <summary>
/// Creates an <see cref="OkPayload"/> from the given <paramref name="span"/>, or throws <see cref="FormatException"/>
/// if the bytes do not represent a valid <see cref="OkPayload"/>.
/// </summary>
/// <param name="span">The bytes from which to read an OK packet.</param>
/// <param name="deprecateEof">Whether the <see cref="ProtocolCapabilities.DeprecateEof"/> flag was set on the connection.</param>
/// <param name="clientSessionTrack">Whether <see cref="ProtocolCapabilities.SessionTrack"/> flag was set on the connection.</param>
/// <returns>A <see cref="OkPayload"/> with the contents of the OK packet.</returns>
/// <exception cref="FormatException">Thrown when the bytes are not a valid OK packet.</exception>
public static OkPayload Create(ReadOnlySpan<byte> span, bool deprecateEof, bool clientSessionTrack) =>
Read(span, deprecateEof, clientSessionTrack, true)!;

/// <summary>
/// Verifies that the bytes in the given <paramref name="span"/> form a valid <see cref="OkPayload"/>, or throws
/// <see cref="FormatException"/> if they do not.
/// </summary>
/// <param name="span">The bytes from which to read an OK packet.</param>
/// <param name="deprecateEof">Whether the <see cref="ProtocolCapabilities.DeprecateEof"/> flag was set on the connection.</param>
/// <param name="clientSessionTrack">Whether <see cref="ProtocolCapabilities.SessionTrack"/> flag was set on the connection.</param>
/// <exception cref="FormatException">Thrown when the bytes are not a valid OK packet.</exception>
public static void Verify(ReadOnlySpan<byte> span, bool deprecateEof, bool clientSessionTrack) =>
Read(span, deprecateEof, clientSessionTrack, createPayload: false);

private static OkPayload? Read(ReadOnlySpan<byte> span, bool deprecateEof, bool clientSessionTrack, bool createPayload)
{
var reader = new ByteArrayReader(span);
var signature = reader.ReadByte();
Expand Down Expand Up @@ -82,17 +105,24 @@ public static OkPayload Create(ReadOnlySpan<byte> span, bool deprecateEof, bool
statusBytes = statusBytes[1..];
}

var statusInfo = statusBytes.Length == 0 ? null : Encoding.UTF8.GetString(statusBytes);
if (createPayload)
{
var statusInfo = statusBytes.Length == 0 ? null : Encoding.UTF8.GetString(statusBytes);

if (affectedRowCount == 0 && lastInsertId == 0 && warningCount == 0 && statusInfo is null && newSchema is null)
if (affectedRowCount == 0 && lastInsertId == 0 && warningCount == 0 && statusInfo is null && newSchema is null)
{
if (serverStatus == ServerStatus.AutoCommit)
return s_autoCommitOk;
if (serverStatus == (ServerStatus.AutoCommit | ServerStatus.SessionStateChanged))
return s_autoCommitSessionStateChangedOk;
}

return new OkPayload(affectedRowCount, lastInsertId, serverStatus, warningCount, statusInfo, newSchema);
}
else
{
if (serverStatus == ServerStatus.AutoCommit)
return s_autoCommitOk;
if (serverStatus == (ServerStatus.AutoCommit | ServerStatus.SessionStateChanged))
return s_autoCommitSessionStateChangedOk;
return null;
}

return new OkPayload(affectedRowCount, lastInsertId, serverStatus, warningCount, statusInfo, newSchema);
}

private OkPayload(ulong affectedRowCount, ulong lastInsertId, ServerStatus serverStatus, int warningCount, string? statusInfo, string? newSchema)
Expand Down

0 comments on commit 640f955

Please sign in to comment.