util: add an LRU cache dict

In certain cases we would like to have a cache of the last N results of a
given computation, where N is small. This will be used in an upcoming patch to
increase the size of the manifest cache from 1 to 3.
This commit is contained in:
Siddharth Agarwal 2013-02-09 15:41:46 +00:00
parent 3d65ebe9c1
commit b13982495e
3 changed files with 86 additions and 0 deletions

View File

@ -211,6 +211,31 @@ except AttributeError:
del self[i]
break
class lrucachedict(object):
'''cache most recent gets from or sets to this dictionary'''
def __init__(self, maxsize):
self._cache = {}
self._maxsize = maxsize
self._order = deque()
def __getitem__(self, key):
value = self._cache[key]
self._order.remove(key)
self._order.append(key)
return value
def __setitem__(self, key, value):
if key not in self._cache:
if len(self._cache) >= self._maxsize:
del self._cache[self._order.popleft()]
else:
self._order.remove(key)
self._cache[key] = value
self._order.append(key)
def __contains__(self, key):
return key in self._cache
def lrucachefunc(func):
'''cache most recent results of function calls'''
cache = {}

View File

@ -0,0 +1,35 @@
from mercurial import util
def printifpresent(d, xs):
for x in xs:
present = x in d
print "'%s' in d: %s" % (x, present)
if present:
print "d['%s']: %s" % (x, d[x])
def test_lrucachedict():
d = util.lrucachedict(4)
d['a'] = 'va'
d['b'] = 'vb'
d['c'] = 'vc'
d['d'] = 'vd'
# all of these should be present
printifpresent(d, ['a', 'b', 'c', 'd'])
# 'a' should be dropped because it was least recently used
d['e'] = 've'
printifpresent(d, ['a', 'b', 'c', 'd', 'e'])
# touch entries in some order (get or set).
d['e']
d['c'] = 'vc2'
d['d']
d['b'] = 'vb2'
# 'e' should be dropped now
d['f'] = 'vf'
printifpresent(d, ['b', 'c', 'd', 'e', 'f'])
if __name__ == '__main__':
test_lrucachedict()

View File

@ -0,0 +1,26 @@
'a' in d: True
d['a']: va
'b' in d: True
d['b']: vb
'c' in d: True
d['c']: vc
'd' in d: True
d['d']: vd
'a' in d: False
'b' in d: True
d['b']: vb
'c' in d: True
d['c']: vc
'd' in d: True
d['d']: vd
'e' in d: True
d['e']: ve
'b' in d: True
d['b']: vb2
'c' in d: True
d['c']: vc2
'd' in d: True
d['d']: vd
'e' in d: False
'f' in d: True
d['f']: vf