blurs optimizations

blurEnhance
Thibault Duplessis 2017-05-08 14:08:00 +02:00
parent 5f5750bde4
commit f1026528ca
5 changed files with 45 additions and 26 deletions

View File

@ -7,7 +7,8 @@ sealed trait Blurs extends Any {
def nb: Int
def bitsOption: Option[BitSet]
def bitsOption: Option[Long]
def bitSetOption: Option[BitSet]
def isEmpty = nb == 0
@ -21,6 +22,7 @@ object Blurs {
case class Nb(nb: Int) extends AnyVal with Blurs {
def bitsOption = none
def bitSetOption = none
def add(moveIndex: Int) = blursZero.zero add moveIndex
}
@ -31,26 +33,39 @@ object Blurs {
def nb = java.lang.Long.bitCount(bits)
def bitsOption = bitSet.some
def bitsOption = bits.some
def bitSetOption = bitSet.some
def add(moveIndex: Int) =
if (moveIndex < 0 || moveIndex > 63) this
else Bits(bits | (1L << moveIndex))
def asInt = (bits <= Int.MaxValue) option bits.toInt
override def toString = java.lang.Long toBinaryString bits
}
implicit val blursZero = Zero.instance[Blurs](Bits(0l))
import reactivemongo.bson._
implicit val BlursBSONHandler = new BSONHandler[BSONValue, Blurs] {
def read(bv: BSONValue): Blurs = bv match {
case BSONInteger(nb) => Nb(nb)
private[game] implicit val BlursBitsBSONHandler = new BSONHandler[BSONValue, Bits] {
def read(bv: BSONValue): Bits = bv match {
case BSONInteger(bits) => Bits(bits)
case BSONLong(bits) => Bits(bits)
case v => sys error s"Invalid blurs $v"
case v => sys error s"Invalid blurs bits $v"
}
def write(b: Blurs) = b match {
case Nb(nb) => BSONInteger(nb)
case Bits(bits) => BSONLong(bits)
def write(b: Bits): BSONValue =
b.asInt.fold[BSONValue](BSONLong(b.bits))(BSONInteger.apply)
}
private[game] implicit val BlursNbBSONReader = Macros.reader[Nb]
private[game] implicit val BlursBSONWriter = new BSONWriter[Blurs, BSONValue] {
def write(b: Blurs): BSONValue = b match {
case bits: Bits => BlursBitsBSONHandler write bits
// only Bits can be written; Nb results to Bits(0)
case _ => BSONInteger(0)
}
}
}

View File

@ -9,7 +9,7 @@ import reactivemongo.bson._
import lila.db.BSON.BSONJodaDateTimeHandler
import lila.db.ByteArray
import lila.db.ByteArray.ByteArrayBSONHandler
import Blurs.BlursBSONHandler
import Blurs.BlursBSONWriter
import chess.Centis
private[game] object GameDiff {
@ -81,7 +81,7 @@ private[game] object GameDiff {
dOpt(s"$name$isOfferingDraw", player(_).isOfferingDraw, w.boolO)
dOpt(s"$name$isOfferingRematch", player(_).isOfferingRematch, w.boolO)
dOpt(s"$name$proposeTakebackAt", player(_).proposeTakebackAt, w.intO)
d(s"$name$blurs", player(_).blurs, BlursBSONHandler.write)
d(s"$name$blursBits", player(_).blurs, BlursBSONWriter.write)
}
d(movedAt, _.movedAt, BSONJodaDateTimeHandler.write)

View File

@ -2,6 +2,7 @@ package lila.game
import play.api.libs.json._
import lila.common.PimpedJson._
import chess.variant.Crazyhouse
object JsonView {
@ -38,4 +39,11 @@ object JsonView {
implicit val crazyhouseDataWriter: OWrites[chess.variant.Crazyhouse.Data] = OWrites { v =>
Json.obj("pockets" -> List(v.pockets.white, v.pockets.black))
}
implicit val blursWriter: OWrites[Blurs] = OWrites { blurs =>
Json.obj("nb" -> blurs.nb).add("bits" -> (blurs match {
case bits: Blurs.Bits => bits.toString.some
case _ => none
}))
}
}

View File

@ -131,7 +131,8 @@ object Player {
val rating = "e"
val ratingDiff = "d"
val provisional = "p"
val blurs = "b"
val blursNb = "b"
val blursBits = "l"
val holdAlert = "h"
val berserk = "be"
val name = "na"
@ -158,7 +159,7 @@ object Player {
implicit val playerBSONHandler = new BSON[Builder] {
import BSONFields._
import Blurs.{ BlursBSONHandler, blursZero }
import Blurs._
def reads(r: BSON.Reader) = color => id => userId => win => Player(
id = id,
@ -173,7 +174,7 @@ object Player {
rating = r intO rating flatMap ratingRange(userId),
ratingDiff = r intO ratingDiff flatMap ratingDiffRange(userId),
provisional = r boolD provisional,
blurs = r.getD[Blurs](blurs),
blurs = r.getO[Blurs.Bits](blursBits) orElse r.getO[Blurs.Nb](blursNb) getOrElse blursZero.zero,
holdAlert = r.getO[HoldAlert](holdAlert),
berserk = r boolD berserk,
name = r strO name
@ -190,10 +191,7 @@ object Player {
rating -> p.rating,
ratingDiff -> p.ratingDiff,
provisional -> w.boolO(p.provisional),
blurs -> {
if (p.blurs.isEmpty) none
else p.blurs.some
},
blursBits -> (!p.blurs.isEmpty).option(BlursBSONWriter write p.blurs),
holdAlert -> p.holdAlert,
name -> p.name
)

View File

@ -6,8 +6,8 @@ import scala.math
import org.apache.commons.lang3.StringEscapeUtils.escapeHtml4
import play.api.libs.json._
import lila.common.PimpedJson._
import lila.common.ApiVersion
import lila.common.PimpedJson._
import lila.game.JsonView._
import lila.game.{ Pov, Game, PerfPicker, Source, GameRepo, CorrespondenceClock }
import lila.pref.Pref
@ -282,13 +282,11 @@ final class JsonView(
"createdAt" -> game.createdAt
).noNull
private def blurs(game: Game, player: lila.game.Player) = {
val percent = game.playerBlurPercent(player.color)
(percent > 30) option Json.obj(
"nb" -> player.blurs.nb,
"percent" -> percent
)
}
private def blurs(game: Game, player: lila.game.Player) =
!player.blurs.isEmpty option {
blursWriter.writes(player.blurs) +
("percent" -> JsNumber(game.playerBlurPercent(player.color)))
}
private def hold(player: lila.game.Player) = player.holdAlert map { h =>
Json.obj(