10000 Replace (Par)TrieMap with ConcurrentHashMap in IncOptimizer by gzm0 · Pull Request #4974 · scala-js/scala-js · GitHub
[go: up one dir, main page]

Skip to content

Replace (Par)TrieMap with ConcurrentHashMap in IncOptimizer #4974

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

package java.util.concurrent

import java.util.function.{BiConsumer, Consumer}

import java.io.Serializable
import java.util._

Expand Down Expand Up @@ -72,6 +74,22 @@ class ConcurrentHashMap[K, V] private (initialCapacity: Int, loadFactor: Float)
new ConcurrentHashMap.KeySetView[K, V](this.inner, mappedValue)
}

def forEach(parallelismThreshold: Long, action: BiConsumer[_ >: K, _ >: V]): Unit = {
// Note: It is tempting to simply call inner.forEach here:
// However, this will not have the correct snapshotting behavior.
val i = inner.nodeIterator()
while (i.hasNext()) {
val n = i.next()
action.accept(n.key, n.value)
}
10000 }

def forEachKey(parallelismThreshold: Long, action: Consumer[_ >: K]): Unit =
inner.keyIterator().forEachRemaining(action)

def forEachValue(parallelismThreshold: Long, action: Consumer[_ >: V]): Unit =
inner.valueIterator().forEachRemaining(action)

override def values(): Collection[V] =
inner.values()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,20 @@ package org.scalajs.linker.frontend.optimizer

import scala.annotation.tailrec

import scala.collection.concurrent.TrieMap
import scala.collection.parallel.mutable.{ParTrieMap, ParArray}
import scala.collection.parallel.mutable.ParArray
import scala.collection.parallel._

import java.util.concurrent.atomic._

private[optimizer] object ParCollOps extends AbsCollOps {
type Map[K, V] = TrieMap[K, V]
type ParMap[K, V] = ParTrieMap[K, V]
type AccMap[K, V] = TrieMap[K, Addable[V]]
type ParIterable[V] = ParArray[V]
type Addable[V] = AtomicReference[List[V]]

def emptyAccMap[K, V]: AccMap[K, V] = TrieMap.empty
def emptyMap[K, V]: Map[K, V] = TrieMap.empty
def emptyParMap[K, V]: ParMap[K, V] = ParTrieMap.empty
def parThreshold: Long = 1 // max parallelism

def emptyParIterable[V]: ParIterable[V] = ParArray.empty
def emptyAddable[V]: Addable[V] = new AtomicReference[List[V]](Nil)

// Operations on ParMap
def isEmpty[K, V](map: ParMap[K, V]): Boolean = map.isEmpty
def forceGet[K, V](map: ParMap[K, V], k: K): V = map(k)
def get[K, V](map: ParMap[K, V], k: K): Option[V] = map.get(k)
def put[K, V](map: ParMap[K, V], k: K, v: V): Unit = map.put(k, v)
def remove[K, V](map: ParMap[K, V], k: K): Option[V] = map.remove(k)

def retain[K, V](map: ParMap[K, V])(p: (K, V) => Boolean): Unit = {
map.foreach { case (k, v) =>
if (!p(k, v))
map.remove(k)
}
}

def valuesForeach[K, V, U](map: ParMap[K, V])(f: V => U): Unit =
map.values.foreach(f)

// Operations on AccMap
def acc[K, V](map: AccMap[K, V], k: K, v: V): Unit =
add(map.getOrElseUpdate(k, emptyAddable), v)

def getAcc[K, V](map: AccMap[K, V], k: K): ParIterable[V] =
map.get(k).fold(emptyParIterable[V])(finishAdd(_))

def parFlatMapKeys[A, B](map: AccMap[A, _])(f: A => Option[B]): ParIterable[B] =
map.keys.flatMap(f(_)).toParArray

// Operations on ParIterable
def prepAdd[V](it: ParIterable[V]): Addable[V] =
new AtomicReference(it.toList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,15 @@ package org.scalajs.linker.frontend.optimizer

import language.higherKinds

import scala.collection.mutable

private[optimizer] trait AbsCollOps {
type Map[K, V] <: mutable.Map[K, V]
type ParMap[K, V] <: AnyRef
type AccMap[K, V] <: AnyRef
type ParIterable[V] <: AnyRef
type Addable[V] <: AnyRef

def emptyAccMap[K, V]: AccMap[K, V]
def emptyMap[K, V]: Map[K, V]
def emptyParMap[K, V]: ParMap[K, V]
def parThreshold: Long

def emptyParIterable[V]: ParIterable[V]
def emptyAddable[V]: Addable[V]

// Operations on ParMap
def isEmpty[K, V](map: ParMap[K, V]): Boolean
def forceGet[K, V](map: ParMap[K, V], k: K): V
def get[K, V](map: ParMap[K, V], k: K): Option[V]
def put[K, V](map: ParMap[K, V], k: K, v: V): Unit
def remove[K, V](map: ParMap[K, V], k: K): Option[V]
def retain[K, V](map: ParMap[K, V])(p: (K, V) => Boolean): Unit
def valuesForeach[K, V, U](map: ParMap[K, V])(f: V => U): Unit

// Operations on AccMap
def acc[K, V](map: AccMap[K, V], k: K, v: V): Unit
def getAcc[K, V](map: AccMap[K, V], k: K): ParIterable[V]
def parFlatMapKeys[A, B](map: AccMap[A, _])(f: A => Option[B]): ParIterable[B]

// Operations on ParIterable
def prepAdd[V](it: ParIterable[V]): Addable[V]
def add[V](addable: Addable[V], v: V): Unit
Expand Down
Loading
0