pat*_*rit 12 java caching scala lru
我知道Guava有一个很棒的缓存库,但我正在寻找更多Scala /功能友好的东西,我可以做的事情cache.getOrElse(query, { /* expensive operation */}).我也查看了Scalaz的备忘录,但是没有lru到期.
Ami*_*ico 17
Spray人员有一个使用Futures 的喷雾缓存模块.有一个普通的LRU版本和一个版本,允许您指定一个明确的生存时间,之后条目自动过期.
Futures的使用显然允许您编写不阻止的代码.然而,真正酷的是,它解决了"雷鸣般的群体"问题作为奖励.比如说,对于不在缓存中的同一条目,一堆请求立即进入.在一个简单的缓存实现中,一百个线程可能会在缓存中的该条目上失败,然后运行以生成该缓存条目的相同数据,但当然99%的线程只是浪费精力.你真正想要的只是一个线程生成数据,所有100个请求者看到结果.如果您的缓存包含Futures,则会很自然地发生这种情况:第一个请求者立即在缓存中安装Future,因此只有第一个请求者未命中.所有100个请求者都获得了生成结果的Future.
基于 Java LinkedHashMap 并公开为 Scala mutable.Map 的 LRUCache 解决方案
import java.util.Collections.synchronizedMap
import scala.collection.JavaConversions._
import scala.collection.mutable
class LRUCache[K, V](maxEntries: Int)
extends java.util.LinkedHashMap[K, V](100, .75f, true) {
override def removeEldestEntry(eldest: java.util.Map.Entry[K, V]): Boolean
= size > maxEntries
}
object LRUCache {
def apply[K, V](maxEntries: Int): mutable.Map[K, V]
= synchronizedMap(new LRUCache[K, V](maxEntries))
}
Run Code Online (Sandbox Code Playgroud)
当地图大小 > maxEntries 时,最近使用的条目将被删除。
对于 LRU 策略,LinkedHashMap 第 3 个构造函数参数应设置为 true。
LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
使用示例:
val cache = LRUCache[String, Int](1000)
val key = "key1"
val value = 111
cache.get(key) shouldBe None
cache += key -> value
cache.get(key) shouldBe Some(value)
cache(key) shouldBe value
Run Code Online (Sandbox Code Playgroud)