forked from TrueCloudLab/neoneo-go
*: use more efficient WriteBytes where appropriate
Before this patch on block import we could easily be spending more than 6 seconds out of 30 in Uint256 encoding for UnspentBalance, now it's completely off the radar.
This commit is contained in:
parent
e7687d620d
commit
844491d365
23 changed files with 40 additions and 40 deletions
|
@ -19,7 +19,7 @@ func emit(w *io.BinWriter, instr opcode.Opcode, b []byte) {
|
||||||
|
|
||||||
// emitOpcode emits a single VM Instruction the given buffer.
|
// emitOpcode emits a single VM Instruction the given buffer.
|
||||||
func emitOpcode(w *io.BinWriter, instr opcode.Opcode) {
|
func emitOpcode(w *io.BinWriter, instr opcode.Opcode) {
|
||||||
w.WriteLE(byte(instr))
|
w.WriteBytes([]byte{byte(instr)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// emitBool emits a bool type the given buffer.
|
// emitBool emits a bool type the given buffer.
|
||||||
|
|
|
@ -18,7 +18,7 @@ var _ payload.Commit = (*commit)(nil)
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable interface.
|
// EncodeBinary implements io.Serializable interface.
|
||||||
func (c *commit) EncodeBinary(w *io.BinWriter) {
|
func (c *commit) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteBE(c.signature)
|
w.WriteBytes(c.signature[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeBinary implements io.Serializable interface.
|
// DecodeBinary implements io.Serializable interface.
|
||||||
|
|
|
@ -162,7 +162,7 @@ func (p *Payload) SetHeight(h uint32) {
|
||||||
// EncodeBinaryUnsigned writes payload to w excluding signature.
|
// EncodeBinaryUnsigned writes payload to w excluding signature.
|
||||||
func (p Payload) EncodeBinaryUnsigned(w *io.BinWriter) {
|
func (p Payload) EncodeBinaryUnsigned(w *io.BinWriter) {
|
||||||
w.WriteLE(p.version)
|
w.WriteLE(p.version)
|
||||||
w.WriteBE(p.prevHash[:])
|
w.WriteBytes(p.prevHash[:])
|
||||||
w.WriteLE(p.height)
|
w.WriteLE(p.height)
|
||||||
w.WriteLE(p.validatorIndex)
|
w.WriteLE(p.validatorIndex)
|
||||||
w.WriteLE(p.timestamp)
|
w.WriteLE(p.timestamp)
|
||||||
|
@ -254,7 +254,7 @@ func (p *Payload) DecodeBinary(r *io.BinReader) {
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable interface.
|
// EncodeBinary implements io.Serializable interface.
|
||||||
func (m *message) EncodeBinary(w *io.BinWriter) {
|
func (m *message) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteLE(byte(m.Type))
|
w.WriteBytes([]byte{byte(m.Type)})
|
||||||
w.WriteLE(m.ViewNumber)
|
w.WriteLE(m.ViewNumber)
|
||||||
m.payload.EncodeBinary(w)
|
m.payload.EncodeBinary(w)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ var _ payload.PrepareRequest = (*prepareRequest)(nil)
|
||||||
func (p *prepareRequest) EncodeBinary(w *io.BinWriter) {
|
func (p *prepareRequest) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteLE(p.timestamp)
|
w.WriteLE(p.timestamp)
|
||||||
w.WriteLE(p.nonce)
|
w.WriteLE(p.nonce)
|
||||||
w.WriteBE(p.nextConsensus[:])
|
w.WriteBytes(p.nextConsensus[:])
|
||||||
w.WriteArray(p.transactionHashes)
|
w.WriteArray(p.transactionHashes)
|
||||||
p.minerTx.EncodeBinary(w)
|
p.minerTx.EncodeBinary(w)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ var _ payload.PrepareResponse = (*prepareResponse)(nil)
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable interface.
|
// EncodeBinary implements io.Serializable interface.
|
||||||
func (p *prepareResponse) EncodeBinary(w *io.BinWriter) {
|
func (p *prepareResponse) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteBE(p.preparationHash[:])
|
w.WriteBytes(p.preparationHash[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeBinary implements io.Serializable interface.
|
// DecodeBinary implements io.Serializable interface.
|
||||||
|
|
|
@ -79,7 +79,7 @@ func (m *recoveryMessage) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteVarUint(0)
|
w.WriteVarUint(0)
|
||||||
} else {
|
} else {
|
||||||
w.WriteVarUint(util.Uint256Size)
|
w.WriteVarUint(util.Uint256Size)
|
||||||
w.WriteBE(m.preparationHash[:])
|
w.WriteBytes(m.preparationHash[:])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ func (p *commitCompact) DecodeBinary(r *io.BinReader) {
|
||||||
func (p *commitCompact) EncodeBinary(w *io.BinWriter) {
|
func (p *commitCompact) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteLE(p.ViewNumber)
|
w.WriteLE(p.ViewNumber)
|
||||||
w.WriteLE(p.ValidatorIndex)
|
w.WriteLE(p.ValidatorIndex)
|
||||||
w.WriteBE(p.Signature)
|
w.WriteBytes(p.Signature[:])
|
||||||
w.WriteVarBytes(p.InvocationScript)
|
w.WriteVarBytes(p.InvocationScript)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,13 +121,13 @@ func (s *AccountState) DecodeBinary(br *io.BinReader) {
|
||||||
// EncodeBinary encodes AccountState to the given BinWriter.
|
// EncodeBinary encodes AccountState to the given BinWriter.
|
||||||
func (s *AccountState) EncodeBinary(bw *io.BinWriter) {
|
func (s *AccountState) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteLE(s.Version)
|
bw.WriteLE(s.Version)
|
||||||
bw.WriteLE(s.ScriptHash)
|
bw.WriteBytes(s.ScriptHash[:])
|
||||||
bw.WriteLE(s.IsFrozen)
|
bw.WriteLE(s.IsFrozen)
|
||||||
bw.WriteArray(s.Votes)
|
bw.WriteArray(s.Votes)
|
||||||
|
|
||||||
bw.WriteVarUint(uint64(len(s.Balances)))
|
bw.WriteVarUint(uint64(len(s.Balances)))
|
||||||
for k, v := range s.Balances {
|
for k, v := range s.Balances {
|
||||||
bw.WriteLE(k)
|
bw.WriteBytes(k[:])
|
||||||
bw.WriteArray(v)
|
bw.WriteArray(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,19 +73,19 @@ func (a *AssetState) DecodeBinary(br *io.BinReader) {
|
||||||
|
|
||||||
// EncodeBinary implements Serializable interface.
|
// EncodeBinary implements Serializable interface.
|
||||||
func (a *AssetState) EncodeBinary(bw *io.BinWriter) {
|
func (a *AssetState) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteLE(a.ID)
|
bw.WriteBytes(a.ID[:])
|
||||||
bw.WriteLE(a.AssetType)
|
bw.WriteLE(a.AssetType)
|
||||||
bw.WriteString(a.Name)
|
bw.WriteString(a.Name)
|
||||||
bw.WriteLE(a.Amount)
|
bw.WriteLE(a.Amount)
|
||||||
bw.WriteLE(a.Available)
|
bw.WriteLE(a.Available)
|
||||||
bw.WriteLE(a.Precision)
|
bw.WriteLE(a.Precision)
|
||||||
bw.WriteLE(a.FeeMode)
|
bw.WriteLE(a.FeeMode)
|
||||||
bw.WriteLE(a.FeeAddress)
|
bw.WriteBytes(a.FeeAddress[:])
|
||||||
|
|
||||||
a.Owner.EncodeBinary(bw)
|
a.Owner.EncodeBinary(bw)
|
||||||
|
|
||||||
bw.WriteLE(a.Admin)
|
bw.WriteBytes(a.Admin[:])
|
||||||
bw.WriteLE(a.Issuer)
|
bw.WriteBytes(a.Issuer[:])
|
||||||
bw.WriteLE(a.Expiration)
|
bw.WriteLE(a.Expiration)
|
||||||
bw.WriteLE(a.IsFrozen)
|
bw.WriteLE(a.IsFrozen)
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,12 +111,12 @@ func NewBlockFromTrimmedBytes(b []byte) (*Block, error) {
|
||||||
func (b *Block) Trim() ([]byte, error) {
|
func (b *Block) Trim() ([]byte, error) {
|
||||||
buf := io.NewBufBinWriter()
|
buf := io.NewBufBinWriter()
|
||||||
b.encodeHashableFields(buf.BinWriter)
|
b.encodeHashableFields(buf.BinWriter)
|
||||||
buf.WriteLE(uint8(1))
|
buf.WriteBytes([]byte{1})
|
||||||
b.Script.EncodeBinary(buf.BinWriter)
|
b.Script.EncodeBinary(buf.BinWriter)
|
||||||
|
|
||||||
buf.WriteVarUint(uint64(len(b.Transactions)))
|
buf.WriteVarUint(uint64(len(b.Transactions)))
|
||||||
for _, tx := range b.Transactions {
|
for _, tx := range b.Transactions {
|
||||||
buf.WriteLE(tx.Hash())
|
tx.Hash().EncodeBinary(buf.BinWriter)
|
||||||
}
|
}
|
||||||
if buf.Err != nil {
|
if buf.Err != nil {
|
||||||
return nil, buf.Err
|
return nil, buf.Err
|
||||||
|
|
|
@ -87,7 +87,7 @@ func (b *BlockBase) DecodeBinary(br *io.BinReader) {
|
||||||
// EncodeBinary implements Serializable interface
|
// EncodeBinary implements Serializable interface
|
||||||
func (b *BlockBase) EncodeBinary(bw *io.BinWriter) {
|
func (b *BlockBase) EncodeBinary(bw *io.BinWriter) {
|
||||||
b.encodeHashableFields(bw)
|
b.encodeHashableFields(bw)
|
||||||
bw.WriteLE(uint8(1))
|
bw.WriteBytes([]byte{1})
|
||||||
b.Script.EncodeBinary(bw)
|
b.Script.EncodeBinary(bw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,12 +116,12 @@ func (b *BlockBase) createHash() {
|
||||||
// see Hash() for more information about the fields.
|
// see Hash() for more information about the fields.
|
||||||
func (b *BlockBase) encodeHashableFields(bw *io.BinWriter) {
|
func (b *BlockBase) encodeHashableFields(bw *io.BinWriter) {
|
||||||
bw.WriteLE(b.Version)
|
bw.WriteLE(b.Version)
|
||||||
bw.WriteLE(b.PrevHash)
|
bw.WriteBytes(b.PrevHash[:])
|
||||||
bw.WriteLE(b.MerkleRoot)
|
bw.WriteBytes(b.MerkleRoot[:])
|
||||||
bw.WriteLE(b.Timestamp)
|
bw.WriteLE(b.Timestamp)
|
||||||
bw.WriteLE(b.Index)
|
bw.WriteLE(b.Index)
|
||||||
bw.WriteLE(b.ConsensusData)
|
bw.WriteLE(b.ConsensusData)
|
||||||
bw.WriteLE(b.NextConsensus)
|
bw.WriteBytes(b.NextConsensus[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// decodeHashableFields decodes the fields used for hashing.
|
// decodeHashableFields decodes the fields used for hashing.
|
||||||
|
|
|
@ -29,5 +29,5 @@ func (h *Header) DecodeBinary(r *io.BinReader) {
|
||||||
// EncodeBinary implements Serializable interface.
|
// EncodeBinary implements Serializable interface.
|
||||||
func (h *Header) EncodeBinary(w *io.BinWriter) {
|
func (h *Header) EncodeBinary(w *io.BinWriter) {
|
||||||
h.BlockBase.EncodeBinary(w)
|
h.BlockBase.EncodeBinary(w)
|
||||||
w.WriteLE(uint8(0))
|
w.WriteBytes([]byte{0})
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ func getAppExecResultFromStore(s storage.Store, hash util.Uint256) (*AppExecResu
|
||||||
|
|
||||||
// EncodeBinary implements the Serializable interface.
|
// EncodeBinary implements the Serializable interface.
|
||||||
func (ne NotificationEvent) EncodeBinary(w *io.BinWriter) {
|
func (ne NotificationEvent) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteLE(ne.ScriptHash)
|
w.WriteBytes(ne.ScriptHash[:])
|
||||||
vm.EncodeBinaryStackItem(ne.Item, w)
|
vm.EncodeBinaryStackItem(ne.Item, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ func (ne *NotificationEvent) DecodeBinary(r *io.BinReader) {
|
||||||
|
|
||||||
// EncodeBinary implements the Serializable interface.
|
// EncodeBinary implements the Serializable interface.
|
||||||
func (aer *AppExecResult) EncodeBinary(w *io.BinWriter) {
|
func (aer *AppExecResult) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteLE(aer.TxHash)
|
w.WriteBytes(aer.TxHash[:])
|
||||||
w.WriteArray(aer.Events)
|
w.WriteArray(aer.Events)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ func (s *SpentCoinState) DecodeBinary(br *io.BinReader) {
|
||||||
|
|
||||||
// EncodeBinary implements Serializable interface.
|
// EncodeBinary implements Serializable interface.
|
||||||
func (s *SpentCoinState) EncodeBinary(bw *io.BinWriter) {
|
func (s *SpentCoinState) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteLE(s.txHash)
|
bw.WriteBytes(s.txHash[:])
|
||||||
bw.WriteLE(s.txHeight)
|
bw.WriteLE(s.txHeight)
|
||||||
bw.WriteVarUint(uint64(len(s.items)))
|
bw.WriteVarUint(uint64(len(s.items)))
|
||||||
for k, v := range s.items {
|
for k, v := range s.items {
|
||||||
|
|
|
@ -22,6 +22,6 @@ func (in *Input) DecodeBinary(br *io.BinReader) {
|
||||||
|
|
||||||
// EncodeBinary implements Serializable interface.
|
// EncodeBinary implements Serializable interface.
|
||||||
func (in *Input) EncodeBinary(bw *io.BinWriter) {
|
func (in *Input) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteLE(in.PrevHash)
|
bw.WriteBytes(in.PrevHash[:])
|
||||||
bw.WriteLE(in.PrevIndex)
|
bw.WriteLE(in.PrevIndex)
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,9 +42,9 @@ func (out *Output) DecodeBinary(br *io.BinReader) {
|
||||||
|
|
||||||
// EncodeBinary implements Serializable interface.
|
// EncodeBinary implements Serializable interface.
|
||||||
func (out *Output) EncodeBinary(bw *io.BinWriter) {
|
func (out *Output) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteLE(out.AssetID)
|
bw.WriteBytes(out.AssetID[:])
|
||||||
bw.WriteLE(out.Amount)
|
bw.WriteLE(out.Amount)
|
||||||
bw.WriteLE(out.ScriptHash)
|
bw.WriteBytes(out.ScriptHash[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements the Marshaler interface.
|
// MarshalJSON implements the Marshaler interface.
|
||||||
|
|
|
@ -50,5 +50,5 @@ func (tx *RegisterTX) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteLE(tx.Amount)
|
bw.WriteLE(tx.Amount)
|
||||||
bw.WriteLE(tx.Precision)
|
bw.WriteLE(tx.Precision)
|
||||||
bw.WriteBytes(tx.Owner.Bytes())
|
bw.WriteBytes(tx.Owner.Bytes())
|
||||||
bw.WriteLE(tx.Admin)
|
bw.WriteBytes(tx.Admin[:])
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,7 @@ func (u UnspentCoins) commit(store storage.Store) error {
|
||||||
func (s *UnspentCoinState) EncodeBinary(bw *io.BinWriter) {
|
func (s *UnspentCoinState) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteVarUint(uint64(len(s.states)))
|
bw.WriteVarUint(uint64(len(s.states)))
|
||||||
for _, state := range s.states {
|
for _, state := range s.states {
|
||||||
bw.WriteLE(byte(state))
|
bw.WriteBytes([]byte{byte(state)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -213,7 +213,7 @@ func (m *Message) decodePayload(br *io.BinReader) error {
|
||||||
// Encode encodes a Message to any given BinWriter.
|
// Encode encodes a Message to any given BinWriter.
|
||||||
func (m *Message) Encode(br *io.BinWriter) error {
|
func (m *Message) Encode(br *io.BinWriter) error {
|
||||||
br.WriteLE(m.Magic)
|
br.WriteLE(m.Magic)
|
||||||
br.WriteLE(m.Command)
|
br.WriteBytes(m.Command[:])
|
||||||
br.WriteLE(m.Length)
|
br.WriteLE(m.Length)
|
||||||
br.WriteLE(m.Checksum)
|
br.WriteLE(m.Checksum)
|
||||||
if m.Payload != nil {
|
if m.Payload != nil {
|
||||||
|
|
|
@ -39,7 +39,7 @@ func (p *AddressAndTime) DecodeBinary(br *io.BinReader) {
|
||||||
func (p *AddressAndTime) EncodeBinary(bw *io.BinWriter) {
|
func (p *AddressAndTime) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteLE(p.Timestamp)
|
bw.WriteLE(p.Timestamp)
|
||||||
bw.WriteLE(p.Services)
|
bw.WriteLE(p.Services)
|
||||||
bw.WriteBE(p.IP)
|
bw.WriteBytes(p.IP[:])
|
||||||
bw.WriteBE(p.Port)
|
bw.WriteBE(p.Port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,5 +30,5 @@ func (p *GetBlocks) DecodeBinary(br *io.BinReader) {
|
||||||
// EncodeBinary implements Serializable interface.
|
// EncodeBinary implements Serializable interface.
|
||||||
func (p *GetBlocks) EncodeBinary(bw *io.BinWriter) {
|
func (p *GetBlocks) EncodeBinary(bw *io.BinWriter) {
|
||||||
bw.WriteArray(p.HashStart)
|
bw.WriteArray(p.HashStart)
|
||||||
bw.WriteLE(p.HashStop)
|
bw.WriteBytes(p.HashStop[:])
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ func (pt ParamType) MarshalJSON() ([]byte, error) {
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable interface.
|
// EncodeBinary implements io.Serializable interface.
|
||||||
func (pt ParamType) EncodeBinary(w *io.BinWriter) {
|
func (pt ParamType) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteLE(pt)
|
w.WriteBytes([]byte{byte(pt)})
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeBinary implements io.Serializable interface.
|
// DecodeBinary implements io.Serializable interface.
|
||||||
|
|
|
@ -98,7 +98,7 @@ func (u Uint256) CompareTo(other Uint256) int { return bytes.Compare(u[:], other
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable interface.
|
// EncodeBinary implements io.Serializable interface.
|
||||||
func (u Uint256) EncodeBinary(w *io.BinWriter) {
|
func (u Uint256) EncodeBinary(w *io.BinWriter) {
|
||||||
w.WriteBE(u)
|
w.WriteBytes(u[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeBinary implements io.Serializable interface.
|
// DecodeBinary implements io.Serializable interface.
|
||||||
|
|
|
@ -43,13 +43,13 @@ func serializeItemTo(item StackItem, w *io.BinWriter, seen map[StackItem]bool) {
|
||||||
|
|
||||||
switch t := item.(type) {
|
switch t := item.(type) {
|
||||||
case *ByteArrayItem:
|
case *ByteArrayItem:
|
||||||
w.WriteLE(byte(byteArrayT))
|
w.WriteBytes([]byte{byte(byteArrayT)})
|
||||||
w.WriteVarBytes(t.value)
|
w.WriteVarBytes(t.value)
|
||||||
case *BoolItem:
|
case *BoolItem:
|
||||||
w.WriteLE(byte(booleanT))
|
w.WriteBytes([]byte{byte(booleanT)})
|
||||||
w.WriteLE(t.value)
|
w.WriteLE(t.value)
|
||||||
case *BigIntegerItem:
|
case *BigIntegerItem:
|
||||||
w.WriteLE(byte(integerT))
|
w.WriteBytes([]byte{byte(integerT)})
|
||||||
w.WriteVarBytes(t.Bytes())
|
w.WriteVarBytes(t.Bytes())
|
||||||
case *InteropItem:
|
case *InteropItem:
|
||||||
w.Err = errors.New("not supported")
|
w.Err = errors.New("not supported")
|
||||||
|
@ -58,9 +58,9 @@ func serializeItemTo(item StackItem, w *io.BinWriter, seen map[StackItem]bool) {
|
||||||
|
|
||||||
_, isArray := t.(*ArrayItem)
|
_, isArray := t.(*ArrayItem)
|
||||||
if isArray {
|
if isArray {
|
||||||
w.WriteLE(byte(arrayT))
|
w.WriteBytes([]byte{byte(arrayT)})
|
||||||
} else {
|
} else {
|
||||||
w.WriteLE(byte(structT))
|
w.WriteBytes([]byte{byte(structT)})
|
||||||
}
|
}
|
||||||
|
|
||||||
arr := t.Value().([]StackItem)
|
arr := t.Value().([]StackItem)
|
||||||
|
@ -71,7 +71,7 @@ func serializeItemTo(item StackItem, w *io.BinWriter, seen map[StackItem]bool) {
|
||||||
case *MapItem:
|
case *MapItem:
|
||||||
seen[item] = true
|
seen[item] = true
|
||||||
|
|
||||||
w.WriteLE(byte(mapT))
|
w.WriteBytes([]byte{byte(mapT)})
|
||||||
w.WriteVarUint(uint64(len(t.value)))
|
w.WriteVarUint(uint64(len(t.value)))
|
||||||
for k, v := range t.value {
|
for k, v := range t.value {
|
||||||
serializeItemTo(v, w, seen)
|
serializeItemTo(v, w, seen)
|
||||||
|
|
Loading…
Reference in a new issue