Mercurial > hg
changeset 18603:2251b3184e6e
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.
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Sat, 09 Feb 2013 15:41:46 +0000 |
parents | 8ba520003ae0 |
children | a1141f04e368 |
files | mercurial/util.py tests/test-lrucachedict.py tests/test-lrucachedict.py.out |
diffstat | 3 files changed, 86 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/util.py Sat Feb 09 15:08:21 2013 +0000 +++ b/mercurial/util.py Sat Feb 09 15:41:46 2013 +0000 @@ -211,6 +211,31 @@ 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 = {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-lrucachedict.py Sat Feb 09 15:41:46 2013 +0000 @@ -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()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-lrucachedict.py.out Sat Feb 09 15:41:46 2013 +0000 @@ -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