[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