[Zope3-checkins] CVS: Zope3/src/zodb/storage - bdbminimal.py:1.22

Barry Warsaw barry@zope.com
Mon, 30 Jun 2003 13:02:23 -0400


Update of /cvs-repository/Zope3/src/zodb/storage
In directory cvs.zope.org:/tmp/cvs-serv24588

Modified Files:
	bdbminimal.py 
Log Message:
Close the theoretical <wink> race condition Tim mentions in the
previous checkin.  When marking, we chase all revisions of the objects
reachable from the root.  Specifically,

_getAllSerials(): Returns the serial numbers associated with an oid
for both revisions of the object that could be in the database
(i.e. the current one and the optimistic one).

_getCurrentSerials(): Rewrite in terms of _getAllSerials().

_mark(): Use _getAllSerials() and chase the references for each object
revision.


=== Zope3/src/zodb/storage/bdbminimal.py 1.21 => 1.22 ===
--- Zope3/src/zodb/storage/bdbminimal.py:1.21	Mon Jun 30 12:35:39 2003
+++ Zope3/src/zodb/storage/bdbminimal.py	Mon Jun 30 13:02:23 2003
@@ -315,7 +315,7 @@
     # Accessor interface
     #
 
-    def _getCurrentSerial(self, oid):
+    def _getAllSerials(self, oid):
         # BAW: We must have the application level lock here.
         c = self._serials.cursor()
         try:
@@ -340,18 +340,22 @@
             while rec:
                 serials.append(rec[1])
                 rec = c.next_dup()
-            if not serials:
-                return None
-            if len(serials) == 1:
-                return serials[0]
-            pending = self._pending.get(self._serial)
-            assert pending in (ABORT, COMMIT)
-            if pending == ABORT:
-                return serials[0]
-            return serials[1]
+            return serials
         finally:
             c.close()
 
+    def _getCurrentSerial(self, oid):
+        serials = self._getAllSerials(oid)
+        if not serials:
+            return None
+        if len(serials) == 1:
+            return serials[0]
+        pending = self._pending.get(self._serial)
+        assert pending in (ABORT, COMMIT)
+        if pending == ABORT:
+            return serials[0]
+        return serials[1]
+
     def load(self, oid, version):
         if version <> '':
             raise NotImplementedError
@@ -448,12 +452,10 @@
             if not self._packmark.has_key(oid):
                 # We've haven't yet seen this object
                 self._packmark.put(oid, PRESENT, txn=txn)
-                # Get the pickle data for this object
-                tid = self._getCurrentSerial(oid)
-                # Say there's no root object (as is the case in some of the
-                # unit tests), and we're looking up oid ZERO.  Then serial
-                # will be None.
-                if tid is not None:
+                # Get the pickle data for every revision of this object we
+                # know about.
+                serials = self._getAllSerials(oid)
+                for tid in serials:
                     # Now get the oids of all the objects referenced by this
                     # object revision
                     references = self._references.get(oid+tid)