[Zope-Checkins] CVS: Zope/lib/python/ZODB - DB.py:1.53.2.4

Tim Peters tim.one at comcast.net
Mon May 10 12:07:56 EDT 2004


Update of /cvs-repository/Zope/lib/python/ZODB
In directory cvs.zope.org:/tmp/cvs-serv19681/lib/python/ZODB

Modified Files:
      Tag: Zope-2_7-branch
	DB.py 
Log Message:
Backport fix for collector #1309:  The reference counts reported by
DB.cacheExtremeDetails() for ghosts were one too small.


=== Zope/lib/python/ZODB/DB.py 1.53.2.3 => 1.53.2.4 ===
--- Zope/lib/python/ZODB/DB.py:1.53.2.3	Mon Nov 17 17:34:18 2003
+++ Zope/lib/python/ZODB/DB.py	Mon May 10 12:07:25 2004
@@ -198,29 +198,40 @@
         return detail
 
     def cacheExtremeDetail(self):
-        detail=[]
+        detail = []
         conn_no = [0]  # A mutable reference to a counter
+
         def f(con, detail=detail, rc=sys.getrefcount, conn_no=conn_no):
-            conn_no[0] = conn_no[0] + 1
+            conn_no[0] += 1
             cn = conn_no[0]
             for oid, ob in con._cache_items():
-                id=''
-                if hasattr(ob,'__dict__'):
-                    d=ob.__dict__
+                id = ''
+                if hasattr(ob, '__dict__'):
+                    d = ob.__dict__
                     if d.has_key('id'):
-                        id=d['id']
+                        id = d['id']
                     elif d.has_key('__name__'):
-                        id=d['__name__']
+                        id = d['__name__']
 
                 module = getattr(ob.__class__, '__module__', '')
-                module = module and '%s.' % module or ''
+                module = module and ('%s.' % module) or ''
 
+                # What refcount ('rc') should we return?  The intent is
+                # that we return the true Python refcount, but as if the
+                # cache didn't exist.  This routine adds 3 to the true
+                # refcount:  1 for binding to name 'ob', another because
+                # ob lives in the con._cache_items() list we're iterating
+                # over, and calling sys.getrefcount(ob) boosts ob's
+                # count by 1 too.  So the true refcount is 3 less than
+                # sys.getrefcount(ob) returns.  But, in addition to that,
+                # the cache holds an extra reference on non-ghost objects,
+                # and we also want to pretend that doesn't exist.
                 detail.append({
                     'conn_no': cn,
                     'oid': oid,
                     'id': id,
                     'klass': "%s%s" % (module, ob.__class__.__name__),
-                    'rc': rc(ob)-4,
+                    'rc': rc(ob) - 3 - (ob._p_changed is not None),
                     'state': ob._p_changed,
                     #'references': con.references(oid),
                     })




More information about the Zope-Checkins mailing list