que - Cómo almacenar los resultados en caché en scala?
que es cache en informatica (5)
Esta página tiene una descripción del método de uso getOrElseUpdate
de Map:
object WithCache{
val cacheFun1 = collection.mutable.Map[Int, Int]()
def fun1(i:Int) = i*i
def catchedFun1(i:Int) = cacheFun1.getOrElseUpdate(i, fun1(i))
}
Entonces puede usar catchedFun1
que verificará si cacheFun1
contiene la clave y el valor de retorno asociado. De lo contrario, invocará fun1
, luego fun1
el resultado de cacheFun1
en cacheFun1
, luego devolverá el resultado de fun1
.
Puedo ver un peligro potencial: cacheFun1
puede convertirse en grande. Entonces cacheFun1
debe ser limpiado de alguna manera por el recolector de basura?
PD ¿Qué pasa con scala.collection.mutable.WeakHashMap and java.lang.ref.*
?
Como no se ha mencionado antes, permítanme poner sobre la mesa el ligero Spray-Caching que se puede usar independientemente de Spray y proporciona estrategias de desahucio de tamaño esperado, tiempo de vida y tiempo de inactividad.
Eche un vistazo al caché de pulverización (muy fácil de usar)
http://spray.io/documentation/1.1-SNAPSHOT/spray-caching/
hace el trabajo fácil y tiene algunas características agradables
por ejemplo :
import spray.caching.{LruCache, Cache}
//this is using Play for a controller example getting something from a user and caching it
object CacheExampleWithPlay extends Controller{
//this will actually create a ExpiringLruCache and hold data for 48 hours
val myCache: Cache[String] = LruCache(timeToLive = new FiniteDuration(48, HOURS))
def putSomeThingInTheCache(@PathParam("getSomeThing") someThing: String) = Action {
//put received data from the user in the cache
myCache(someThing, () => future(someThing))
Ok(someThing)
}
def checkIfSomeThingInTheCache(@PathParam("checkSomeThing") someThing: String) = Action {
if (myCache.get(someThing).isDefined)
Ok(s"just $someThing found this in the cache")
else
NotFound(s"$someThing NOT found this in the cache")
}
}
En la lista de correo de scala, a sometimes apuntan a MapMaker en la biblioteca de colecciones de Google . Es posible que desee echar un vistazo a eso.
Para las necesidades simples de almacenamiento en caché, todavía estoy usando la solución de caché de guayaba en Scala. Ligero y probado en batalla.
Si se ajusta a sus requisitos y limitaciones generalmente detallados a continuación, podría ser una excelente opción:
- Dispuesto a gastar algo de memoria para mejorar la velocidad.
- Esperando que las claves a veces sean consultadas más de una vez.
- Su caché no necesitará almacenar más datos de los que cabrían en la memoria RAM. (Las memorias caché de Guava son locales para una sola ejecución de su aplicación. No almacenan datos en archivos ni en servidores externos).
El ejemplo para usarlo será algo como esto:
lazy val cachedData = CacheBuilder.newBuilder()
.expireAfterWrite(60, TimeUnit.MINUTES)
.maximumSize(10)
.build(
new CacheLoader[Key, Data] {
def load(key: Key): Data = {
veryExpansiveDataCreation(key)
}
}
)
Para leer de él, puede usar algo como:
def cachedData(ketToData: Key): Data = {
try {
return cachedData.get(ketToData)
} catch {
case ee: Exception => throw new YourSpecialException(ee.getMessage);
}
}
Ver el patrón Memo y la implementación de Scalaz de dicho documento.
También consulte una implementación de STM como Akka .
No es que esto sea solo un almacenamiento en caché local, por lo que es posible que desee buscar en un caché distribuido o STM como CCSTM , Terracotta o Hazelcast