Skip to content

Commit

Permalink
Performance of CommonHeader.CalcSize
Browse files Browse the repository at this point in the history
  • Loading branch information
ShortDevelopment committed Jan 27, 2025
1 parent 0fc18bb commit ef96997
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 9 deletions.
34 changes: 32 additions & 2 deletions lib/ShortDev.Microsoft.ConnectedDevices/Messages/CommonHeaders.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Buffers.Binary;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;

namespace ShortDev.Microsoft.ConnectedDevices.Messages;

Expand Down Expand Up @@ -93,6 +94,35 @@ public void Write(EndianWriter writer)
writer.Write((byte)0);
}

[MethodImpl(MethodImplOptions.AggressiveOptimization | MethodImplOptions.AggressiveInlining)]
internal int CalcSize()
{
int size =
sizeof(ushort) + // Constants.Signature
sizeof(ushort) + // MessageLength
sizeof(byte) + // Constants.ProtocolVersion
sizeof(byte) + // Type
sizeof(short) + // Flags
sizeof(uint) + // SequenceNumber
sizeof(ulong) + // RequestID
sizeof(ushort) + // FragmentIndex
sizeof(ushort) + // FragmentCount
sizeof(ulong) + // SessionId
sizeof(ulong); // ChannelId

foreach (var header in AdditionalHeaders)
{
size +=
sizeof(byte) + // Type
sizeof(byte) + // Value.Length
header.Value.Length; // Value
}

return size +
sizeof(byte) + // AdditionalHeaderType.None
sizeof(byte); // 0
}

/// <summary>
/// Entire message length in bytes including signature.
/// </summary>
Expand Down Expand Up @@ -150,7 +180,7 @@ public void Write(EndianWriter writer)
/// Returns size of the whole rest of the message (excluding headers) (including hmac)
/// </summary>
public int PayloadSize
=> MessageLength - (int)((ICdpSerializable<CommonHeader>)this).CalcSize();
=> MessageLength - (int)CalcSize();


#region Flags
Expand All @@ -171,7 +201,7 @@ public void CorrectClientSessionBit()
public const int MessageLengthOffset = 2;
public void SetPayloadLength(int payloadSize)
{
MessageLength = (ushort)(payloadSize + ((ICdpSerializable<CommonHeader>)this).CalcSize());
MessageLength = (ushort)(payloadSize + CalcSize());
}

public static void ModifyMessageLength(Span<byte> msgBuffer, short delta)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,6 @@ public interface ICdpSerializable<T> : ICdpWriteable where T : ICdpSerializable<
static abstract T Parse(ref EndianReader reader);
public static bool TryParse(ref EndianReader reader, out T? result, out Exception? error)
=> throw new NotImplementedException();

public long CalcSize()
{
EndianWriter writer = new(Endianness.BigEndian);
Write(writer);
return writer.Buffer.Size;
}
}

public interface ICdpArraySerializable<T> where T : ICdpArraySerializable<T>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using ShortDev.Microsoft.ConnectedDevices.Messages;

namespace ShortDev.Microsoft.ConnectedDevices.Test.Messages;

public class CommonHeaderTest
{
[Fact]
public void CalcSize_YieldsCorrectResult_WhenNoHeaders()
{
EndianWriter writer = new(Endianness.BigEndian);

CommonHeader header = new();
header.Write(writer);
var expected = writer.Buffer.Size;

var actual = header.CalcSize();

Assert.Equal(expected, actual);
}

[Fact]
public void CalcSize_YieldsCorrectResult_WhenWithHeaders()
{
EndianWriter writer = new(Endianness.BigEndian);

CommonHeader header = new()
{
Type = MessageType.Connect,
AdditionalHeaders = {
AdditionalHeader.FromUInt32(AdditionalHeaderType.Header129, 0x70_00_00_03),
AdditionalHeader.FromUInt64(AdditionalHeaderType.PeerCapabilities, (ulong)PeerCapabilities.All),
AdditionalHeader.FromUInt64(AdditionalHeaderType.Header131, 6u)
}
};
header.Write(writer);
var expected = writer.Buffer.Size;

var actual = header.CalcSize();

Assert.Equal(expected, actual);
}
}

0 comments on commit ef96997

Please sign in to comment.