mirror of
https://github.com/facebook/sapling.git
synced 2025-01-07 22:21:40 +03:00
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:
parent
3d65ebe9c1
commit
b13982495e
@ -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 = {}
|
||||
|
35
tests/test-lrucachedict.py
Normal file
35
tests/test-lrucachedict.py
Normal 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()
|
26
tests/test-lrucachedict.py.out
Normal file
26
tests/test-lrucachedict.py.out
Normal 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
|
Loading…
Reference in New Issue
Block a user