Skip to content

Commit baa73f9

Browse files
committed
expand bit-manipulations to switch in Vector.addArrN
1 parent 379833f commit baa73f9

File tree

1 file changed

+76
-28
lines changed

1 file changed

+76
-28
lines changed

library/src/scala/collection/immutable/Vector.scala

Lines changed: 76 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,37 +1691,85 @@ final class VectorBuilder[A] extends ReusableBuilder[A, Vector[A]] {
16911691
}
16921692
}
16931693

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-
17031694
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)
17051698
if (slice.isEmpty) return
17061699
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+
}
17251773
}
17261774
}
17271775

0 commit comments

Comments
 (0)