Skip to content

Commit

Permalink
refactor: implementing flexible solution
Browse files Browse the repository at this point in the history
  • Loading branch information
Farenheith committed Nov 10, 2024
1 parent 74323fe commit 2c5c573
Show file tree
Hide file tree
Showing 17 changed files with 88 additions and 128 deletions.
13 changes: 7 additions & 6 deletions .github/workflows/semantic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ jobs:
run: npm run build

- name: Test
uses: paambaati/[email protected]
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
with:
coverageCommand: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=./coverage/lcov.info
coverageLocations: ${{github.workspace}}/test/Codibre.GrpcSqlProxy.Test/coverage/lcov.info:lcov
run: npm run test:coverage
# uses: paambaati/[email protected]
# env:
# CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
# with:
# coverageCommand: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=./coverage/lcov.info
# coverageLocations: ${{github.workspace}}/test/Codibre.GrpcSqlProxy.Test/coverage/lcov.info:lcov

- name: Semantic Release
run: npm i -g @semantic-release/changelog @semantic-release/commit-analyzer @semantic-release/git @semantic-release/github @semantic-release/exec @droidsolutions-oss/semantic-release-nuget @semantic-release/release-notes-generator semantic-release @semantic-release/error
Expand Down
13 changes: 7 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ jobs:
# run: npm run docker:run

- name: Test
uses: paambaati/[email protected]
env:
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
with:
coverageCommand: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=./coverage/lcov.info
coverageLocations: ${{github.workspace}}/test/Codibre.GrpcSqlProxy.Test/coverage/lcov.info:lcov
run: npm run test:coverage
# uses: paambaati/[email protected]
# env:
# CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
# with:
# coverageCommand: dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=./coverage/lcov.info
# coverageLocations: ${{github.workspace}}/test/Codibre.GrpcSqlProxy.Test/coverage/lcov.info:lcov
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Codibre.EnumerableExtensions.Branching.Internal;

namespace Codibre.EnumerableExtensions.Branching;
public class AsyncBranchingBuilder<T>(IAsyncEnumerable<T> source) : BaseBranchingBuilder<T>
public sealed class AsyncBranchingBuilder<T>(IAsyncEnumerable<T> source) : BaseBranchingBuilder<T>
{
internal override async ValueTask<(LinkedNode<T>?, Task)> Iterate()
internal override LinkedNode<T> Iterate(int branchCount)
{
var enumerator = source.GetAsyncEnumerator();
var node = await enumerator.MoveLoose() ? new LinkedNode<T>(enumerator.Current) : null;
return (node, node is null ? Task.CompletedTask : Task.Run(async () =>
{
try
{
while (await enumerator.MoveLoose()) node = node.Next = new LinkedNode<T>(enumerator.Current);
}
finally
{
node.End = true;
}
}));
return new(enumerator.Current, new(
async (c) => await enumerator.MoveNextAsync() ? new(enumerator.Current, c) : null,
branchCount
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@ internal BaseBranchingBuilder<T> Add(Func<IAsyncEnumerable<T>, Task> branch)

public async Task Run()
{
var (node, iterate) = await Iterate().ConfigureAwait(false);
await Task.WhenAll(
_branches
.Select((x, index) => x(node.GetBranchedIterable()))
.Append(iterate)
).ConfigureAwait(false);
var node = Iterate(_branches.Count);
await Task.WhenAll(_branches.Select(x => x(node.GetBranchedIterable())));
}

internal abstract ValueTask<(LinkedNode<T>?, Task)> Iterate();
internal abstract LinkedNode<T> Iterate(int branchCount);
}
2 changes: 1 addition & 1 deletion src/Codibre.EnumerableExtensions.Branching/BranchResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Codibre.EnumerableExtensions.Branching;

public record BranchResult<R>
public sealed record BranchResult<R>
{
private bool _set = false;
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
Expand Down
20 changes: 6 additions & 14 deletions src/Codibre.EnumerableExtensions.Branching/BranchingBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,14 @@

namespace Codibre.EnumerableExtensions.Branching;

public class BranchingBuilder<T>(IEnumerable<T> source) : BaseBranchingBuilder<T>
public sealed class BranchingBuilder<T>(IEnumerable<T> source) : BaseBranchingBuilder<T>
{
internal override ValueTask<(LinkedNode<T>?, Task)> Iterate()
internal override LinkedNode<T> Iterate(int branchCount)
{
var enumerator = source.GetEnumerator();
var node = enumerator.MoveNext() ? new LinkedNode<T>(enumerator.Current) : null;
return ValueTask.FromResult((node, node is null ? Task.CompletedTask : Task.Run(async () =>
{
try
{
while (enumerator.MoveNext()) node = node.Next = new LinkedNode<T>(enumerator.Current);
}
finally
{
node.End = true;
}
})));
return new LinkedNode<T>(default!, new(
(c) => ValueTask.FromResult<LinkedNode<T>?>(enumerator.MoveNext() ? new(enumerator.Current, c) : null),
branchCount
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ public static class BranchingExtensions
public static BaseBranchingBuilder<T> Add<T, R>(this BaseBranchingBuilder<T> builder, Func<IAsyncEnumerable<T>, ValueTask<R>> branch, out BranchResult<R> result)
{
var refResult = result = new();
return builder.Add(async (x) => refResult.Result = await branch(x).ConfigureAwait(false));
return builder.Add(async (x) => refResult.Result = await branch(x));
}

public static BaseBranchingBuilder<T> Add<T, R>(this BaseBranchingBuilder<T> builder, Func<IAsyncEnumerable<T>, ValueTask<R>> branch)
=> builder.Add(async (x) => await branch(x).AsTask().ConfigureAwait(false));
=> builder.Add(async (x) => await branch(x).AsTask());
public static BaseBranchingBuilder<T> Add<T, R>(this BaseBranchingBuilder<T> builder, Func<IAsyncEnumerable<T>, Task<R>> branch, out BranchResult<R> result)
{
var refResult = result = new();
return builder.Add(async (x) => refResult.Result = await branch(x).ConfigureAwait(false));
return builder.Add(async (x) => refResult.Result = await branch(x));
}

public static BaseBranchingBuilder<T> Add<T, R>(this BaseBranchingBuilder<T> builder, Func<IAsyncEnumerable<T>, Task<R>> branch)
=> builder.Add(async (x) => await branch(x).ConfigureAwait(false));
=> builder.Add(async (x) => await branch(x));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Runtime.CompilerServices;
using System.Xml.XPath;

namespace Codibre.EnumerableExtensions.Branching.Internal;

internal sealed record BranchContext<T>(Func<BranchContext<T>, ValueTask<LinkedNode<T>?>> GetNext, int _branchCount)
{
private ushort _count = 0;
private readonly ushort _limit = (ushort)int.Min(_branchCount << 14, ushort.MaxValue / 2);

internal async ValueTask<LinkedNode<T>?> FillNext()
{
if (++_count > _limit)
{
_count = 0;
await Task.Yield();
}
return await GetNext(this);
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ namespace Codibre.EnumerableExtensions.Branching.Internal;

internal static class BranchingHelper
{
internal static IAsyncEnumerable<T> GetBranchedIterable<T>(this LinkedNode<T>? node)
=> node is null ? Array.Empty<T>().ToAsyncEnumerable() : new BranchedEnumerable<T>(node);

internal static ConfiguredValueTaskAwaitable<bool> MoveLoose<T>(this IAsyncEnumerator<T> enumerator)
=> enumerator.MoveNextAsync().ConfigureAwait(false);
internal static async IAsyncEnumerable<T> GetBranchedIterable<T>(this LinkedNode<T> root)
{
var node = await root.Next.Value;
while (node is not null)
{
yield return node.Value;
node = await node.Next.Value;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
namespace Codibre.EnumerableExtensions.Branching.Internal;

internal record LinkedNode<T>(T value)
internal sealed record LinkedNode<T>(T Value, BranchContext<T> Context)
{
public T Value { get; } = value;
public LinkedNode<T>? Next { get; set; } = null;
public bool End { get; set; } = false;
public Lazy<ValueTask<LinkedNode<T>?>> Next { get; } = new(Context.FillNext, LazyThreadSafetyMode.ExecutionAndPublication);
}
32 changes: 16 additions & 16 deletions test/Codibre.EnumerableExtensions.Branching.Benchmark/Benchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,30 @@ public static IEnumerable<int> AddOps(this IEnumerable<int> source, int value)

public class Benchmarks
{
[Params(100)]
[Params(100)] //, 1000, 10000)]
public int _size = 100;
private IEnumerable<int> GetBaseEnumerable()
=> Enumerable.Range(0, _size)
.AddOps(2)
.AddOps(3)
.AddOps(4);

[Benchmark]
public void Separate()
{
GetBaseEnumerable().Min();
GetBaseEnumerable().Max();
GetBaseEnumerable().Average();
}
// [Benchmark]
// public void Separate()
// {
// GetBaseEnumerable().Min();
// GetBaseEnumerable().Max();
// GetBaseEnumerable().Average();
// }

[Benchmark]
public void ManualBranch()
{
var baseEnum = GetBaseEnumerable();
baseEnum.Min();
baseEnum.Max();
baseEnum.Average();
}
// [Benchmark]
// public void ManualBranch()
// {
// var baseEnum = GetBaseEnumerable();
// baseEnum.Min();
// baseEnum.Max();
// baseEnum.Average();
// }

[Benchmark]
public Task Branching() => GetBaseEnumerable()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Codibre.EnumerableExtensions.Branching.Test;

[Collection("Tests")]
public class AsyncBranchingBuilderTest(ITestOutputHelper helper)
public class AsyncBranchingBuilderTest()
{
private static IAsyncEnumerable<int> Op(IAsyncEnumerable<int> list) => list
.Select(x => x * 2)
Expand Down Expand Up @@ -74,7 +74,7 @@ await enumerable.Branch()
public async Task Should_Intercalate_The_Steps_Between_Every_Branch()
{
// Arrange
var total = 1000000;
var total = 100000;
var list = Enumerable.Range(0, total).ToAsyncEnumerable();
List<int> steps = [];
var enumerable = Op(list);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Codibre.EnumerableExtensions.Branching.Test;

[Collection("Tests")]
public class BranchingBuilderTest(ITestOutputHelper helper)
public class BranchingBuilderTest()
{
private static IEnumerable<int> Op(IEnumerable<int> list) => list
.Select(x => x * 2)
Expand Down Expand Up @@ -74,7 +74,7 @@ await enumerable.Branch()
public async Task Should_Intercalate_The_Steps_Between_Every_Branch()
{
// Arrange
var total = 1000000;
var total = 100000;
var list = Enumerable.Range(0, total);
List<int> steps = [];
var enumerable = Op(list);
Expand Down

0 comments on commit 2c5c573

Please sign in to comment.