Skip to content

Commit

Permalink
SystemProperties is a MapRef
Browse files Browse the repository at this point in the history
  • Loading branch information
armanbilge committed Oct 31, 2024
1 parent 51c219f commit 99de034
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 48 deletions.
14 changes: 11 additions & 3 deletions std/shared/src/main/scala/cats/effect/std/MapRef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import cats.data._
import cats.effect.kernel._
import cats.syntax.all._

import java.util.Hashtable
import java.util.concurrent.ConcurrentHashMap

/**
Expand All @@ -34,12 +35,15 @@ import java.util.concurrent.ConcurrentHashMap
* concurrent updates may be executed independently to each other, as long as their keys belong
* to different shards.
*/
trait MapRef[F[_], K, V] extends Function1[K, Ref[F, V]] {
trait MapRef[F[_], K, V] extends Function1[K, Ref[F, V]] { outer =>

/**
* Access the reference for this Key
*/
def apply(k: K): Ref[F, V]

def mapK[G[_]](f: F ~> G)(implicit G: Functor[G]): MapRef[G, K, V] =
outer(_).mapK(f)
}

object MapRef extends MapRefCompanionPlatform {
Expand Down Expand Up @@ -123,7 +127,7 @@ object MapRef extends MapRefCompanionPlatform {
ref: Ref[F, Map[K, V]]): MapRef[F, K, Option[V]] =
k => Ref.lens(ref)(_.get(k), m => _.fold(m - k)(v => m + (k -> v)))

private class ConcurrentHashMapImpl[F[_], K, V](chm: ConcurrentHashMap[K, V], sync: Sync[F])
private class JavaMapImpl[F[_], K, V](chm: java.util.Map[K, V], sync: Sync[F])
extends MapRef[F, K, Option[V]] {
private implicit def syncF: Sync[F] = sync

Expand Down Expand Up @@ -241,7 +245,11 @@ object MapRef extends MapRefCompanionPlatform {
*/
def fromConcurrentHashMap[F[_]: Sync, K, V](
map: ConcurrentHashMap[K, V]): MapRef[F, K, Option[V]] =
new ConcurrentHashMapImpl[F, K, V](map, Sync[F])
new JavaMapImpl[F, K, V](map, Sync[F])

private[std] def fromHashtable[F[_]: Sync, K, V](
map: Hashtable[K, V]): MapRef[F, K, Option[V]] =
new JavaMapImpl[F, K, V](map, Sync[F])

/**
* This allocates mutable memory, so it has to be inside F. The way to use things like this is
Expand Down
55 changes: 10 additions & 45 deletions std/shared/src/main/scala/cats/effect/std/SystemProperties.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,17 @@ package cats.effect.std

import cats.{~>, Applicative, Functor}
import cats.data.{EitherT, IorT, Kleisli, OptionT, ReaderWriterStateT, StateT, WriterT}
import cats.effect.kernel.Sync
import cats.effect.kernel.{Ref, Sync}
import cats.kernel.Monoid

import org.typelevel.scalaccompat.annotation._
import java.util.Hashtable

import scala.collection.immutable.Map
trait SystemProperties[F[_]] extends MapRef[F, String, Option[String]] { outer =>

trait SystemProperties[F[_]] { self =>
def apply(key: String): Ref[F, Option[String]]

/**
* Retrieves the value for the specified key.
*/
def get(key: String): F[Option[String]]

/**
* Sets the value for the specified key to `value` disregarding any previous value for the
* same key.
*/
def set(key: String, value: String): F[Unit]

/**
* Removes the property.
*/
def unset(key: String): F[Unit]

def entries: F[Map[String, String]]

def mapK[G[_]](f: F ~> G): SystemProperties[G] = new SystemProperties[G] {
def get(key: String): G[Option[String]] = f(self.get(key))
def set(key: String, value: String): G[Unit] = f(self.set(key, value))
def unset(key: String) = f(self.unset(key))
def entries: G[Map[String, String]] = f(self.entries)
}
override def mapK[G[_]](f: F ~> G)(implicit G: Functor[G]): SystemProperties[G] =
outer(_).mapK(f)
}

object SystemProperties {
Expand Down Expand Up @@ -78,7 +56,7 @@ object SystemProperties {
* [[Prop]] instance built for `cats.data.Kleisli` values initialized with any `F` data type
* that also implements `Prop`.
*/
implicit def catsKleisliSystemProperties[F[_]: SystemProperties, R]
implicit def catsKleisliSystemProperties[F[_]: Functor: SystemProperties, R]
: SystemProperties[Kleisli[F, R, *]] =
SystemProperties[F].mapK(Kleisli.liftK)

Expand Down Expand Up @@ -131,22 +109,9 @@ object SystemProperties {
private[std] final class SyncSystemProperties[F[_]](implicit F: Sync[F])
extends SystemProperties[F] {

def get(key: String): F[Option[String]] =
F.delay(Option(System.getProperty(key))) // thread-safe

def set(key: String, value: String): F[Unit] =
F.void(F.blocking(System.setProperty(key, value)))

def unset(key: String): F[Unit] = F.void(F.delay(System.clearProperty(key)))
private[this] val underlying =
MapRef.fromHashtable(System.getProperties().asInstanceOf[Hashtable[String, String]])

@nowarn213("cat=deprecation")
@nowarn3("cat=deprecation")
def entries: F[Map[String, String]] =
F.blocking {
import scala.collection.JavaConverters._
val props = System.getProperties
val back = props.clone().asInstanceOf[java.util.Map[String, String]]
Map.empty ++ back.asScala
}
def apply(key: String) = underlying(key)
}
}

0 comments on commit 99de034

Please sign in to comment.