Scala中的LRUCache?

时间:2013-01-28 12:15:17

标签: scala caching java lru

我知道Guava有an excellent caching library但我正在寻找更多Scala /功能友好的地方,我可以做cache.getOrElse(query, { /* expensive operation */})之类的事情。我也看了Scalaz's Memo,但没有lru到期。

3 个答案:

答案 0 :(得分:17)

Spray人员有一个使用Futures的spray-caching模块。有一个简单的LRU版本和一个版本,允许您指定一个明确的生存时间,之后条目自动过期。

Futures的使用显然允许您编写不阻止的代码。然而,真正酷的是,它解决了“雷鸣般的群体”问题作为奖励。比如说,对于不在缓存中的同一条目,一堆请求立即进入。在一个简单的缓存实现中,一百个线程可能会在缓存中的该条目上失败,然后运行以生成该缓存条目的相同数据,但当然99%的线程只是浪费精力。你真正想要的只是一个线程生成数据,所有100个请求者看到结果。如果您的缓存包含Futures,则会很自然地发生这种情况:第一个请求者立即在缓存中安装Future,因此只有第一个请求者未命中。所有100个请求者都会获得生成结果的Future。

答案 1 :(得分:10)

找到我在Twitter's Scala Util library

中看到的确切内容

答案 2 :(得分:1)

基于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))
}

当地图大小> 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