diff --git a/package-lock.json b/package-lock.json index 7c5355ceb9..69951c8a6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,39 +1,5 @@ { - "name": "cats-effect", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "devDependencies": { - "source-map-support": "^0.5.19" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - }, + "lockfileVersion": 1, "dependencies": { "buffer-from": { "version": "1.1.2", diff --git a/std/shared/src/main/scala/cats/effect/std/MapRef.scala b/std/shared/src/main/scala/cats/effect/std/MapRef.scala index 17b8d4ac97..69b6dd80d2 100644 --- a/std/shared/src/main/scala/cats/effect/std/MapRef.scala +++ b/std/shared/src/main/scala/cats/effect/std/MapRef.scala @@ -45,6 +45,22 @@ trait MapRef[F[_], K, V] extends Function1[K, Ref[F, V]] { object MapRef extends MapRefCompanionPlatform { + /** + * the default Constructor for MapRef. + * If Async is available, it will use a ConcurrentHashMap, otherwise it will use a sharded immutable map. + */ + def apply[F[_]: Concurrent, K, V](): F[MapRef[F, K, Option[V]]] = { + + Concurrent[F] match { + case a: Async[_] => + implicit val async: Async[F] = a + ofConcurrentHashMap() + case _ => + ofShardedImmutableMap[F, K, V](Runtime.getRuntime.availableProcessors()) + } + + } + /** * Creates a sharded map ref to reduce atomic contention on the Map, given an efficient and * equally distributed hash, the contention should allow for interaction like a general diff --git a/tests/shared/src/test/scala/cats/effect/std/MapRefSpec.scala b/tests/shared/src/test/scala/cats/effect/std/MapRefSpec.scala index 2ee9166631..9a8cdf4886 100644 --- a/tests/shared/src/test/scala/cats/effect/std/MapRefSpec.scala +++ b/tests/shared/src/test/scala/cats/effect/std/MapRefSpec.scala @@ -16,18 +16,27 @@ package cats.effect.std -import cats._ +import cats.* import cats.data.State -import cats.effect._ -import cats.implicits._ +import cats.effect.* +import cats.effect.unsafe.implicits.global +import cats.implicits.* -import scala.concurrent.duration._ +import java.util.concurrent.ConcurrentHashMap +import scala.concurrent.duration.* class MapRefSpec extends BaseSpec { private val smallDelay: IO[Unit] = IO.sleep(20.millis) private def awaitEqual[A: Eq](t: IO[A], success: A): IO[Unit] = t.flatMap(a => if (Eq[A].eqv(a, success)) IO.unit else smallDelay *> awaitEqual(t, success)) + "MapRef[Async]()" should { + "be instance of ConcurrentHashMap" in real { + val mapRef = MapRef[IO,Int, Int]().unsafeRunSync() + mapRef.isInstanceOf[ConcurrentHashMap[ Int, Int]] must_=== true + + } + } "MapRef.ofSingleImmutableMapRef" should { "concurrent modifications" in real {