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:
parent
e928c5dd02
commit
41c1a59392
7 changed files with 485 additions and 31 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue