blob: df9e51574c3c0520e86b4c220b600dee85e2226f [file] [log] [blame]
package com.daumkakao.s2graph.core
import scalikejdbc.ConnectionPool
import scalikejdbc._
import com.twitter.util.SynchronizedLruMap
import HBaseElement.InnerVal
import play.api.libs.json._
import com.google.common.cache.CacheBuilder
import java.util.concurrent.{Callable, TimeUnit}
import com.google.common.cache.CacheLoader
import com.typesafe.config.Config
object Model {
val defaultConfigs = Map("db.default.driver" -> "com.mysql.jdbc.Driver",
"db.default.url" -> "jdbc:mysql://localhost:3306/graph_dev",
"db.default.password" -> "graph",
"db.default.user" -> "graph")
var settings: ConnectionPoolSettings = null
var maxSize = 10000
var ttl = 60
val logger = Graph.logger
def apply(config: Config) = {
val configVals = for ((k, v) <- defaultConfigs) yield {
logger.debug(s"initializing db connection: $k, $v")
val currentVal = GraphConnection.getOrElse(config)(k, v)
k -> currentVal
}
maxSize = GraphConnection.getOrElse(config)("cache.max.size", 10000)
ttl = GraphConnection.getOrElse(config)("cache.ttl.seconds", 120)
Class.forName(configVals("db.default.driver"))
settings = ConnectionPoolSettings(initialSize = 1, maxSize = 5,
connectionTimeoutMillis = 60000L, validationQuery = "select 1;")
ConnectionPool.singleton(configVals("db.default.url"), configVals("db.default.user"), configVals("db.default.password"), settings)
}
}
trait LocalCache[V] {
import Model._
private lazy val cName = this.getClass.getSimpleName()
implicit val s: DBSession = AutoSession
val cache = CacheBuilder.newBuilder()
.expireAfterWrite(ttl, TimeUnit.SECONDS)
.maximumSize(maxSize)
.build[String, Option[V]]()
val caches = CacheBuilder.newBuilder()
.expireAfterWrite(ttl, TimeUnit.SECONDS)
.maximumSize(maxSize / 10).build[String, List[V]]()
def withCache(key: String)(op: => Option[V]): Option[V] = {
val newKey = s"$cName:$key"
val view = cache.asMap()
if (view.containsKey(newKey)) view.get(newKey)
else {
val newVal = op
cache.put(newKey, newVal)
newVal
}
}
def withCaches(key: String)(op: => List[V]): List[V] = {
val newKey = s"$cName:$key"
val view = caches.asMap()
if (view.containsKey(newKey)) view.get(newKey)
else {
val newVal = op
caches.put(newKey, newVal)
newVal
}
}
def expireCache(key: String): Unit = {
val newKey = s"$cName:$key"
cache.invalidate(newKey)
}
def expireCaches(key: String): Unit = {
val newKey = s"$cName:$key"
caches.invalidate(newKey)
}
def putsToCache(kvs: List[(String, V)]) = {
kvs.foreach {
case (key, value) =>
val newKey = s"$cName:$key"
cache.put(newKey, Some(value))
}
}
}
//trait Model[V] extends SQLSyntaxSupport[V] {
//
// import Model._
// implicit val s: DBSession = AutoSession
// private val cache = new SynchronizedLruMap[String, (Option[V], Int)](maxSize)
// private val caches = new SynchronizedLruMap[String, (List[V], Int)](maxSize / 10)
// private lazy val cName = this.getClass.getSimpleName()
// val logger = Graph.logger
//
// private def withTTL(key: String, op: => Option[V]): Option[V] = {
// cache.get(key) match {
// case Some((existed, ts)) =>
// val elapsed = System.currentTimeMillis() / 1000 - ts
// if (elapsed > ttl) {
// cache.remove(key)
// val fetched = op
// val current = System.currentTimeMillis() / 1000
// cache.put(key, (fetched, current.toInt))
// fetched
// } else {
// existed
// }
// case None =>
// val fetched = op
// val current = System.currentTimeMillis() / 1000
// cache.put(key, (fetched, current.toInt))
// fetched
// }
// }
// private def withTTLs(key: String, op: => List[V]): List[V] = {
// caches.get(key) match {
// case Some((existed, ts)) =>
// val elapsed = System.currentTimeMillis() / 1000 - ts
// if (elapsed > ttl) {
// caches.remove(key)
// val fetched = op
// val current = System.currentTimeMillis() / 1000
// caches.put(key, (fetched, current.toInt))
// fetched
// } else {
// existed
// }
// case None =>
// val fetched = op
// val current = System.currentTimeMillis() / 1000
// caches.put(key, (fetched, current.toInt))
// fetched
// }
// }
// def withCache(key: String)(op: => Option[V]): Option[V] = {
// withTTL(s"$cName:$key", op)
// }
// def withCaches(key: String)(op: => List[V]): List[V] = {
// withTTLs(s"$cName:$key", op)
// }
// def expireCache(key: String): Unit = {
// val k = s"$cName:$key"
// if (cache.contains(k)) cache.remove(k)
// }
// def expireCaches(key: String): Unit = {
// val k = s"$cName:$key"
// if (caches.contains(k)) caches.remove(k)
// }
// def putsToCache(kvs: List[(String, V)]) = {
// kvs.foreach {
// case (key, value) =>
// withTTL(s"$cName:$key", Some(value))
// }
// }
//}