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

metrics.Chosen.scala Maven / Gradle / Ivy

The newest version!
package jjm.metrics

import cats.Applicative
import cats.Eval
import cats.Monoid
import cats.Order
import cats.Show
import cats.Traverse
import cats.implicits._

import monocle.function.Each

import jjm.implicits._
import io.circe.Encoder
import io.circe.Decoder

case class Chosen[Param, MetricData](
  data: Map[Param, MetricData]
) {
  // TODO TraverseFilter
  def filter(p: MetricData => Boolean) = Chosen(
    data.collect { case (k, v) if p(v) => k -> v }
  )
  def keepMaximaBy[O](f: MetricData => O)(implicit o: Order[O]) = {
    Chosen(data.toList.maximaBy(p => f(p._2)).toMap)
  }
  def keepMaxBy[O](f: MetricData => O)(implicit o: Ordering[O]) = {
    if(data.nonEmpty) Chosen(Map(data.toList.maxBy(p => f(p._2))))
    else Chosen[Param, MetricData](Map())
  }
  def keepMinimaBy[O](f: MetricData => O)(implicit o: Order[O]) = {
    Chosen(data.toList.minimaBy(p => f(p._2)).toMap)
  }
  def keepMinBy[O](f: MetricData => O)(implicit o: Ordering[O]) = {
    if(data.nonEmpty) Chosen(Map(data.toList.minBy(p => f(p._2))))
    else Chosen[Param, MetricData](Map())
  }
}
object Chosen {
  implicit def chosenTraverse[Param]: Traverse[Chosen[Param, *]] = new Traverse[Chosen[Param, *]] {
    def traverse[G[_]: Applicative, A, B](fa: Chosen[Param, A])(f: A => G[B]): G[Chosen[Param, B]] = {
      fa.data.toList.traverse { case (param, value) => f(value).map(param -> _) }.map(l => Chosen(l.toMap))
    }
    def foldLeft[A, B](fa: Chosen[Param, A], b: B)(f: (B, A) => B): B = fa.data.values.foldLeft(b)(f)
    def foldRight[A, B](fa: Chosen[Param, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = fa.data.values.foldRight(lb)(f)
  }
  implicit def chosenMonoid[Param, A: Monoid]: Monoid[Chosen[Param, A]] = {
    import cats.derived.auto.monoid._
    cats.derived.semiauto.monoid
  }
  implicit def chosenHasMetrics[Param: Show, A: HasMetrics]: HasMetrics[Chosen[Param, A]] = new HasMetrics[Chosen[Param, A]] {
    def getMetrics(ba: Chosen[Param, A]): MapTree[String, Metric] = {
      MapTree.fork(
        ba.data.map { case (param, bucketData) =>
          param.show -> bucketData.getMetrics
        }
      )
    }
  }
  implicit def chosenEach[Param, A] = Each.fromTraverse[Chosen[Param, *], A]

  import io.circe.syntax._

  implicit def chosenEncoder[Param: Encoder, A: Encoder]: Encoder[Chosen[Param, A]] =
    Encoder.instance[Chosen[Param, A]](chosen => chosen.data.toVector.asJson)

  implicit def chosenDecoder[Param: Decoder, A: Decoder](
  ): Decoder[Chosen[Param, A]] = Decoder.instance[Chosen[Param, A]] { cursor =>
    cursor.as[Vector[(Param, A)]].map(x => Chosen(x.toMap))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy