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

scala.concurrent.stm.SourceLike.scala Maven / Gradle / Ivy

/* scala-stm - (c) 2009-2010, Stanford University, PPL */

package scala.concurrent.stm


/** Provides all of the operations of a `Source[A]`, without the ability to get
 *  a `Source.View`.
 *
 *  @author Nathan Bronson
 */
trait SourceLike[+A, Context] {

  /** Performs a transactional read and checks that it is consistent with all
   *  reads already made by `txn`.  Equivalent to `get`.
   *
   *  Example: {{{
   *    val x = Ref(0)
   *    atomic { implicit t =>
   *      ...
   *      val v = x() // perform a read inside a transaction
   *      ...
   *    }
   *  }}}
   *  @param txn an active transaction.
   *  @return the value of the `Ref` as observed by `txn`.
   *  @throws IllegalStateException if `txn` is not active.
   */
  def apply()(implicit txn: Context): A = get
  
  /** Performs a transactional read and checks that it is consistent with all
   *  reads already made by `txn`.  Equivalent to `apply()`, which is more
   *  concise in many situations.
   *  @param txn an active transaction.
   *  @return the value of the `Ref` as observed by `txn`.
   *  @throws IllegalStateException if `txn` is not active.
   */
  def get(implicit txn: Context): A

  /** Returns `f(get)`, possibly reevaluating `f` to avoid rollback if a
   *  conflicting change is made but the old and new values are equal after
   *  application of `f`.  Requires that `f(x) == f(y)` if `x == y`.
   *
   *  `getWith(f)` is equivalent to `f(relaxedGet({ f(_) == f(_) }))`, although
   *  perhaps more efficient.
   *  @param f an idempotent function.
   *  @return the result of applying `f` to the value contained in this `Ref`.
   */
  def getWith[Z](f: A => Z)(implicit txn: Context): Z

  /** Returns the same value as `get`, but allows the caller to determine
   *  whether `txn` should be rolled back if another thread changes the value
   *  of this `Ref` before `txn` is committed.  If `ref.relaxedGet(equiv)`
   *  returns `v0` in `txn`, another context changes `ref` to `v1`, and
   *  `equiv(v0, v1) == true`, then `txn` won't be required to roll back (at
   *  least not due to this read).  If additional changes are made to `ref`
   *  additional calls to the equivalence function will be made, always with
   *  `v0` as the first parameter.
   *
   *  `equiv` will always be invoked on the current thread.  Extreme care
   *  should be taken if the equivalence function accesses any `Ref`s.
   *
   *  As an example, to perform a read that will not be validated during commit
   *  you can use the maximally permissive equivalence function: {{{
   *    val unvalidatedValue = ref.relaxedGet({ (_, _) => true })
   *  }}}
   *  To check view serializability rather than conflict serializability for a
   *  read: {{{
   *    val viewSerializableValue = ref.relaxedGet({ _ == _ })
   *  }}}
   *  The `getWith` method provides related functionality.
   *  @param equiv an equivalence function that returns true if a transaction
   *      that observed the first argument will still complete correctly,
   *      where the second argument is the actual value that should have been
   *      observed.
   *  @return a value of the `Ref`, not necessary consistent with the rest of
   *      the reads performed by `txn`.
   */
  def relaxedGet(equiv: (A, A) => Boolean)(implicit txn: Context): A
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy