@@ -70,13 +70,6 @@ class ArrayBuffer[A] private (initialElements: Array[AnyRef], initialSize: Int)
70
70
array = ArrayBuffer .ensureSize(array, size0, n)
71
71
}
72
72
73
- // TODO 3.T: should be `protected`, perhaps `protected[this]`
74
- /** Ensure that the internal array has at least `n` additional cells more than `size0`. */
75
- private [mutable] def ensureAdditionalSize (n : Int ): Unit = {
76
- // `.toLong` to ensure `Long` arithmetic is used and prevent `Int` overflow
77
- array = ArrayBuffer .ensureSize(array, size0, size0.toLong + n)
78
- }
79
-
80
73
/** Uses the given size to resize internal storage, if necessary.
81
74
*
82
75
* @param size Expected maximum number of elements.
@@ -147,10 +140,10 @@ class ArrayBuffer[A] private (initialElements: Array[AnyRef], initialSize: Int)
147
140
148
141
def addOne (elem : A ): this .type = {
149
142
mutationCount += 1
150
- ensureAdditionalSize( 1 )
151
- val oldSize = size0
152
- size0 = oldSize + 1
153
- this (oldSize ) = elem
143
+ val newSize = size0 + 1
144
+ ensureSize(newSize)
145
+ size0 = newSize
146
+ this (size0 - 1 ) = elem
154
147
this
155
148
}
156
149
@@ -161,7 +154,7 @@ class ArrayBuffer[A] private (initialElements: Array[AnyRef], initialSize: Int)
161
154
val elemsLength = elems.size0
162
155
if (elemsLength > 0 ) {
163
156
mutationCount += 1
164
- ensureAdditionalSize( elemsLength)
157
+ ensureSize(size0 + elemsLength)
165
158
Array .copy(elems.array, 0 , array, length, elemsLength)
166
159
size0 = length + elemsLength
167
160
}
@@ -173,7 +166,7 @@ class ArrayBuffer[A] private (initialElements: Array[AnyRef], initialSize: Int)
173
166
def insert (@ deprecatedName(" n" , " 2.13.0" ) index : Int , elem : A ): Unit = {
174
167
checkWithinBounds(index, index)
175
168
mutationCount += 1
176
- ensureAdditionalSize( 1 )
169
+ ensureSize(size0 + 1 )
177
170
Array .copy(array, index, array, index + 1 , size0 - index)
178
171
size0 += 1
179
172
this (index) = elem
@@ -191,7 +184,7 @@ class ArrayBuffer[A] private (initialElements: Array[AnyRef], initialSize: Int)
191
184
val elemsLength = elems.size
192
185
if (elemsLength > 0 ) {
193
186
mutationCount += 1
194
- ensureAdditionalSize( elemsLength)
187
+ ensureSize(size0 + elemsLength)
195
188
val len = size0
196
189
Array .copy(array, index, array, index + elemsLength, len - index)
197
190
// if `elems eq this`, this copy is safe because
@@ -314,24 +307,30 @@ object ArrayBuffer extends StrictOptimizedSeqFactory[ArrayBuffer] {
314
307
315
308
def empty [A ]: ArrayBuffer [A ] = new ArrayBuffer [A ]()
316
309
310
+ import scala .runtime .PStatics .VM_MaxArraySize
317
311
/**
318
312
* @param arrayLen the length of the backing array
319
313
* @param targetLen the minimum length to resize up to
320
- * @return -1 if no resizing is needed, or the size for the new array otherwise
314
+ * @return -1 if no resizing is needed, the greater of targetLen and 2 * arrayLen if neither exceeds VM_MaxArraySize,
315
+ * or VM_MaxArraySize otherwise.
321
316
*/
322
- private def resizeUp (arrayLen : Long , targetLen : Long ): Int = {
323
- if (targetLen <= arrayLen) - 1
317
+ private [mutable] def resizeUp (arrayLen : Int , targetLen : Int ): Int = {
318
+ // Hybrid
319
+ if (targetLen > 0 && targetLen <= arrayLen) - 1
324
320
else {
325
- if (targetLen > Int .MaxValue ) throw new Exception (s " Collections cannot have more than ${Int .MaxValue } elements " )
326
- IterableOnce .checkArraySizeWithinVMLimit(targetLen.toInt) // safe because `targetSize <= Int.MaxValue`
321
+ IterableOnce .checkArraySizeWithinVMLimit(targetLen) // safe because `targetSize <= Int.MaxValue`
327
322
328
- val newLen = math.max(targetLen, math.max(arrayLen * 2 , DefaultInitialSize ))
329
- math.min(newLen, scala.runtime.PStatics .VM_MaxArraySize ).toInt
323
+ math.min(
324
+ if (targetLen > (Int .MaxValue >> 1 )) VM_MaxArraySize
325
+ else math.max(targetLen, math.max(arrayLen << 1 , DefaultInitialSize )),
326
+ VM_MaxArraySize
327
+ )
330
328
}
331
329
}
330
+
332
331
// if necessary, copy (curSize elements of) the array to a new array of capacity n.
333
332
// Should use Array.copyOf(array, resizeEnsuring(array.length))?
334
- private def ensureSize (array : Array [AnyRef ], curSize : Int , targetSize : Long ): Array [AnyRef ] = {
333
+ private def ensureSize (array : Array [AnyRef ], curSize : Int , targetSize : Int ): Array [AnyRef ] = {
335
334
val newLen = resizeUp(array.length, targetSize)
336
335
if (newLen < 0 ) array
337
336
else {
0 commit comments