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 java.util.concurrent.atomic.{AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray}

import scala.collection.mutable
import scala.reflect.ClassTag

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

object AtomicArrayBuilder {
  def of[T](m: ClassTag[T]): mutable.Builder[T, AtomicArray[T]] = {
    (m.newArray(0).asInstanceOf[AnyRef] match {
      case _: Array[Boolean]  => new ofBoolean
      case _: Array[Byte]     => new ofByte
      case _: Array[Short]    => new ofShort
      case _: Array[Char]     => new ofChar
      case _: Array[Int]      => new ofInt
      case _: Array[Float]    => new ofFloat
      case _: Array[Long]     => new ofLong
      case _: Array[Double]   => new ofDouble
      case _: Array[Unit]     => new ofUnit
      case _: 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: Array[Int] = EmptyIntArray
    protected var size: Int = 0

    protected def setCapacity(newCap: Int): Unit =
      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): Unit =
      if (elems.length < sizeHint) setCapacity(sizeHint)

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

    def clear(): Unit =
      size = 0
  }

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

    protected def setCapacity(newCap: Int): Unit =
      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): Unit =
      if (elems.length < sizeHint) setCapacity(sizeHint)

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

    def clear(): Unit =
      size = 0
  }


  class ofBoolean extends IntBacked[Boolean] {
    def addOne(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 addOne(elem: Byte): this.type = {
      ensureSpace()
      elems(size) = elem.toInt
      size += 1
      this
    }

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

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

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

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

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

  class ofInt extends IntBacked[Int] {
    def addOne(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 addOne(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 addOne(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 addOne(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 addOne(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: Array[AnyRef] = EmptyRefArray
    protected var size: Int = 0

    protected def setCapacity(newCap: Int): Unit = {
      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): Unit = {
      if (elems.length < sizeHint) setCapacity(sizeHint)
    }

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

    def clear(): Unit =
      size = 0

    def addOne(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