6
6
// more info in ThirdPartyNotices.txt in the root of the project.
7
7
8
8
using System ;
9
+ using System . Buffers ;
9
10
using System . Collections . Immutable ;
10
11
using System . Runtime . CompilerServices ;
11
12
@@ -17,11 +18,6 @@ namespace CommunityToolkit.Mvvm.SourceGenerators.Helpers;
17
18
/// <typeparam name="T">The type of items to create sequences for.</typeparam>
18
19
internal struct ImmutableArrayBuilder < T > : IDisposable
19
20
{
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
-
25
21
/// <summary>
26
22
/// The rented <see cref="Writer"/> instance to use.
27
23
/// </summary>
@@ -33,7 +29,7 @@ internal struct ImmutableArrayBuilder<T> : IDisposable
33
29
/// <returns>A <see cref="ImmutableArrayBuilder{T}"/> instance to write data to.</returns>
34
30
public static ImmutableArrayBuilder < T > Rent ( )
35
31
{
36
- return new ( SharedObjectPool . Allocate ( ) ) ;
32
+ return new ( new Writer ( ) ) ;
37
33
}
38
34
39
35
/// <summary>
@@ -103,23 +99,18 @@ public void Dispose()
103
99
104
100
this . writer = null ;
105
101
106
- if ( writer is not null )
107
- {
108
- writer . Clear ( ) ;
109
-
110
- SharedObjectPool . Free ( writer ) ;
111
- }
102
+ writer ? . Dispose ( ) ;
112
103
}
113
104
114
105
/// <summary>
115
106
/// A class handling the actual buffer writing.
116
107
/// </summary>
117
- private sealed class Writer
108
+ private sealed class Writer : IDisposable
118
109
{
119
110
/// <summary>
120
111
/// The underlying <typeparamref name="T"/> array.
121
112
/// </summary>
122
- private T [ ] array ;
113
+ private T ? [ ] ? array ;
123
114
124
115
/// <summary>
125
116
/// The starting offset within <see cref="array"/>.
@@ -131,15 +122,7 @@ private sealed class Writer
131
122
/// </summary>
132
123
public Writer ( )
133
124
{
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 ) ;
143
126
this . index = 0 ;
144
127
}
145
128
@@ -154,38 +137,38 @@ public int Count
154
137
public ReadOnlySpan < T > WrittenSpan
155
138
{
156
139
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
157
- get => new ( this . array , 0 , this . index ) ;
140
+ get => new ( this . array ! , 0 , this . index ) ;
158
141
}
159
142
160
143
/// <inheritdoc cref="ImmutableArrayBuilder{T}.Add"/>
161
144
public void Add ( T value )
162
145
{
163
146
EnsureCapacity ( 1 ) ;
164
147
165
- this . array [ this . index ++ ] = value ;
148
+ this . array ! [ this . index ++ ] = value ;
166
149
}
167
150
168
151
/// <inheritdoc cref="ImmutableArrayBuilder{T}.AddRange"/>
169
152
public void AddRange ( ReadOnlySpan < T > items )
170
153
{
171
154
EnsureCapacity ( items . Length ) ;
172
155
173
- items . CopyTo ( this . array . AsSpan ( this . index ) ) ;
156
+ items . CopyTo ( this . array . AsSpan ( this . index ) ! ) ;
174
157
175
158
this . index += items . Length ;
176
159
}
177
160
178
- /// <summary>
179
- /// Clears the items in the current writer.
180
- /// </summary>
181
- public void Clear ( )
161
+ /// <inheritdoc/>
162
+ public void Dispose ( )
182
163
{
183
- if ( typeof ( T ) != typeof ( char ) )
164
+ T ? [ ] ? array = this . array ;
165
+
166
+ this . array = null ;
167
+
168
+ if ( array is not null )
184
169
{
185
- this . array . AsSpan ( 0 , this . index ) . Clear ( ) ;
170
+ ArrayPool < T ? > . Shared . Return ( array , clearArray : typeof ( T ) != typeof ( char ) ) ;
186
171
}
187
-
188
- this . index = 0 ;
189
172
}
190
173
191
174
/// <summary>
@@ -195,7 +178,7 @@ public void Clear()
195
178
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
196
179
private void EnsureCapacity ( int requestedSize )
197
180
{
198
- if ( requestedSize > this . array . Length - this . index )
181
+ if ( requestedSize > this . array ! . Length - this . index )
199
182
{
200
183
ResizeBuffer ( requestedSize ) ;
201
184
}
@@ -209,13 +192,15 @@ private void EnsureCapacity(int requestedSize)
209
192
private void ResizeBuffer ( int sizeHint )
210
193
{
211
194
int minimumSize = this . index + sizeHint ;
212
- int requestedSize = Math . Max ( this . array . Length * 2 , minimumSize ) ;
213
195
214
- T [ ] newArray = new T [ requestedSize ] ;
196
+ T ? [ ] oldArray = this . array ! ;
197
+ T ? [ ] newArray = ArrayPool < T ? > . Shared . Rent ( minimumSize ) ;
215
198
216
- Array . Copy ( this . array , newArray , this . index ) ;
199
+ Array . Copy ( oldArray , newArray , this . index ) ;
217
200
218
201
this . array = newArray ;
202
+
203
+ ArrayPool < T ? > . Shared . Return ( oldArray , clearArray : typeof ( T ) != typeof ( char ) ) ;
219
204
}
220
205
}
221
206
}
0 commit comments