This page描述了地图的getOrElseUpdate
使用方法:
object WithCache{
val cacheFun1 = collection.mutable.Map[Int, Int]()
def fun1(i:Int) = i*i
def catchedFun1(i:Int) = cacheFun1.getOrElseUpdate(i, fun1(i))
}
因此,您可以使用catchedFun1
来检查cacheFun1
是否包含与之关联的密钥和返回值。否则,它会调用fun1
,然后将fun1
的结果缓存到cacheFun1
,然后返回fun1
的结果。
我可以看到一个潜在的危险 - cacheFun1
可能变得很大。那么垃圾收集器必须以某种方式清除cacheFun1
吗?
P.S。那么scala.collection.mutable.WeakHashMap and java.lang.ref.*
呢?
答案 0 :(得分:16)
请参阅所述论文的Memo pattern和Scalaz implementation。
同时查看STM实施,例如Akka。
这不仅仅是本地缓存,因此您可能希望查看分布式缓存或STM,例如CCSTM,Terracotta或Hazelcast
答案 1 :(得分:8)
看看喷雾缓存(超级简单易用)
http://spray.io/documentation/1.1-SNAPSHOT/spray-caching/
使工作变得轻松,并具有一些不错的功能
例如:
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")
}
}
答案 2 :(得分:6)
在scala邮件列表中,他们sometimes指向MapMaker中的Google collections library。你可能想看一下。
答案 3 :(得分:3)
对于简单的缓存需求,我仍然在Scala中使用Guava cache solution。 轻量级和战斗测试。
如果符合您的要求和约束条件,则可能是一个很好的选择:
使用它的示例如下:
lazy val cachedData = CacheBuilder.newBuilder()
.expireAfterWrite(60, TimeUnit.MINUTES)
.maximumSize(10)
.build(
new CacheLoader[Key, Data] {
def load(key: Key): Data = {
veryExpansiveDataCreation(key)
}
}
)
要阅读它,您可以使用以下内容:
def cachedData(ketToData: Key): Data = {
try {
return cachedData.get(ketToData)
} catch {
case ee: Exception => throw new YourSpecialException(ee.getMessage);
}
}
答案 4 :(得分:2)
由于之前没有提到过,让我在桌面上摆放可以独立于Spray使用的灯Spray-Caching,并提供预期的尺寸,生存时间,空闲时间驱逐策略。
答案 5 :(得分:1)
我们正在使用 Scaffeine (Scala + Caffeine),您可以通过 here 了解其与其他框架相比的优缺点。
你添加你的 sbt,
"com.github.blemale" %% "scaffeine" % "4.0.1"
建立你的缓存
import com.github.blemale.scaffeine.{Cache, Scaffeine}
import scala.concurrent.duration._
val cachedItems: Cache[String, Int] =
Scaffeine()
.recordStats()
.expireAtferWrite(60.seconds)
.maximumSize(500)
.buid[String, Int]()
cachedItems.put("key", 1) // Add items
cache.getIfPresent("key") // Returns an option