mirror of
https://github.com/LBRYFoundation/LBRY-Vault.git
synced 2025-09-04 04:45:16 +00:00
lnmsg: small speed-up: read first, check length after
this saves around ~13% wall clock time in ChannelDB.load_data
This commit is contained in:
parent
71635216df
commit
eecdd056b3
1 changed files with 24 additions and 10 deletions
|
@ -25,6 +25,8 @@ def _num_remaining_bytes_to_read(fd: io.BytesIO) -> int:
|
||||||
|
|
||||||
|
|
||||||
def _assert_can_read_at_least_n_bytes(fd: io.BytesIO, n: int) -> None:
|
def _assert_can_read_at_least_n_bytes(fd: io.BytesIO, n: int) -> None:
|
||||||
|
# note: it's faster to read n bytes and then check if we read n, than
|
||||||
|
# to assert we can read at least n and then read n bytes.
|
||||||
nremaining = _num_remaining_bytes_to_read(fd)
|
nremaining = _num_remaining_bytes_to_read(fd)
|
||||||
if nremaining < n:
|
if nremaining < n:
|
||||||
raise UnexpectedEndOfStream(f"wants to read {n} bytes but only {nremaining} bytes left")
|
raise UnexpectedEndOfStream(f"wants to read {n} bytes but only {nremaining} bytes left")
|
||||||
|
@ -50,20 +52,26 @@ def read_bigsize_int(fd: io.BytesIO) -> Optional[int]:
|
||||||
if first < 0xfd:
|
if first < 0xfd:
|
||||||
return first
|
return first
|
||||||
elif first == 0xfd:
|
elif first == 0xfd:
|
||||||
_assert_can_read_at_least_n_bytes(fd, 2)
|
buf = fd.read(2)
|
||||||
val = int.from_bytes(fd.read(2), byteorder="big", signed=False)
|
if len(buf) != 2:
|
||||||
|
raise UnexpectedEndOfStream()
|
||||||
|
val = int.from_bytes(buf, byteorder="big", signed=False)
|
||||||
if not (0xfd <= val < 0x1_0000):
|
if not (0xfd <= val < 0x1_0000):
|
||||||
raise FieldEncodingNotMinimal()
|
raise FieldEncodingNotMinimal()
|
||||||
return val
|
return val
|
||||||
elif first == 0xfe:
|
elif first == 0xfe:
|
||||||
_assert_can_read_at_least_n_bytes(fd, 4)
|
buf = fd.read(4)
|
||||||
val = int.from_bytes(fd.read(4), byteorder="big", signed=False)
|
if len(buf) != 4:
|
||||||
|
raise UnexpectedEndOfStream()
|
||||||
|
val = int.from_bytes(buf, byteorder="big", signed=False)
|
||||||
if not (0x1_0000 <= val < 0x1_0000_0000):
|
if not (0x1_0000 <= val < 0x1_0000_0000):
|
||||||
raise FieldEncodingNotMinimal()
|
raise FieldEncodingNotMinimal()
|
||||||
return val
|
return val
|
||||||
elif first == 0xff:
|
elif first == 0xff:
|
||||||
_assert_can_read_at_least_n_bytes(fd, 8)
|
buf = fd.read(8)
|
||||||
val = int.from_bytes(fd.read(8), byteorder="big", signed=False)
|
if len(buf) != 8:
|
||||||
|
raise UnexpectedEndOfStream()
|
||||||
|
val = int.from_bytes(buf, byteorder="big", signed=False)
|
||||||
if not (0x1_0000_0000 <= val):
|
if not (0x1_0000_0000 <= val):
|
||||||
raise FieldEncodingNotMinimal()
|
raise FieldEncodingNotMinimal()
|
||||||
return val
|
return val
|
||||||
|
@ -96,8 +104,10 @@ def _read_field(*, fd: io.BytesIO, field_type: str, count: Union[int, str]) -> U
|
||||||
assert field_type == 'u64'
|
assert field_type == 'u64'
|
||||||
type_len = 8
|
type_len = 8
|
||||||
assert count == 1, count
|
assert count == 1, count
|
||||||
_assert_can_read_at_least_n_bytes(fd, type_len)
|
buf = fd.read(type_len)
|
||||||
return int.from_bytes(fd.read(type_len), byteorder="big", signed=False)
|
if len(buf) != type_len:
|
||||||
|
raise UnexpectedEndOfStream()
|
||||||
|
return int.from_bytes(buf, byteorder="big", signed=False)
|
||||||
elif field_type in ('tu16', 'tu32', 'tu64'):
|
elif field_type in ('tu16', 'tu32', 'tu64'):
|
||||||
if field_type == 'tu16':
|
if field_type == 'tu16':
|
||||||
type_len = 2
|
type_len = 2
|
||||||
|
@ -129,14 +139,18 @@ def _read_field(*, fd: io.BytesIO, field_type: str, count: Union[int, str]) -> U
|
||||||
type_len = 33
|
type_len = 33
|
||||||
elif field_type == 'short_channel_id':
|
elif field_type == 'short_channel_id':
|
||||||
type_len = 8
|
type_len = 8
|
||||||
|
|
||||||
if count == "...":
|
if count == "...":
|
||||||
total_len = -1 # read all
|
total_len = -1 # read all
|
||||||
else:
|
else:
|
||||||
if type_len is None:
|
if type_len is None:
|
||||||
raise UnknownMsgFieldType(f"unknown field type: {field_type!r}")
|
raise UnknownMsgFieldType(f"unknown field type: {field_type!r}")
|
||||||
total_len = count * type_len
|
total_len = count * type_len
|
||||||
_assert_can_read_at_least_n_bytes(fd, total_len)
|
|
||||||
return fd.read(total_len)
|
buf = fd.read(total_len)
|
||||||
|
if total_len >= 0 and len(buf) != total_len:
|
||||||
|
raise UnexpectedEndOfStream()
|
||||||
|
return buf
|
||||||
|
|
||||||
|
|
||||||
# TODO: maybe for "value" we could accept a list with len "count" of appropriate items
|
# TODO: maybe for "value" we could accept a list with len "count" of appropriate items
|
||||||
|
|
Loading…
Add table
Reference in a new issue