Skip to content

Commit 1d0e755

Browse files
committed
Revert ArrayBuilder changes, it cannot be changed
1 parent 02f311f commit 1d0e755

File tree

1 file changed

+26
-45
lines changed

1 file changed

+26
-45
lines changed

src/libraries/Common/src/System/Collections/Generic/ArrayBuilder.cs

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Diagnostics;
5-
using System.Runtime.CompilerServices;
65

76
namespace System.Collections.Generic
87
{
@@ -12,9 +11,7 @@ namespace System.Collections.Generic
1211
/// <typeparam name="T">The element type.</typeparam>
1312
internal struct ArrayBuilder<T>
1413
{
15-
private InlineArray16<T> _stackAllocatedBuffer = default;
16-
private const int StackAllocatedCapacity = 16;
17-
private const int DefaultHeapCapacity = 4;
14+
private const int DefaultCapacity = 4;
1815

1916
private T[]? _array; // Starts out null, initialized on first Add.
2017
private int _count; // Number of items into _array we're using.
@@ -26,17 +23,20 @@ internal struct ArrayBuilder<T>
2623
public ArrayBuilder(int capacity) : this()
2724
{
2825
Debug.Assert(capacity >= 0);
29-
if (capacity > StackAllocatedCapacity)
26+
if (capacity > 0)
3027
{
31-
_array = new T[capacity - StackAllocatedCapacity];
28+
_array = new T[capacity];
3229
}
3330
}
3431

3532
/// <summary>
3633
/// Gets the number of items this instance can store without re-allocating,
3734
/// or 0 if the backing array is <c>null</c>.
3835
/// </summary>
39-
public int Capacity => _array?.Length + StackAllocatedCapacity ?? StackAllocatedCapacity;
36+
public int Capacity => _array?.Length ?? 0;
37+
38+
/// <summary>Gets the current underlying array.</summary>
39+
public T[]? Buffer => _array;
4040

4141
/// <summary>
4242
/// Gets the number of items in the array currently in use.
@@ -52,7 +52,7 @@ public T this[int index]
5252
get
5353
{
5454
Debug.Assert(index >= 0 && index < _count);
55-
return index < StackAllocatedCapacity ? _stackAllocatedBuffer[index] : _array![index - StackAllocatedCapacity];
55+
return _array![index];
5656
}
5757
}
5858

@@ -76,7 +76,7 @@ public void Add(T item)
7676
public T First()
7777
{
7878
Debug.Assert(_count > 0);
79-
return _stackAllocatedBuffer[0];
79+
return _array![0];
8080
}
8181

8282
/// <summary>
@@ -85,7 +85,7 @@ public T First()
8585
public T Last()
8686
{
8787
Debug.Assert(_count > 0);
88-
return _count <= StackAllocatedCapacity ? _stackAllocatedBuffer[_count - 1] : _array![_count - StackAllocatedCapacity - 1];
88+
return _array![_count - 1];
8989
}
9090

9191
/// <summary>
@@ -101,19 +101,17 @@ public T[] ToArray()
101101
return Array.Empty<T>();
102102
}
103103

104-
T[] result = new T[_count];
105-
int index = 0;
106-
foreach (T stackAllocatedValue in _stackAllocatedBuffer)
104+
Debug.Assert(_array != null); // Nonzero _count should imply this
105+
106+
T[] result = _array;
107+
if (_count < result.Length)
107108
{
108-
result[index++] = stackAllocatedValue;
109-
if (index >= _count)
110-
{
111-
return result;
112-
}
109+
// Avoid a bit of overhead (method call, some branches, extra codegen)
110+
// which would be incurred by using Array.Resize
111+
result = new T[_count];
112+
Array.Copy(_array, result, _count);
113113
}
114114

115-
_array.AsSpan(0, _count - StackAllocatedCapacity).CopyTo(result.AsSpan(start: StackAllocatedCapacity));
116-
117115
#if DEBUG
118116
// Try to prevent callers from using the ArrayBuilder after ToArray, if _count != 0.
119117
_count = -1;
@@ -134,42 +132,25 @@ public T[] ToArray()
134132
public void UncheckedAdd(T item)
135133
{
136134
Debug.Assert(_count < Capacity);
137-
if (_count < StackAllocatedCapacity)
138-
{
139-
_stackAllocatedBuffer[_count++] = item;
140-
}
141-
else
142-
{
143-
_array![_count++ - StackAllocatedCapacity] = item;
144-
}
135+
136+
_array![_count++] = item;
145137
}
146138

147139
private void EnsureCapacity(int minimum)
148140
{
149141
Debug.Assert(minimum > Capacity);
150142

151-
if (minimum < StackAllocatedCapacity)
152-
{
153-
return;
154-
}
155-
156-
if (_array == null)
157-
{
158-
// Initial capacity has not been set correctly, we will use the default size
159-
_array = new T[DefaultHeapCapacity];
160-
return;
161-
}
162-
163-
int nextHeapCapacity = 2 * _array.Length;
143+
int capacity = Capacity;
144+
int nextCapacity = capacity == 0 ? DefaultCapacity : 2 * capacity;
164145

165-
if ((uint)nextHeapCapacity > (uint)Array.MaxLength)
146+
if ((uint)nextCapacity > (uint)Array.MaxLength)
166147
{
167-
nextHeapCapacity = Math.Max(_array.Length + 1, Array.MaxLength);
148+
nextCapacity = Math.Max(capacity + 1, Array.MaxLength);
168149
}
169150

170-
nextHeapCapacity = Math.Max(nextHeapCapacity, minimum);
151+
nextCapacity = Math.Max(nextCapacity, minimum);
171152

172-
T[] next = new T[nextHeapCapacity];
153+
T[] next = new T[nextCapacity];
173154
if (_count > 0)
174155
{
175156
Array.Copy(_array!, next, _count);

0 commit comments

Comments
 (0)