perf(net): frame recurring sends in place

Write normal game-message and ACK packet framing directly into bounded stack spans, hash fragments without materialization, and send the populated slice to the socket. Preserve exact wire bytes and ISAAC failure ordering with differential and zero-allocation tests.
This commit is contained in:
Erik 2026-07-25 06:02:52 +02:00
parent e928c5dd02
commit 41c1a59392
7 changed files with 485 additions and 31 deletions

View file

@ -54,6 +54,50 @@ public static class GameMessageFragment
return new MessageFragment(header, gameMessageBytes.ToArray());
}
/// <summary>
/// Write one complete fragment directly into caller-owned storage.
/// Returns the number of bytes written. This is the production send-path
/// primitive; it creates no intermediate payload or serialized array.
/// </summary>
internal static int WriteSingleFragment(
Span<byte> destination,
uint fragmentSequence,
GameMessageGroup queue,
ReadOnlySpan<byte> gameMessageBytes)
{
if (gameMessageBytes.Length
> MessageFragmentHeader.MaxFragmentDataSize)
{
throw new ArgumentException(
$"game message body ({gameMessageBytes.Length} bytes) exceeds single-fragment capacity "
+ $"({MessageFragmentHeader.MaxFragmentDataSize} bytes). Multi-fragment split TBD.",
nameof(gameMessageBytes));
}
int wireSize =
MessageFragmentHeader.Size + gameMessageBytes.Length;
if (destination.Length < wireSize)
{
throw new ArgumentException(
$"destination must be at least {wireSize} bytes",
nameof(destination));
}
var header = new MessageFragmentHeader
{
Sequence = fragmentSequence,
Id = OutboundFragmentId,
Count = 1,
TotalSize = checked((ushort)wireSize),
Index = 0,
Queue = (ushort)queue,
};
header.Pack(destination);
gameMessageBytes.CopyTo(
destination.Slice(MessageFragmentHeader.Size));
return wireSize;
}
/// <summary>
/// Concatenate a fragment's header + payload into the bytes that go
/// into a packet's body. Use when building the full <c>body</c> span