[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