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

scroll.internal.util.Memoiser.scala Maven / Gradle / Ivy

The newest version!
package scroll.internal.util

import com.google.common.cache.Cache
import com.google.common.cache.CacheBuilder

/**
  * Support for memoization, encapsulating common behaviour of memoised
  * entities and a general reset mechanism for all such entities.
  */
trait Memoiser {

  /**
    * Common interface for encapsulation of memoization for a single memoised
    * entity backed by a configurable cache.
    */
  trait MemoisedBase[T, U] {

    /**
      * The memo table.
      */
    def memo: Cache[AnyRef, AnyRef]

    /**
      * Return the value stored at key `t` as an option.
      */
    def get(t: T): Option[U] = Option(memo.getIfPresent(t).asInstanceOf[U])

    /**
      * Return the value stored at key `t` if there is one, otherwise
      * return `u`. `u` is only evaluated if necessary and put into the cache.
      */
    def getAndPutWithDefault(t: T, u: => U): U = get(t) match {
      case Some(v) => v
      case None =>
        val newU = u
        put(t, newU)
        newU
    }

    /**
      * Has the value at `t` already been computed or not? By default, does
      * the memo table contain a value for `t`?
      */
    def hasBeenComputedAt(t: T): Boolean = get(t).isDefined

    /**
      * Store the value `u` under the key `t`.
      */
    def put(t: T, u: U): Unit = {
      memo.put(t.asInstanceOf[AnyRef], u.asInstanceOf[AnyRef])
    }

    /**
      * Immediately reset the memo table.
      */
    def reset(): Unit = {
      memo.invalidateAll()
    }

    /**
      * Immediately reset the memo table at `t`.
      */
    def resetAt(t: T): Unit = {
      memo.invalidate(t)
    }

    /**
      * The number of entries in the memo table.
      */
    def size(): Long = memo.size
  }

  /**
    * A memoised entity that uses equality to compare keys.
    */
  trait Memoised[T, U] extends MemoisedBase[T, U] {
    val memo: Cache[AnyRef, AnyRef] = CacheBuilder.newBuilder.build()
  }

  /**
    * A memoised entity that weakly holds onto its keys and uses identity
    * to compare them.
    */
  trait IdMemoised[T, U] extends MemoisedBase[T, U] {
    val memo: Cache[AnyRef, AnyRef] = CacheBuilder.newBuilder.weakKeys.build()
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy