Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Due to a performance profiling hot spot detailed in http://stackoverflow.com/questions/27632554/scala-enumeration-valueset-slow-replacement-based-on-java-bitset , 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))

}
share|improve this question
    
This code review was originally part of stackoverflow.com/questions/27632554/… –  experquisite Dec 24 '14 at 19:09
    
Can anyone give me any pointers on how to improve this, please? –  experquisite Dec 30 '14 at 4:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.