remove game2.turns & game2.updatedAt indexes, cache more counts

This commit is contained in:
Thibault Duplessis 2012-06-13 22:23:32 +02:00
parent 4a86d2c27d
commit 2ee23eca20
13 changed files with 65 additions and 41 deletions

View file

@ -36,10 +36,4 @@ object Monitor extends LilaController {
(reporting ? GetNbMembers).mapTo[Int].asPromise map { Ok(_) }
}
}
val nbPlaying = Action {
Async {
(reporting ? GetNbPlaying).mapTo[Int].asPromise map { Ok(_) }
}
}
}

View file

@ -30,7 +30,7 @@ final class Titivate(
val cleanupNext: IO[Unit] = {
val cursor = gameRepo.collection.find(
("next" $exists true) ++ ("updatedAt" $gt (DateTime.now - 3.days)),
("next" $exists true) ++ ("createdAt" $gt (DateTime.now - 3.days)),
DBObject("next" -> true)
)
val unsetNext = (id: String) gameRepo.collection.update(

View file

@ -19,6 +19,7 @@ final class GameEnv(
lazy val paginator = new PaginatorBuilder(
gameRepo = gameRepo,
cached = cached,
maxPerPage = GamePaginatorMaxPerPage)
lazy val export = Export(gameRepo) _

View file

@ -55,7 +55,7 @@ class GameRepo(collection: MongoCollection)
def save(progress: Progress): IO[Unit] =
new GameDiff(progress.origin.encode, progress.game.encode)() |> { diffs
if (diffs.nonEmpty) {
val fullDiffs = ("updatedAt" -> new Date()) :: diffs
val fullDiffs = ("updatedAt" -> new Date) :: diffs
io { update(idSelector(progress.origin), $set(fullDiffs: _*)) }
}
else io()
@ -131,7 +131,7 @@ class GameRepo(collection: MongoCollection)
primitiveProjection[String](idSelector(gameId), "initialFen")
}
def unplayedIds: IO[List[String]] = io {
val unplayedIds: IO[List[String]] = io {
primitiveProjections[String](
("turns" $lt 2) ++ ("createdAt" $lt (DateTime.now - 2.day)),
"_id"
@ -150,6 +150,7 @@ class GameRepo(collection: MongoCollection)
def candidatesToAutofinish: IO[List[DbGame]] = io {
find(Query.playable ++
Query.clock(true) ++
("createdAt" $gt (DateTime.now - 1.day)) ++ // index
("updatedAt" $lt (DateTime.now - 2.hour))
).toList.map(_.decode).flatten
}
@ -163,8 +164,8 @@ class GameRepo(collection: MongoCollection)
def exists(id: String) = count(idSelector(id)) map (_ > 0)
def recentGames(limit: Int): IO[List[DbGame]] = io {
find(Query.started)
.sort(DBObject("updatedAt" -> -1))
find(Query.started ++ Query.turnsGt(1))
.sort(DBObject("createdAt" -> -1))
.limit(limit)
.toList.map(_.decode).flatten sortBy (_.id)
}

View file

@ -3,43 +3,53 @@ package game
import user.User
import chess.Status
import mongodb.CachedAdapter
import com.github.ornicar.paginator._
import com.mongodb.casbah.Imports._
final class PaginatorBuilder(
gameRepo: GameRepo,
cached: Cached,
maxPerPage: Int) {
def recent(page: Int): Paginator[DbGame] =
def recent(page: Int): Paginator[DbGame] =
paginator(recentAdapter, page)
def checkmate(page: Int): Paginator[DbGame] =
def checkmate(page: Int): Paginator[DbGame] =
paginator(checkmateAdapter, page)
def popular(page: Int): Paginator[DbGame] =
def popular(page: Int): Paginator[DbGame] =
paginator(popularAdapter, page)
def recentlyUpdated(query: DBObject) = apply(query, Query.sortUpdated) _
def recentlyCreated(query: DBObject) = apply(query, Query.sortCreated) _
def apply(query: DBObject, sort: DBObject)(page: Int): Paginator[DbGame] =
apply(adapter(query, sort))(page)
def apply(query: DBObject, sort: DBObject)(page: Int): Paginator[DbGame] =
apply(noCacheAdapter(query, sort))(page)
private def apply(adapter: Adapter[DbGame])(page: Int): Paginator[DbGame] =
paginator(adapter, page)
private val recentAdapter =
adapter(DBObject(), Query.sortUpdated)
private val recentAdapter =
adapter(DBObject(), Query.sortCreated, cached.nbGames)
private val checkmateAdapter =
adapter(Query.mate, Query.sortUpdated)
private val checkmateAdapter =
adapter(Query.mate, Query.sortCreated, cached.nbMates)
private val popularAdapter =
adapter(Query.popular, Query.sortPopular)
private val popularAdapter =
adapter(Query.popular, Query.sortPopular, cached.nbPopular)
private def adapter(query: DBObject, sort: DBObject) = SalatAdapter(
private def adapter(
query: DBObject,
sort: DBObject,
nbResults: Int) = new CachedAdapter(
dao = gameRepo,
query = query,
sort = sort,
nbResults = nbResults
) map (_.decode.get) // unsafe
private def noCacheAdapter(query: DBObject, sort: DBObject) = SalatAdapter(
dao = gameRepo,
query = query,
sort = sort

View file

@ -21,8 +21,6 @@ object Query {
val playable: DBObject = ("status" $lt Status.Aborted.id)
val playing: DBObject = "updatedAt" $gt (DateTime.now - 15.seconds)
val mate: DBObject = DBObject("status" -> Status.Mate.id)
val draw: DBObject = "status" $in List(Status.Draw.id, Status.Stalemate.id)
@ -51,9 +49,9 @@ object Query {
def opponents(u1: User, u2: User) = "userIds" $all List(u1.id, u2.id)
val sortCreated = DBObject("createdAt" -> -1)
def turnsGt(nb: Int) = "turns" $gt nb
val sortUpdated = DBObject("updatedAt" -> -1)
val sortCreated = DBObject("createdAt" -> -1)
val sortPopular = DBObject("bm" -> -1)
}

View file

@ -0,0 +1,21 @@
package lila
package mongodb
import com.github.ornicar.paginator._
import com.novus.salat.dao.DAO
import com.novus.salat._
import com.mongodb.casbah.Imports.DBObject
final class CachedAdapter[A <: CaseClass, B <: Any](
dao: DAO[A, B],
query: DBObject,
sort: DBObject,
val nbResults: Int) extends Adapter[A] {
private val salatAdapter = SalatAdapter(
dao = dao,
query = query,
sort = sort)
def slice(offset: Int, length: Int) = salatAdapter.slice(offset, length)
}

View file

@ -55,8 +55,6 @@ final class Reporting(
case GetNbGames sender ! nbGames
case GetNbPlaying sender ! nbPlaying
case GetStatus sender ! status
case GetMonitorData sender ! monitorData
@ -104,7 +102,6 @@ final class Reporting(
"lobby" -> lobby.nbMembers,
"game" -> game.nbMembers,
"hubs" -> game.nbHubs,
"recent" -> nbPlaying,
"lat." -> latency,
"thread" -> nbThreads,
"load" -> loadAvg.toString.replace("0.", "."),
@ -122,7 +119,6 @@ final class Reporting(
private def status = List(
allMembers,
nbGames,
nbPlaying,
game.nbHubs,
loadAvg.toString,
(remoteAi | 9999)

View file

@ -5,7 +5,6 @@ import core.CoreEnv
import socket.SocketMember
case object GetNbGames
case object GetNbPlaying
case object GetStatus
case object GetMonitorData

View file

@ -4,6 +4,8 @@ package user
import com.github.ornicar.paginator._
import com.mongodb.casbah.Imports.DBObject
import mongodb.CachedAdapter
final class PaginatorBuilder(
userRepo: UserRepo,
countUsers: () Int,
@ -15,11 +17,11 @@ final class PaginatorBuilder(
private val recentAdapter =
adapter(DBObject("enabled" -> true))
private def adapter(query: DBObject) = new Adapter[User] {
private val salatAdapter = SalatAdapter(userRepo, query, DBObject("elo" -> -1))
def nbResults = countUsers()
def slice(offset: Int, length: Int) = salatAdapter.slice(offset, length)
}
private def adapter(query: DBObject) = new CachedAdapter(
dao = userRepo,
query = query,
sort = DBObject("elo" -> -1),
nbResults = countUsers())
private def paginator(adapter: Adapter[User], page: Int) = Paginator(
adapter,

View file

@ -30,6 +30,8 @@ case class UserInfo(
object UserInfo {
private val rankMinElo = 1600
def apply(
userRepo: UserRepo,
countUsers: () => Int,
@ -40,7 +42,7 @@ object UserInfo {
bookmarkApi: BookmarkApi,
userSpy: Option[String IO[UserSpy]],
ctx: Context): IO[UserInfo] = for {
rank (user.elo >= 1500).fold(
rank (user.elo >= rankMinElo).fold(
userRepo rank user map { rank
Some(rank -> countUsers())
},

View file

@ -119,7 +119,6 @@ POST /inbox/$id<[\w]{8}>/delete controllers.Message.delete(id: String)
GET /monitor controllers.Monitor.index
GET /monitor/socket controllers.Monitor.websocket
GET /nb-players controllers.Monitor.nbPlayers
GET /nb-playing controllers.Monitor.nbPlaying
GET /status controllers.Monitor.status
# Assets

1
todo
View file

@ -22,6 +22,7 @@ autoclose top menus
tournaments http://www.chess.com/tournaments/help.html
fix game list translations
temporary mod IP ban to help stopping cheaters
join game as player from player page
new translations:
-rematchOfferCanceled=Rematch offer canceled