mirror of https://github.com/status-im/nim-eth.git
rlp: avoid or make faster seq copies (#689)
This commit is contained in:
parent
68bd675b75
commit
d935c0de47
|
@ -1,7 +1,8 @@
|
||||||
import
|
import
|
||||||
std/options,
|
std/options,
|
||||||
stew/[shims/macros, results],
|
results,
|
||||||
./object_serialization, ./priv/defs
|
stew/[assign2, shims/macros],
|
||||||
|
./priv/defs
|
||||||
|
|
||||||
type
|
type
|
||||||
RlpWriter* = object
|
RlpWriter* = object
|
||||||
|
@ -45,12 +46,13 @@ proc writeCount(bytes: var seq[byte], count: int, baseMarker: byte) =
|
||||||
bytes.writeBigEndian(uint64(count), bytes.len - 1, lenPrefixBytes)
|
bytes.writeBigEndian(uint64(count), bytes.len - 1, lenPrefixBytes)
|
||||||
|
|
||||||
proc initRlpWriter*: RlpWriter =
|
proc initRlpWriter*: RlpWriter =
|
||||||
newSeq(result.pendingLists, 0)
|
# Avoid allocations during initial write of small items - since the writer is
|
||||||
newSeq(result.output, 0)
|
# expected to be short-lived, it doesn't hurt to allocate this buffer
|
||||||
|
result.output = newSeqOfCap[byte](2000)
|
||||||
|
|
||||||
proc decRet(n: var int, delta: int): int =
|
proc decRet(n: var int, delta: int): int =
|
||||||
n -= delta
|
n -= delta
|
||||||
return n
|
n
|
||||||
|
|
||||||
proc maybeClosePendingLists(self: var RlpWriter) =
|
proc maybeClosePendingLists(self: var RlpWriter) =
|
||||||
while self.pendingLists.len > 0:
|
while self.pendingLists.len > 0:
|
||||||
|
@ -86,14 +88,15 @@ proc maybeClosePendingLists(self: var RlpWriter) =
|
||||||
# The currently open list is not finished yet. Nothing to do.
|
# The currently open list is not finished yet. Nothing to do.
|
||||||
return
|
return
|
||||||
|
|
||||||
proc appendRawList(self: var RlpWriter, bytes: openArray[byte]) =
|
proc appendRawBytes*(self: var RlpWriter, bytes: openArray[byte]) =
|
||||||
self.output.writeCount(bytes.len, LIST_START_MARKER)
|
self.output.setLen(self.output.len + bytes.len)
|
||||||
self.output.add(bytes)
|
assign(self.output.toOpenArray(
|
||||||
|
self.output.len - bytes.len, self.output.len - 1), bytes)
|
||||||
self.maybeClosePendingLists()
|
self.maybeClosePendingLists()
|
||||||
|
|
||||||
proc appendRawBytes*(self: var RlpWriter, bytes: openArray[byte]) =
|
proc appendRawList(self: var RlpWriter, bytes: openArray[byte]) =
|
||||||
self.output.add(bytes)
|
self.output.writeCount(bytes.len, LIST_START_MARKER)
|
||||||
self.maybeClosePendingLists()
|
self.appendRawBytes(bytes)
|
||||||
|
|
||||||
proc startList*(self: var RlpWriter, listSize: int) =
|
proc startList*(self: var RlpWriter, listSize: int) =
|
||||||
if listSize == 0:
|
if listSize == 0:
|
||||||
|
@ -104,11 +107,10 @@ proc startList*(self: var RlpWriter, listSize: int) =
|
||||||
proc appendBlob(self: var RlpWriter, data: openArray[byte], startMarker: byte) =
|
proc appendBlob(self: var RlpWriter, data: openArray[byte], startMarker: byte) =
|
||||||
if data.len == 1 and byte(data[0]) < BLOB_START_MARKER:
|
if data.len == 1 and byte(data[0]) < BLOB_START_MARKER:
|
||||||
self.output.add byte(data[0])
|
self.output.add byte(data[0])
|
||||||
|
self.maybeClosePendingLists()
|
||||||
else:
|
else:
|
||||||
self.output.writeCount(data.len, startMarker)
|
self.output.writeCount(data.len, startMarker)
|
||||||
self.output.add data
|
self.appendRawBytes(data)
|
||||||
|
|
||||||
self.maybeClosePendingLists()
|
|
||||||
|
|
||||||
proc appendImpl(self: var RlpWriter, data: string) =
|
proc appendImpl(self: var RlpWriter, data: string) =
|
||||||
appendBlob(self, data.toOpenArrayByte(0, data.high), BLOB_START_MARKER)
|
appendBlob(self, data.toOpenArrayByte(0, data.high), BLOB_START_MARKER)
|
||||||
|
@ -321,12 +323,12 @@ proc encode*[T](v: T): seq[byte] =
|
||||||
mixin append
|
mixin append
|
||||||
var writer = initRlpWriter()
|
var writer = initRlpWriter()
|
||||||
writer.append(v)
|
writer.append(v)
|
||||||
return writer.finish
|
move(writer.finish)
|
||||||
|
|
||||||
proc encodeInt*(i: SomeUnsignedInt): seq[byte] =
|
proc encodeInt*(i: SomeUnsignedInt): seq[byte] =
|
||||||
var writer = initRlpWriter()
|
var writer = initRlpWriter()
|
||||||
writer.appendInt(i)
|
writer.appendInt(i)
|
||||||
return writer.finish
|
move(writer.finish)
|
||||||
|
|
||||||
macro encodeList*(args: varargs[untyped]): seq[byte] =
|
macro encodeList*(args: varargs[untyped]): seq[byte] =
|
||||||
var
|
var
|
||||||
|
@ -342,7 +344,7 @@ macro encodeList*(args: varargs[untyped]): seq[byte] =
|
||||||
result = quote do:
|
result = quote do:
|
||||||
var `writer` = initRlpList(`listLen`)
|
var `writer` = initRlpList(`listLen`)
|
||||||
`body`
|
`body`
|
||||||
finish(`writer`)
|
move(finish(`writer`))
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
# XXX: Currently fails with a malformed AST error on the args.len expression
|
# XXX: Currently fails with a malformed AST error on the args.len expression
|
||||||
|
|
Loading…
Reference in New Issue