summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/immutable/BitSet.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/library/scala/collection/immutable/BitSet.scala')
-rw-r--r--src/library/scala/collection/immutable/BitSet.scala41
1 files changed, 36 insertions, 5 deletions
diff --git a/src/library/scala/collection/immutable/BitSet.scala b/src/library/scala/collection/immutable/BitSet.scala
index 70543aa3a6..ecf3326c7f 100644
--- a/src/library/scala/collection/immutable/BitSet.scala
+++ b/src/library/scala/collection/immutable/BitSet.scala
@@ -14,7 +14,7 @@ package immutable
import generic._
import BitSetLike.{LogWL, updateArray}
-import mutable.{ Builder, SetBuilder }
+import mutable.Builder
/** A class for immutable bitsets.
* $bitsetinfo
@@ -68,6 +68,8 @@ object BitSet extends BitSetFactory[BitSet] {
/** The empty bitset */
val empty: BitSet = new BitSet1(0L)
+ private def createSmall(a: Long, b: Long): BitSet = if (b == 0L) new BitSet1(a) else new BitSet2(a, b)
+
/** A builder that takes advantage of mutable BitSets. */
def newBuilder: Builder[Int, BitSet] = new Builder[Int, BitSet] {
private[this] val b = new mutable.BitSet
@@ -84,7 +86,7 @@ object BitSet extends BitSetFactory[BitSet] {
val len = elems.length
if (len == 0) empty
else if (len == 1) new BitSet1(elems(0))
- else if (len == 2) new BitSet2(elems(0), elems(1))
+ else if (len == 2) createSmall(elems(0), elems(1))
else {
val a = new Array[Long](len)
Array.copy(elems, 0, a, 0, len)
@@ -99,17 +101,24 @@ object BitSet extends BitSetFactory[BitSet] {
val len = elems.length
if (len == 0) empty
else if (len == 1) new BitSet1(elems(0))
- else if (len == 2) new BitSet2(elems(0), elems(1))
+ else if (len == 2) createSmall(elems(0), elems(1))
else new BitSetN(elems)
}
+ @SerialVersionUID(2260107458435649300L)
class BitSet1(val elems: Long) extends BitSet {
protected def nwords = 1
protected def word(idx: Int) = if (idx == 0) elems else 0L
protected def updateWord(idx: Int, w: Long): BitSet =
if (idx == 0) new BitSet1(w)
- else if (idx == 1) new BitSet2(elems, w)
+ else if (idx == 1) createSmall(elems, w)
else fromBitMaskNoCopy(updateArray(Array(elems), idx, w))
+ override def head: Int =
+ if (elems == 0L) throw new NoSuchElementException("Empty BitSet")
+ else java.lang.Long.numberOfTrailingZeros(elems)
+ override def tail: BitSet =
+ if (elems == 0L) throw new NoSuchElementException("Empty BitSet")
+ else new BitSet1(elems - java.lang.Long.lowestOneBit(elems))
}
class BitSet2(val elems0: Long, elems1: Long) extends BitSet {
@@ -117,8 +126,20 @@ object BitSet extends BitSetFactory[BitSet] {
protected def word(idx: Int) = if (idx == 0) elems0 else if (idx == 1) elems1 else 0L
protected def updateWord(idx: Int, w: Long): BitSet =
if (idx == 0) new BitSet2(w, elems1)
- else if (idx == 1) new BitSet2(elems0, w)
+ else if (idx == 1) createSmall(elems0, w)
else fromBitMaskNoCopy(updateArray(Array(elems0, elems1), idx, w))
+ override def head: Int =
+ if (elems0 == 0L) {
+ if (elems1 == 0) throw new NoSuchElementException("Empty BitSet")
+ 64 + java.lang.Long.numberOfTrailingZeros(elems1)
+ }
+ else java.lang.Long.numberOfTrailingZeros(elems0)
+ override def tail: BitSet =
+ if (elems0 == 0L) {
+ if (elems1 == 0L) throw new NoSuchElementException("Empty BitSet")
+ createSmall(elems0, elems1 - java.lang.Long.lowestOneBit(elems1))
+ }
+ else new BitSet2(elems0 - java.lang.Long.lowestOneBit(elems0), elems1)
}
/** The implementing class for bit sets with elements >= 128 (exceeding
@@ -131,5 +152,15 @@ object BitSet extends BitSetFactory[BitSet] {
protected def nwords = elems.length
protected def word(idx: Int) = if (idx < nwords) elems(idx) else 0L
protected def updateWord(idx: Int, w: Long): BitSet = fromBitMaskNoCopy(updateArray(elems, idx, w))
+ override def tail: BitSet = {
+ val n = nwords
+ var i = 0
+ while (i < n) {
+ val wi = word(i)
+ if (wi != 0L) return fromBitMaskNoCopy(updateArray(elems, i, wi - java.lang.Long.lowestOneBit(wi)))
+ i += 1
+ }
+ throw new NoSuchElementException("Empty BitSet")
+ }
}
}