All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.concurrent.stm.skel.AtomicArrayBuilder.scala Maven / Gradle / Ivy

The newest version!
/* scala-stm - (c) 2009-2011, Stanford University, PPL */

package scala.concurrent.stm.skel

import scala.collection.mutable.Builder
import java.util.concurrent.atomic.{AtomicReferenceArray, AtomicLongArray, AtomicIntegerArray}

trait AtomicArrayBuilder[A] extends Builder[A, AtomicArray[A]]

object AtomicArrayBuilder {
  def of[T](m: ClassManifest[T]): Builder[T, AtomicArray[T]] = {
    (m.newArray(0).asInstanceOf[AnyRef] match {
      case x: Array[Boolean] => new ofBoolean
      case x: Array[Byte] => new ofByte
      case x: Array[Short] => new ofShort
      case x: Array[Char] => new ofChar
      case x: Array[Int] => new ofInt
      case x: Array[Float] => new ofFloat
      case x: Array[Long] => new ofLong
      case x: Array[Double] => new ofDouble
      case x: Array[Unit] => new ofUnit
      case x: Array[AnyRef] => new ofRef[AnyRef]
    }).asInstanceOf[AtomicArrayBuilder[T]]
  }

  private val EmptyIntArray = new Array[Int](0)
  private val EmptyLongArray = new Array[Long](0)
  private val EmptyRefArray = new Array[AnyRef](0)

  abstract class IntBacked[T] extends AtomicArrayBuilder[T] {
    protected var elems = EmptyIntArray
    protected var size: Int = 0

    protected def setCapacity(newCap: Int) {
      if (newCap != elems.length) {
        val newElems = new Array[Int](newCap)
        if (size > 0) Array.copy(elems, 0, newElems, 0, size)
        elems = newElems
      }
    }

    override def sizeHint(sizeHint: Int) {
      if (elems.length < sizeHint) setCapacity(sizeHint)
    }

    protected def ensureSpace() {
      val cap = elems.length
      if (size == cap) setCapacity(if (cap == 0) 16 else cap * 2)
    }

    def clear() {
      size = 0
    }
  }

  abstract class LongBacked[T] extends AtomicArrayBuilder[T] {
    protected var elems = EmptyLongArray
    protected var size: Int = 0

    protected def setCapacity(newCap: Int) {
      if (newCap != elems.length) {
        val newElems = new Array[Long](newCap)
        if (size > 0) Array.copy(elems, 0, newElems, 0, size)
        elems = newElems
      }
    }

    override def sizeHint(sizeHint: Int) {
      if (elems.length < sizeHint) setCapacity(sizeHint)
    }

    protected def ensureSpace() {
      val cap = elems.length
      if (size == cap) setCapacity(if (cap == 0) 16 else cap * 2)
    }

    def clear() {
      size = 0
    }
  }


  class ofBoolean extends IntBacked[Boolean] {
    def +=(elem: Boolean): this.type = {
      ensureSpace()
      elems(size) = if (elem) 1 else 0
      size += 1
      this
    }

    def result(): AtomicArray[Boolean] = {
      setCapacity(size)
      new AtomicArray.ofBoolean(new AtomicIntegerArray(elems))
    }
  }

  class ofByte extends IntBacked[Byte] {
    def +=(elem: Byte): this.type = {
      ensureSpace()
      elems(size) = elem
      size += 1
      this
    }

    def result(): AtomicArray[Byte] = {
      setCapacity(size)
      new AtomicArray.ofByte(new AtomicIntegerArray(elems))
    }
  }

  class ofShort extends IntBacked[Short] {
    def +=(elem: Short): this.type = {
      ensureSpace()
      elems(size) = elem
      size += 1
      this
    }

    def result(): AtomicArray[Short] = {
      setCapacity(size)
      new AtomicArray.ofShort(new AtomicIntegerArray(elems))
    }
  }

  class ofChar extends IntBacked[Char] {
    def +=(elem: Char): this.type = {
      ensureSpace()
      elems(size) = elem
      size += 1
      this
    }

    def result(): AtomicArray[Char] = {
      setCapacity(size)
      new AtomicArray.ofChar(new AtomicIntegerArray(elems))
    }
  }

  class ofInt extends IntBacked[Int] {
    def +=(elem: Int): this.type = {
      ensureSpace()
      elems(size) = elem
      size += 1
      this
    }

    def result(): AtomicArray[Int] = {
      setCapacity(size)
      new AtomicArray.ofInt(new AtomicIntegerArray(elems))
    }
  }

  class ofFloat extends IntBacked[Float] {
    def +=(elem: Float): this.type = {
      ensureSpace()
      elems(size) = java.lang.Float.floatToRawIntBits(elem)
      size += 1
      this
    }

    def result(): AtomicArray[Float] = {
      setCapacity(size)
      new AtomicArray.ofFloat(new AtomicIntegerArray(elems))
    }
  }

  class ofLong extends LongBacked[Long] {
    def +=(elem: Long): this.type = {
      ensureSpace()
      elems(size) = elem
      size += 1
      this
    }

    def result(): AtomicArray[Long] = {
      setCapacity(size)
      new AtomicArray.ofLong(new AtomicLongArray(elems))
    }
  }

  class ofDouble extends LongBacked[Double] {
    def +=(elem: Double): this.type = {
      ensureSpace()
      elems(size) = java.lang.Double.doubleToRawLongBits(elem)
      size += 1
      this
    }

    def result(): AtomicArray[Double] = {
      setCapacity(size)
      new AtomicArray.ofDouble(new AtomicLongArray(elems))
    }
  }

  class ofUnit extends AtomicArrayBuilder[Unit] {
    protected var size = 0

    def clear(): Unit = { size = 0 }
    def +=(elem: Unit): this.type = { size += 1; this }
    def result(): AtomicArray[Unit] = new AtomicArray.ofUnit(size)
  }

  class ofRef[T <: AnyRef] extends AtomicArrayBuilder[T] {
    protected var elems = EmptyRefArray
    protected var size: Int = 0

    protected def setCapacity(newCap: Int) {
      if (newCap != elems.length) {
        val newElems = new Array[AnyRef](newCap)
        if (size > 0) Array.copy(elems, 0, newElems, 0, size)
        elems = newElems
      }
    }

    override def sizeHint(sizeHint: Int) {
      if (elems.length < sizeHint) setCapacity(sizeHint)
    }

    protected def ensureSpace() {
      val cap = elems.length
      if (size == cap) setCapacity(if (cap == 0) 16 else cap * 2)
    }

    def clear() {
      size = 0
    }

    def +=(elem: T): this.type = {
      ensureSpace()
      elems(size) = elem
      size += 1
      this
    }

    def result(): AtomicArray[T] = {
      setCapacity(size)
      new AtomicArray.ofRef(new AtomicReferenceArray[AnyRef](elems).asInstanceOf[AtomicReferenceArray[T]])
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy