Skip to content
This repository has been archived by the owner on Apr 13, 2022. It is now read-only.

Commit

Permalink
Merge pull request #386 from ScorexFoundation/msgs-opt
Browse files Browse the repository at this point in the history
Message deserialization optimization
  • Loading branch information
kushti committed Nov 17, 2020
2 parents 4405ea4 + a2505c7 commit ba19aba
Showing 1 changed file with 17 additions and 7 deletions.
24 changes: 17 additions & 7 deletions src/main/scala/scorex/core/network/message/BasicMessagesRepo.scala
Expand Up @@ -10,6 +10,8 @@ import scorex.util.Extensions._
import scorex.util.serialization.{Reader, Writer}
import scorex.util.{ModifierId, ScorexLogging, bytesToId, idToBytes}

import scala.collection.immutable

case class ModifiersData(typeId: ModifierTypeId, modifiers: Map[ModifierId, Array[Byte]])

case class InvData(typeId: ModifierTypeId, ids: Seq[ModifierId])
Expand Down Expand Up @@ -131,13 +133,15 @@ class ModifiersSpec(maxMessageSize: Int) extends MessageSpecV1[ModifiersData] wi
override val messageCode: MessageCode = MessageCode
override val messageName: String = MessageName

private val HeaderLength = 5 // msg type Id + modifiersCount

override def serialize(data: ModifiersData, w: Writer): Unit = {

val typeId = data.typeId
val modifiers = data.modifiers
require(modifiers.nonEmpty, "empty modifiers list")

val (msgCount, msgSize) = modifiers.foldLeft((0, 5)) { case ((c, s), (id, modifier)) =>
val (msgCount, msgSize) = modifiers.foldLeft((0, HeaderLength)) { case ((c, s), (id, modifier)) =>
val size = s + NodeViewModifier.ModifierIdSize + 4 + modifier.length
val count = if (size <= maxMessageSize) c + 1 else c
count -> size
Expand All @@ -154,21 +158,27 @@ class ModifiersSpec(maxMessageSize: Int) extends MessageSpecV1[ModifiersData] wi
}

if (msgSize > maxMessageSize) {
log.warn(s"Message with modifiers ${modifiers.keySet} have size $msgSize exceeding limit $maxMessageSize." +
log.warn(s"Message with modifiers ${modifiers.keySet} has size $msgSize exceeding limit $maxMessageSize." +
s" Sending ${w.length() - start} bytes instead")
}
}

override def parse(r: Reader): ModifiersData = {
val typeId = ModifierTypeId @@ r.getByte()
val count = r.getUInt().toIntExact
val seq = (0 until count).map { _ =>
val typeId = ModifierTypeId @@ r.getByte() // 1 byte
val count = r.getUInt().toIntExact // 8 bytes
val resMap = immutable.Map.newBuilder[ModifierId, Array[Byte]]
(0 until count).foldLeft(HeaderLength) { case (msgSize, _) =>
val id = bytesToId(r.getBytes(NodeViewModifier.ModifierIdSize))
val objBytesCnt = r.getUInt().toIntExact
val newMsgSize = msgSize + NodeViewModifier.ModifierIdSize + objBytesCnt
if (newMsgSize > maxMessageSize) {
throw new Exception("Too big message with modifiers, size: " + maxMessageSize)
}
val obj = r.getBytes(objBytesCnt)
id -> obj
resMap += (id -> obj)
newMsgSize
}
ModifiersData(typeId, seq.toMap)
ModifiersData(typeId, resMap.result())
}
}

Expand Down

0 comments on commit ba19aba

Please sign in to comment.