Skip to content

Commit

Permalink
Move EnsureCapacity to its own file
Browse files Browse the repository at this point in the history
  • Loading branch information
Joy-less committed Jan 24, 2025
1 parent fa3bc0f commit 8bcec51
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 53 deletions.
57 changes: 57 additions & 0 deletions src/LinkDotNet.StringBuilder/ValueStringBuilder.EnsureCapacity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace LinkDotNet.StringBuilder;

public ref partial struct ValueStringBuilder
{
/// <summary>
/// Ensures the builder's buffer size is at least <paramref name="newCapacity"/>, renting a larger buffer if not.
/// </summary>
/// <param name="newCapacity">New capacity for the builder.</param>
/// <remarks>
/// If <see cref="Length"/> is already &gt;= <paramref name="newCapacity"/>, nothing is done.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void EnsureCapacity(int newCapacity)
{
if (Length >= newCapacity)
{
return;
}

var newSize = FindSmallestPowerOf2Above(newCapacity);

var rented = ArrayPool<char>.Shared.Rent(newSize);

if (bufferPosition > 0)
{
ref var sourceRef = ref MemoryMarshal.GetReference(buffer);
ref var destinationRef = ref MemoryMarshal.GetReference(rented.AsSpan());

Unsafe.CopyBlock(
ref Unsafe.As<char, byte>(ref destinationRef),
ref Unsafe.As<char, byte>(ref sourceRef),
(uint)bufferPosition * sizeof(char));
}

if (arrayFromPool is not null)
{
ArrayPool<char>.Shared.Return(arrayFromPool);
}

buffer = rented;
arrayFromPool = rented;
}

/// <summary>
/// Finds the smallest power of 2 which is greater than or equal to <paramref name="minimum"/>.
/// </summary>
/// <param name="minimum">The value the result should be greater than or equal to.</param>
/// <returns>The smallest power of 2 >= <paramref name="minimum"/>.</returns>
private static int FindSmallestPowerOf2Above(int minimum)
{
return 1 << (int)Math.Ceiling(Math.Log2(minimum));
}
}
14 changes: 0 additions & 14 deletions src/LinkDotNet.StringBuilder/ValueStringBuilder.Helper.cs

This file was deleted.

39 changes: 0 additions & 39 deletions src/LinkDotNet.StringBuilder/ValueStringBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,45 +167,6 @@ public readonly string ToString(Range range)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear() => bufferPosition = 0;

/// <summary>
/// Ensures the builder's buffer size is at least <paramref name="newCapacity"/>, renting a larger buffer if not.
/// </summary>
/// <param name="newCapacity">New capacity for the builder.</param>
/// <remarks>
/// If <see cref="Length"/> is already &gt;= <paramref name="newCapacity"/>, nothing is done.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void EnsureCapacity(int newCapacity)
{
if (Length >= newCapacity)
{
return;
}

int newSize = FindSmallestPowerOf2Above(newCapacity);

char[] rented = ArrayPool<char>.Shared.Rent(newSize);

if (bufferPosition > 0)
{
ref char sourceRef = ref MemoryMarshal.GetReference(buffer);
ref char destinationRef = ref MemoryMarshal.GetReference(rented.AsSpan());

Unsafe.CopyBlock(
ref Unsafe.As<char, byte>(ref destinationRef),
ref Unsafe.As<char, byte>(ref sourceRef),
(uint)bufferPosition * sizeof(char));
}

if (arrayFromPool is not null)
{
ArrayPool<char>.Shared.Return(arrayFromPool);
}

buffer = rented;
arrayFromPool = rented;
}

/// <summary>
/// Removes a range of characters from this builder.
/// </summary>
Expand Down

0 comments on commit 8bcec51

Please sign in to comment.