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

org.scaladebugger.api.utils.Memoization.scala Maven / Gradle / Ivy

The newest version!
package org.scaladebugger.api.utils

import scala.collection.mutable.{Map => MutableMap}

/**
 * Represents a generic form of memoization. Modified from Pathikrit Bhowmick's
 * copy of Scala Memoization.
 *
 * @see https://github.com/pathikrit/scalgos/blob/master/src/main/scala/com/github/pathikrit/scalgos/Memo.scala
 *
 * @param memoFunc Represents the function that will be memoized
 * @param cacheInvalidFunc Represents a function that, if it yields true, will
 *                         mark the current cache element represented by K as
 *                         invalid and rerun the memo function
 * @param cache The map used to store the cache of results to be fed back as
 *              a result of memoization
 * @tparam I Represents the input to the memoized function
 * @tparam K Represents the type of key to use for cached results
 * @tparam O Represents the output of the memoized function
 */
class Memoization[I, K, O](
  private val memoFunc: I => O,
  private val cacheInvalidFunc: K => Boolean = (_: K) => false,
  private val cache: MutableMap[K, O] = MutableMap.empty[K, O]
)(
  implicit convertToKey: I => K
) extends (I => O) {
  /**
   * Clears the internal memoization, allowing new results to be calculated
   * from previously-used input.
   */
  def clear(): Unit = cache.clear()

  /**
   * Executes the memoized function if the given input is new, otherwise
   * returns the result from a previous execution.
   *
   * @param input The input to execute upon
   *
   * @return The result of the execution
   */
  override def apply(input: I) = cache.synchronized {
    val key = convertToKey(input)

    if (!cacheInvalidFunc(key)) {
      cache.getOrElseUpdate(key, memoFunc(input))
    } else {
      cache.put(key, memoFunc(input))
      cache(key)
    }
  }
}

/**
 * Provides additional abstractions on top of memoization.
 */
object Memoization {
  /**
   * Type of a simple memoized function e.g. when I = K
   */
  type ==>[I, O] = Memoization[I, I, O]
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy