summaryrefslogtreecommitdiff
path: root/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ConcurrencyUtils.scala
diff options
context:
space:
mode:
Diffstat (limited to 'tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ConcurrencyUtils.scala')
-rw-r--r--tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ConcurrencyUtils.scala74
1 files changed, 74 insertions, 0 deletions
diff --git a/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ConcurrencyUtils.scala b/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ConcurrencyUtils.scala
new file mode 100644
index 0000000..471ed65
--- /dev/null
+++ b/tools/jvm/src/main/scala/scala/scalajs/tools/optimizer/ConcurrencyUtils.scala
@@ -0,0 +1,74 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js tools **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.tools.optimizer
+
+import scala.annotation.tailrec
+
+import scala.collection.concurrent.TrieMap
+
+import java.util.concurrent.atomic._
+
+private[optimizer] object ConcurrencyUtils {
+
+ /** An atomic accumulator supports adding single elements and retrieving and
+ * deleting all contained elements */
+ type AtomicAcc[T] = AtomicReference[List[T]]
+
+ object AtomicAcc {
+ @inline final def empty[T]: AtomicAcc[T] =
+ new AtomicReference[List[T]](Nil)
+ @inline final def apply[T](l: List[T]): AtomicAcc[T] =
+ new AtomicReference(l)
+ }
+
+ implicit class AtomicAccOps[T](val acc: AtomicAcc[T]) extends AnyVal {
+ @inline final def size: Int = acc.get.size
+
+ @inline
+ final def +=(x: T): Unit = AtomicAccOps.append(acc, x)
+
+ @inline
+ final def removeAll(): List[T] = AtomicAccOps.removeAll(acc)
+ }
+
+ object AtomicAccOps {
+ @inline
+ @tailrec
+ private final def append[T](acc: AtomicAcc[T], x: T): Boolean = {
+ val oldV = acc.get
+ val newV = x :: oldV
+ acc.compareAndSet(oldV, newV) || append(acc, x)
+ }
+
+ @inline
+ private final def removeAll[T](acc: AtomicAcc[T]): List[T] =
+ acc.getAndSet(Nil)
+ }
+
+ type TrieSet[T] = TrieMap[T, Null]
+
+ implicit class TrieSetOps[T](val set: TrieSet[T]) extends AnyVal {
+ @inline final def +=(x: T): Unit = set.put(x, null)
+ }
+
+ object TrieSet {
+ @inline final def empty[T]: TrieSet[T] = TrieMap.empty
+ }
+
+ implicit class TrieMapOps[K,V](val map: TrieMap[K,V]) extends AnyVal {
+ @inline final def getOrPut(k: K, default: => V): V = {
+ map.get(k).getOrElse {
+ val v = default
+ map.putIfAbsent(k, v).getOrElse(v)
+ }
+ }
+ }
+
+}