[Zodb-checkins] CVS: Packages/StorageGC - CyclicGC.py:1.11

tim@digicool.com tim@digicool.com
Sun, 22 Apr 2001 17:42:13 -0400 (EDT)


Update of /cvs-repository/Packages/StorageGC
In directory korak:/tmp/cvs-serv30801

Modified Files:
	CyclicGC.py 
Log Message:
Map storage objects directly to their descriptors, instead of to
descriptor indices (into the _allobjds list).  The layer of indexing
indirection is no longer needed, and so the code got a little simpler,
clearer and faster in several places.



--- Updated File CyclicGC.py in package Packages/StorageGC --
--- CyclicGC.py	2001/04/22 05:50:16	1.10
+++ CyclicGC.py	2001/04/22 21:42:12	1.11
@@ -162,11 +162,14 @@
         self._storage = storage
 
         # List of object descriptors.  This is the transitive closure of all
-        # objects reachable from the roots passed to .start().
+        # objects reachable from the roots passed to .start().  Note that
+        # _allobjds is some permutation of _obj2d.values().
+
         self._allobjds = []
 
-        # Map object to index of its descriptor in _allobjds.
-        self._obj2index = {}
+        # Map object to its descriptor.
+        # Note that _obj2d.values() is some permutation of _allobjds.
+        self._obj2d = {}
 
         # List of objects passed to .start() while a previous computation
         # was still in progress.
@@ -258,7 +261,7 @@
         "Build descriptors for the passed-in objects."
 
         assert len(self._allobjds) == 0
-        assert len(self._obj2index) == 0
+        assert len(self._obj2d) == 0
         for x in objs:
             # Note that _get_initial_info() weeds out duplicates.
             self._get_initial_info(x)
@@ -266,13 +269,12 @@
     def _get_initial_info(self, obj):
         """Return descriptor for obj, building a new one if obj is new.
 
-        Weed out duplicates.  If not already seen, build descriptor and
-        append to  _allobjds, and remember the _allobjds index in
-        _obj2index.
+        Weed out duplicates.  If not already seen, build descriptor, append
+        to  _allobjds, and map obj to it via _obj2d.
         """
 
-        index = self._obj2index.get(obj, None)
-        if index is None:
+        d = self._obj2d.get(obj)
+        if d is None:
             rc = self._get_storage_rc(obj)
 
             d = [None] * NUM_DESCRIPTOR_SLOTS
@@ -281,12 +283,9 @@
             d[ADJRC]  = rc
             d[ISFREE] = FALSE
 
-            self._obj2index[obj] = len(self._allobjds)
+            self._obj2d[obj] = d
             self._allobjds.append(d)
 
-        else:
-            d = self._allobjds[index]
-
         return d
 
     def _build_transitive_closure(self):
@@ -370,8 +369,7 @@
         # prevents any object from getting pushed onto the mistakes stack
         # more than once.
 
-        for ichild in self._getkids_byindex(obj):
-            d = self._allobjds[ichild]
+        for d in self._get_kids_descriptors(obj):
             d[ADJRC] += 1
             if d[ISFREE]:
                 d[ISFREE] = FALSE
@@ -410,7 +408,7 @@
         "Start next batch of work (if any)."
 
         self._allobjds = []
-        self._obj2index.clear()
+        self._obj2d.clear()
         if self._pending:
             temp = self._pending
             self._pending = []
@@ -429,14 +427,14 @@
         "Return list of obj's immediate successors."
         return self._storage.gcReferences(obj)
 
-    def _getkids_byindex(self, obj):
-        "Return list of ._allobjs indices for obj's immediate successors."
+    def _get_kids_descriptors(self, obj):
+        "Return list of descriptors of obj's immediate successors."
         result = []
-        obj2index = self._obj2index
+        getd = self._obj2d.get
         for child in self._storage.gcReferences(obj):
-            i = obj2index.get(child, None)
-            if i is not None:
-                result.append(i)
+            d = getd(child)
+            if d:
+                result.append(d)
             # Else this reference popped into existence after we captured
             # the initial refcount info.  So why don't we raise
             # _TopologyError?  I don't think it can hurt!  The ultimate