Skip to content

Commit d4cffcb

Browse files
committed
BitSet shift left - skip zero words
1 parent 2690dbe commit d4cffcb

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

src/main/scala/scala/collection/decorators/BitSetDecorator.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,13 @@ class BitSetDecorator[+C <: BitSet with BitSetOps[C]](protected val bs: C) {
4444
val bitOffset = shiftBy & WordMask
4545
val wordOffset = shiftBy >>> LogWL
4646

47+
var significantWordCount = bs.nwords
48+
while (significantWordCount > 0 && bs.word(significantWordCount - 1) == 0) {
49+
significantWordCount -= 1
50+
}
51+
4752
if (bitOffset == 0) {
48-
val newSize = bs.nwords + wordOffset
53+
val newSize = significantWordCount + wordOffset
4954
require(newSize <= MaxSize)
5055
val newBits = Array.ofDim[Long](newSize)
5156
var i = wordOffset
@@ -56,14 +61,14 @@ class BitSetDecorator[+C <: BitSet with BitSetOps[C]](protected val bs: C) {
5661
newBits
5762
} else {
5863
val revBitOffset = WordLength - bitOffset
59-
val extraBits = bs.word(bs.nwords - 1) >>> revBitOffset
64+
val extraBits = bs.word(significantWordCount - 1) >>> revBitOffset
6065
val extraWordCount = if (extraBits == 0) 0 else 1
61-
val newSize = bs.nwords + wordOffset + extraWordCount
66+
val newSize = significantWordCount + wordOffset + extraWordCount
6267
require(newSize <= MaxSize)
6368
val newBits = Array.ofDim[Long](newSize)
6469
var previous = 0L
6570
var i = 0
66-
while (i < bs.nwords) {
71+
while (i < significantWordCount) {
6772
val current = bs.word(i)
6873
newBits(i + wordOffset) = (previous >>> revBitOffset) | (current << bitOffset)
6974
previous = current

src/test/scala/scala/collection/decorators/BitSetDecoratorTest.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ class BitSetDecoratorTest {
3636
}
3737
}
3838

39+
@Test
40+
def skipZeroWordsOnShiftLeft(): Unit = {
41+
val result = BitSet(5 * 64 - 1) << 64
42+
assertEquals(BitSet(6 * 64 - 1), result)
43+
assertEquals(6, result.nwords)
44+
}
45+
3946
@Test
4047
def shiftEmptyRight(): Unit = {
4148
for (shiftBy <- 0 to 128) {

0 commit comments

Comments
 (0)