rlp: avoid or make faster seq copies (#689)

This commit is contained in:
Jacek Sieka 2024-06-06 20:27:43 +02:00 committed by GitHub
parent 68bd675b75
commit d935c0de47
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 19 additions and 17 deletions

View File

@ -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