perf(net): borrow inbound packet storage
Decode headers, optional fields, fragments, and single-fragment messages directly over pooled datagrams. Copy only fragment state that crosses a datagram lifetime, preserve synchronous dispatch and ACK ordering, and lock the path to the owned decoder with differential and zero-allocation tests.
This commit is contained in:
parent
7211bb1bf7
commit
e928c5dd02
18 changed files with 1329 additions and 66 deletions
|
|
@ -95,6 +95,80 @@ public sealed class FragmentAssembler
|
|||
return combined;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Production borrowed-memory path. A complete single-fragment message
|
||||
/// is returned as a view into the current datagram. Multi-fragment
|
||||
/// payloads are copied only because they must survive that datagram's
|
||||
/// pooled lifetime.
|
||||
/// </summary>
|
||||
internal bool TryIngest(
|
||||
in BorrowedMessageFragment fragment,
|
||||
out ReadOnlyMemory<byte> message,
|
||||
out ushort messageQueue)
|
||||
{
|
||||
MessageFragmentHeader header = fragment.Header;
|
||||
message = ReadOnlyMemory<byte>.Empty;
|
||||
messageQueue = 0;
|
||||
|
||||
if (header.Count == 1 && header.Index == 0)
|
||||
{
|
||||
message = fragment.Payload;
|
||||
messageQueue = header.Queue;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!_inFlight.TryGetValue(
|
||||
header.Sequence,
|
||||
out PartialMessage? partial))
|
||||
{
|
||||
partial = new PartialMessage(
|
||||
header.Count,
|
||||
header.Queue);
|
||||
_inFlight[header.Sequence] = partial;
|
||||
}
|
||||
else if (partial.TotalFragments != header.Count
|
||||
|| partial.Queue != header.Queue)
|
||||
{
|
||||
// Same sequence with conflicting identity is malformed. Preserve
|
||||
// the first accepted partial instead of corrupting its layout.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (partial.Fragments[header.Index] is null)
|
||||
{
|
||||
partial.Fragments[header.Index] =
|
||||
fragment.Payload.ToArray();
|
||||
partial.ReceivedCount++;
|
||||
}
|
||||
|
||||
if (partial.ReceivedCount < partial.TotalFragments)
|
||||
return false;
|
||||
|
||||
int totalBytes = 0;
|
||||
for (int index = 0;
|
||||
index < partial.TotalFragments;
|
||||
index++)
|
||||
{
|
||||
totalBytes += partial.Fragments[index]!.Length;
|
||||
}
|
||||
|
||||
var combined = new byte[totalBytes];
|
||||
int offset = 0;
|
||||
for (int index = 0;
|
||||
index < partial.TotalFragments;
|
||||
index++)
|
||||
{
|
||||
byte[] payload = partial.Fragments[index]!;
|
||||
payload.CopyTo(combined, offset);
|
||||
offset += payload.Length;
|
||||
}
|
||||
|
||||
_inFlight.Remove(header.Sequence);
|
||||
message = combined;
|
||||
messageQueue = partial.Queue;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Discard all in-flight partial messages.</summary>
|
||||
public void DropAll() => _inFlight.Clear();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue