Skip to content

Commit 8bcec51

Browse files
committed
Move EnsureCapacity to its own file
1 parent fa3bc0f commit 8bcec51

File tree

3 files changed

+57
-53
lines changed

3 files changed

+57
-53
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System.Buffers;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
namespace LinkDotNet.StringBuilder;
6+
7+
public ref partial struct ValueStringBuilder
8+
{
9+
/// <summary>
10+
/// Ensures the builder's buffer size is at least <paramref name="newCapacity"/>, renting a larger buffer if not.
11+
/// </summary>
12+
/// <param name="newCapacity">New capacity for the builder.</param>
13+
/// <remarks>
14+
/// If <see cref="Length"/> is already &gt;= <paramref name="newCapacity"/>, nothing is done.
15+
/// </remarks>
16+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
17+
public void EnsureCapacity(int newCapacity)
18+
{
19+
if (Length >= newCapacity)
20+
{
21+
return;
22+
}
23+
24+
var newSize = FindSmallestPowerOf2Above(newCapacity);
25+
26+
var rented = ArrayPool<char>.Shared.Rent(newSize);
27+
28+
if (bufferPosition > 0)
29+
{
30+
ref var sourceRef = ref MemoryMarshal.GetReference(buffer);
31+
ref var destinationRef = ref MemoryMarshal.GetReference(rented.AsSpan());
32+
33+
Unsafe.CopyBlock(
34+
ref Unsafe.As<char, byte>(ref destinationRef),
35+
ref Unsafe.As<char, byte>(ref sourceRef),
36+
(uint)bufferPosition * sizeof(char));
37+
}
38+
39+
if (arrayFromPool is not null)
40+
{
41+
ArrayPool<char>.Shared.Return(arrayFromPool);
42+
}
43+
44+
buffer = rented;
45+
arrayFromPool = rented;
46+
}
47+
48+
/// <summary>
49+
/// Finds the smallest power of 2 which is greater than or equal to <paramref name="minimum"/>.
50+
/// </summary>
51+
/// <param name="minimum">The value the result should be greater than or equal to.</param>
52+
/// <returns>The smallest power of 2 >= <paramref name="minimum"/>.</returns>
53+
private static int FindSmallestPowerOf2Above(int minimum)
54+
{
55+
return 1 << (int)Math.Ceiling(Math.Log2(minimum));
56+
}
57+
}

src/LinkDotNet.StringBuilder/ValueStringBuilder.Helper.cs

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/LinkDotNet.StringBuilder/ValueStringBuilder.cs

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -167,45 +167,6 @@ public readonly string ToString(Range range)
167167
[MethodImpl(MethodImplOptions.AggressiveInlining)]
168168
public void Clear() => bufferPosition = 0;
169169

170-
/// <summary>
171-
/// Ensures the builder's buffer size is at least <paramref name="newCapacity"/>, renting a larger buffer if not.
172-
/// </summary>
173-
/// <param name="newCapacity">New capacity for the builder.</param>
174-
/// <remarks>
175-
/// If <see cref="Length"/> is already &gt;= <paramref name="newCapacity"/>, nothing is done.
176-
/// </remarks>
177-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
178-
public void EnsureCapacity(int newCapacity)
179-
{
180-
if (Length >= newCapacity)
181-
{
182-
return;
183-
}
184-
185-
int newSize = FindSmallestPowerOf2Above(newCapacity);
186-
187-
char[] rented = ArrayPool<char>.Shared.Rent(newSize);
188-
189-
if (bufferPosition > 0)
190-
{
191-
ref char sourceRef = ref MemoryMarshal.GetReference(buffer);
192-
ref char destinationRef = ref MemoryMarshal.GetReference(rented.AsSpan());
193-
194-
Unsafe.CopyBlock(
195-
ref Unsafe.As<char, byte>(ref destinationRef),
196-
ref Unsafe.As<char, byte>(ref sourceRef),
197-
(uint)bufferPosition * sizeof(char));
198-
}
199-
200-
if (arrayFromPool is not null)
201-
{
202-
ArrayPool<char>.Shared.Return(arrayFromPool);
203-
}
204-
205-
buffer = rented;
206-
arrayFromPool = rented;
207-
}
208-
209170
/// <summary>
210171
/// Removes a range of characters from this builder.
211172
/// </summary>

0 commit comments

Comments
 (0)