Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/aspnet/MessagePack-CSharp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@live.com>2022-05-24 19:04:44 +0300
committerAndrew Arnott <andrewarnott@live.com>2022-05-24 19:08:26 +0300
commit50b549fe1ffa6346675a55e5bb914c0a8def3c37 (patch)
tree7621851346f82992ae53754d0aab3594a0ecdf4a
parentc3fcd1d87c222314bcf108337687d6ff40b140f1 (diff)
Update Nerdbank.Streams
-rw-r--r--sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj2
-rw-r--r--sandbox/PerfBenchmarkDotNet/PerfBenchmarkDotNet.csproj2
-rw-r--r--sandbox/PerfNetFramework/PerfNetFramework.csproj2
-rw-r--r--src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Internal/Sequence`1.cs120
-rw-r--r--tests/MessagePack.GeneratedCode.Tests/MessagePack.GeneratedCode.Tests.csproj2
-rw-r--r--tests/MessagePack.Generator.Tests/MessagePack.Generator.Tests.csproj2
-rw-r--r--tests/MessagePack.Tests/MessagePack.Tests.csproj2
7 files changed, 104 insertions, 28 deletions
diff --git a/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj b/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj
index 633265af..0daf9da4 100644
--- a/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj
+++ b/sandbox/DynamicCodeDumper/DynamicCodeDumper.csproj
@@ -143,7 +143,7 @@
</Compile>
</ItemGroup>
<ItemGroup>
- <PackageReference Include="Nerdbank.Streams" Version="2.4.48" />
+ <PackageReference Include="Nerdbank.Streams" Version="2.8.57" />
<PackageReference Include="Microsoft.NET.StringTools" Version="1.0.0" />
</ItemGroup>
</Project>
diff --git a/sandbox/PerfBenchmarkDotNet/PerfBenchmarkDotNet.csproj b/sandbox/PerfBenchmarkDotNet/PerfBenchmarkDotNet.csproj
index 36fe6baf..d9a575d0 100644
--- a/sandbox/PerfBenchmarkDotNet/PerfBenchmarkDotNet.csproj
+++ b/sandbox/PerfBenchmarkDotNet/PerfBenchmarkDotNet.csproj
@@ -19,7 +19,7 @@
<PackageReference Include="Jil" version="2.15.4" />
<PackageReference Include="MessagePack" version="1.4.3" />
<PackageReference Include="MsgPack.Cli" version="0.9.0-rc1" />
- <PackageReference Include="Nerdbank.Streams" Version="2.4.48" />
+ <PackageReference Include="Nerdbank.Streams" Version="2.8.57" />
<PackageReference Include="Newtonsoft.Json" version="10.0.3" />
<PackageReference Include="protobuf-net" version="2.3.2" />
<PackageReference Include="RandomFixtureKit" Version="1.0.0" />
diff --git a/sandbox/PerfNetFramework/PerfNetFramework.csproj b/sandbox/PerfNetFramework/PerfNetFramework.csproj
index 080b4fb7..89e5cedf 100644
--- a/sandbox/PerfNetFramework/PerfNetFramework.csproj
+++ b/sandbox/PerfNetFramework/PerfNetFramework.csproj
@@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MsgPack.Cli" version="0.9.0-beta2" />
- <PackageReference Include="Nerdbank.Streams" Version="2.4.48" />
+ <PackageReference Include="Nerdbank.Streams" Version="2.8.57" />
<PackageReference Include="Newtonsoft.Json" version="10.0.3" />
<PackageReference Include="protobuf-net" version="2.1.0" />
<PackageReference Include="ZeroFormatter" version="1.6.4" />
diff --git a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Internal/Sequence`1.cs b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Internal/Sequence`1.cs
index 9fe752df..2813b92e 100644
--- a/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Internal/Sequence`1.cs
+++ b/src/MessagePack.UnityClient/Assets/Scripts/MessagePack/Internal/Sequence`1.cs
@@ -27,7 +27,11 @@ namespace Nerdbank.Streams
[DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")]
internal class Sequence<T> : IBufferWriter<T>, IDisposable
{
- private static readonly int DefaultLengthFromArrayPool = 1 + (4095 / Marshal.SizeOf<T>());
+ private const int MaximumAutoGrowSize = 32 * 1024;
+
+ private static readonly int DefaultLengthFromArrayPool = 1 + (4095 / Unsafe.SizeOf<T>());
+
+ private static readonly ReadOnlySequence<T> Empty = new ReadOnlySequence<T>(SequenceSegment.Empty, 0, SequenceSegment.Empty, 0);
private readonly Stack<SequenceSegment> segmentPool = new Stack<SequenceSegment>();
@@ -87,10 +91,22 @@ namespace Nerdbank.Streams
/// The <see cref="MemoryPool{T}"/> in use may itself have a minimum array length as well,
/// in which case the higher of the two minimums dictate the minimum array size that will be allocated.
/// </para>
+ /// <para>
+ /// If <see cref="AutoIncreaseMinimumSpanLength"/> is <c>true</c>, this value may be automatically increased as the length of a sequence grows.
+ /// </para>
/// </remarks>
public int MinimumSpanLength { get; set; } = 0;
/// <summary>
+ /// Gets or sets a value indicating whether the <see cref="MinimumSpanLength"/> should be
+ /// intelligently increased as the length of the sequence grows.
+ /// </summary>
+ /// <remarks>
+ /// This can help prevent long sequences made up of many very small arrays.
+ /// </remarks>
+ public bool AutoIncreaseMinimumSpanLength { get; set; } = true;
+
+ /// <summary>
/// Gets this sequence expressed as a <see cref="ReadOnlySequence{T}"/>.
/// </summary>
/// <returns>A read only sequence representing the data in this object.</returns>
@@ -112,9 +128,9 @@ namespace Nerdbank.Streams
/// <param name="sequence">The sequence to convert.</param>
public static implicit operator ReadOnlySequence<T>(Sequence<T> sequence)
{
- return sequence.first != null
+ return sequence.first != null && sequence.last != null
? new ReadOnlySequence<T>(sequence.first, sequence.first.Start, sequence.last, sequence.last.End)
- : ReadOnlySequence<T>.Empty;
+ : Empty;
}
/// <summary>
@@ -128,10 +144,22 @@ namespace Nerdbank.Streams
public void AdvanceTo(SequencePosition position)
{
var firstSegment = (SequenceSegment)position.GetObject();
+ if (firstSegment == null)
+ {
+ // Emulate PipeReader behavior which is to just return for default(SequencePosition)
+ return;
+ }
+
+ if (ReferenceEquals(firstSegment, SequenceSegment.Empty) && this.Length == 0)
+ {
+ // We were called with our own empty buffer segment.
+ return;
+ }
+
int firstIndex = position.GetInteger();
// Before making any mutations, confirm that the block specified belongs to this sequence.
- var current = this.first;
+ Sequence<T>.SequenceSegment current = this.first;
while (current != firstSegment && current != null)
{
current = current.Next;
@@ -151,12 +179,7 @@ namespace Nerdbank.Streams
firstSegment.AdvanceTo(firstIndex);
- if (firstSegment.Length == 0)
- {
- firstSegment = this.RecycleAndGetNext(firstSegment);
- }
-
- this.first = firstSegment;
+ this.first = firstSegment.Length == 0 ? this.RecycleAndGetNext(firstSegment) : firstSegment;
if (this.first == null)
{
@@ -174,6 +197,7 @@ namespace Nerdbank.Streams
SequenceSegment last = this.last;
Verify.Operation(last != null, "Cannot advance before acquiring memory.");
last.Advance(count);
+ this.ConsiderMinimumSizeIncrease();
}
/// <summary>
@@ -191,6 +215,24 @@ namespace Nerdbank.Streams
public Span<T> GetSpan(int sizeHint) => this.GetSegment(sizeHint).RemainingSpan;
/// <summary>
+ /// Adds an existing memory location to this sequence without copying.
+ /// </summary>
+ /// <param name="memory">The memory to add.</param>
+ /// <remarks>
+ /// This *may* leave significant slack space in a previously allocated block if calls to <see cref="Append(ReadOnlyMemory{T})"/>
+ /// follow calls to <see cref="GetMemory(int)"/> or <see cref="GetSpan(int)"/>.
+ /// </remarks>
+ public void Append(ReadOnlyMemory<T> memory)
+ {
+ if (memory.Length > 0)
+ {
+ Sequence<T>.SequenceSegment segment = this.segmentPool.Count > 0 ? this.segmentPool.Pop() : new SequenceSegment();
+ segment.AssignForeign(memory);
+ this.Append(segment);
+ }
+ }
+
+ /// <summary>
/// Clears the entire sequence, recycles associated memory into pools,
/// and resets this instance for reuse.
/// This invalidates any <see cref="ReadOnlySequence{T}"/> previously produced by this instance.
@@ -204,7 +246,7 @@ namespace Nerdbank.Streams
/// </summary>
public void Reset()
{
- var current = this.first;
+ Sequence<T>.SequenceSegment current = this.first;
while (current != null)
{
current = this.RecycleAndGetNext(current);
@@ -236,7 +278,7 @@ namespace Nerdbank.Streams
if (minBufferSize.HasValue)
{
- var segment = this.segmentPool.Count > 0 ? this.segmentPool.Pop() : new SequenceSegment();
+ Sequence<T>.SequenceSegment segment = this.segmentPool.Count > 0 ? this.segmentPool.Pop() : new SequenceSegment();
if (this.arrayPool != null)
{
segment.Assign(this.arrayPool.Rent(minBufferSize.Value == -1 ? DefaultLengthFromArrayPool : minBufferSize.Value));
@@ -268,7 +310,7 @@ namespace Nerdbank.Streams
else
{
// The last block is completely unused. Replace it instead of appending to it.
- var current = this.first;
+ Sequence<T>.SequenceSegment current = this.first;
if (this.first != this.last)
{
while (current.Next != this.last)
@@ -291,24 +333,40 @@ namespace Nerdbank.Streams
private SequenceSegment RecycleAndGetNext(SequenceSegment segment)
{
- var recycledSegment = segment;
- segment = segment.Next;
+ Sequence<T>.SequenceSegment recycledSegment = segment;
+ Sequence<T>.SequenceSegment nextSegment = segment.Next;
recycledSegment.ResetMemory(this.arrayPool);
this.segmentPool.Push(recycledSegment);
- return segment;
+ return nextSegment;
+ }
+
+ private void ConsiderMinimumSizeIncrease()
+ {
+ if (this.AutoIncreaseMinimumSpanLength && this.MinimumSpanLength < MaximumAutoGrowSize)
+ {
+ int autoSize = Math.Min(MaximumAutoGrowSize, (int)Math.Min(int.MaxValue, this.Length / 2));
+ if (this.MinimumSpanLength < autoSize)
+ {
+ this.MinimumSpanLength = autoSize;
+ }
+ }
}
private class SequenceSegment : ReadOnlySequenceSegment<T>
{
+ internal static readonly SequenceSegment Empty = new SequenceSegment();
+
/// <summary>
/// A value indicating whether the element may contain references (and thus must be cleared).
/// </summary>
private static readonly bool MayContainReferences = !typeof(T).GetTypeInfo().IsPrimitive;
+#pragma warning disable SA1011 // Closing square brackets should be spaced correctly
/// <summary>
/// Gets the backing array, when using an <see cref="ArrayPool{T}"/> instead of a <see cref="MemoryPool{T}"/>.
/// </summary>
private T[] array;
+#pragma warning restore SA1011 // Closing square brackets should be spaced correctly
/// <summary>
/// Gets the position within <see cref="ReadOnlySequenceSegment{T}.Memory"/> where the data starts.
@@ -363,6 +421,11 @@ namespace Nerdbank.Streams
}
/// <summary>
+ /// Gets a value indicating whether this segment refers to memory that came from outside and that we cannot write to nor recycle.
+ /// </summary>
+ internal bool IsForeignMemory => this.array == null && this.MemoryOwner == null;
+
+ /// <summary>
/// Assigns this (recyclable) segment a new area in memory.
/// </summary>
/// <param name="memoryOwner">The memory and a means to recycle it.</param>
@@ -383,11 +446,21 @@ namespace Nerdbank.Streams
}
/// <summary>
+ /// Assigns this (recyclable) segment a new area in memory.
+ /// </summary>
+ /// <param name="memory">A memory block obtained from outside, that we do not own and should not recycle.</param>
+ internal void AssignForeign(ReadOnlyMemory<T> memory)
+ {
+ this.Memory = memory;
+ this.End = memory.Length;
+ }
+
+ /// <summary>
/// Clears all fields in preparation to recycle this instance.
/// </summary>
internal void ResetMemory(ArrayPool<T> arrayPool)
{
- this.ClearReferences(this.Start, this.End);
+ this.ClearReferences(this.Start, this.End - this.Start);
this.Memory = default;
this.Next = null;
this.RunningIndex = 0;
@@ -411,14 +484,17 @@ namespace Nerdbank.Streams
/// <param name="segment">The next segment in the linked list.</param>
internal void SetNext(SequenceSegment segment)
{
- Debug.Assert(segment != null, "Null not allowed.");
this.Next = segment;
segment.RunningIndex = this.RunningIndex + this.Start + this.Length;
- // When setting Memory, we start with index 0 instead of this.Start because
- // the first segment has an explicit index set anyway,
- // and we don't want to double-count it here.
- this.Memory = this.AvailableMemory.Slice(0, this.Start + this.Length);
+ // Trim any slack on this segment.
+ if (!this.IsForeignMemory)
+ {
+ // When setting Memory, we start with index 0 instead of this.Start because
+ // the first segment has an explicit index set anyway,
+ // and we don't want to double-count it here.
+ this.Memory = this.AvailableMemory.Slice(0, this.Start + this.Length);
+ }
}
/// <summary>
diff --git a/tests/MessagePack.GeneratedCode.Tests/MessagePack.GeneratedCode.Tests.csproj b/tests/MessagePack.GeneratedCode.Tests/MessagePack.GeneratedCode.Tests.csproj
index 99ef099c..0844ff4e 100644
--- a/tests/MessagePack.GeneratedCode.Tests/MessagePack.GeneratedCode.Tests.csproj
+++ b/tests/MessagePack.GeneratedCode.Tests/MessagePack.GeneratedCode.Tests.csproj
@@ -8,7 +8,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
- <PackageReference Include="Nerdbank.Streams" Version="2.4.48" />
+ <PackageReference Include="Nerdbank.Streams" Version="2.8.57" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
diff --git a/tests/MessagePack.Generator.Tests/MessagePack.Generator.Tests.csproj b/tests/MessagePack.Generator.Tests/MessagePack.Generator.Tests.csproj
index 9f399389..7c12e7f5 100644
--- a/tests/MessagePack.Generator.Tests/MessagePack.Generator.Tests.csproj
+++ b/tests/MessagePack.Generator.Tests/MessagePack.Generator.Tests.csproj
@@ -13,7 +13,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
- <PackageReference Include="Nerdbank.Streams" Version="2.4.48" />
+ <PackageReference Include="Nerdbank.Streams" Version="2.8.57" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
diff --git a/tests/MessagePack.Tests/MessagePack.Tests.csproj b/tests/MessagePack.Tests/MessagePack.Tests.csproj
index 9f7d9832..f6ff6860 100644
--- a/tests/MessagePack.Tests/MessagePack.Tests.csproj
+++ b/tests/MessagePack.Tests/MessagePack.Tests.csproj
@@ -27,7 +27,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="MsgPack.Cli" version="0.9.0-beta2" />
- <PackageReference Include="Nerdbank.Streams" Version="2.4.48" />
+ <PackageReference Include="Nerdbank.Streams" Version="2.8.57" />
<PackageReference Include="ReactiveProperty" version="4.2.2" />
<PackageReference Include="xunit" version="2.4.1" />
<PackageReference Include="xunit.runner.console" Version="2.4.1" />