X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=p2pool%2Futil%2Fexpiring_dict.py;h=8a3c9eede5635a68b1c565ce4b190063ed1707d9;hb=0a3493d6873cfef4fb189d39e64dfbc6e162e2a7;hp=180cd422fe8e9510e691c50cbcc256c1ff264230;hpb=176dd2aa7ed7abbb2146d45dcc993177c339dfc0;p=p2pool.git diff --git a/p2pool/util/expiring_dict.py b/p2pool/util/expiring_dict.py index 180cd42..8a3c9ee 100644 --- a/p2pool/util/expiring_dict.py +++ b/p2pool/util/expiring_dict.py @@ -1,8 +1,9 @@ from __future__ import division import time +import weakref -from twisted.internet import reactor +from p2pool.util import deferral class Node(object): def __init__(self, contents, prev=None, next=None): @@ -61,7 +62,6 @@ class LinkedList(object): yield cur2 def __getitem__(self, index): - # odd one out - probably should return Node instance instead of its contents if index < 0: cur = self.end for i in xrange(-index): @@ -98,19 +98,24 @@ class LinkedList(object): class ExpiringDict(object): - def __init__(self, expiry_time=100, get_touches=True): + def __init__(self, expiry_time, get_touches=True): self.expiry_time = expiry_time self.get_touches = get_touches self.expiry_deque = LinkedList() self.d = dict() # key -> node, value + + self_ref = weakref.ref(self, lambda _: expire_loop.stop() if expire_loop.running else None) + self._expire_loop = expire_loop = deferral.RobustLoopingCall(lambda: self_ref().expire()) + expire_loop.start(1) + + def stop(self): + self._expire_loop.stop() def __repr__(self): - reactor.callLater(0, self.expire) return 'ExpiringDict' + repr(self.__dict__) def __len__(self): - reactor.callLater(0, self.expire) return len(self.d) _nothing = object() @@ -121,13 +126,14 @@ class ExpiringDict(object): node.delete() new_value = old_value if value is self._nothing else value - self.d[key] = self.expiry_deque.append((time.time(), key)), new_value + self.d[key] = self.expiry_deque.append((time.time() + self.expiry_time, key)), new_value return new_value def expire(self): + t = time.time() for node in self.expiry_deque: timestamp, key = node.contents - if timestamp + self.expiry_time > time.time(): + if timestamp > t: break del self.d[key] node.delete() @@ -140,24 +146,20 @@ class ExpiringDict(object): value = self.touch(key) else: node, value = self.d[key] - reactor.callLater(0, self.expire) return value def __setitem__(self, key, value): self.touch(key, value) - reactor.callLater(0, self.expire) def __delitem__(self, key): node, value = self.d.pop(key) node.delete() - reactor.callLater(0, self.expire) def get(self, key, default_value=None): if key in self.d: res = self[key] else: res = default_value - reactor.callLater(0, self.expire) return res def setdefault(self, key, default_value): @@ -176,23 +178,3 @@ class ExpiringDict(object): def itervalues(self): for node, value in self.d.itervalues(): yield value - -if __name__ == '__main__': - x = ExpiringDict(5) - print x - - time.sleep(1) - - x[1] = 2 - print 'x[1] = 2' - print x - - time.sleep(1) - - x[1] = 3 - print 'x[1] = 3' - print x - - time.sleep(5) - - print x