-
Notifications
You must be signed in to change notification settings - Fork 41
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[6.0] Global.deserializeTo[] method #979
Conversation
* @param votes - votes for changing system parameters | ||
* @param _bytes - serialized bytes of the header when not `null` | ||
*/ | ||
class ErgoHeader(override val version: ErgoHeader.Version, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the motivation for having this class. Why sigma.data.CHeader is not enough?
I think it is better to have unification of domain types if possible.
data/shared/src/main/scala/org/ergoplatform/HeaderWithoutPow.scala
Outdated
Show resolved
Hide resolved
|
||
override def parse(r: SigmaByteReader): Long = { | ||
readUint32BE(r.getBytes(4)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Array allocation can be avoided.
lazy val checkPowMethod = SMethod( | ||
this, "checkPow", SFunc(Array(SHeader), SBoolean), 16, GroupGenerator.costKind) // todo: cost | ||
.withIRInfo(MethodCallIrBuilder) | ||
.withInfo(Xor, "Check PoW of this header") // todo: desc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can use .withInfo
overload without opDesc. Note, opDesc should point to the operation this Method can be lowered to. In this case there is no such operation.
lazy val deserializeRawMethod = SMethod( | ||
this, "deserializeRaw", SFunc(Array(SGlobal, SByteArray), tT, Array(paramT)), 3, Xor.costKind) // todo: cost | ||
.copy(irInfo = MethodIRInfo(None, Some(desJava), None)) | ||
.withInfo(Xor, "Byte-wise XOR of two collections of bytes", // todo: desc |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use different .withInfo
overload.
@@ -23,6 +25,9 @@ case class MethodCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[S | |||
w.putValue(mc.obj, objInfo) | |||
assert(mc.args.nonEmpty) | |||
w.putValues(mc.args, argsInfo, argsItemInfo) | |||
if(mc.method.name == SGlobalMethods.deserializeRawMethod.name){ | |||
w.putType(mc.tpe, typeInfo) | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better leave MethodCall unchanged and use PolyMethodCall as described in #980
This will also give both simplicity of code and efficiency of execution, because specialization will happen at compile time and most of the method calls are simple method calls.
|
||
an[SerializerException] should be thrownBy ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For negative cases there is assertExceptionThrown
which allows testing not only exception type but also the message. See other usages of it as an example.
@@ -19,6 +20,25 @@ import sigma.serialization.OpCodes | |||
|
|||
import scala.collection.mutable.ArrayBuffer | |||
|
|||
|
|||
case class DeserializeRawBytes[V <: SType](bytes: Value[SByteArray], tpe: V) extends NotReadyValue[V] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not necessary to introduce new operation with opcode for each method, MethodCall is enough and can be translated to MethodCall from GraphBuilding.
@@ -536,6 +556,9 @@ trait GraphBuilding extends SigmaLibrary { IR: IRContext => | |||
val e = stypeToElem(optTpe.elemType) | |||
ctx.getVar(id)(e) | |||
|
|||
case DeserializeRawBytes(bytes, tpe) => | |||
sigmaDslBuilder.deserializeRaw(asRep[Coll[Byte]](eval(bytes)))(stypeToElem(tpe)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not necessary.
} | ||
case _ => | ||
error(s"Cannot find Global method: $n", bound.sourceContext) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, see also 1 comment
@@ -1824,6 +1825,16 @@ case object SGlobalMethods extends MonoTypeMethods { | |||
.withInfo(Xor, "Byte-wise XOR of two collections of bytes", | |||
ArgInfo("left", "left operand"), ArgInfo("right", "right operand")) | |||
|
|||
private val deserializeCostKind = PerItemCost( | |||
baseCost = JitCost(20), perChunkCost = JitCost(7), chunkSize = 128) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels like two big chunkSize (or small perChunkCost) considering that deserialization is many allocations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, raised cost to
baseCost = JitCost(30), perChunkCost = JitCost(20), chunkSize = 32
ae351a0
to
f195072
Compare
This PR is introducing new Global.deserializeRaw method which is allowing to deserialize a typed object from underlying bytes. It is compatible (has roundtrip with) Global.serialize from #989 .
example: