[Checkins] SVN: zc.zodbdgc/branches/dev/src/zc/zodbdgc/ If no references db is specified, don't track references. This makes

Jim Fulton jim at zope.com
Wed Jun 3 11:48:41 EDT 2009


Log message for revision 100615:
  If no references db is specified, don't track references.  This makes
  the analysis go faster and sue less memory.
  
  Also provide a helper class for using the references db after the
  fact.
  

Changed:
  U   zc.zodbdgc/branches/dev/src/zc/zodbdgc/README.test
  U   zc.zodbdgc/branches/dev/src/zc/zodbdgc/__init__.py

-=-
Modified: zc.zodbdgc/branches/dev/src/zc/zodbdgc/README.test
===================================================================
--- zc.zodbdgc/branches/dev/src/zc/zodbdgc/README.test	2009-06-03 12:21:40 UTC (rev 100614)
+++ zc.zodbdgc/branches/dev/src/zc/zodbdgc/README.test	2009-06-03 15:48:41 UTC (rev 100615)
@@ -386,11 +386,35 @@
     ...     d.close()
 
     >>> zc.zodbdgc.check_command(['config2'])
+    !!! db1 2216 ?
+    POSKeyError: 'No blob file'
+    !!! db2 2 ?
+    POSKeyError: 0x02
+
+We get a list of missing objects.  We don't get the refering objects.
+To get the, we have to use the -r option to specify the name of a
+database to use.
+
+    >>> zc.zodbdgc.check_command(['-rrefs.fs', 'config2'])
     !!! db1 2216 db1 0
     POSKeyError: 'No blob file'
     !!! db2 2 db1 1
     POSKeyError: 0x02
 
+Note that now we get information about what was referencing the
+missing object. Not just that, we also get a database we can use to
+query about any references:
+
+    >>> refs = zc.zodbdgc.References('refs.fs')
+    >>> list(refs['db2', 2])
+    [('db1', 1)]
+    >>> list(refs['db2', '\0'*7+'\2'])
+    [('db1', 1)]
+    >>> list(refs['db1', 1])
+    [('db1', 0)]
+
+
+
 Note that we see the missing link from db1 to db2.  There is not
 missing link from db1 to db3 because the referencing object was
 incorrectly removed as garbage.
@@ -408,11 +432,14 @@
     ... """)
 
     >>> zc.zodbdgc.check_command(['config2'])
-    !!! db1 2216 db1 0
+    !!! db1 2216 ?
     POSKeyError: 'No blob file'
     !!! db2 2 db1 1
     bad db
 
+(Note that we get the refereing object info here because it is redily
+available at the time the bad reference is detected.)
+
 If a database is configured to not allow cross references, we complain
 about cross references that we see:
 
@@ -439,10 +466,10 @@
     ... """)
 
     >>> zc.zodbdgc.check_command(['config2'])
-    !!! db1 2216 db1 0
+    !!! db1 2216 ?
     POSKeyError: 'No blob file'
     bad xref db2 2 db1 1
-    !!! db2 2 db1 1
+    !!! db2 2 ?
     POSKeyError: 0x02
 
 .. cleanup

Modified: zc.zodbdgc/branches/dev/src/zc/zodbdgc/__init__.py
===================================================================
--- zc.zodbdgc/branches/dev/src/zc/zodbdgc/__init__.py	2009-06-03 12:21:40 UTC (rev 100614)
+++ zc.zodbdgc/branches/dev/src/zc/zodbdgc/__init__.py	2009-06-03 15:48:41 UTC (rev 100615)
@@ -276,10 +276,9 @@
 
 
 def check(config, refdb=None):
-    tempdir = None
     if refdb is None:
-        tempdir = tempfile.mkdtemp('check_refs')
-        refdb = os.path.join(tempdir, 'refs.fs')
+        return check_(config)
+
     fs = ZODB.FileStorage.FileStorage(refdb, create=True)
     conn = ZODB.connection(fs)
     references = conn.root.references = {}
@@ -288,10 +287,10 @@
     finally:
         transaction.commit()
         conn.close()
-        if tempdir:
-            shutil.rmtree(tempdir)
 
 def _insert_ref(references, rname, roid, name, oid):
+    if references is None:
+        return False
     oid = u64(oid)
     roid = u64(roid)
     by_oid = references.get(name)
@@ -322,6 +321,8 @@
     return False
 
 def _get_referer(references, name, oid):
+    if references is None:
+        return
     by_oid = references.get(name)
     if by_oid:
         oid = u64(oid)
@@ -333,7 +334,7 @@
             else:
                 return name, p64(iter(by_rname).next())
 
-def check_(config, references):
+def check_(config, references=None):
     db = ZODB.config.databaseFromFile(open(config))
     databases = db.databases
     storages = dict((name, db.storage) for (name, db) in databases.iteritems())
@@ -407,3 +408,21 @@
         parser.parse_args(['-h'])
 
     check(args[0], options.refdb)
+
+class References:
+
+    def __init__(self, db):
+        self._conn = ZODB.connection(db)
+        self._refs = self._conn.root.references
+
+    def __getitem__(self, (name, oid)):
+        if isinstance(oid, str):
+            oid = u64(oid)
+        by_rname = self._refs[name][oid]
+        if isinstance(by_rname, dict):
+            for rname, roids in by_rname.iteritems():
+                for roid in roids:
+                    yield rname, roid
+        else:
+            for roid in by_rname:
+                yield name, roid



More information about the Checkins mailing list