@@ -1691,37 +1691,85 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] {
1691
1691
}
1692
1692
}
1693
1693
1694
- private [this ] def arrN (dim : Int ): Array [AnyRef ] = dim match {
1695
- case 1 => a1
1696
- case 2 => a2.asInstanceOf [Array [AnyRef ]]
1697
- case 3 => a3.asInstanceOf [Array [AnyRef ]]
1698
- case 4 => a4.asInstanceOf [Array [AnyRef ]]
1699
- case 5 => a5.asInstanceOf [Array [AnyRef ]]
1700
- case 6 => a6.asInstanceOf [Array [AnyRef ]]
1701
- }
1702
-
1703
1694
private [this ] def addArrN (slice : Array [AnyRef ], dim : Int ): Unit = {
1704
- assert(dim >= 2 )
1695
+ // assert(dim >= 2)
1696
+ // assert(lenRest % WIDTH == 0)
1697
+ // assert(len1 == 0 || len1 == WIDTH)
1705
1698
if (slice.isEmpty) return
1706
1699
if (len1 == WIDTH ) advance()
1707
- val sl = slice.length
1708
- val bits = if (dim == 6 ) BITS * dim + 1 else BITS * dim
1709
- val lBits = BITS * (dim- 1 )
1710
- val width = 1 << bits
1711
- val lWidth = 1 << lBits
1712
- val lowerMask = lWidth - 1
1713
- val mask = if (dim == 6 ) - 1 else MASK
1714
- if ((lenRest & lowerMask) == 0 ) { // lenRest is multiple of lWidth, so the elements of this slice do not need to be split, so they can be reused
1715
- val copy1 = mmin(((width - lenRest) >>> lBits) & mask, sl)
1716
- val copy2 = sl - copy1
1717
- System .arraycopy(slice, 0 , arrN(dim), (lenRest >>> lBits) & MASK , copy1)
1718
- advanceN(lWidth * copy1)
1719
- if (copy2 > 0 ) {
1720
- System .arraycopy(slice, copy1, arrN(dim), 0 , copy2)
1721
- advanceN(lWidth * copy2)
1722
- }
1723
- } else { // this slice does not align, need to try lower dimensions
1724
- slice.foreach(e => addArrN(e.asInstanceOf [Array [AnyRef ]], dim- 1 ))
1700
+ val sl = slice.length
1701
+ (dim : @ switch) match {
1702
+ case 2 =>
1703
+ // lenRest is always a multiple of WIDTH
1704
+ val copy1 = mmin(((WIDTH2 - lenRest) >>> BITS ) & MASK , sl)
1705
+ val copy2 = sl - copy1
1706
+ val destPos = (lenRest >>> BITS ) & MASK
1707
+ System .arraycopy(slice, 0 , a2, destPos, copy1)
1708
+ advanceN(WIDTH * copy1)
1709
+ if (copy2 > 0 ) {
1710
+ System .arraycopy(slice, copy1, a2, 0 , copy2)
1711
+ advanceN(WIDTH * copy2)
1712
+ }
1713
+ case 3 =>
1714
+ if (lenRest % WIDTH2 != 0 ) {
1715
+ // lenRest is not multiple of WIDTH2, so this slice does not align, need to try lower dimension
1716
+ slice.foreach(e => addArrN(e.asInstanceOf [Array [AnyRef ]], 2 ))
1717
+ return
1718
+ }
1719
+ val copy1 = mmin(((WIDTH3 - lenRest) >>> BITS2 ) & MASK , sl)
1720
+ val copy2 = sl - copy1
1721
+ val destPos = (lenRest >>> BITS2 ) & MASK
1722
+ System .arraycopy(slice, 0 , a3, destPos, copy1)
1723
+ advanceN(WIDTH2 * copy1)
1724
+ if (copy2 > 0 ) {
1725
+ System .arraycopy(slice, copy1, a3, 0 , copy2)
1726
+ advanceN(WIDTH2 * copy2)
1727
+ }
1728
+ case 4 =>
1729
+ if (lenRest % WIDTH3 != 0 ) {
1730
+ // lenRest is not multiple of WIDTH3, so this slice does not align, need to try lower dimensions
1731
+ slice.foreach(e => addArrN(e.asInstanceOf [Array [AnyRef ]], 3 ))
1732
+ return
1733
+ }
1734
+ val copy1 = mmin(((WIDTH4 - lenRest) >>> BITS3 ) & MASK , sl)
1735
+ val copy2 = sl - copy1
1736
+ val destPos = (lenRest >>> BITS3 ) & MASK
1737
+ System .arraycopy(slice, 0 , a4, destPos, copy1)
1738
+ advanceN(WIDTH3 * copy1)
1739
+ if (copy2 > 0 ) {
1740
+ System .arraycopy(slice, copy1, a4, 0 , copy2)
1741
+ advanceN(WIDTH3 * copy2)
1742
+ }
1743
+ case 5 =>
1744
+ if (lenRest % WIDTH4 != 0 ) {
1745
+ // lenRest is not multiple of WIDTH4, so this slice does not align, need to try lower dimensions
1746
+ slice.foreach(e => addArrN(e.asInstanceOf [Array [AnyRef ]], 4 ))
1747
+ return
1748
+ }
1749
+ val copy1 = mmin(((WIDTH5 - lenRest) >>> BITS4 ) & MASK , sl)
1750
+ val copy2 = sl - copy1
1751
+ val destPos = (lenRest >>> BITS4 ) & MASK
1752
+ System .arraycopy(slice, 0 , a5, destPos, copy1)
1753
+ advanceN(WIDTH4 * copy1)
1754
+ if (copy2 > 0 ) {
1755
+ System .arraycopy(slice, copy1, a5, 0 , copy2)
1756
+ advanceN(WIDTH4 * copy2)
1757
+ }
1758
+ case 6 => // note width is now LASTWIDTH
1759
+ if (lenRest % WIDTH5 != 0 ) {
1760
+ // lenRest is not multiple of WIDTH5, so this slice does not align, need to try lower dimensions
1761
+ slice.foreach(e => addArrN(e.asInstanceOf [Array [AnyRef ]], 5 ))
1762
+ return
1763
+ }
1764
+ val copy1 = mmin((BITS * 6 + 1 - lenRest) >>> BITS5 , sl)
1765
+ val copy2 = sl - copy1
1766
+ val destPos = lenRest >>> BITS5
1767
+ System .arraycopy(slice, 0 , a6, destPos, copy1)
1768
+ advanceN(WIDTH5 * copy1)
1769
+ if (copy2 > 0 ) {
1770
+ System .arraycopy(slice, copy1, a6, 0 , copy2)
1771
+ advanceN(WIDTH5 * copy2)
1772
+ }
1725
1773
}
1726
1774
}
1727
1775
0 commit comments