Use shorter field names when serializing file transmission commands to reduce overhead

This commit is contained in:
Kovid Goyal 2021-11-18 10:55:57 +05:30
parent d30ba9654f
commit c29f50b0d6
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -28,6 +28,7 @@ from kittens.transfer.utils import (
from kitty.fast_data_types import ( from kitty.fast_data_types import (
FILE_TRANSFER_CODE, OSC, add_timer, get_boss, get_options FILE_TRANSFER_CODE, OSC, add_timer, get_boss, get_options
) )
from kitty.types import run_once
from .utils import log_error, sanitize_control_codes from .utils import log_error, sanitize_control_codes
@ -233,24 +234,40 @@ class TransmissionError(Exception):
) )
@run_once
def name_to_serialized_map() -> Dict[str, str]:
ans: Dict[str, str] = {}
for k in fields(FileTransmissionCommand):
ans[k.name] = k.metadata.get('sname', k.name)
return ans
@run_once
def serialized_to_field_map() -> Dict[bytes, Field[Any]]:
ans: Dict[bytes, Field[Any]] = {}
for k in fields(FileTransmissionCommand):
ans[k.metadata.get('sname', k.name).encode('ascii')] = k
return ans
@dataclass @dataclass
class FileTransmissionCommand: class FileTransmissionCommand:
action: Action = Action.invalid action: Action = field(default=Action.invalid, metadata={'sname': 'ac'})
compression: Compression = Compression.none compression: Compression = field(default=Compression.none, metadata={'sname': 'zip'})
ftype: FileType = FileType.regular ftype: FileType = field(default=FileType.regular, metadata={'sname': 'ft'})
ttype: TransmissionType = TransmissionType.simple ttype: TransmissionType = field(default=TransmissionType.simple, metadata={'sname': 'tt'})
id: str = '' id: str = ''
file_id: str = '' file_id: str = field(default='', metadata={'sname': 'fid'})
bypass: str = field(default='', metadata={'base64': True}) bypass: str = field(default='', metadata={'base64': True, 'sname': 'pw'})
quiet: int = 0 quiet: int = field(default=0, metadata={'sname': 'q'})
mtime: int = -1 mtime: int = field(default=-1, metadata={'sname': 'mod'})
permissions: int = -1 permissions: int = field(default=-1, metadata={'sname': 'prm'})
size: int = -1 size: int = field(default=-1, metadata={'sname': 'sz'})
name: str = field(default='', metadata={'base64': True}) name: str = field(default='', metadata={'base64': True, 'sname': 'n'})
status: str = field(default='', metadata={'base64': True}) status: str = field(default='', metadata={'base64': True, 'sname': 'st'})
parent: str = field(default='', metadata={'base64': True}) parent: str = field(default='', metadata={'base64': True, 'sname': 'pr'})
data: bytes = field(default=b'', repr=False) data: bytes = field(default=b'', repr=False, metadata={'sname': 'd'})
def __repr__(self) -> str: def __repr__(self) -> str:
ans = [] ans = []
@ -274,6 +291,7 @@ class FileTransmissionCommand:
return ans return ans
def get_serialized_fields(self, prefix_with_osc_code: bool = False) -> Iterator[Union[str, bytes]]: def get_serialized_fields(self, prefix_with_osc_code: bool = False) -> Iterator[Union[str, bytes]]:
nts = name_to_serialized_map()
found = False found = False
if prefix_with_osc_code: if prefix_with_osc_code:
yield ftc_prefix yield ftc_prefix
@ -288,7 +306,7 @@ class FileTransmissionCommand:
yield ';' yield ';'
else: else:
found = True found = True
yield name yield nts[name]
yield '=' yield '='
if issubclass(k.type, Enum): if issubclass(k.type, Enum):
yield val.name yield val.name
@ -310,10 +328,7 @@ class FileTransmissionCommand:
@classmethod @classmethod
def deserialize(cls, data: Union[str, bytes, memoryview]) -> 'FileTransmissionCommand': def deserialize(cls, data: Union[str, bytes, memoryview]) -> 'FileTransmissionCommand':
ans = FileTransmissionCommand() ans = FileTransmissionCommand()
fmap: Dict[bytes, 'Field[Union[str, int, bytes, Enum]]'] = getattr(cls, 'fmap', None) fmap = serialized_to_field_map()
if not fmap:
fmap = {k.name.encode('ascii'): k for k in fields(cls)}
setattr(cls, 'fmap', fmap)
from kittens.transfer.rsync import decode_utf8_buffer, parse_ftc from kittens.transfer.rsync import decode_utf8_buffer, parse_ftc
def handle_item(key: memoryview, val: memoryview, has_semicolons: bool) -> None: def handle_item(key: memoryview, val: memoryview, has_semicolons: bool) -> None: