krzysztof-w
2/2/2015 - 10:54 PM

Memoize

object Helpers {
  def time[R](block: => R): (R, Long) = {
    val t0 = System.nanoTime()
    val result = block    // call-by-name
    val t1 = System.nanoTime()
    (result, t1 - t0)
  }
}
case class Memoize[-T , +R : ClassTag](duration : Duration, refreshOnGet : Boolean = false)(f: T => R)
                                      (implicit app : Application) extends (T => R) {
  val safeCounter = Cache.getAs[Int](Memoize.CACHE_KEY).getOrElse(0)
  Cache.set(Memoize.CACHE_KEY, safeCounter + 1)

  def apply(x: T) : R = {
    val key = safeCounter + x.toString
    val result = Cache.getAs[R](key).getOrElse {
      val result = f(x)
      Cache.set(key, result, duration)
      result
    }
    if(refreshOnGet) Cache.set(key, result, duration)
    result
  }
}
object Memoize {
  implicit def functionToMemoizer[T,R : ClassTag] (f:(T => R)) : Memoizable[T,R] = Memoizable(f)
  lazy val CACHE_KEY = "memoize-safe-counter"
}