Implement version cache using scalaz Memo and guava cache builder
This commit is contained in:
parent
02ab64c0e8
commit
3b0c3d72ff
|
@ -8,14 +8,11 @@ trait Resolvers {
|
|||
val iliaz = "iliaz.com" at "http://scala.iliaz.com/"
|
||||
val sonatype = "sonatype" at "http://oss.sonatype.org/content/repositories/releases"
|
||||
val novusS = "repo.novus snaps" at "http://repo.novus.com/snapshots/"
|
||||
val guice = "guice-maven" at "http://guice-maven.googlecode.com/svn/trunk"
|
||||
}
|
||||
|
||||
trait Dependencies {
|
||||
val scalaz = "org.scalaz" %% "scalaz-core" % "6.0.4"
|
||||
val specs2 = "org.specs2" %% "specs2" % "1.8.2"
|
||||
//val redis = "net.debasishg" %% "redisclient" % "2.4.2"
|
||||
val redis = "org.sedis" %% "sedis" % "1.0"
|
||||
val casbah = "com.mongodb.casbah" %% "casbah" % "2.1.5-1"
|
||||
val salat = "com.novus" %% "salat-core" % "0.0.8-SNAPSHOT"
|
||||
val slf4j = "org.slf4j" % "slf4j-nop" % "1.6.4"
|
||||
|
@ -23,6 +20,7 @@ trait Dependencies {
|
|||
val hasher = "com.roundeights" % "hasher" % "0.3" from "http://cloud.github.com/downloads/Nycto/Hasher/hasher_2.9.1-0.3.jar"
|
||||
val config = "com.typesafe.config" % "config" % "0.3.0"
|
||||
val json = "com.codahale" %% "jerkson" % "0.5.0"
|
||||
val guava = "com.google.guava" % "guava" % "11.0.1"
|
||||
|
||||
// benchmark
|
||||
val instrumenter = "com.google.code.java-allocation-instrumenter" % "java-allocation-instrumenter" % "2.0"
|
||||
|
@ -35,7 +33,7 @@ object ApplicationBuild extends Build with Resolvers with Dependencies {
|
|||
organization := "com.github.ornicar",
|
||||
version := "0.1",
|
||||
scalaVersion := "2.9.1",
|
||||
resolvers := Seq(iliaz, codahale, sonatype, novusS, typesafe, guice),
|
||||
resolvers := Seq(iliaz, codahale, sonatype, novusS, typesafe),
|
||||
libraryDependencies := Seq(scalalib),
|
||||
libraryDependencies in test := Seq(specs2),
|
||||
shellPrompt := {
|
||||
|
@ -53,7 +51,7 @@ object ApplicationBuild extends Build with Resolvers with Dependencies {
|
|||
) dependsOn (system)
|
||||
|
||||
lazy val system = Project("system", file("system"), settings = buildSettings).settings(
|
||||
libraryDependencies ++= Seq(scalaz, config, redis, json, casbah, salat, slf4j)
|
||||
libraryDependencies ++= Seq(scalaz, config, json, casbah, salat, guava, slf4j)
|
||||
) dependsOn (chess)
|
||||
|
||||
lazy val chess = Project("chess", file("chess"), settings = buildSettings).settings(
|
||||
|
|
|
@ -4,10 +4,8 @@ import com.mongodb.casbah.MongoConnection
|
|||
import com.mongodb.casbah.commons.conversions.scala._
|
||||
import com.typesafe.config._
|
||||
|
||||
import org.sedis._
|
||||
import redis.clients.jedis._
|
||||
|
||||
import ai._
|
||||
import memo._
|
||||
|
||||
trait SystemEnv {
|
||||
|
||||
|
@ -30,12 +28,7 @@ trait SystemEnv {
|
|||
config getInt "mongo.port"
|
||||
)(config getString "mongo.dbName")
|
||||
|
||||
def versionCache = new VersionCache(redis)
|
||||
|
||||
def redis = new Pool(new JedisPool(
|
||||
new JedisPoolConfig(),
|
||||
config getString "redis.host",
|
||||
config getInt "redis.port"))
|
||||
def versionMemo = new VersionMemo
|
||||
}
|
||||
|
||||
object SystemEnv extends EnvBuilder {
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
package lila.system
|
||||
|
||||
import org.sedis._
|
||||
import redis.clients.jedis._
|
||||
import Dress._
|
||||
|
||||
final class VersionCache(pool: Pool) {
|
||||
|
||||
def get(gameId: String, color: Color): Option[Int] =
|
||||
pool.withClient { client ⇒
|
||||
client get key(gameId, color) flatMap parseIntOption
|
||||
}
|
||||
|
||||
def key(gameId: String, color: Color) = gameId + ":" + color.letter + ":v"
|
||||
}
|
33
system/src/main/scala/memo/Builder.scala
Normal file
33
system/src/main/scala/memo/Builder.scala
Normal file
|
@ -0,0 +1,33 @@
|
|||
package lila.system
|
||||
package memo
|
||||
|
||||
import com.google.common.base.Function
|
||||
import com.google.common.cache._
|
||||
import java.util.concurrent.TimeUnit
|
||||
import scalaz.Memo
|
||||
|
||||
object Builder extends scalaz.Memos {
|
||||
|
||||
/**
|
||||
* A caching wrapper for a function (K => V),
|
||||
* backed by a Cache from Google Collections.
|
||||
*/
|
||||
def cache[K, V](ttl: Int): Memo[K, V] = memo[K, V] { (f: (K ⇒ V)) ⇒
|
||||
val map = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(ttl, TimeUnit.SECONDS)
|
||||
.asInstanceOf[CacheBuilder[K, V]]
|
||||
.build[K, V](f)
|
||||
.asMap()
|
||||
(k: K) ⇒ map.get(k)
|
||||
}
|
||||
|
||||
implicit def functionToGoogleFunction[T, R](f: T ⇒ R): Function[T, R] =
|
||||
new Function[T, R] {
|
||||
def apply(p1: T) = f(p1)
|
||||
}
|
||||
|
||||
implicit def functionToGoogleCacheLoader[T, R](f: T ⇒ R): CacheLoader[T, R] =
|
||||
new CacheLoader[T, R] {
|
||||
def load(p1: T) = f(p1)
|
||||
}
|
||||
}
|
28
system/src/main/scala/memo/VersionCache.scala
Normal file
28
system/src/main/scala/memo/VersionCache.scala
Normal file
|
@ -0,0 +1,28 @@
|
|||
package lila.system
|
||||
package memo
|
||||
|
||||
import lila.chess.Color
|
||||
import scalaz.Memo
|
||||
|
||||
final class VersionMemo {
|
||||
|
||||
private val memo: String ⇒ Int = Builder.cache(1800)(compute)
|
||||
|
||||
def get(gameId: String, color: Color): Int =
|
||||
memo(toKey(gameId, color))
|
||||
|
||||
private def toKey(gameId: String, color: Color): String =
|
||||
gameId + ":" + color.name + ":v"
|
||||
|
||||
private def fromKey(key: String): Option[(String, Color)] =
|
||||
key.split(':').toList match {
|
||||
case gameId :: cName :: "v" :: Nil ⇒ Color(cName) map { (gameId, _) }
|
||||
case _ ⇒ None
|
||||
}
|
||||
|
||||
private def compute(key: String): Int = fromKey(key) map {
|
||||
case (gameId, color) ⇒ compute(gameId, color)
|
||||
} getOrElse 0
|
||||
|
||||
private def compute(gameId: String, color: Color): Int = 33
|
||||
}
|
Loading…
Reference in a new issue