[Zodb-checkins] CVS: ZODB3/bsddb3Storage/bsddb3Storage - Full.py:1.52

Barry Warsaw barry@wooz.org
Thu, 14 Nov 2002 13:50:52 -0500


Update of /cvs-repository/ZODB3/bsddb3Storage/bsddb3Storage
In directory cvs.zope.org:/tmp/cvs-serv17899

Modified Files:
	Full.py 
Log Message:
_collect_revs(): It's possible that the metadata and txnoids entries
for an object revision in objrevs got collected away when the entire
object was refcounted to zero.  Be more defensive about find and
deleting these records.

Also, truncate the packtime table before writing the new record, to
maintain the database invariant that there is only allowed one entry
in this table at a time.


=== ZODB3/bsddb3Storage/bsddb3Storage/Full.py 1.51 => 1.52 ===
--- ZODB3/bsddb3Storage/bsddb3Storage/Full.py:1.51	Mon Nov 11 17:05:41 2002
+++ ZODB3/bsddb3Storage/bsddb3Storage/Full.py	Thu Nov 14 13:50:52 2002
@@ -1452,13 +1452,24 @@
                 # with it again.  Otherwise, we can remove the metadata record
                 # for this revision and decref the corresponding pickle.
                 if oldserial <> ZERO:
-                    metadata = self._metadata[oid+oldserial]
-                    self._metadata.delete(oid+oldserial, txn=txn)
-                    # Decref the pickle
-                    self._decrefPickle(oid, metadata[16:24], txn)
-                    # Remove the txnoids entry.  We have to use a cursor here.
-                    ct.set_both(oldserial, oid)
-                    ct.delete()
+                    # It's possible this object revision has already been
+                    # deleted, if the oid points to a decref'd away object
+                    try:
+                        metadata = self._metadata[oid+oldserial]
+                    except KeyError:
+                        pass
+                    else:
+                        self._metadata.delete(oid+oldserial, txn=txn)
+                        # Decref the pickle
+                        self._decrefPickle(oid, metadata[16:24], txn)
+                    try:
+                        # Remove the txnoids entry.  We have to use a cursor
+                        # here because of the set_both().
+                        ct.set_both(oldserial, oid)
+                    except db.DBNotFoundError:
+                        pass
+                    else:
+                        ct.delete()
                 co.delete()
                 rec = co.next()
         finally:
@@ -1467,6 +1478,7 @@
         # Note that before we commit this Berkeley transaction, we also need
         # to update the packtime table, so we can't have the possibility of a
         # race condition with undoLog().
+        self._packtime.truncate(txn)
         self._packtime.put(packtid, PRESENT, txn=txn)
 
     def _decrefPickle(self, oid, lrevid, txn):