From 07498a0243d34562709f4b3760463dbd23db2ede Mon Sep 17 00:00:00 2001 From: Sean Reifschneider Date: Sat, 4 May 2013 22:53:19 -0600 Subject: check_key disabling and performance improvements. * Client() now takes a "check_key" option, which defaults to True. If False, it disables the checking of keys to ensure they have acceptable size and are composed of non-control characters. Suggested by Ben Hoyt. * Converting control character checking of keys based on performance testing of alternatives by Ben Hoyt. --- ChangeLog | 8 ++++++++ memcache.py | 31 ++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 059b389..3715b82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ + * Client() now takes a "check_key" option, which defaults to True. + If False, it disables the checking of keys to ensure they have + acceptable size and are composed of non-control characters. + Suggested by Ben Hoyt. + + * Converting control character checking of keys based on performance + testing of alternatives by Ben Hoyt. + * Converted unicode tests from using u'', patch from Eren Güve. * Included license file (pull request by "Philippe" pombredanne). diff --git a/memcache.py b/memcache.py index 6cd45ff..4865b90 100644 --- a/memcache.py +++ b/memcache.py @@ -77,6 +77,8 @@ try: except ImportError: from StringIO import StringIO +invalid_key_characters = ''.join(map(chr, range(33) + [127])) + # Original author: Evan Martin of Danga Interactive __author__ = "Sean Reifschneider " @@ -161,7 +163,7 @@ class Client(local): server_max_key_length=SERVER_MAX_KEY_LENGTH, server_max_value_length=SERVER_MAX_VALUE_LENGTH, dead_retry=_DEAD_RETRY, socket_timeout=_SOCKET_TIMEOUT, - cache_cas = False, flush_on_reconnect=0): + cache_cas = False, flush_on_reconnect=0, check_key=True): """ Create a new Client object with the given list of servers. @@ -194,6 +196,8 @@ class Client(local): back, those keys will map to it again. If it still has its data, get()s can read stale data that was overwritten on another server. This flag is off by default for backwards compatibility. + @param check_key: (default True) If True, the key is checked to + ensure it is the correct length and composed of the right characters. """ local.__init__(self) self.debug = debug @@ -204,6 +208,7 @@ class Client(local): self.stats = {} self.cache_cas = cache_cas self.reset_cas() + self.do_check_key = check_key # Allow users to modify pickling/unpickling behavior self.pickleProtocol = pickleProtocol @@ -430,7 +435,8 @@ class Client(local): should fail. Defaults to None for no delay. @rtype: int ''' - self.check_key(key) + if self.do_check_key: + self.check_key(key) server, key = self._get_server(key) if not server: return 0 @@ -490,7 +496,8 @@ class Client(local): return self._incrdecr("decr", key, delta) def _incrdecr(self, cmd, key, delta): - self.check_key(key) + if self.do_check_key: + self.check_key(key) server, key = self._get_server(key) if not server: return None @@ -615,7 +622,7 @@ class Client(local): """ # Check it just once ... key_extra_len=len(key_prefix) - if key_prefix: + if key_prefix and self.do_check_key: self.check_key(key_prefix) # server (_Host) -> list of unprefixed server keys in mapping @@ -634,7 +641,8 @@ class Client(local): server, key = self._get_server(key_prefix + str_orig_key) # Now check to make sure key length is proper ... - self.check_key(str_orig_key, key_extra_len=key_extra_len) + if self.do_check_key: + self.check_key(str_orig_key, key_extra_len=key_extra_len) if not server: continue @@ -781,7 +789,8 @@ class Client(local): return (flags, len(val), val) def _set(self, cmd, key, val, time, min_compress_len = 0): - self.check_key(key) + if self.do_check_key: + self.check_key(key) server, key = self._get_server(key) if not server: return 0 @@ -823,7 +832,8 @@ class Client(local): return 0 def _get(self, cmd, key): - self.check_key(key) + if self.do_check_key: + self.check_key(key) server, key = self._get_server(key) if not server: return None @@ -1036,10 +1046,9 @@ class Client(local): len(key) + key_extra_len > self.server_max_key_length: raise Client.MemcachedKeyLengthError("Key length is > %s" % self.server_max_key_length) - for char in key: - if ord(char) < 33 or ord(char) == 127: - raise Client.MemcachedKeyCharacterError( - "Control characters not allowed") + if len(key) != len(key.translate(None, invalid_key_characters)): + raise Client.MemcachedKeyCharacterError( + "Control characters not allowed") class _Host(object): -- cgit v1.2.1