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

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

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

package scala.concurrent.stm.ccstm

import annotation.tailrec


/** This is basically a specialized builder for a map from `Handle` to
 *  `Version`. 
 *
 *  @author Nathan Bronson
 */
private[ccstm] final class RetrySetBuilder {
  private var _size = 0
  private var _handles = new Array[Handle[_]](maxSizeForCap(InitialCap) + 1)
  private var _versions = new Array[CCSTM.Version](maxSizeForCap(InitialCap) + 1)
  private var _next = new Array[Int](maxSizeForCap(InitialCap) + 1)
  private var _dispatch = new Array[Int](InitialCap)

  private final val InitialCap = 16
  private def maxSizeForCap(cap: Int) = cap - (cap / 4)

  def size = _size

  def += (handle: Handle[_], version: CCSTM.Version) {
    val slot = CCSTM.hash(handle.base, handle.offset) & (_dispatch.length - 1)
    addImpl(slot, _dispatch(slot), handle, version)
  }

  @tailrec
  private def addImpl(slot: Int, i: Int, handle: Handle[_], version: CCSTM.Version) {
    if (i == 0)
      append(slot, handle, version)
    else if (!hEq(_handles(i - 1), handle))
      addImpl(slot, _next(i - 1), handle, version)
    // else it is a duplicate
  }

  private def append(slot: Int, handle: Handle[_], version: CCSTM.Version) {
    val i = _size + 1
    _size = i
    _handles(i - 1) = handle
    _versions(i - 1) = version
    _next(i - 1) = _dispatch(slot)
    _dispatch(slot) = i
    if (_size > maxSizeForCap(_dispatch.length))
      grow()
  }

  private def grow() {
    // store the current contents
    val s = _size
    val hh = _handles
    val vv = _versions

    // reallocate
    _size = 0
    val c = _dispatch.length * 2
    _handles = new Array[Handle[_]](maxSizeForCap(c) + 1)
    _versions = new Array[CCSTM.Version](maxSizeForCap(c) + 1)
    _next = new Array[Int](maxSizeForCap(c) + 1)
    _dispatch = new Array[Int](c)

    // reinsert the current contents
    var i = 0
    while (i < s) {
      val h = hh(i)
      append(CCSTM.hash(h.base, h.offset) & (c - 1), h, vv(i))
      i += 1
    }
  }

  private def hEq(a: Handle[_], b: Handle[_]) = (a eq b) || ((a.base eq b.base) && (a.offset == b.offset))

  def result(): RetrySet = {
    _dispatch = null
    _next = null
    new RetrySet(_size, _handles, _versions)
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy