@@ -1593,76 +1593,102 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] {
1593
1593
* Removes `offset` leading `null`s in the prefix.
1594
1594
* This is needed after calling `alignTo` and subsequent additions,
1595
1595
* directly before the result is used for creating a new Vector.
1596
+ * Note that the outermost array keeps its length to keep the
1597
+ * Builder re-usable.
1596
1598
*
1597
1599
* example:
1598
1600
* a2 = Array(null, ..., null, Array(null, .., null, 0, 1, .., x), Array(x+1, .., x+32), ...)
1599
1601
* becomes
1600
- * a2 = Array(Array(0, 1, .., x), Array(x+1, .., x+32), ...)
1602
+ * a2 = Array(Array(0, 1, .., x), Array(x+1, .., x+32), ..., ?, ..., ? )
1601
1603
*/
1602
1604
private [this ] def leftAlignPrefix (): Unit = {
1605
+ @ inline def shrinkOffsetIfToLarge (width : Int ): Unit = {
1606
+ val newOffset = offset % width
1607
+ lenRest -= offset - newOffset
1608
+ offset = newOffset
1609
+ }
1603
1610
var a : Array [AnyRef ] = null // the array we modify
1604
1611
var aParent : Array [AnyRef ] = null // a's parent, so aParent(0) == a
1605
1612
if (depth >= 6 ) {
1606
1613
a = a6.asInstanceOf [Array [AnyRef ]]
1607
1614
val i = offset >>> BITS5
1608
- if (i > 0 ) {
1609
- a = copyOfRange(a, i, LASTWIDTH )
1610
- a6 = a.asInstanceOf [Arr6 ]
1611
- }
1615
+ if (i > 0 ) System .arraycopy(a, i, a, 0 , LASTWIDTH - i)
1616
+ shrinkOffsetIfToLarge(WIDTH5 )
1617
+ if ((lenRest >>> BITS5 ) == 0 ) depth = 5
1612
1618
aParent = a
1613
1619
a = a(0 ).asInstanceOf [Array [AnyRef ]]
1614
1620
}
1615
1621
if (depth >= 5 ) {
1616
1622
if (a == null ) a = a5.asInstanceOf [Array [AnyRef ]]
1617
1623
val i = (offset >>> BITS4 ) & MASK
1618
- if (i > 0 ) {
1619
- a = copyOfRange(a, i, WIDTH )
1620
- if (depth == 5 ) a5 = a.asInstanceOf [Arr5 ]
1621
- else aParent(0 ) = a
1624
+ if (depth == 5 ) {
1625
+ if (i > 0 ) System .arraycopy(a, i, a, 0 , WIDTH - i)
1626
+ a5 = a.asInstanceOf [Arr5 ]
1627
+ shrinkOffsetIfToLarge(WIDTH4 )
1628
+ if ((lenRest >>> BITS4 ) == 0 ) depth = 4
1629
+ } else {
1630
+ if (i > 0 ) a = copyOfRange(a, i, WIDTH )
1631
+ aParent(0 ) = a
1622
1632
}
1623
1633
aParent = a
1624
1634
a = a(0 ).asInstanceOf [Array [AnyRef ]]
1625
1635
}
1626
1636
if (depth >= 4 ) {
1627
1637
if (a == null ) a = a4.asInstanceOf [Array [AnyRef ]]
1628
1638
val i = (offset >>> BITS3 ) & MASK
1629
- if (i > 0 ) {
1630
- a = copyOfRange(a, i, WIDTH )
1631
- if (depth == 4 ) a4 = a.asInstanceOf [Arr4 ]
1632
- else aParent(0 ) = a
1639
+ if (depth == 4 ) {
1640
+ if (i > 0 ) System .arraycopy(a, i, a, 0 , WIDTH - i)
1641
+ a4 = a.asInstanceOf [Arr4 ]
1642
+ shrinkOffsetIfToLarge(WIDTH3 )
1643
+ if ((lenRest >>> BITS3 ) == 0 ) depth = 3
1644
+ } else {
1645
+ if (i > 0 ) a = copyOfRange(a, i, WIDTH )
1646
+ aParent(0 ) = a
1633
1647
}
1634
1648
aParent = a
1635
1649
a = a(0 ).asInstanceOf [Array [AnyRef ]]
1636
1650
}
1637
1651
if (depth >= 3 ) {
1638
1652
if (a == null ) a = a3.asInstanceOf [Array [AnyRef ]]
1639
1653
val i = (offset >>> BITS2 ) & MASK
1640
- if (i > 0 ) {
1641
- a = copyOfRange(a, i, WIDTH )
1642
- if (depth == 3 ) a3 = a.asInstanceOf [Arr3 ]
1643
- else aParent(0 ) = a
1654
+ if (depth == 3 ) {
1655
+ if (i > 0 ) System .arraycopy(a, i, a, 0 , WIDTH - i)
1656
+ a3 = a.asInstanceOf [Arr3 ]
1657
+ shrinkOffsetIfToLarge(WIDTH2 )
1658
+ if ((lenRest >>> BITS2 ) == 0 ) depth = 2
1659
+ } else {
1660
+ if (i > 0 ) a = copyOfRange(a, i, WIDTH )
1661
+ aParent(0 ) = a
1644
1662
}
1645
1663
aParent = a
1646
1664
a = a(0 ).asInstanceOf [Array [AnyRef ]]
1647
1665
}
1648
1666
if (depth >= 2 ) {
1649
1667
if (a == null ) a = a2.asInstanceOf [Array [AnyRef ]]
1650
1668
val i = (offset >>> BITS ) & MASK
1651
- if (i > 0 ) {
1652
- a = copyOfRange(a, i, WIDTH )
1653
- if (depth == 2 ) a2 = a.asInstanceOf [Arr2 ]
1654
- else aParent(0 ) = a
1669
+ if (depth == 2 ) {
1670
+ if (i > 0 ) System .arraycopy(a, i, a, 0 , WIDTH - i)
1671
+ a2 = a.asInstanceOf [Arr2 ]
1672
+ shrinkOffsetIfToLarge(WIDTH )
1673
+ if ((lenRest >>> BITS ) == 0 ) depth = 1
1674
+ } else {
1675
+ if (i > 0 ) a = copyOfRange(a, i, WIDTH )
1676
+ aParent(0 ) = a
1655
1677
}
1656
1678
aParent = a
1657
1679
a = a(0 ).asInstanceOf [Array [AnyRef ]]
1658
1680
}
1659
1681
if (depth >= 1 ) {
1660
1682
if (a == null ) a = a1.asInstanceOf [Array [AnyRef ]]
1661
1683
val i = offset & MASK
1662
- if (i > 0 ) {
1663
- a = copyOfRange(a, i, WIDTH )
1664
- if (depth == 1 ) a1 = a.asInstanceOf [Arr1 ]
1665
- else aParent(0 ) = a
1684
+ if (depth == 1 ) {
1685
+ if (i > 0 ) System .arraycopy(a, i, a, 0 , WIDTH - i)
1686
+ a1 = a.asInstanceOf [Arr1 ]
1687
+ len1 -= offset
1688
+ offset = 0
1689
+ } else {
1690
+ if (i > 0 ) a = copyOfRange(a, i, WIDTH )
1691
+ aParent(0 ) = a
1666
1692
}
1667
1693
}
1668
1694
prefixIsRightAligned = false
@@ -1761,15 +1787,13 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] {
1761
1787
slice.foreach(e => addArrN(e.asInstanceOf [Array [AnyRef ]], 5 ))
1762
1788
return
1763
1789
}
1764
- val copy1 = mmin(( BITS * 6 + 1 - lenRest) >>> BITS5 , sl)
1765
- val copy2 = sl - copy1
1790
+ val copy1 = sl
1791
+ // there is no copy2 because there can't be another a6 to copy to
1766
1792
val destPos = lenRest >>> BITS5
1793
+ if (destPos + copy1 > LASTWIDTH )
1794
+ throw new IllegalArgumentException (" exceeding 2^31 elements" )
1767
1795
System .arraycopy(slice, 0 , a6, destPos, copy1)
1768
1796
advanceN(WIDTH5 * copy1)
1769
- if (copy2 > 0 ) {
1770
- System .arraycopy(slice, copy1, a6, 0 , copy2)
1771
- advanceN(WIDTH5 * copy2)
1772
- }
1773
1797
}
1774
1798
}
1775
1799
@@ -1867,8 +1891,7 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] {
1867
1891
if (realLen == 0 ) Vector .empty
1868
1892
else if (len < 0 ) throw new IndexOutOfBoundsException (s " Vector cannot have negative size $len" )
1869
1893
else if (len <= WIDTH ) {
1870
- if (realLen == WIDTH ) new Vector1 (a1)
1871
- else new Vector1 (copyOf(a1, realLen))
1894
+ new Vector1 (copyIfDifferentSize(a1, realLen))
1872
1895
} else if (len <= WIDTH2 ) {
1873
1896
val i1 = (len- 1 ) & MASK
1874
1897
val i2 = (len- 1 ) >>> BITS
0 commit comments