Move prime tracking into CalculationResultHandler
This commit is contained in:
1 parent
194f10d00b
commit
e338497c2f
7 files changed
+1656
-942
No files matched your search
@@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace PerfectNumbers.Core;
|
||||
|
||||
public ref struct PooledValueStringBuilder
|
||||
{
|
||||
private Span<char> _span;
|
||||
private char[]? _arrayFromPool;
|
||||
private int _pos;
|
||||
|
||||
public PooledValueStringBuilder(Span<char> initialBuffer)
|
||||
{
|
||||
_span = initialBuffer;
|
||||
_arrayFromPool = null;
|
||||
_pos = 0;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Append(char value)
|
||||
{
|
||||
int position = _pos;
|
||||
if (position < _span.Length)
|
||||
{
|
||||
_span[position] = value;
|
||||
_pos = position + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
Grow(1);
|
||||
_span[_pos++] = value;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Append(string? value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
Append(value.AsSpan());
|
||||
}
|
||||
}
|
||||
|
||||
public void Append(ReadOnlySpan<char> value)
|
||||
{
|
||||
if (value.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int remaining = _span.Length - _pos;
|
||||
if (value.Length <= remaining)
|
||||
{
|
||||
value.CopyTo(_span[_pos..]);
|
||||
_pos += value.Length;
|
||||
return;
|
||||
}
|
||||
|
||||
Grow(value.Length);
|
||||
value.CopyTo(_span[_pos..]);
|
||||
_pos += value.Length;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Append(int value)
|
||||
{
|
||||
AppendSpanFormattable(value);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Append(ulong value)
|
||||
{
|
||||
AppendSpanFormattable(value);
|
||||
}
|
||||
|
||||
public ReadOnlySpan<char> AsSpan() => _span[.._pos];
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return new string(_span[.._pos]);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_arrayFromPool is { } array)
|
||||
{
|
||||
ThreadStaticPools.CharPool.Return(array);
|
||||
_arrayFromPool = null;
|
||||
}
|
||||
|
||||
_span = Span<char>.Empty;
|
||||
_pos = 0;
|
||||
}
|
||||
|
||||
private void AppendSpanFormattable<T>(T value) where T : ISpanFormattable
|
||||
{
|
||||
int charsWritten;
|
||||
while (!value.TryFormat(_span[_pos..], out charsWritten, default, CultureInfo.InvariantCulture))
|
||||
{
|
||||
Grow(Math.Max(4, _span.Length));
|
||||
}
|
||||
|
||||
_pos += charsWritten;
|
||||
}
|
||||
|
||||
private void Grow(int additionalCapacity)
|
||||
{
|
||||
int required = _pos + additionalCapacity;
|
||||
int currentLength = _span.Length;
|
||||
int newCapacity = currentLength == 0 ? Math.Max(4, required) : Math.Max(currentLength * 2, required);
|
||||
char[] newArray = ThreadStaticPools.CharPool.Rent(newCapacity);
|
||||
_span[.._pos].CopyTo(newArray.AsSpan());
|
||||
if (_arrayFromPool is { } toReturn)
|
||||
{
|
||||
ThreadStaticPools.CharPool.Return(toReturn);
|
||||
}
|
||||
|
||||
_span = newArray;
|
||||
_arrayFromPool = newArray;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace PerfectNumbers.Core;
|
||||
|
||||
/// <summary>
|
||||
@@ -70,6 +73,41 @@ public sealed class TextFileWriter : IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteLine(ReadOnlySpan<char> line)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
StreamWriter writer = TextWriter;
|
||||
writer.Write(line);
|
||||
writer.WriteLine();
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(ReadOnlySpan<char> text)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
StreamWriter writer = TextWriter;
|
||||
writer.Write(text);
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(StringBuilder builder)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
StreamWriter writer = TextWriter;
|
||||
foreach (ReadOnlyMemory<char> chunk in builder.GetChunks())
|
||||
{
|
||||
writer.Write(chunk.Span);
|
||||
}
|
||||
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a binary writing action within the internal lock.
|
||||
/// </summary>
|
||||
|
||||
@@ -101,6 +101,18 @@ namespace PerfectNumbers.Core
|
||||
}
|
||||
}
|
||||
|
||||
[ThreadStatic]
|
||||
private static ArrayPool<char>? _charPool;
|
||||
|
||||
public static ArrayPool<char> CharPool
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return _charPool ??= ArrayPool<char>.Create();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[ThreadStatic]
|
||||
private static List<List<ulong>>? _ulongListPool;
|
||||
|
||||
Reference in new issue
Block a user