Beispiel #1
0
 def basics(self):
     cache = LFUCache(maxsize=2)
     cache[1] = 2
     cache[3] = 4
     cache[3]
     cache[5] = 6
     Assert(cache.items()) == [(1, 2), (5, 6)]
Beispiel #2
0
 def basics(self):
     cache = LFUCache(maxsize=2)
     cache[1] = 2
     cache[3] = 4
     cache[3]
     cache[5] = 6
     Assert(cache.items()) == [(1, 2), (5, 6)]
Beispiel #3
0
 def __init__(self, _object_cache_maxsize=256):
     self._application_stack = []
     self._cache = LFUCache(maxsize=_object_cache_maxsize)
     self._contexts = []
     self._stackop = count().next
Beispiel #4
0
class ContextStackManagerBase(object):
    """
    Helper which manages context dependant stacks.

    A common API pattern is using context managers to change options; those
    options are internally stored on a stack.

    However larger applications have multiple execution contexts such as
    processes, threads and/or coroutines/greenthreads and such an API becomes
    a problem as each modification of the stack becomes visible to every
    execution context.

    This helper allows you to make stack operations local to the current
    execution context, ensuring that the stack remains the same in other
    contexts unless you want it to change there.

    As applications tend to have very different requirements and use different
    contexts each is implemented in a separate mixin, this way it easily
    possible to create a `ContextStackManager` for your needs.

    Assuming your application uses threads and eventlet for greenthreads you
    would create a `ContextStackManager` like this::

        class ContextStackManager(
                ContextStackManagerEventletMixin,
                ContextStackManagerThreadMixin,
                ContextStackManagerBase
            ):
            pass

    Greenthreads are executed in a thread, whereas threads are executed in
    the application thread (handled by the base class) this is why
    `ContextStackManager` inherits from these classes exactly in this order.

    Currently available mixins are:

    - :class:`ContextStackManagerThreadMixin`
    - :class:`ContextStackManagerEventletMixin`
    """
    def __init__(self, _object_cache_maxsize=256):
        self._application_stack = []
        self._cache = LFUCache(maxsize=_object_cache_maxsize)
        self._contexts = []
        self._stackop = count().next

    def _get_ident(self):
        return ()

    def _make_item(self, obj):
        return self._stackop(), obj

    def _get_objects(self, context):
        return getattr(context, 'objects', None)

    def _add_object(self, context, obj):
        item = self._make_item(obj)
        objects = self._get_objects(context)
        if objects is None:
            context.objects = [item]
        else:
            objects.append(item)

    def iter_current_stack(self):
        """
        Returns an iterator over the items in the 'current' stack, ordered
        from top to bottom.
        """
        ident = self._get_ident()
        objects = self._cache.get(ident)
        if objects is None:
            objects = self._application_stack[:]
            for context in self._contexts:
                objects.extend(getattr(context, 'objects', ()))
            objects.reverse()
            self._cache[ident] = objects = map(itemgetter(1), objects)
        return iter(objects)

    def push_application(self, obj):
        """
        Pushes the given object onto the application stack.
        """
        self._application_stack.append(self._make_item(obj))
        self._cache.clear()

    def pop_application(self):
        """
        Pops and returns an object from the application stack.
        """
        if not self._application_stack:
            raise RuntimeError('no objects on application stack')
        self._cache.clear()
        return self._application_stack.pop()[1]
Beispiel #5
0
 def __init__(self, _object_cache_maxsize=256):
     self._application_stack = []
     self._cache = LFUCache(maxsize=_object_cache_maxsize)
     self._contexts = []
     self._stackop = count().next
Beispiel #6
0
class ContextStackManagerBase(object):
    """
    Helper which manages context dependant stacks.

    A common API pattern is using context managers to change options; those
    options are internally stored on a stack.

    However larger applications have multiple execution contexts such as
    processes, threads and/or coroutines/greenthreads and such an API becomes
    a problem as each modification of the stack becomes visible to every
    execution context.

    This helper allows you to make stack operations local to the current
    execution context, ensuring that the stack remains the same in other
    contexts unless you want it to change there.

    As applications tend to have very different requirements and use different
    contexts each is implemented in a separate mixin, this way it easily
    possible to create a `ContextStackManager` for your needs.

    Assuming your application uses threads and eventlet for greenthreads you
    would create a `ContextStackManager` like this::

        class ContextStackManager(
                ContextStackManagerEventletMixin,
                ContextStackManagerThreadMixin,
                ContextStackManagerBase
            ):
            pass

    Greenthreads are executed in a thread, whereas threads are executed in
    the application thread (handled by the base class) this is why
    `ContextStackManager` inherits from these classes exactly in this order.

    Currently available mixins are:

    - :class:`ContextStackManagerThreadMixin`
    - :class:`ContextStackManagerEventletMixin`
    """
    def __init__(self, _object_cache_maxsize=256):
        self._application_stack = []
        self._cache = LFUCache(maxsize=_object_cache_maxsize)
        self._contexts = []
        self._stackop = count().next

    def _get_ident(self):
        return ()

    def _make_item(self, obj):
        return self._stackop(), obj

    def _get_objects(self, context):
        return getattr(context, 'objects', None)

    def _add_object(self, context, obj):
        item = self._make_item(obj)
        objects = self._get_objects(context)
        if objects is None:
            context.objects = [item]
        else:
            objects.append(item)

    def iter_current_stack(self):
        """
        Returns an iterator over the items in the 'current' stack, ordered
        from top to bottom.
        """
        ident = self._get_ident()
        objects = self._cache.get(ident)
        if objects is None:
            objects = self._application_stack[:]
            for context in self._contexts:
                objects.extend(getattr(context, 'objects', ()))
            objects.reverse()
            self._cache[ident] = objects = map(itemgetter(1), objects)
        return iter(objects)

    def push_application(self, obj):
        """
        Pushes the given object onto the application stack.
        """
        self._application_stack.append(self._make_item(obj))
        self._cache.clear()

    def pop_application(self):
        """
        Pops and returns an object from the application stack.
        """
        if not self._application_stack:
            raise RuntimeError('no objects on application stack')
        self._cache.clear()
        return self._application_stack.pop()[1]
Beispiel #7
0
 def repr(self):
     cache = LFUCache()
     Assert(repr(cache)) == 'LFUCache({}, inf)'