optimise study comment updates
parent
28f619c815
commit
8b4797797d
|
@ -80,7 +80,7 @@ object BSONHandlers {
|
|||
|
||||
implicit val ShapesBSONHandler: BSONHandler[BSONArray, Shapes] =
|
||||
isoHandler[Shapes, List[Shape], BSONArray](
|
||||
(s: Shapes) => s.value.distinct,
|
||||
(s: Shapes) => s.value,
|
||||
Shapes(_)
|
||||
)
|
||||
|
||||
|
@ -108,8 +108,11 @@ object BSONHandlers {
|
|||
}
|
||||
private implicit val CommentBSONHandler = Macros.handler[Comment]
|
||||
|
||||
private def readComments(r: Reader) =
|
||||
Comments(r.getsD[Comment]("co").filter(_.text.value.nonEmpty))
|
||||
implicit val CommentsBSONHandler: BSONHandler[BSONArray, Comments] =
|
||||
isoHandler[Comments, List[Comment], BSONArray](
|
||||
(s: Comments) => s.value,
|
||||
Comments(_)
|
||||
)
|
||||
|
||||
private implicit def CrazyDataBSONHandler: BSON[Crazyhouse.Data] = new BSON[Crazyhouse.Data] {
|
||||
private def writePocket(p: Crazyhouse.Pocket) = p.roles.map(_.forsyth).mkString
|
||||
|
@ -143,7 +146,7 @@ object BSONHandlers {
|
|||
fen = r.get[FEN]("f"),
|
||||
check = r boolD "c",
|
||||
shapes = r.getO[Shapes]("h") | Shapes.empty,
|
||||
comments = readComments(r),
|
||||
comments = r.getO[Comments]("co") | Comments.empty,
|
||||
glyphs = r.getO[Glyphs]("g") | Glyphs.empty,
|
||||
crazyData = r.getO[Crazyhouse.Data]("z"),
|
||||
clock = r.getO[Centis]("l"),
|
||||
|
@ -156,8 +159,8 @@ object BSONHandlers {
|
|||
"s" -> s.move.san,
|
||||
"f" -> s.fen,
|
||||
"c" -> w.boolO(s.check),
|
||||
"h" -> w.listO(s.shapes.list.distinct),
|
||||
"co" -> w.listO(s.comments.list),
|
||||
"h" -> s.shapes.value.nonEmpty.option(s.shapes),
|
||||
"co" -> s.comments.value.nonEmpty.option(s.comments),
|
||||
"g" -> s.glyphs.nonEmpty,
|
||||
"l" -> s.clock,
|
||||
"z" -> s.crazyData,
|
||||
|
@ -171,7 +174,7 @@ object BSONHandlers {
|
|||
fen = r.get[FEN]("f"),
|
||||
check = r boolD "c",
|
||||
shapes = r.getO[Shapes]("h") | Shapes.empty,
|
||||
comments = readComments(r),
|
||||
comments = r.getO[Comments]("co") | Comments.empty,
|
||||
glyphs = r.getO[Glyphs]("g") | Glyphs.empty,
|
||||
clock = r.getO[Centis]("l"),
|
||||
crazyData = r.getO[Crazyhouse.Data]("z"),
|
||||
|
@ -181,8 +184,8 @@ object BSONHandlers {
|
|||
"p" -> s.ply,
|
||||
"f" -> s.fen,
|
||||
"c" -> w.boolO(s.check),
|
||||
"h" -> w.listO(s.shapes.list.distinct),
|
||||
"co" -> w.listO(s.comments.list),
|
||||
"h" -> s.shapes.value.nonEmpty.option(s.shapes),
|
||||
"co" -> s.comments.value.nonEmpty.option(s.comments),
|
||||
"g" -> s.glyphs.nonEmpty,
|
||||
"l" -> s.clock,
|
||||
"z" -> s.crazyData,
|
||||
|
|
|
@ -59,17 +59,28 @@ final class ChapterRepo(coll: Coll) {
|
|||
def setTagsFor(chapter: Chapter) =
|
||||
coll.updateField($id(chapter.id), "tags", chapter.tags).void
|
||||
|
||||
def setShapes(chapter: Chapter, path: Path, shapes: lila.tree.Node.Shapes): Option[Funit] =
|
||||
pathToField(chapter, path) map { field =>
|
||||
val shapesField = s"$field.h"
|
||||
if (shapes.value.isEmpty) coll.unsetField($id(chapter.id), shapesField).void
|
||||
else coll.updateField($id(chapter.id), shapesField, shapes).void
|
||||
def setShapes(chapter: Chapter, path: Path, shapes: lila.tree.Node.Shapes): Funit =
|
||||
setNodeValue(chapter, path, "h", shapes.value.nonEmpty option shapes)
|
||||
|
||||
def setComments(chapter: Chapter, path: Path, comments: lila.tree.Node.Comments): Funit =
|
||||
setNodeValue(chapter, path, "co", comments.value.nonEmpty option comments)
|
||||
|
||||
private def setNodeValue[A: BSONValueWriter](chapter: Chapter, path: Path, field: String, value: Option[A]): Funit =
|
||||
pathToField(chapter, path, field) match {
|
||||
case None =>
|
||||
logger.warn(s"Can't setNodeValue ${chapter.id} $path $field")
|
||||
funit
|
||||
case Some(field) =>
|
||||
(value match {
|
||||
case None => coll.unsetField($id(chapter.id), field)
|
||||
case Some(v) => coll.updateField($id(chapter.id), field, v)
|
||||
}) void
|
||||
}
|
||||
|
||||
// root.n[0].n[0].n[1].n[0].n[2]
|
||||
private def pathToField(chapter: Chapter, path: Path): Option[String] =
|
||||
private def pathToField(chapter: Chapter, path: Path, subField: String): Option[String] =
|
||||
chapter.root.children.pathToIndexes(path) map { indexes =>
|
||||
s"root.n.${indexes.mkString(".n.")}"
|
||||
s"root.n.${indexes.mkString(".n.")}.$subField"
|
||||
}
|
||||
|
||||
private[study] def idNamesByStudyIds(studyIds: Seq[Study.Id]): Fu[Map[Study.Id, Vector[Chapter.IdName]]] =
|
||||
|
|
|
@ -251,10 +251,7 @@ final class StudyApi(
|
|||
chapter.setShapes(shapes, position.path) match {
|
||||
case Some(newChapter) =>
|
||||
studyRepo.updateNow(study)
|
||||
chapterRepo.setShapes(newChapter, position.path, shapes) | {
|
||||
logger.warn(s"Failed to setShapes $studyId $position")
|
||||
chapterRepo update newChapter
|
||||
} >>-
|
||||
chapterRepo.setShapes(newChapter, position.path, shapes) >>-
|
||||
sendTo(study, Socket.SetShapes(position, shapes, uid))
|
||||
case None => fufail(s"Invalid setShapes $position $shapes") >>- reloadUid(study, uid)
|
||||
}
|
||||
|
@ -287,11 +284,13 @@ final class StudyApi(
|
|||
chapter.setComment(comment, position.path) match {
|
||||
case Some(newChapter) =>
|
||||
studyRepo.updateNow(study)
|
||||
newChapter.root.nodeAt(position.path).flatMap(_.comments findBy comment.by) ?? { c =>
|
||||
chapterRepo.update(newChapter) >>-
|
||||
sendTo(study, Socket.SetComment(position, c, uid)) >>-
|
||||
indexStudy(study) >>-
|
||||
sendStudyEnters(study, userId)
|
||||
newChapter.root.nodeAt(position.path) ?? { node =>
|
||||
node.comments.findBy(comment.by) ?? { c =>
|
||||
chapterRepo.setComments(newChapter, position.path, node.comments.filterEmpty) >>-
|
||||
sendTo(study, Socket.SetComment(position, c, uid)) >>-
|
||||
indexStudy(study) >>-
|
||||
sendStudyEnters(study, userId)
|
||||
}
|
||||
}
|
||||
case None => fufail(s"Invalid setComment $studyId $position") >>- reloadUid(study, uid)
|
||||
}
|
||||
|
|
|
@ -107,7 +107,9 @@ object Node {
|
|||
}
|
||||
case class Shapes(value: List[Shape]) extends AnyVal {
|
||||
def list = value
|
||||
def ++(shapes: Shapes) = Shapes(value ::: shapes.value)
|
||||
def ++(shapes: Shapes) = Shapes {
|
||||
(value ::: shapes.value).distinct
|
||||
}
|
||||
}
|
||||
object Shapes {
|
||||
val empty = Shapes(Nil)
|
||||
|
@ -159,6 +161,11 @@ object Node {
|
|||
value.filterNot(_.id == commentId)
|
||||
}
|
||||
def +(comment: Comment) = Comments(comment :: value)
|
||||
|
||||
def filterEmpty = Comments(value.filter(_.text.value.nonEmpty))
|
||||
}
|
||||
object Comments {
|
||||
val empty = Comments(Nil)
|
||||
}
|
||||
|
||||
// TODO copied from lila.game
|
||||
|
|
Loading…
Reference in New Issue