[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):