4199ccb36fa849e6b80fc9b3d9985be6d664e38e
[p2pool.git] / p2pool / util / memoize.py
1 import itertools
2
3 class LRUDict(object):
4     def __init__(self, n):
5         self.n = n
6         self.inner = {}
7         self.counter = itertools.count()
8     def get(self, key, default=None):
9         if key in self.inner:
10             x, value = self.inner[key]
11             self.inner[key] = self.counter.next(), value
12             return value
13         return default
14     def __setitem__(self, key, value):
15         self.inner[key] = self.counter.next(), value
16         while len(self.inner) > self.n:
17             self.inner.pop(min(self.inner, key=lambda k: self.inner[k][0]))
18
19 _nothing = object()
20
21 def memoize_with_backing(backing, has_inverses=set()):
22     def a(f):
23         def b(*args):
24             res = backing.get((f, args), _nothing)
25             if res is not _nothing:
26                 return res
27             
28             res = f(*args)
29             
30             backing[(f, args)] = res
31             for inverse in has_inverses:
32                 backing[(inverse, args[:-1] + (res,))] = args[-1]
33             
34             return res
35         return b
36     return a
37
38 def memoize(f):
39     return memoize_with_backing({})(f)