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

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

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

package scala.concurrent.stm

import scala.collection.mutable.Set
import scala.collection.{IterableFactory, IterableFactoryDefaults, immutable, mutable}
import scala.language.implicitConversions

object TSet extends IterableFactory[TSet] {

  object View extends IterableFactory[TSet.View] {

    override def empty[A]: View[A] = TSet.empty[A].single

    override def newBuilder[A]: mutable.Builder[A, View[A]] = TSet.newBuilder[A].mapResult(_.single)

    def from[A](it: IterableOnce[A]): TSet.View[A] = TSet.from(it).single
  }

  /** A `Set` that provides atomic execution of all of its methods. */
  trait View[A] extends mutable.Set[A]
    with mutable.SetOps[A, TSet.View, TSet.View[A]]
    with IterableFactoryDefaults[A, TSet.View]
    with TxnDebuggable {

    /** Returns the `TSet` perspective on this transactional set, which
     *  provides set functionality only inside atomic blocks.
     */
    def tset: TSet[A]

    def clone: TSet.View[A]

    /** Takes an atomic snapshot of this transactional set. */
    def snapshot: immutable.Set[A]

    override def empty: View[A] = TSet.empty[A].single

    override def iterableFactory: IterableFactory[TSet.View] = TSet.View

    override def className = "TSet"
  }


  /** Constructs and returns a new empty `TSet`. */
  def empty[A]: TSet[A] = impl.STMImpl.instance.newTSet[A]

  /** Returns a builder of `TSet`. */
  def newBuilder[A]: mutable.Builder[A, TSet[A]] = impl.STMImpl.instance.newTSetBuilder[A]

  /** Constructs and returns a new `TSet` that will contain the elements from
   *  `it`.
   */
  def from[A](it: IterableOnce[A]): TSet[A] = {
    val b = TSet.newBuilder[A]
    val sizeHint = it.knownSize
    if (sizeHint >= 0)
      b.sizeHint(sizeHint)
    b ++= it
    b.result()
  }


  /** Allows a `TSet` in a transactional context to be used as a `Set`. */
  implicit def asSet[A](s: TSet[A])(implicit txn: InTxn): View[A] = s.single
}


/** A transactional set implementation that requires that all of its set-like
 *  operations be called from inside an atomic block.  Rather than extending
 *  `Set`, an implicit conversion is provided from `TSet` to `Set` if the
 *  current scope is part of an atomic block (see `TSet.asSet`).
 *
 *  The elements (with type `A`) must be immutable, or at least not modified
 *  while they are in the set.  The `TSet` implementation assumes that it can
 *  safely perform equality and hash checks outside a transaction without
 *  affecting atomicity.
 *
 *  @author Nathan Bronson
 */
trait TSet[A] extends TxnDebuggable {

  /** Returns an instance that provides transactional set functionality without
   *  requiring that operations be performed inside the static scope of an
   *  atomic block.
   */
  def single: TSet.View[A]

  def clone(implicit txn: InTxn): TSet[A] = single.clone.tset

  // Fast snapshots are one of TSet's core features, so we don't want the
  // implicit conversion to hide it from ScalaDoc and IDE completion
  def snapshot: immutable.Set[A] = single.snapshot

  // The following methods work fine via the asSet mechanism, but are heavily
  // used.  We add transactional versions of them to allow overrides.

  def isEmpty(implicit txn: InTxn): Boolean
  def size(implicit txn: InTxn): Int
  def foreach[U](f: A => U)(implicit txn: InTxn): Unit
  def contains(elem: A)(implicit txn: InTxn): Boolean
  def apply(elem: A)(implicit txn: InTxn): Boolean = contains(elem)
  def add(elem: A)(implicit txn: InTxn): Boolean
  def update(elem: A, included: Boolean)(implicit txn: InTxn): Unit = if (included) add(elem) else remove(elem)
  def remove(elem: A)(implicit txn: InTxn): Boolean

  // The following methods return the wrong receiver when invoked via the asSet
  // conversion.  They are exactly the methods of mutable.Set whose return type
  // is this.type.

  def += (x: A)(implicit txn: InTxn): this.type = { add(x) ; this }
  @deprecated("use ++=", "0.8")
  def += (x1: A, x2: A, xs: A*)(implicit txn: InTxn): this.type = { this += x1 += x2 ++= xs }
  def ++= (xs: IterableOnce[A])(implicit txn: InTxn): this.type = { for (x <- xs.iterator) this += x ; this }
  def -= (x: A)(implicit txn: InTxn): this.type = { remove(x) ; this }
  @deprecated("use --=", "0.8")
  def -= (x1: A, x2: A, xs: A*)(implicit txn: InTxn): this.type = { this -= x1 -= x2 --= xs }
  def --= (xs: IterableOnce[A])(implicit txn: InTxn): this.type = { for (x <- xs.iterator) this -= x ; this }

  @deprecated("Use .filterInPlace instead of .retain", "0.8")
  @`inline` final def retain(p: A => Boolean)(implicit txn: InTxn): this.type = filterInPlace(p)

  def filterInPlace(p: A => Boolean)(implicit txn: InTxn): this.type
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy