summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLance Stout <lancestout@gmail.com>2012-10-22 12:05:49 -0700
committerLance Stout <lancestout@gmail.com>2012-10-22 13:57:49 -0700
commit5e9266ba90a11eb5f20d3f049b34ef296411f225 (patch)
treefca38f7c522ab5e6289046c6d6f96ed218de8eea
parente6c95f0a2acfd56ad47f60d9576a0db5458ed118 (diff)
downloadslixmpp-5e9266ba90a11eb5f20d3f049b34ef296411f225.tar.gz
slixmpp-5e9266ba90a11eb5f20d3f049b34ef296411f225.tar.bz2
slixmpp-5e9266ba90a11eb5f20d3f049b34ef296411f225.tar.xz
slixmpp-5e9266ba90a11eb5f20d3f049b34ef296411f225.zip
Optimize generating JIDs with some caching.
-rw-r--r--sleekxmpp/jid.py57
1 files changed, 35 insertions, 22 deletions
diff --git a/sleekxmpp/jid.py b/sleekxmpp/jid.py
index 47d5cd78..007bebac 100644
--- a/sleekxmpp/jid.py
+++ b/sleekxmpp/jid.py
@@ -19,6 +19,7 @@ import stringprep
import encodings.idna
from sleekxmpp.util import stringprep_profiles
+from sleekxmpp.thirdparty import OrderedDict
#: These characters are not allowed to appear in a JID.
ILLEGAL_CHARS = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r' + \
@@ -63,6 +64,9 @@ JID_UNESCAPE_TRANSFORMATIONS = {'\\20': ' ',
'\\40': '@',
'\\5c': '\\'}
+JID_CACHE = OrderedDict()
+JID_CACHE_MAX_SIZE = 1024
+
# pylint: disable=c0103
#: The nodeprep profile of stringprep used to validate the local,
@@ -415,26 +419,35 @@ class JID(object):
self._jid = (None, None, None)
if jid is None or jid == '':
- jid = (None, None, None)
- elif not isinstance(jid, JID):
- jid = _parse_jid(jid)
- else:
- jid = jid._jid
-
- local, domain, resource = jid
+ jid = ''
- local = kwargs.get('local', local)
- domain = kwargs.get('domain', domain)
- resource = kwargs.get('resource', resource)
-
- if 'local' in kwargs:
- local = _escape_node(local)
- if 'domain' in kwargs:
- domain = _validate_domain(domain)
- if 'resource' in kwargs:
- resource = _validate_resource(resource)
-
- self._jid = (local, domain, resource)
+ if jid in JID_CACHE:
+ self._jid = JID_CACHE[jid]
+ else:
+ if not jid:
+ jid = (None, None, None)
+ elif not isinstance(jid, JID):
+ jid = _parse_jid(jid)
+ else:
+ jid = jid._jid
+
+ local, domain, resource = jid
+
+ local = kwargs.get('local', local)
+ domain = kwargs.get('domain', domain)
+ resource = kwargs.get('resource', resource)
+
+ if 'local' in kwargs:
+ local = _escape_node(local)
+ if 'domain' in kwargs:
+ domain = _validate_domain(domain)
+ if 'resource' in kwargs:
+ resource = _validate_resource(resource)
+
+ self._jid = (local, domain, resource)
+ JID_CACHE[_format_jid(*self._jid)] = self._jid
+ if len(JID_CACHE) > JID_CACHE_MAX_SIZE:
+ JID_CACHE.popitem(False)
def unescape(self):
"""Return an unescaped JID object.
@@ -498,7 +511,9 @@ class JID(object):
``resource``, ``full``, ``jid``, or ``bare``.
:param value: The new string value of the JID component.
"""
- if name == 'resource':
+ if name == '_jid':
+ super(JID, self).__setattr__('_jid', value)
+ elif name == 'resource':
self._jid = JID(self, resource=value)._jid
elif name in ('user', 'username', 'local', 'node'):
self._jid = JID(self, local=value)._jid
@@ -509,8 +524,6 @@ class JID(object):
elif name == 'bare':
parsed = JID(value)._jid
self._jid = (parsed[0], parsed[1], self._jid[2])
- elif name == '_jid':
- super(JID, self).__setattr__('_jid', value)
def __str__(self):
"""Use the full JID as the string value."""