Due to a performance profiling hotspot detailed here, I implemented my own BitSet
using Java's BitSet
. This is intended to replace the Enumeration.ValueSet
. However, it's a bit awkward to use, primarily due to my likely misunderstanding of the relationships between the Enumeration
class, Enumeration
type and concrete Enumeration
object.
In my enumeration objects, I have to have code like this:
type BitSet = alder.BitSet[this.type]
val empty = alder.BitSet[this.type]()
Elsewhere, I need to do things like this:
alder.BitSet.fromBitMask[SomeEnumeration.type](...)
For mkString
I need to actually pass in the enumeration object itself. Is there any way to make this entire edifice a little more user-friendly?
package alder
import scala.language.implicitConversions
class BitSet[E <: Enumeration](val bits: java.util.BitSet) {
def isEmpty: Boolean = bits.isEmpty
def nonEmpty: Boolean = !isEmpty
override def hashCode = bits.hashCode
override def equals(o: Any) = o match {
case that: BitSet[E] => this.bits equals that.bits
case _ => false
}
def union(that: BitSet[E]): BitSet[E] = {
var newBits = bits
newBits.or(that.bits)
new BitSet[E](newBits)
}
def |(that: BitSet[E]): BitSet[E] = union(that)
def |(v: E#Value): BitSet[E] = union(BitSet(v))
def intersection(that: BitSet[E]): BitSet[E] = {
var newBits = bits
newBits.and(that.bits)
new BitSet(newBits)
}
def &(that: BitSet[E]): BitSet[E] = intersection(that)
def &(v: E#Value): BitSet[E] = intersection(BitSet(v))
def contains(v: E#Value): Boolean = bits.get(v.id)
def containsAll(that: BitSet[E]): Boolean = intersection(that) == that
def containsAny(that: BitSet[E]): Boolean = intersection(that).nonEmpty
def toBitMask(): Array[Long] = bits.toLongArray
def mkString(e: E, sep: String): String =
{
val vs = e.ValueSet.fromBitMask(toBitMask())
vs.mkString(sep)
}
}
object BitSet {
def apply[E <: Enumeration](): BitSet[E] = new BitSet[E](new java.util.BitSet)
def apply[E <: Enumeration](vs: E#Value*): BitSet[E] = {
var bits = new java.util.BitSet
for (v <- vs) {
bits.set(v.id)
}
new BitSet[E](bits)
}
def fromBitMask[E <: Enumeration](mask: Array[Long]): BitSet[E] =
new BitSet[E](java.util.BitSet.valueOf(mask))
}