made skiplist not forget skips until corresponding item in parent is removed instead...
authorForrest Voight <forrest@forre.st>
Fri, 23 Dec 2011 05:34:17 +0000 (00:34 -0500)
committerForrest Voight <forrest@forre.st>
Fri, 23 Dec 2011 05:34:17 +0000 (00:34 -0500)
p2pool/skiplists.py
p2pool/util/forest.py
p2pool/util/skiplist.py

index e6dbeb6..6ff9905 100644 (file)
@@ -1,15 +1,8 @@
-from p2pool.util import math, skiplist
+from p2pool.util import forest, math
 
-class WeightsSkipList(skiplist.SkipList):
+class WeightsSkipList(forest.TrackerSkipList):
     # share_count, weights, total_weight
     
-    def __init__(self, tracker):
-        skiplist.SkipList.__init__(self)
-        self.tracker = tracker
-    
-    def previous(self, element):
-        return self.tracker.shares[element].previous_hash
-    
     def get_delta(self, element):
         from p2pool.bitcoin import data as bitcoin_data
         if element is None:
@@ -45,17 +38,13 @@ class WeightsSkipList(skiplist.SkipList):
     def finalize(self, (share_count, weights, total_weight, total_donation_weight)):
         return weights, total_weight, total_donation_weight
 
-class CountsSkipList(skiplist.SkipList):
+class CountsSkipList(forest.TrackerSkipList):
     # share_count, counts, total_count
     
     def __init__(self, tracker, run_identifier):
-        skiplist.SkipList.__init__(self)
-        self.tracker = tracker
+        forest.TrackerSkipList.__init__(self, tracker)
         self.run_identifier = run_identifier
     
-    def previous(self, element):
-        return self.tracker.shares[element].previous_hash
-    
     def get_delta(self, element):
         if element is None:
             raise AssertionError()
index 5990d41..6e877b4 100644 (file)
@@ -3,19 +3,25 @@ forest data structure
 '''
 
 import itertools
+import weakref
 
 from p2pool.util import skiplist, variable
 from p2pool.bitcoin import data as bitcoin_data
 
 
-class DistanceSkipList(skiplist.SkipList):
+class TrackerSkipList(skiplist.SkipList):
     def __init__(self, tracker):
         skiplist.SkipList.__init__(self)
         self.tracker = tracker
+        
+        self_ref = weakref.ref(self, lambda _: tracker.removed.unwatch(watch_id))
+        watch_id = self.tracker.removed.watch(lambda share: self_ref().forget_item(share.hash))
     
     def previous(self, element):
         return self.tracker.shares[element].previous_hash
-    
+
+
+class DistanceSkipList(TrackerSkipList):
     def get_delta(self, element):
         return element, 1, self.tracker.shares[element].previous_hash
     
@@ -59,11 +65,11 @@ class Tracker(object):
         self.height_refs = {} # ref -> height, share_hash, work_inc
         self.reverse_height_refs = {} # share_hash -> ref
         
-        self.get_nth_parent_hash = DistanceSkipList(self)
-        
         self.added = variable.Event()
         self.removed = variable.Event()
         
+        self.get_nth_parent_hash = DistanceSkipList(self)
+        
         for share in shares:
             self.add(share)
     
index 57af4bf..8d8f26f 100644 (file)
@@ -1,4 +1,4 @@
-from p2pool.util import math, expiring_dict, memoize
+from p2pool.util import math
 
 class Base(object):
     def finalize(self, sol):
@@ -8,9 +8,11 @@ class SkipList(Base):
     P = .5
     
     def __init__(self):
-        self.skips = expiring_dict.ExpiringDict(600)
+        self.skips = {}
+    
+    def forget_item(self, item):
+        self.skips.pop(item, None)
     
-    @memoize.memoize_with_backing(expiring_dict.ExpiringDict(5, get_touches=False))
     def __call__(self, start, *args, **kwargs):
         updates = {}
         pos = start