tournament leader WIP

This commit is contained in:
Thibault Duplessis 2016-01-23 22:02:22 +07:00
parent 2b89d72e91
commit 0d37355295
4 changed files with 27 additions and 9 deletions

View file

@ -25,11 +25,17 @@ private[tournament] final class Cached(
// only applies to ongoing tournaments
private val ongoingRanking = AsyncCache[String, Ranking](
PlayerRepo.computeRanking,
tourId => PlayerRepo computeRanking tourId map {
case (ranking, leaderIdOption) =>
leaderIdOption foreach {
TournamentRepo.setLeaderId(tourId, _)
}
ranking
},
timeToLive = 3.seconds)
// only applies to finished tournaments
private val finishedRanking = AsyncCache[String, Ranking](
PlayerRepo.computeRanking,
tourId => PlayerRepo computeRanking tourId map (_._1),
timeToLive = rankingTtl)
}

View file

@ -111,21 +111,24 @@ object PlayerRepo {
coll.find(selectTour(tourId)).sort(bestSort).one[Player]
// freaking expensive (marathons)
private[tournament] def computeRanking(tourId: String): Fu[Ranking] =
private[tournament] def computeRanking(tourId: String): Fu[(Ranking, Option[User.ID])] =
coll.aggregate(Match(selectTour(tourId)), List(Sort(Descending("m")),
Group(BSONNull)("uids" -> Push("uid")))) map {
_.documents.headOption.fold(Map.empty: Ranking) {
_.documents.headOption.fold((Map.empty: Ranking, none[String])) {
_ get "uids" match {
case Some(BSONArray(uids)) =>
// mutable optimized implementation
val b = Map.newBuilder[String, Int]
var r = 0
var leaderId = none[String]
for (u <- uids) {
b += (u.get.asInstanceOf[BSONString].value -> r)
val uid = u.get.asInstanceOf[BSONString].value
b += (uid -> r)
if (r == 0) leaderId = uid.some
r = r + 1
}
b.result()
case _ => Map.empty
b.result -> leaderId
case _ => Map.empty -> none
}
}
}

View file

@ -23,7 +23,8 @@ case class Tournament(
createdAt: DateTime,
createdBy: String,
startsAt: DateTime,
winnerId: Option[String] = None) {
winnerId: Option[String] = None,
leaderId: Option[String] = None) {
def isCreated = status == Status.Created
def isStarted = status == Status.Started

View file

@ -111,9 +111,17 @@ object TournamentRepo {
def setWinnerId(tourId: String, userId: String) = coll.update(
selectId(tourId),
BSONDocument("$set" -> BSONDocument("winner" -> userId))
BSONDocument("$set" -> BSONDocument(
"winner" -> userId,
"leader" -> userId
))
).void
def setLeaderId(tourId: String, userId: String) = coll.uncheckedUpdate(
selectId(tourId),
BSONDocument("$set" -> BSONDocument("leader" -> userId))
)
private def allCreatedSelect(aheadMinutes: Int) = createdSelect ++ BSONDocument(
"$or" -> BSONArray(
BSONDocument("schedule" -> BSONDocument("$exists" -> false)),