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

scala.concurrent.stm.ccstm.CCSTMRefs.scala Maven / Gradle / Ivy

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

package scala.concurrent.stm
package ccstm

import java.util.concurrent.atomic.AtomicLongFieldUpdater

import scala.collection.mutable
import scala.concurrent.stm.compat._  // used
import scala.reflect.ClassTag

private[ccstm] object CCSTMRefs {
  
  trait Factory extends impl.RefFactory {
    def newRef(v0: Boolean): Ref[Boolean] = new BooleanRef(v0)
    def newRef(v0: Byte   ): Ref[Byte   ] = new ByteRef   (v0)
    def newRef(v0: Short  ): Ref[Short  ] = new ShortRef  (v0)
    def newRef(v0: Char   ): Ref[Char   ] = new CharRef   (v0)
    def newRef(v0: Int    ): Ref[Int    ] = new IntRef    (v0)
    def newRef(v0: Float  ): Ref[Float  ] = new FloatRef  (v0)
    def newRef(v0: Long   ): Ref[Long   ] = new LongRef   (v0)
    def newRef(v0: Double ): Ref[Double ] = new DoubleRef (v0)
    def newRef(v0: Unit   ): Ref[Unit   ] = new GenericRef(v0)
    def newRef[T: ClassTag](v0: T): Ref[T]= new GenericRef(v0)

    def newTxnLocal[A](init: => A,
                       initialValue: InTxn => A,
                       beforeCommit: InTxn => Unit,
                       whilePreparing: InTxnEnd => Unit,
                       whileCommitting: InTxnEnd => Unit,
                       afterCommit: A => Unit,
                       afterRollback: Txn.Status => Unit,
                       afterCompletion: Txn.Status => Unit): TxnLocal[A] = new TxnLocalImpl(
        init, initialValue, beforeCommit, whilePreparing, whileCommitting, afterCommit, afterRollback, afterCompletion)

    def newTArray[A: ClassTag](length: Int): TArray[A] = new TArrayImpl[A](length)
    def newTArray[A: ClassTag](xs: IterableOnce[A]): TArray[A] = new TArrayImpl[A](xs)

    def newTMap[A, B]: TMap[A, B] = skel.HashTrieTMap.empty[A, B]
    def newTMapBuilder[A, B]: mutable.Builder[(A, B), TMap[A, B]] = skel.HashTrieTMap.newBuilder[A, B]

    def newTSet[A]: TSet[A] = skel.HashTrieTSet.empty[A]
    def newTSetBuilder[A]: mutable.Builder[A, TSet[A]] = skel.HashTrieTSet.newBuilder[A]
  }

  private abstract class BaseRef[A] extends Handle[A] with RefOps[A] with ViewOps[A] {
    def handle: Handle[A] = this
    def single: Ref.View[A] = this
    def ref: Ref[A] = this
    def base: AnyRef = this
    def metaOffset: Int = 0
    def offset: Int = 0

    override def dbgStr: String = super[RefOps].dbgStr
    override def dbgValue: Any = super[RefOps].dbgValue
  }

  // Every call to AtomicLongFieldUpdater checks the receiver's type with
  // receiver.getClass().isInstanceOf(declaringClass).  This means that there
  // is a substantial performance benefit to putting the meta field in the
  // concrete leaf classes instead of the abstract base class. 

  private val booleanUpdater  = new BooleanRef(false).newMetaUpdater
  private val byteUpdater     = new ByteRef(0: Byte).newMetaUpdater
  private val shortUpdater    = new ShortRef(0: Short).newMetaUpdater
  private val charUpdater     = new CharRef(0: Char).newMetaUpdater
  private val intUpdater      = new IntRef(0: Int).newMetaUpdater
  private val floatUpdater    = new FloatRef(0: Float).newMetaUpdater
  private val longUpdater     = new LongRef(0: Long).newMetaUpdater
  private val doubleUpdater   = new DoubleRef(0: Double).newMetaUpdater
  private val genericUpdater  = new GenericRef("").newMetaUpdater

  private class BooleanRef(@volatile var data: Boolean) extends BaseRef[Boolean] {
    @volatile var meta = 0L
    def metaCAS(m0: Long, m1: Long): Boolean = booleanUpdater.compareAndSet(this, m0, m1)
    def newMetaUpdater: AtomicLongFieldUpdater[BooleanRef] =
      AtomicLongFieldUpdater.newUpdater(classOf[BooleanRef], "meta")
  }

  private class ByteRef(@volatile var data: Byte) extends BaseRef[Byte] {
    @volatile var meta = 0L
    def metaCAS(m0: Long, m1: Long): Boolean = byteUpdater.compareAndSet(this, m0, m1)
    def newMetaUpdater: AtomicLongFieldUpdater[ByteRef] =
      AtomicLongFieldUpdater.newUpdater(classOf[ByteRef], "meta")
  }

  private class ShortRef(@volatile var data: Short) extends BaseRef[Short] {
    @volatile var meta = 0L
    def metaCAS(m0: Long, m1: Long): Boolean = shortUpdater.compareAndSet(this, m0, m1)
    def newMetaUpdater: AtomicLongFieldUpdater[ShortRef] =
      AtomicLongFieldUpdater.newUpdater(classOf[ShortRef], "meta")
  }

  private class CharRef(@volatile var data: Char) extends BaseRef[Char] {
    @volatile var meta = 0L
    def metaCAS(m0: Long, m1: Long): Boolean = charUpdater.compareAndSet(this, m0, m1)
    def newMetaUpdater: AtomicLongFieldUpdater[CharRef] =
      AtomicLongFieldUpdater.newUpdater(classOf[CharRef], "meta")
  }

  private class IntRef(@volatile var data: Int) extends BaseRef[Int] {
    @volatile var meta = 0L
    def metaCAS(m0: Long, m1: Long): Boolean = intUpdater.compareAndSet(this, m0, m1)
    def newMetaUpdater: AtomicLongFieldUpdater[IntRef] =
      AtomicLongFieldUpdater.newUpdater(classOf[IntRef], "meta")

    override def += (rhs: Int)(implicit num: Numeric[Int]): Unit = incr(rhs)
    override def -= (rhs: Int)(implicit num: Numeric[Int]): Unit = incr(-rhs)

    private def incr(delta: Int): Unit =
      if (delta != 0) {
        InTxnImpl.dynCurrentOrNull match {
          case null => NonTxn.getAndAdd(handle, delta)
          case txn => txn.getAndAdd(handle, delta)
        }
      }
  }

  private class FloatRef(@volatile var data: Float) extends BaseRef[Float] {
    @volatile var meta = 0L
    def metaCAS(m0: Long, m1: Long): Boolean = floatUpdater.compareAndSet(this, m0, m1)
    def newMetaUpdater: AtomicLongFieldUpdater[FloatRef] =
      AtomicLongFieldUpdater.newUpdater(classOf[FloatRef], "meta")
  }

  private class LongRef(@volatile var data: Long) extends BaseRef[Long] {
    @volatile var meta = 0L
    def metaCAS(m0: Long, m1: Long): Boolean = longUpdater.compareAndSet(this, m0, m1)
    def newMetaUpdater: AtomicLongFieldUpdater[LongRef] =
      AtomicLongFieldUpdater.newUpdater(classOf[LongRef], "meta")
  }

  private class DoubleRef(@volatile var data: Double) extends BaseRef[Double] {
    @volatile var meta = 0L
    def metaCAS(m0: Long, m1: Long): Boolean = doubleUpdater.compareAndSet(this, m0, m1)
    def newMetaUpdater: AtomicLongFieldUpdater[DoubleRef] =
      AtomicLongFieldUpdater.newUpdater(classOf[DoubleRef], "meta")
  }

  private class GenericRef[A](@volatile var data: A) extends BaseRef[A] {
    @volatile var meta = 0L
    def metaCAS(m0: Long, m1: Long): Boolean = genericUpdater.compareAndSet(this, m0, m1)
    def newMetaUpdater: AtomicLongFieldUpdater[GenericRef[_]] =
      AtomicLongFieldUpdater.newUpdater(classOf[GenericRef[_]], "meta")
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy