Skip to content

Commit f87610a

Browse files
committed
Switch source generator cache to ArrayPool<T>
1 parent eef21e2 commit f87610a

File tree

3 files changed

+23
-202
lines changed

3 files changed

+23
-202
lines changed

src/CommunityToolkit.Mvvm.SourceGenerators/CommunityToolkit.Mvvm.SourceGenerators.projitems

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
<Compile Include="$(MSBuildThisFileDirectory)Helpers\EquatableArray{T}.cs" />
6868
<Compile Include="$(MSBuildThisFileDirectory)Helpers\HashCode.cs" />
6969
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ImmutableArrayBuilder{T}.cs" />
70-
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ObjectPool{T}.cs" />
7170
<Compile Include="$(MSBuildThisFileDirectory)Input\Models\CanExecuteExpressionType.cs" />
7271
<Compile Include="$(MSBuildThisFileDirectory)Input\Models\CommandInfo.cs" />
7372
<Compile Include="$(MSBuildThisFileDirectory)Input\RelayCommandGenerator.cs" />

src/CommunityToolkit.Mvvm.SourceGenerators/Helpers/ImmutableArrayBuilder{T}.cs

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// more info in ThirdPartyNotices.txt in the root of the project.
77

88
using System;
9+
using System.Buffers;
910
using System.Collections.Immutable;
1011
using System.Runtime.CompilerServices;
1112

@@ -17,11 +18,6 @@ namespace CommunityToolkit.Mvvm.SourceGenerators.Helpers;
1718
/// <typeparam name="T">The type of items to create sequences for.</typeparam>
1819
internal struct ImmutableArrayBuilder<T> : IDisposable
1920
{
20-
/// <summary>
21-
/// The shared <see cref="ObjectPool{T}"/> instance to share <see cref="Writer"/> objects.
22-
/// </summary>
23-
private static readonly ObjectPool<Writer> SharedObjectPool = new(static () => new Writer());
24-
2521
/// <summary>
2622
/// The rented <see cref="Writer"/> instance to use.
2723
/// </summary>
@@ -33,7 +29,7 @@ internal struct ImmutableArrayBuilder<T> : IDisposable
3329
/// <returns>A <see cref="ImmutableArrayBuilder{T}"/> instance to write data to.</returns>
3430
public static ImmutableArrayBuilder<T> Rent()
3531
{
36-
return new(SharedObjectPool.Allocate());
32+
return new(new Writer());
3733
}
3834

3935
/// <summary>
@@ -103,23 +99,18 @@ public void Dispose()
10399

104100
this.writer = null;
105101

106-
if (writer is not null)
107-
{
108-
writer.Clear();
109-
110-
SharedObjectPool.Free(writer);
111-
}
102+
writer?.Dispose();
112103
}
113104

114105
/// <summary>
115106
/// A class handling the actual buffer writing.
116107
/// </summary>
117-
private sealed class Writer
108+
private sealed class Writer : IDisposable
118109
{
119110
/// <summary>
120111
/// The underlying <typeparamref name="T"/> array.
121112
/// </summary>
122-
private T[] array;
113+
private T?[]? array;
123114

124115
/// <summary>
125116
/// The starting offset within <see cref="array"/>.
@@ -131,15 +122,7 @@ private sealed class Writer
131122
/// </summary>
132123
public Writer()
133124
{
134-
if (typeof(T) == typeof(char))
135-
{
136-
this.array = new T[1024];
137-
}
138-
else
139-
{
140-
this.array = new T[8];
141-
}
142-
125+
this.array = ArrayPool<T?>.Shared.Rent(typeof(T) == typeof(char) ? 1024 : 8);
143126
this.index = 0;
144127
}
145128

@@ -154,38 +137,38 @@ public int Count
154137
public ReadOnlySpan<T> WrittenSpan
155138
{
156139
[MethodImpl(MethodImplOptions.AggressiveInlining)]
157-
get => new(this.array, 0, this.index);
140+
get => new(this.array!, 0, this.index);
158141
}
159142

160143
/// <inheritdoc cref="ImmutableArrayBuilder{T}.Add"/>
161144
public void Add(T value)
162145
{
163146
EnsureCapacity(1);
164147

165-
this.array[this.index++] = value;
148+
this.array![this.index++] = value;
166149
}
167150

168151
/// <inheritdoc cref="ImmutableArrayBuilder{T}.AddRange"/>
169152
public void AddRange(ReadOnlySpan<T> items)
170153
{
171154
EnsureCapacity(items.Length);
172155

173-
items.CopyTo(this.array.AsSpan(this.index));
156+
items.CopyTo(this.array.AsSpan(this.index)!);
174157

175158
this.index += items.Length;
176159
}
177160

178-
/// <summary>
179-
/// Clears the items in the current writer.
180-
/// </summary>
181-
public void Clear()
161+
/// <inheritdoc/>
162+
public void Dispose()
182163
{
183-
if (typeof(T) != typeof(char))
164+
T?[]? array = this.array;
165+
166+
this.array = null;
167+
168+
if (array is not null)
184169
{
185-
this.array.AsSpan(0, this.index).Clear();
170+
ArrayPool<T?>.Shared.Return(array, clearArray: typeof(T) != typeof(char));
186171
}
187-
188-
this.index = 0;
189172
}
190173

191174
/// <summary>
@@ -195,7 +178,7 @@ public void Clear()
195178
[MethodImpl(MethodImplOptions.AggressiveInlining)]
196179
private void EnsureCapacity(int requestedSize)
197180
{
198-
if (requestedSize > this.array.Length - this.index)
181+
if (requestedSize > this.array!.Length - this.index)
199182
{
200183
ResizeBuffer(requestedSize);
201184
}
@@ -209,13 +192,15 @@ private void EnsureCapacity(int requestedSize)
209192
private void ResizeBuffer(int sizeHint)
210193
{
211194
int minimumSize = this.index + sizeHint;
212-
int requestedSize = Math.Max(this.array.Length * 2, minimumSize);
213195

214-
T[] newArray = new T[requestedSize];
196+
T?[] oldArray = this.array!;
197+
T?[] newArray = ArrayPool<T?>.Shared.Rent(minimumSize);
215198

216-
Array.Copy(this.array, newArray, this.index);
199+
Array.Copy(oldArray, newArray, this.index);
217200

218201
this.array = newArray;
202+
203+
ArrayPool<T?>.Shared.Return(oldArray, clearArray: typeof(T) != typeof(char));
219204
}
220205
}
221206
}

src/CommunityToolkit.Mvvm.SourceGenerators/Helpers/ObjectPool{T}.cs

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

0 commit comments

Comments
 (0)