Source code for wheezy.caching.pylibmc

""" ``pylibmc`` module.
"""

from wheezy.caching.comp import __import__
from wheezy.caching.encoding import encode_keys
from wheezy.caching.encoding import string_encode

try:
    c = __import__('pylibmc', None, None, ['Client', 'NotFound'])
    Client = c.Client
    NotFound = c.NotFound

    def client_factory(*args, **kwargs):
[docs] """ Client factory for pylibmc. """ kwargs.setdefault('binary', True) behaviors = kwargs.setdefault('behaviors', {}) behaviors.setdefault('tcp_nodelay', True) behaviors.setdefault('ketama', True) return Client(*args, **kwargs) del c
except ImportError: # pragma: nocover import warnings warnings.warn("No module named 'pylibmc'", stacklevel=2) class MemcachedClient(object):
[docs] """ A wrapper around pylibmc Client in order to adapt cache contract. """ def __init__(self, pool, key_encode=None): assert hasattr(pool, 'acquire') assert hasattr(pool, 'get_back') self.pool = pool self.key_encode = key_encode or string_encode def set(self, key, value, time=0, namespace=None):
[docs] """ Sets a key's value, regardless of previous contents in cache. """ key = self.key_encode(key) try: client = self.pool.acquire() return client.set(key, value, time) finally: self.pool.get_back(client) def set_multi(self, mapping, time=0, namespace=None):
[docs] """ Set multiple keys' values at once. """ key_encode = self.key_encode keys, mapping = encode_keys(mapping, key_encode) try: client = self.pool.acquire() failed = client.set_multi(mapping, time) finally: self.pool.get_back(client) return failed and [keys[key] for key in failed] or failed def add(self, key, value, time=0, namespace=None):
[docs] """ Sets a key's value, if and only if the item is not already. """ key = self.key_encode(key) try: client = self.pool.acquire() return client.add(key, value, time) finally: self.pool.get_back(client) def add_multi(self, mapping, time=0, namespace=None):
[docs] """ Adds multiple values at once, with no effect for keys already in cache. """ key_encode = self.key_encode keys, mapping = encode_keys(mapping, key_encode) try: client = self.pool.acquire() failed = client.add_multi(mapping, time) finally: self.pool.get_back(client) return failed and [keys[key] for key in failed] or failed def replace(self, key, value, time=0, namespace=None):
[docs] """ Replaces a key's value, failing if item isn't already. """ key = self.key_encode(key) try: try: client = self.pool.acquire() return client.replace(key, value, time) except NotFound: return False finally: self.pool.get_back(client) def replace_multi(self, mapping, time=0, namespace=None):
[docs] """ Replaces multiple values at once, with no effect for keys not in cache. """ key_encode = self.key_encode failed = [] mapping = [(key, key_encode(key), mapping[key]) for key in mapping] try: client = self.pool.acquire() for key, key_encoded, value in mapping: try: client.replace(key_encoded, value, time) except NotFound: failed.append(key) finally: self.pool.get_back(client) return failed def get(self, key, namespace=None):
[docs] """ Looks up a single key. """ key = self.key_encode(key) try: client = self.pool.acquire() return client.get(key) finally: self.pool.get_back(client) def get_multi(self, keys, namespace=None):
[docs] """ Looks up multiple keys from cache in one operation. This is the recommended way to do bulk loads. """ key_encode = self.key_encode encoded_keys = map(key_encode, keys) try: client = self.pool.acquire() mapping = client.get_multi(encoded_keys) finally: self.pool.get_back(client) if mapping: key_mapping = dict(zip(encoded_keys, keys)) return dict([(key_mapping[key], mapping[key]) for key in mapping]) return mapping def delete(self, key, seconds=0, namespace=None):
[docs] """ Deletes a key from cache. """ key = self.key_encode(key) try: client = self.pool.acquire() return client.delete(key) finally: self.pool.get_back(client) def delete_multi(self, keys, seconds=0, namespace=None):
[docs] """ Delete multiple keys at once. """ key_encode = self.key_encode keys = map(key_encode, keys) try: client = self.pool.acquire() return client.delete_multi(keys) finally: self.pool.get_back(client) def incr(self, key, delta=1, namespace=None, initial_value=None):
[docs] """ Atomically increments a key's value. The value, if too large, will wrap around. If the key does not yet exist in the cache and you specify an initial_value, the key's value will be set to this initial value and then incremented. If the key does not exist and no initial_value is specified, the key's value will not be set. """ key = self.key_encode(key) try: client = self.pool.acquire() try: return client.incr(key, delta) except NotFound: if initial_value is None: return None client.add(key, initial_value) return client.incr(key, delta) finally: self.pool.get_back(client) def decr(self, key, delta=1, namespace=None, initial_value=None):
[docs] """ Atomically decrements a key's value. The value, if too large, will wrap around. If the key does not yet exist in the cache and you specify an initial_value, the key's value will be set to this initial value and then decremented. If the key does not exist and no initial_value is specified, the key's value will not be set. """ key = self.key_encode(key) try: client = self.pool.acquire() try: return client.decr(key, delta) except NotFound: if initial_value is None: return None client.add(key, initial_value) return client.decr(key, delta) finally: self.pool.get_back(client) def flush_all(self):
[docs] """ Deletes everything in cache. """ try: client = self.pool.acquire() client.flush_all() finally: self.pool.get_back(client) return True