summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2013-10-31 20:03:39 +0000
committerLars Wirzenius <liw@liw.fi>2013-11-06 20:20:06 +0000
commit0fc9df23884c5cacb6be2f9866bd5c8a70f8f5e1 (patch)
treed9fdf1670d742423bfcd7eef5c4b4f9f28eddf26
parent267b049865cc239e98847ea013dd9c88abe3f8e6 (diff)
downloadlarch-0fc9df23884c5cacb6be2f9866bd5c8a70f8f5e1.tar.gz
Fix KeyError for missing refcount
We would sometimes, rarely, have a crash that looked like this: File "..refcountstore.py", line 76, in get_refcount return self.refcounts[node_id] KeyError: 32970 In other words, the object keeping track of reference counts for B-tree nodes would think it doesn't have the reference count for a node, when it should have it. After much debugging, by myself and Itamar Turner-Trauring, and greatly helped by a repeatable test case provided by Rob Kendrick, this was tracked to an optimisation in the set_refcount method, which would remove (to save memory) the refcount for a node (remove the entry for a node's id in the refcount dict), when the refcount was set to zero. Unfortunately this conflicted with an assumption in get_refcount that a refcount for a node that was in the dirty set was actually present in the refcount dict. The bug fix is easy: don't remove the node from the refcount dict, and eat the (very minor) memory consumption hit, in the name of correctness.
-rw-r--r--larch/refcountstore.py6
1 files changed, 1 insertions, 5 deletions
diff --git a/larch/refcountstore.py b/larch/refcountstore.py
index 0aea53e..18fb9e7 100644
--- a/larch/refcountstore.py
+++ b/larch/refcountstore.py
@@ -78,11 +78,7 @@ class RefcountStore(object):
def set_refcount(self, node_id, refcount):
'''Set the reference count for a given node.'''
tracing.trace('setting refcoutn for %s to %s' % (node_id, refcount))
- if refcount == 0:
- if node_id in self.refcounts:
- del self.refcounts[node_id]
- else:
- self.refcounts[node_id] = refcount
+ self.refcounts[node_id] = refcount
self.dirty.add(node_id)
def save_refcounts(self):