Skip to content

Commit

Permalink
Release 5.13.0
Browse files Browse the repository at this point in the history
  • Loading branch information
sakno committed Aug 30, 2024
1 parent 4071a42 commit 06ed95f
Show file tree
Hide file tree
Showing 66 changed files with 1,913 additions and 1,083 deletions.
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
Release Notes
====

# 08-30-2024
<a href="https://www.nuget.org/packages/dotnext/5.13.0">DotNext 5.13.0</a>
* Improved interoperability of `DotNext.Runtime.ValueReference<T>` and `DotNext.Runtime.ReadOnlyValueReference<T>` with .NEXT ecosystem
* Fixed [249](https://github.com/dotnet/dotNext/issues/249)
* Improved codegen quality for ad-hoc enumerator types

<a href="https://www.nuget.org/packages/dotnext.metaprogramming/5.13.0">DotNext.Metaprogramming 5.13.0</a>
* Updated dependencies

<a href="https://www.nuget.org/packages/dotnext.unsafe/5.13.0">DotNext.Unsafe 5.13.0</a>
* Updated dependencies

<a href="https://www.nuget.org/packages/dotnext.threading/5.13.0">DotNext.Threading 5.13.0</a>
* Redesigned `AsyncEventHub` to improve overall performance and reduce memory allocation
* Improved codegen quality for ad-hoc enumerator types

<a href="https://www.nuget.org/packages/dotnext.io/5.13.0">DotNext.IO 5.13.0</a>
* Improved codegen quality for ad-hoc enumerator types

<a href="https://www.nuget.org/packages/dotnext.net.cluster/5.13.0">DotNext.Net.Cluster 5.13.0</a>
* Updated dependencies

<a href="https://www.nuget.org/packages/dotnext.aspnetcore.cluster/5.13.0">DotNext.AspNetCore.Cluster 5.13.0</a>
* Updated dependencies

<a href="https://www.nuget.org/packages/dotnext.maintenanceservices/0.4.0">DotNext.MaintenanceServices 0.4.0</a>
* Added [gc refresh-mem-limit](https://learn.microsoft.com/en-us/dotnet/api/system.gc.refreshmemorylimit) maintenance command
* Updated dependencies

# 08-19-2024
<a href="https://www.nuget.org/packages/dotnext/5.12.1">DotNext 5.12.1</a>
* Added support of static field references to `DotNext.Runtime.ValueReference<T>` data type
Expand Down
32 changes: 27 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,35 @@ All these things are implemented in 100% managed code on top of existing .NET AP
* [NuGet Packages](https://www.nuget.org/profiles/rvsakno)

# What's new
Release Date: 08-19-2024
Release Date: 08-30-2024

<a href="https://www.nuget.org/packages/dotnext/5.12.1">DotNext 5.12.1</a>
* Added support of static field references to `DotNext.Runtime.ValueReference<T>` data type
<a href="https://www.nuget.org/packages/dotnext/5.13.0">DotNext 5.13.0</a>
* Improved interoperability of `DotNext.Runtime.ValueReference<T>` and `DotNext.Runtime.ReadOnlyValueReference<T>` with .NEXT ecosystem
* Fixed [249](https://github.com/dotnet/dotNext/issues/249)
* Improved codegen quality for ad-hoc enumerator types

<a href="https://www.nuget.org/packages/dotnext.threading/5.12.1">DotNext.Threading 5.12.1</a>
* Smallish performance improvements of `RandomAccessCache<TKey, TValue>` class
<a href="https://www.nuget.org/packages/dotnext.metaprogramming/5.13.0">DotNext.Metaprogramming 5.13.0</a>
* Updated dependencies

<a href="https://www.nuget.org/packages/dotnext.unsafe/5.13.0">DotNext.Unsafe 5.13.0</a>
* Updated dependencies

<a href="https://www.nuget.org/packages/dotnext.threading/5.13.0">DotNext.Threading 5.13.0</a>
* Redesigned `AsyncEventHub` to improve overall performance and reduce memory allocation
* Improved codegen quality for ad-hoc enumerator types

<a href="https://www.nuget.org/packages/dotnext.io/5.13.0">DotNext.IO 5.13.0</a>
* Improved codegen quality for ad-hoc enumerator types

<a href="https://www.nuget.org/packages/dotnext.net.cluster/5.13.0">DotNext.Net.Cluster 5.13.0</a>
* Updated dependencies

<a href="https://www.nuget.org/packages/dotnext.aspnetcore.cluster/5.13.0">DotNext.AspNetCore.Cluster 5.13.0</a>
* Updated dependencies

<a href="https://www.nuget.org/packages/dotnext.maintenanceservices/0.4.0">DotNext.MaintenanceServices 0.4.0</a>
* Added [gc refresh-mem-limit](https://learn.microsoft.com/en-us/dotnet/api/system.gc.refreshmemorylimit) maintenance command
* Updated dependencies

Changelog for previous versions located [here](./CHANGELOG.md).

Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<!--Misc packages-->
<PackageVersion Include="BenchmarkDotNet" Version="0.13.12" />
<PackageVersion Include="FastMember.Signed" Version="1.5.0" />
<PackageVersion Include="xunit" Version="2.8.0" />
<PackageVersion Include="xunit" Version="2.9.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.0"/>
<PackageVersion Include="coverlet.collector" Version="6.0.2"/>
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/DotNext.IO/Buffers/SevenBitEncodedInt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public bool MoveNext()
}

[StructLayout(LayoutKind.Auto)]
internal struct Reader() : IBufferReader, ISupplier<int>
internal struct Reader : IBufferReader, ISupplier<int>
{
private SevenBitEncodedInt value;
private bool completed;
Expand Down
2 changes: 1 addition & 1 deletion src/DotNext.IO/DotNext.IO.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<Authors>.NET Foundation and Contributors</Authors>
<Company />
<Product>.NEXT Family of Libraries</Product>
<VersionPrefix>5.12.0</VersionPrefix>
<VersionPrefix>5.13.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
<AssemblyName>DotNext.IO</AssemblyName>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
68 changes: 36 additions & 32 deletions src/DotNext.IO/IO/SequenceReader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Buffers;
using System.Collections;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
Expand All @@ -12,6 +13,7 @@ namespace DotNext.IO;

using Buffers;
using Buffers.Binary;
using Collections.Generic;
using static Pipelines.PipeExtensions;
using DecodingContext = Text.DecodingContext;

Expand Down Expand Up @@ -89,7 +91,7 @@ public T Read<T>()
/// <typeparam name="T">The integer type.</typeparam>
/// <returns>The integer value.</returns>
/// <exception cref="EndOfStreamException">The underlying source doesn't contain necessary amount of bytes to decode the value.</exception>
public unsafe T ReadLittleEndian<T>()
public T ReadLittleEndian<T>()
where T : notnull, IBinaryInteger<T>
{
var type = typeof(T);
Expand All @@ -111,7 +113,7 @@ public unsafe T ReadLittleEndian<T>()
/// <typeparam name="T">The integer type.</typeparam>
/// <returns>The integer value.</returns>
/// <exception cref="EndOfStreamException">The underlying source doesn't contain necessary amount of bytes to decode the value.</exception>
public unsafe T ReadBigEndian<T>()
public T ReadBigEndian<T>()
where T : notnull, IBinaryInteger<T>
{
var type = typeof(T);
Expand Down Expand Up @@ -215,9 +217,12 @@ public bool TryRead(int maxLength, out ReadOnlyMemory<byte> chunk)
chunk = remaining.First.TrimLength(maxLength);
position = remaining.GetPosition(chunk.Length);
}
else
{
chunk = default;
}

chunk = default;
return false;
return !chunk.IsEmpty;
}

/// <summary>
Expand Down Expand Up @@ -379,18 +384,15 @@ private unsafe TResult Parse<TArg, TResult>(TArg arg, delegate*<ReadOnlySpan<byt
if (length is 0)
return parser([], arg);

unsafe
if (length <= Parsing256Reader<IFormatProvider?, TResult>.MaxSize)
{
if (length <= Parsing256Reader<IFormatProvider?, TResult>.MaxSize)
{
var reader = new Parsing256Reader<TArg, TResult>(arg, parser, length);
return Read<TResult, Parsing256Reader<TArg, TResult>>(ref reader);
}
else
{
var reader = new ParsingReader<TArg, TResult>(arg, parser, length);
return Read<TResult, ParsingReader<TArg, TResult>>(ref reader);
}
var reader = new Parsing256Reader<TArg, TResult>(arg, parser, length);
return Read<TResult, Parsing256Reader<TArg, TResult>>(ref reader);
}
else
{
var reader = new ParsingReader<TArg, TResult>(arg, parser, length);
return Read<TResult, ParsingReader<TArg, TResult>>(ref reader);
}
}

Expand Down Expand Up @@ -744,8 +746,9 @@ ValueTask<MemoryOwner<char>> IAsyncBinaryReader.DecodeAsync(DecodingContext cont
}

/// <inheritdoc/>
IAsyncEnumerable<ReadOnlyMemory<char>> IAsyncBinaryReader.DecodeAsync(DecodingContext context, LengthFormat lengthFormat, Memory<char> buffer, CancellationToken token)
=> Decode(context, lengthFormat, buffer).AsAsyncEnumerable(token);
IAsyncEnumerable<ReadOnlyMemory<char>> IAsyncBinaryReader.DecodeAsync(DecodingContext context, LengthFormat lengthFormat, Memory<char> buffer,
CancellationToken token)
=> Decode(context, lengthFormat, buffer);

/// <inheritdoc/>
ValueTask IAsyncBinaryReader.CopyToAsync(Stream destination, long? count, CancellationToken token)
Expand Down Expand Up @@ -839,7 +842,7 @@ readonly bool IAsyncBinaryReader.TryGetRemainingBytesCount(out long count)
/// Represents decoding enumerable.
/// </summary>
[StructLayout(LayoutKind.Auto)]
public readonly struct DecodingEnumerable
public readonly struct DecodingEnumerable : IEnumerable<ReadOnlyMemory<char>>, IAsyncEnumerable<ReadOnlyMemory<char>>
{
private readonly ReadOnlySequence<byte> bytes;
private readonly DecodingContext context;
Expand All @@ -859,23 +862,24 @@ internal DecodingEnumerable(ReadOnlySequence<byte> bytes, in DecodingContext con
/// </summary>
/// <returns>The enumerator over decoded chunks of characters.</returns>
public Enumerator GetEnumerator() => new(in bytes, in context, buffer);

/// <inheritdoc />
IEnumerator<ReadOnlyMemory<char>> IEnumerable<ReadOnlyMemory<char>>.GetEnumerator()
=> GetEnumerator().ToClassicEnumerator<Enumerator, ReadOnlyMemory<char>>();

#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
internal async IAsyncEnumerable<ReadOnlyMemory<char>> AsAsyncEnumerable([EnumeratorCancellation] CancellationToken token)
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
{
foreach (var chunk in this)
{
token.ThrowIfCancellationRequested();
yield return chunk;
}
}
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator().ToClassicEnumerator<Enumerator, ReadOnlyMemory<char>>();

/// <inheritdoc />
IAsyncEnumerator<ReadOnlyMemory<char>> IAsyncEnumerable<ReadOnlyMemory<char>>.GetAsyncEnumerator(CancellationToken token)
=> GetEnumerator().ToAsyncEnumerator<Enumerator, ReadOnlyMemory<char>>(token);

/// <summary>
/// Represents enumerator over decoded characters.
/// </summary>
[StructLayout(LayoutKind.Auto)]
public struct Enumerator
public struct Enumerator : IEnumerator<Enumerator, ReadOnlyMemory<char>>
{
private readonly ReadOnlySequence<byte> bytes;
private readonly Decoder decoder;
Expand All @@ -899,7 +903,7 @@ internal Enumerator(in ReadOnlySequence<byte> bytes, in DecodingContext context,
/// <summary>
/// Decodes the next chunk of bytes.
/// </summary>
/// <returns><see langword="true"/> if decoding is successfull; <see langword="false"/> if nothing to decode.</returns>
/// <returns><see langword="true"/> if decoding is successful; <see langword="false"/> if nothing to decode.</returns>
public bool MoveNext()
=> (charsWritten = GetChars(in bytes, ref position, decoder, buffer.Span)) > 0;
}
Expand Down Expand Up @@ -941,7 +945,7 @@ public ref struct Enumerator
private readonly ReadOnlySequence<byte> bytes;
private readonly Decoder decoder;
private readonly Span<char> buffer;
private ref SequencePosition position;
private readonly ref SequencePosition position;
private int charsWritten;

internal Enumerator(scoped in ReadOnlySequence<byte> bytes, ref SequencePosition position, scoped in DecodingContext context, Span<char> buffer)
Expand All @@ -960,7 +964,7 @@ internal Enumerator(scoped in ReadOnlySequence<byte> bytes, ref SequencePosition
/// <summary>
/// Decodes the next chunk of bytes.
/// </summary>
/// <returns><see langword="true"/> if decoding is successfull; <see langword="false"/> if nothing to decode.</returns>
/// <returns><see langword="true"/> if decoding is successful; <see langword="false"/> if nothing to decode.</returns>
public bool MoveNext()
=> (charsWritten = GetChars(in bytes, ref position, decoder, buffer)) > 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<Authors>.NET Foundation and Contributors</Authors>
<Company />
<Product>.NEXT Family of Libraries</Product>
<VersionPrefix>0.3.0</VersionPrefix>
<VersionPrefix>0.4.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
<AssemblyName>DotNext.MaintenanceServices</AssemblyName>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ static GCLargeObjectHeapCompactionMode ParseMode(ArgumentResult result)
}
}

private static Command RefreshMemoryLimitsCommand()
{
var command = new ApplicationMaintenanceCommand("refresh-mem-limit", CommandResources.GCRefreshMemoryLimit);
command.SetHandler(GC.RefreshMemoryLimit);
return command;
}

/// <summary>
/// Creates a command that allows to force Garbage Collection.
/// </summary>
Expand All @@ -85,6 +92,7 @@ public static ApplicationMaintenanceCommand GCCommand()
var command = new ApplicationMaintenanceCommand("gc", CommandResources.GCCommandDescription);
command.AddCommand(GCCollectCommand());
command.AddCommand(LohCompactionModeCommand());
command.AddCommand(RefreshMemoryLimitsCommand());
return command;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ internal static Task SetDefaultPrincipal(InvocationContext context, Func<Invocat
private static void Forbid(InvocationContext context)
{
context.ExitCode = ForbiddenExitCode;
context.Console.Error.Write(CommandResources.AccessDenined);
context.Console.Error.Write(CommandResources.AccessDenied);
context.Console.Error.Write(Environment.NewLine);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal static async Task AuthorizeAsync(this AuthorizationCallback? globalAuth
}
else
{
console.Error.WriteLine(CommandResources.AccessDenined);
console.Error.WriteLine(CommandResources.AccessDenied);
context.ExitCode = ForbiddenExitCode;
console.Session.IsInteractive = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ internal static string WelcomeMessage(string appName)

internal static string CommandTimeoutOccurred => (string)Resources.Get();

internal static string AccessDenined => (string)Resources.Get();
internal static string AccessDenied => (string)Resources.Get();

internal static string LoginOptionName => (string)Resources.Get();

Expand All @@ -42,6 +42,8 @@ internal static string GCCollectCommandInvalidGenerationArg(string? generation)
internal static string GCLohModeCommandInvalidModeArg(string? mode)
=> Resources.Get().Format(mode);

internal static string GCRefreshMemoryLimit => (string)Resources.Get();

internal static string InteractiveCommandDescription => (string)Resources.Get();

internal static string ExitCommandDescription => (string)Resources.Get();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
WelcomeMessage = Welcome to {0} Maintenance Interface! Type -h or --help to get help
CommandTimeoutOccurred=Command has timed out. Please try again
AccessDenined=Access denied
AccessDenied=Access denied
GCCommandDescription=Provides interaction with GC
GCCollectCommandDescription=Forces Garbage Collection
GCCollectCommandGenerationArgDescription=The number of the oldest generation to be garbage collected
Expand All @@ -10,6 +10,7 @@ GCCollectCommandCompactingOptionDescription=Enables compaction of small object h
GCLohModeCommandDescription=Overrides Large Object Heap compaction mode
GCLohModeCommandModeArgDescription=Large Object Heap compaction mode
GCLohModeCommandInvalidModeArg=Incorrect Large Object Heap compaction mode {0}
GCRefreshMemoryLimit=Instructs the Garbage Collector to reconfigure itself by detecting the various memory limits on the system
InteractiveCommandDescription=Enters interactive mode
ExitCommandDescription=Leaves interactive mode
ProbeCommandDescription=Invokes application probe
Expand Down
2 changes: 1 addition & 1 deletion src/DotNext.Metaprogramming/DotNext.Metaprogramming.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ImplicitUsings>true</ImplicitUsings>
<IsTrimmable>false</IsTrimmable>
<Features>nullablePublicOnly</Features>
<VersionPrefix>5.12.0</VersionPrefix>
<VersionPrefix>5.13.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
<Authors>.NET Foundation</Authors>
<Product>.NEXT Family of Libraries</Product>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Buffers;
using System.Buffers.Binary;
using System.Collections;
using System.Runtime.InteropServices;

namespace DotNext.Buffers.Binary;
Expand Down
20 changes: 10 additions & 10 deletions src/DotNext.Tests/Buffers/BufferWriterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ public static async Task ReadWriteBufferedStringAsync(LengthFormat lengthEnc)
await ReadWriteStringUsingEncodingAsync(testString2, Encoding.UTF32, lengthEnc);
}

public static IEnumerable<object[]> CharWriters()
public static TheoryData<IBufferWriter<char>> CharWriters() => new()
{
yield return new object[] { new PoolingBufferWriter<char>(MemoryPool<char>.Shared.ToAllocator()) };
yield return new object[] { new PoolingArrayBufferWriter<char>() };
yield return new object[] { new SparseBufferWriter<char>() };
yield return new object[] { new SparseBufferWriter<char>(32) };
}
new PoolingBufferWriter<char>(MemoryPool<char>.Shared.ToAllocator()),
new PoolingArrayBufferWriter<char>(),
new SparseBufferWriter<char>(),
new SparseBufferWriter<char>(32),
};

[Theory]
[MemberData(nameof(CharWriters))]
Expand Down Expand Up @@ -183,11 +183,11 @@ public static void FormatValues()
Equal("56", writer.ToString());
}

public static IEnumerable<object[]> ContiguousBuffers()
public static TheoryData<BufferWriter<byte>> ContiguousBuffers() => new()
{
yield return new object[] { new PoolingBufferWriter<byte>() };
yield return new object[] { new PoolingArrayBufferWriter<byte>() };
}
new PoolingBufferWriter<byte>(),
new PoolingArrayBufferWriter<byte>(),
};

[Theory]
[MemberData(nameof(ContiguousBuffers))]
Expand Down
Loading

0 comments on commit 06ed95f

Please sign in to comment.