Skip to content

Commit 9134f98

Browse files
committed
Defer array resize on empty
1 parent 34bc424 commit 9134f98

File tree

2 files changed

+22
-21
lines changed

2 files changed

+22
-21
lines changed

library/src/scala/collection/mutable/ArrayBuffer.scala

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -316,20 +316,12 @@ object ArrayBuffer extends StrictOptimizedSeqFactory[ArrayBuffer] {
316316
* - `max(targetLen, arrayLen * 2, DefaultInitialSize)`.
317317
* - Throws an exception if `targetLen` exceeds `VM_MaxArraySize` or is negative (overflow).
318318
*/
319-
private[mutable] def resizeUp(arrayLen: Int, targetLen: Int): Int = {
320-
def checkArrayLengthLimit(): Unit =
321-
if (targetLen > VM_MaxArraySize)
322-
throw new Exception(s"Array of array-backed collection exceeds VM length limit of $VM_MaxArraySize. Requested length: $targetLen; current length: $arrayLen")
323-
else if (targetLen < 0)
324-
throw new Exception(s"Overflow while resizing array of array-backed collection. Requested length: $targetLen; current length: $arrayLen; increase: ${targetLen - arrayLen}")
325-
326-
if (targetLen > 0 && targetLen <= arrayLen) -1
327-
else {
328-
checkArrayLengthLimit()
329-
if (arrayLen > VM_MaxArraySize / 2) VM_MaxArraySize
330-
else math.max(targetLen, math.max(arrayLen * 2, DefaultInitialSize))
331-
}
332-
}
319+
private[mutable] def resizeUp(arrayLen: Int, targetLen: Int): Int =
320+
if (targetLen < 0) throw new Exception(s"Overflow while resizing array of array-backed collection. Requested length: $targetLen; current length: $arrayLen; increase: ${targetLen - arrayLen}")
321+
else if (targetLen <= arrayLen) -1
322+
else if (targetLen > VM_MaxArraySize) throw new Exception(s"Array of array-backed collection exceeds VM length limit of $VM_MaxArraySize. Requested length: $targetLen; current length: $arrayLen")
323+
else if (arrayLen > VM_MaxArraySize / 2) VM_MaxArraySize
324+
else math.max(targetLen, math.max(arrayLen * 2, DefaultInitialSize))
333325

334326
// if necessary, copy (curSize elements of) the array to a new array of capacity n.
335327
// Should use Array.copyOf(array, resizeEnsuring(array.length))?

library/src/scala/collection/mutable/ArrayBuilder.scala

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ sealed abstract class ArrayBuilder[T]
2525
extends ReusableBuilder[T, Array[T]]
2626
with Serializable {
2727
protected[this] var capacity: Int = 0
28-
protected[this] def elems: Array[T]
28+
protected[this] def elems: Array[T] // may not be allocated at size = capacity = 0
2929
protected var size: Int = 0
3030

3131
/** Current number of elements. */
@@ -45,14 +45,23 @@ sealed abstract class ArrayBuilder[T]
4545

4646
protected[this] def resize(size: Int): Unit
4747

48-
/** Add all elements of an array */
49-
def addAll(xs: Array[_ <: T]): this.type = addAll(xs, 0, xs.length)
48+
/** Add all elements of an array. */
49+
def addAll(xs: Array[_ <: T]): this.type = doAddAll(xs, 0, xs.length)
5050

51-
/** Add a slice of an array */
51+
/** Add a slice of an array. */
5252
def addAll(xs: Array[_ <: T], offset: Int, length: Int): this.type = {
53-
ensureSize(this.size + length)
54-
Array.copy(xs, offset, elems, this.size, length)
55-
size += length
53+
val offset1 = offset.max(0)
54+
val length1 = length.max(0)
55+
val effectiveLength = length1.min(xs.length - offset1)
56+
doAddAll(xs, offset1, effectiveLength)
57+
}
58+
59+
private def doAddAll(xs: Array[_ <: T], offset: Int, length: Int): this.type = {
60+
if (length > 0) {
61+
ensureSize(this.size + length)
62+
Array.copy(xs, offset, elems, this.size, length)
63+
size += length
64+
}
5665
this
5766
}
5867

0 commit comments

Comments
 (0)