1. Alexander Fedorov
  2. dogpile.cache

Source

dogpile.cache / dogpile / cache / util.py

zzzeek 5e26bea 
zzzeek ecc26c1 
Mike Bayer b9f7ff4 
Mike Bayer 676f00d 
Mike Bayer 0232773 
Alex...@winwork cbd44bb 

zzzeek ecc26c1 
Mike Bayer 8a6571a 




Mike Bayer 676f00d 



Alex...@winwork cbd44bb 
Mike Bayer 676f00d 













zzzeek ecc26c1 















zzzeek 0ee7467 
zzzeek ecc26c1 











Mike Bayer b4b1b54 
zzzeek ecc26c1 


Mike Bayer 0232773 
zzzeek ecc26c1 

Mike Bayer 0232773 
zzzeek ecc26c1 

Mike Bayer 0232773 
zzzeek ecc26c1 

Mike Bayer b4b1b54 

zzzeek ecc26c1 
Mike Bayer b4b1b54 
zzzeek ecc26c1 
zzzeek 0ee7467 
zzzeek ecc26c1 







Alex...@winwork cbd44bb 
zzzeek ecc26c1 

zzzeek 4192624 

zzzeek ecc26c1 

zzzeek 0ee7467 



Mike Bayer 0232773 
zzzeek 0ee7467 





zzzeek 5735098 













Mike Bayer 8a6571a 








Mike Bayer 0232773 











































from hashlib import sha1
import inspect
import sys
import re
import collections
from dogpile.compat import string_types, text_type, pickle


try:
    import threading
except ImportError:
    import dummy_threading as threading


def coerce_string_conf(d):
    result = {}
    for k, v in d.items():
        if not isinstance(v, string_types):
            result[k] = v
            continue

        v = v.strip()
        if re.match(r'^\d+$', v):
            result[k] = int(v)
        elif v.lower() in ('false', 'true'):
            result[k] = v.lower() == 'true'
        elif v == 'None':
            result[k] = None
        else:
            result[k] = v
    return result

class PluginLoader(object):
    def __init__(self, group):
        self.group = group
        self.impls = {}

    def load(self, name):
        if name in self.impls:
             return self.impls[name]()
        else:
            import pkg_resources
            for impl in pkg_resources.iter_entry_points(
                                self.group, 
                                name):
                self.impls[name] = impl.load
                return impl.load()
            else:
                raise Exception(
                        "Can't load plugin %s %s" % 
                        (self.group, name))

    def register(self, name, modulepath, objname):
        def load():
            mod = __import__(modulepath)
            for token in modulepath.split(".")[1:]:
                mod = getattr(mod, token)
            return getattr(mod, objname)
        self.impls[name] = load


def function_key_generator(namespace, fn):
    """Return a function that generates a string
    key, based on a given function as well as
    arguments to the returned function itself.

    This is used by :meth:`.CacheRegion.cache_on_arguments`
    to generate a cache key from a decorated function.

    It can be replaced using the ``function_key_generator``
    argument passed to :func:`.make_region`.

    """

    if namespace is None:
        namespace = '%s:%s' % (fn.__module__, fn.__name__)
    else:
        namespace = '%s:%s|%s' % (fn.__module__, fn.__name__, namespace)

    args = inspect.getargspec(fn)
    has_self = args[0] and args[0][0] in ('self', 'cls')
    def generate_key(*args, **kw):
        if kw:
            raise ValueError(
                    "dogpile.cache's default key creation "
                    "function does not accept keyword arguments.")
        if has_self:
            args = args[1:]
        return namespace + "|" + " ".join(map(text_type, args))
    return generate_key

def sha1_mangle_key(key):
    """a SHA1 key mangler."""

    return sha1(key).hexdigest()

def length_conditional_mangler(length, mangler):
    """a key mangler that mangles if the length of the key is
    past a certain threshold.

    """
    def mangle(key):
        if len(key) >= length:
            return mangler(key)
        else:
            return key
    return mangle

class memoized_property(object):
    """A read-only @property that is only evaluated once."""
    def __init__(self, fget, doc=None):
        self.fget = fget
        self.__doc__ = doc or fget.__doc__
        self.__name__ = fget.__name__

    def __get__(self, obj, cls):
        if obj is None:
            return self
        obj.__dict__[self.__name__] = result = self.fget(obj)
        return result

def to_list(x, default=None):
    """Coerce to a list."""
    if x is None:
        return default
    if not isinstance(x, (list, tuple)):
        return [x]
    else:
        return x


class KeyReentrantMutex(object):

    def __init__(self, key, mutex, keys):
        self.key = key
        self.mutex = mutex
        self.keys = keys

    @classmethod
    def factory(cls, mutex):
        # this collection holds zero or one
        # thread idents as the key; a set of
        # keynames held as the value.
        keystore = collections.defaultdict(set)
        def fac(key):
            return KeyReentrantMutex(key, mutex, keystore)
        return fac

    def acquire(self, wait=True):
        current_thread = threading.current_thread().ident
        keys = self.keys.get(current_thread)
        if keys is not None and \
            self.key not in keys:
            # current lockholder, new key. add it in
            keys.add(self.key)
            return True
        elif self.mutex.acquire(wait=wait):
            # after acquire, create new set and add our key
            self.keys[current_thread].add(self.key)
            return True
        else:
            return False

    def release(self):
        current_thread = threading.current_thread().ident
        keys = self.keys.get(current_thread)
        assert keys is not None, "this thread didn't do the acquire"
        assert self.key in keys, "No acquire held for key '%s'" % self.key
        keys.remove(self.key)
        if not keys:
            # when list of keys empty, remove
            # the thread ident and unlock.
            del self.keys[current_thread]
            self.mutex.release()