Use the new in-memory entity cache

This should avoid a disk access every time an input entity
is needed, which is very often. Another step for #1141.
This commit is contained in:
Lonami Exo 2019-03-26 11:39:25 +01:00
parent 4d35e8c80f
commit 8abc7ade22
10 changed files with 24 additions and 29 deletions

View File

@ -235,7 +235,6 @@ class TelegramBaseClient(abc.ABC):
# #
# The session files only wants the entities to persist # The session files only wants the entities to persist
# them to disk, and to save additional useful information. # them to disk, and to save additional useful information.
# TODO Make use of _entity_cache
# TODO Session should probably return all cached # TODO Session should probably return all cached
# info of entities, not just the input versions # info of entities, not just the input versions
self.session = session self.session = session

View File

@ -308,8 +308,8 @@ class UserMethods(TelegramBaseClient):
try: try:
# First try to get the entity from cache, otherwise figure it out # First try to get the entity from cache, otherwise figure it out
return self.session.get_input_entity(peer) return self._entity_cache[peer]
except ValueError: except KeyError:
pass pass
if isinstance(peer, str): if isinstance(peer, str):

View File

@ -31,15 +31,17 @@ class EntityCache:
def __getitem__(self, item): def __getitem__(self, item):
""" """
Gets the corresponding :tl:`InputPeer` for the given ID or peer, Gets the corresponding :tl:`InputPeer` for the given ID or peer,
or returns `None` on error/not found. or raises ``KeyError`` on any error (i.e. cannot be found).
""" """
if not isinstance(item, int) or item < 0: if not isinstance(item, int) or item < 0:
try: try:
return self.__dict__.get(utils.get_peer_id(item)) return self.__dict__[utils.get_peer_id(item)]
except TypeError: except TypeError:
return None raise KeyError('Invalid key will not have entity') from None
for cls in (types.PeerUser, types.PeerChat, types.PeerChannel): for cls in (types.PeerUser, types.PeerChat, types.PeerChannel):
result = self.__dict__.get(cls(item)) result = self.__dict__.get(utils.get_peer_id(cls(item)))
if result: if result:
return result return result
raise KeyError('No cached entity for the given key')

View File

@ -156,10 +156,8 @@ class CallbackQuery(EventBuilder):
if not getattr(self._input_sender, 'access_hash', True): if not getattr(self._input_sender, 'access_hash', True):
# getattr with True to handle the InputPeerSelf() case # getattr with True to handle the InputPeerSelf() case
try: try:
self._input_sender = self._client.session.get_input_entity( self._input_sender = self._client._entity_cache[self._sender_id]
self._sender_id except KeyError:
)
except ValueError:
m = await self.get_message() m = await self.get_message()
if m: if m:
self._sender = m._sender self._sender = m._sender

View File

@ -362,10 +362,8 @@ class ChatAction(EventBuilder):
self._input_users = [] self._input_users = []
for peer in self._user_peers: for peer in self._user_peers:
try: try:
self._input_users.append( self._input_users.append(self._client._entity_cache[peer])
self._client.session.get_input_entity(peer) except KeyError:
)
except ValueError:
pass pass
return self._input_users or [] return self._input_users or []

View File

@ -154,10 +154,8 @@ class EventCommon(ChatGetter, abc.ABC):
self._input_chat = utils.get_input_peer(self._chat) self._input_chat = utils.get_input_peer(self._chat)
except TypeError: except TypeError:
try: try:
self._input_chat = self._client.session.get_input_entity( self._input_chat = self._client._entity_cache[self._chat_peer]
self._chat_peer except KeyError:
)
except ValueError:
self._input_chat = None self._input_chat = None
@property @property

View File

@ -170,7 +170,7 @@ class UserUpdate(EventBuilder):
def _set_client(self, client): def _set_client(self, client):
if isinstance(self._chat_peer, int): if isinstance(self._chat_peer, int):
try: try:
chat = client.session.get_input_entity(self._chat_peer) chat = client._entity_cache[self._chat_peer]
if isinstance(chat, types.InputPeerChat): if isinstance(chat, types.InputPeerChat):
self._chat_peer = types.PeerChat(self._chat_peer) self._chat_peer = types.PeerChat(self._chat_peer)
elif isinstance(chat, types.InputPeerChannel): elif isinstance(chat, types.InputPeerChannel):
@ -178,7 +178,7 @@ class UserUpdate(EventBuilder):
else: else:
# Should not happen # Should not happen
self._chat_peer = types.PeerUser(self._chat_peer) self._chat_peer = types.PeerUser(self._chat_peer)
except ValueError: except KeyError:
# Hope for the best. We don't know where this event # Hope for the best. We don't know where this event
# occurred but it was most likely in a channel. # occurred but it was most likely in a channel.
self._chat_peer = types.PeerChannel(self._chat_peer) self._chat_peer = types.PeerChannel(self._chat_peer)

View File

@ -49,9 +49,8 @@ class ChatGetter(abc.ABC):
""" """
if self._input_chat is None and self._chat_peer: if self._input_chat is None and self._chat_peer:
try: try:
self._input_chat =\ self._input_chat = self._client._entity_cache(self._chat_peer)
self._client.session.get_input_entity(self._chat_peer) except KeyError:
except ValueError:
pass pass
return self._input_chat return self._input_chat

View File

@ -64,9 +64,8 @@ class Draft:
""" """
if not self._input_entity: if not self._input_entity:
try: try:
self._input_entity =\ self._input_entity = self._client._entity_cache[self._peer]
self._client.session.get_input_entity(self._peer) except KeyError:
except ValueError:
pass pass
return self._input_entity return self._input_entity

View File

@ -834,8 +834,10 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
if not bot: if not bot:
raise ValueError('No input sender') raise ValueError('No input sender')
else: else:
return self._client.session.get_input_entity( try:
self.via_bot_id) return self._client._entity_cache[self.via_bot_id]
except KeyError:
raise ValueError('No input sender') from None
def _document_by_attribute(self, kind, condition=None): def _document_by_attribute(self, kind, condition=None):
""" """