summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Reifschneider <jafo@tummy.com>2013-05-04 22:53:19 -0600
committerSean Reifschneider <jafo@tummy.com>2013-05-04 22:53:19 -0600
commit07498a0243d34562709f4b3760463dbd23db2ede (patch)
tree51b41e1ab80b212d0f056f525bfe17dedbad568b
parent1b3f0c0f35456dfd997e0a6c96150f52efbdff01 (diff)
downloadpython-memcached-07498a0243d34562709f4b3760463dbd23db2ede.tar.gz
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.
-rw-r--r--ChangeLog8
-rw-r--r--memcache.py31
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 <jafo-memcached@tummy.com>"
@@ -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):