[Zodb-checkins] CVS: Packages/StorageGC - CyclicGC.py:1.8
tim@digicool.com
tim@digicool.com
Sun, 22 Apr 2001 01:00:58 -0400 (EDT)
Update of /cvs-repository/Packages/StorageGC
In directory korak:/tmp/cvs-serv30808
Modified Files:
CyclicGC.py
Log Message:
Document why it's safe not to raise TopologyError when gcReferences(x)
returns inconsistent results across calls.
--- Updated File CyclicGC.py in package Packages/StorageGC --
--- CyclicGC.py 2001/04/21 18:13:35 1.7
+++ CyclicGC.py 2001/04/22 05:00:57 1.8
@@ -435,7 +435,41 @@
if i is not None:
result.append(i)
# Else this reference popped into existence after we captured
- # the initial refcount info.
+ # the initial refcount info. So why don't we raise
+ # _TopologyError? I don't think it can hurt! The ultimate
+ # result is the transitive closure of the root set, less
+ # everything reachable starting from outside the TC. Since
+ # we didn't know about this node before, obj is pointing to a
+ # child *outside* the TC. That *can* make something we're
+ # looking at trash and we won't realize it. For example,
+ # A<->B <- C<->D
+ # If we were initially passed A, the TC is {A, B}, and the
+ # C->B reference prevents us from collecting anything. If a
+ # new B->C pointer popped into existence, we'd realize the
+ # whole shebang is trash if we got to start over.
+ # So *maybe* this new reference is causing us to overlook trash.
+ # But probably not, most of the time. and it's *safe* not to
+ # detect trash instantly.
+ # The question is whether this new reference can cause us to
+ # think something is trash that actually isn't. For that to
+ # happen, something in the TC must be reachable from outside
+ # the TC that wasn't reachable from outside the TC before this
+ # new reference popped up. But this new pointer goes from
+ # inside the TC (obj) to outside the TC (child): it's "going
+ # in the wrong direction" to hurt.
+ # Detail: A path from something outside the TC to something
+ # inside the TC that contains this new pointer has to get
+ # inside the TC *before* reaching this pointer (because this
+ # pointer *starts* in the TC). So the endpoint of that pointer
+ # was already reachable from outside the TC, and therefore also
+ # everything in the TC along the path from that endpoint to
+ # obj. So if such a new path exists, there are no *newly*
+ # reachable objects in the TC from the start of the path up
+ # through and including obj.
+ # What about the path after obj? Since obj ends in child, if
+ # there's a path from child to something in the TC, that path
+ # still goes from child to something in the TC without the
+ # obj->child pointer, so again the object was reachable before.
return result
def _get_storage_rc(self, obj):