This is a mapping-like object that attempts to efficiently hold a fixed number of previous entries, automatically discarding older entries.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | # This could much more completely be done as a subclass of dict, but for
# brevity we'll just define it like this for now.
class FifoCache:
'''
A mapping(ish) object that remembers the past <entries> items set.
'''
def __init__(self, entries):
self.entries = entries
self.dct = {}
self.lst = []
self.__repr__ = self.dct.__repr__
self.__contains__ = self.dct.__contains__
self.__getitem__ = self.dct.__getitem__
def __setitem__(self, key, value):
dct = self.dct
lst = self.lst
if key in self:
del self[key]
lst.append(key)
dct[key] = value
if len(lst) > self.entries:
del dct[lst.pop(0)]
def __delitem__(self, key):
if not self.dct.has_key(key):
raise KeyError, key
self.lst.remove(key)
self.dct.pop(key)
# f = FifoCache(entries = 3)
# f["fly"] = "foo"
# f["moo"] = "two"
# f["bar"] = "baz"
# f["dave"] = "wilson"
# f["age"] = 20
# f now has keys 'bar', 'dave', and 'age'.
|
For any case where you might use a dictionary object to cache expensive lookups, this might be a safer alternative for use in long-running applications, who's caches may consume all system memory if left unchecked.
The one problem with this implementation is that it is not a full dictionary; you cannot safely replace dict() with FifoCache(), since FifoCache has not got the same methods as dict. It does however support item getting, setting, and __contains__, which should be adequate for 50%+ uses.
At a little cost to speed for the wrapped methods, this could be rewritten properly as a subclass of the dict type, providing drop-in compatibility, which would make for an excellent tool in an optimiser's toolset.
Full Dictionary Interface. An easy way to expand the interface is to subclass from UserDict.DictMixin in Py2.3.
Similar recipe... I will point to a similar recipe here:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252524
It uses LRU and offers a fairly complete dictionary interface.