Skip to content

Commit 7c01a17

Browse files
authored
Merge pull request #50 from linasm/skip-zero-words-on-shift-left
BitSet shift left - skip zero words
2 parents 8f64810 + c9e14ab commit 7c01a17

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class BitSetDecorator[+C <: BitSet with BitSetOps[C]](protected val bs: C) {
88
import BitSetOps._
99

1010
/**
11-
* Bitwise left shift of this BitSet by given the shift distance.
11+
* Bitwise left shift of this BitSet by the given shift distance.
1212
* The shift distance may be negative, in which case this method performs a right shift.
1313
* @param shiftBy shift distance, in bits
1414
* @return a new BitSet whose value is a bitwise shift left of this BitSet by given shift distance (`shiftBy`)
@@ -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)