Skip to content

Commit

Permalink
Fix #23: Refactor LFUCache.
Browse files Browse the repository at this point in the history
  • Loading branch information
tkem committed Nov 11, 2014
1 parent 8dd2764 commit cef6653
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 16 deletions.
9 changes: 5 additions & 4 deletions CHANGES.rst
@@ -1,13 +1,14 @@
0.7.0 UNRELEASED
----------------

- Add `choice` argument to ``RRCache`` constructor.

- Deprecate ``TTLCache.ExpiredError``.

- Refactor ``LRUCache``, ``TTLCache``.
- Add `choice` argument to ``RRCache`` constructor.

- Refactor ``LFUCache``, ``LRUCache`` and ``TTLCache``.

- Use custom ``NullContext`` implementation.
- Always use custom ``NullContext`` implementation for unsynchronized
function decorators.


0.6.0 2014-10-13
Expand Down
26 changes: 14 additions & 12 deletions cachetools/lfucache.py
Expand Up @@ -2,6 +2,7 @@
from .decorators import cachedfunc
from .lock import RLock

import collections
import operator


Expand All @@ -14,28 +15,29 @@ class LFUCache(Cache):
"""

def __init__(self, maxsize, getsizeof=None):
if getsizeof is None:
Cache.__init__(self, maxsize)
else:
Cache.__init__(self, maxsize, lambda e: getsizeof(e[0]))
self.getsizeof = getsizeof
Cache.__init__(self, maxsize, getsizeof=getsizeof)
self.__counter = collections.Counter()

def __getitem__(self, key, cache_getitem=Cache.__getitem__):
entry = cache_getitem(self, key)
entry[1] += 1
return entry[0]
value = cache_getitem(self, key)
self.__counter[key] += 1
return value

def __setitem__(self, key, value, cache_setitem=Cache.__setitem__):
cache_setitem(self, key, [value, 0])
cache_setitem(self, key, value)
self.__counter[key] += 1

def __delitem__(self, key, cache_delitem=Cache.__delitem__):
cache_delitem(self, key)
del self.__counter[key]

def popitem(self):
"""Remove and return the `(key, value)` pair least frequently used."""
items = ((key, Cache.__getitem__(self, key)[1]) for key in self)
try:
key, _ = min(items, key=operator.itemgetter(1))
key, _ = min(self.__counter.items(), key=operator.itemgetter(1))
except ValueError:
raise KeyError('cache is empty')
return (key, self.pop(key))
return key, self.pop(key)


def lfu_cache(maxsize=128, typed=False, getsizeof=None, lock=RLock):
Expand Down

0 comments on commit cef6653

Please sign in to comment.