[Zodb-checkins] CVS: ZODB3/bsddb3Storage/bsddb3Storage - Minimal.py:1.12.4.5

Barry Warsaw barry@wooz.org
Thu, 19 Sep 2002 18:07:47 -0400


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

Modified Files:
      Tag: bdb-nolocks
	Minimal.py 
Log Message:
Code reorg and comment clean up.


=== ZODB3/bsddb3Storage/bsddb3Storage/Minimal.py 1.12.4.4 => 1.12.4.5 ===
--- ZODB3/bsddb3Storage/bsddb3Storage/Minimal.py:1.12.4.4	Tue Sep 17 18:08:41 2002
+++ ZODB3/bsddb3Storage/bsddb3Storage/Minimal.py	Thu Sep 19 18:07:47 2002
@@ -41,12 +41,13 @@
     def _setupDBs(self):
         # Data Type Assumptions:
         #
-        # - object ids (oid) are 8-bytes
-        # - object revision ids (revid), aka serial numbers, are 8-bytes
-        # - transaction ids (tid) are 8-bytes
-        # - data pickles are of arbitrary length
+        # - Object ids (oid) are 8-bytes
+        # - Objects have revisions, with each revision being identified by a
+        #   unique serial number.
+        # - Transaction ids (tid) are 8-bytes
+        # - Data pickles are of arbitrary length
         #
-        # The minimal storage uses the following tables:
+        # The Minimal storage uses the following tables:
         #
         # serials -- {oid -> [serial]}
         #     Maps oids to serial numbers.  Each oid can be mapped to 1 or 2
@@ -55,7 +56,7 @@
         #     pending flag (see below).
         #
         # pickles -- {oid+serial -> pickle}
-        #     Maps the oid plus the serial number to the object's data pickle.
+        #     Maps the object revisions to the revision's pickle data.
         #
         # refcounts -- {oid -> count}
         #     Maps the oid to the reference count for the object.  This
@@ -63,19 +64,18 @@
         #     goes to zero, the object is automatically deleted.
         #
         # oids -- [oid]
-        #     This is just a list of oids of objects that are modified in the
-        #     current transaction.
+        #     This is a list of oids of objects that are modified in the
+        #     current uncommitted transaction.
         #
-        # pending -- |tid -> 'A' | 'C'|
+        # pending -- tid -> 'A' | 'C'
         #     This is an optional flag which says what to do when the database
         #     is recovering from a crash.  The flag is normally 'A' which
-        #     means any pending data should be aborted.  After a tpc_vote()
-        #     but before the end of the tpc_finish(), this flag will be 'C'
-        #     which means, upon recovery/restart, all pending data should be
-        #     committed.  Outside of any transaction (e.g. before the
-        #     tpc_begin()), there will be no pending entry.  It is a database
-        #     invariant that if the pending table is empty, the oids table
-        #     must also be empty.
+        #     means any pending data should be aborted.  At the start of the
+        #     tpc_finish() this flag will be changed to 'C' which means, upon
+        #     recovery/restart, all pending data should be committed.  Outside
+        #     of any transaction (e.g. before the tpc_begin()), there will be
+        #     no pending entry.  It is a database invariant that if the
+        #     pending table is empty, the oids table must also be empty.
         #
         self._serials = self._setupDB('serials', db.DB_DUP)
         self._pickles = self._setupDB('pickles')
@@ -101,6 +101,14 @@
         finally:
             self._lock_release()
 
+    def close(self):
+        self._serials.close()
+        self._pickles.close()
+        self._refcounts.close()
+        self._oids.close()
+        self._pending.close()
+        BerkeleyBase.close(self)
+
     def _do(self, meth, tid):
         txn = self._env.txn_begin()
         try:
@@ -133,7 +141,7 @@
                 # And delete the pickle table entry for this revision.
                 self._pickles.delete(oid+tid, txn=txn)
         finally:
-            # There's a small window of opportunity for leakinga cursor here,
+            # There's a small window of opportunity for leaking a cursor here,
             # if co.close() were to fail.  In practice this shouldn't happen.
             if co: co.close()
             if cs: cs.close()
@@ -162,16 +170,16 @@
                         cs.delete()
                         data = self._pickles.get(oid+stid, txn=txn)
                         assert data is not None
-                        _update(deltas, data, -1)
+                        self._update(deltas, data, -1)
                         self._pickles.delete(oid+stid, txn=txn)
                     srec = cs.next_dup()
                 # Now add incref deltas for all objects referenced by the new
                 # revision of this object.
                 data = self._pickles.get(oid+tid, txn=txn)
                 assert data is not None
-                _update(deltas, data, 1)
+                self._update(deltas, data, 1)
         finally:
-            # There's a small window of opportunity for leakinga cursor here,
+            # There's a small window of opportunity for leaking a cursor here,
             # if co.close() were to fail.  In practice this shouldn't happen.
             if co: co.close()
             if cs: cs.close()
@@ -193,7 +201,7 @@
                 # pickle, we need to decref all the objects referenced by it.
                 current = self._getCurrentSerial(oid)
                 data = self._pickles.get(oid+current, txn=txn)
-                _update(newdeltas, data, -1)
+                self._update(newdeltas, data, -1)
                 # And delete the serials, pickle and refcount entries.  At
                 # this point, I believe we should have just one serial entry.
                 self._serials.delete(oid, txn=txn)
@@ -212,43 +220,6 @@
         # will be aborted.
         self._pending[self._serial] = ABORT
 
-    def _getCurrentSerial(self, oid):
-        # BAW: We must have the application level lock here.
-        c = self._serials.cursor()
-        try:
-            # There can be zero, one, or two entries in the serials table for
-            # this oid.  If there are no entries, raise a KeyError (we know
-            # nothing about this object).
-            #
-            # If there is exactly one entry then this has to be the entry for
-            # the object, regardless of the pending flag.
-            #
-            # If there are two entries, then we need to look at the pending
-            # flag to decide which to return (there /better/ be a pending flag
-            # set!).  If the pending flag is COMMIT then we've already voted
-            # so the second one is the good one.  If the pending flag is ABORT
-            # then we haven't yet committed to this transaction so the first
-            # one is the good one.
-            serials = []
-            try:
-                rec = c.set(oid)
-            except db.DBNotFoundError:
-                rec = None
-            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]
-        finally:
-            c.close()
-
     def store(self, oid, serial, data, version, transaction):
         if transaction is not self._transaction:
             raise POSException.StorageTransactionError(self, transaction)
@@ -286,9 +257,6 @@
         # Return the new serial number for the object
         return newserial
 
-    def _vote(self):
-        pass
-
     def _finish(self, tid, u, d, e):
         # Twiddle the pending flag to COMMIT now since after the vote call, we
         # promise that the changes will be committed, no matter what.  The
@@ -299,18 +267,47 @@
     def _abort(self):
         self._do(self._doabort, self._serial)
 
-    def close(self):
-        self._serials.close()
-        self._pickles.close()
-        self._refcounts.close()
-        self._oids.close()
-        self._pending.close()
-        BerkeleyBase.close(self)
-
     #
-    # Public storage interface
+    # Accessor interface
     #
 
+    def _getCurrentSerial(self, oid):
+        # BAW: We must have the application level lock here.
+        c = self._serials.cursor()
+        try:
+            # There can be zero, one, or two entries in the serials table for
+            # this oid.  If there are no entries, raise a KeyError (we know
+            # nothing about this object).
+            #
+            # If there is exactly one entry then this has to be the entry for
+            # the object, regardless of the pending flag.
+            #
+            # If there are two entries, then we need to look at the pending
+            # flag to decide which to return (there /better/ be a pending flag
+            # set!).  If the pending flag is COMMIT then we've already voted
+            # so the second one is the good one.  If the pending flag is ABORT
+            # then we haven't yet committed to this transaction so the first
+            # one is the good one.
+            serials = []
+            try:
+                rec = c.set(oid)
+            except db.DBNotFoundError:
+                rec = None
+            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]
+        finally:
+            c.close()
+
     def load(self, oid, version):
         if version <> '':
             raise POSException.Unsupported, 'versions are not supported'
@@ -326,19 +323,6 @@
             self._lock_release()
 
     def modifiedInVersion(self, oid):
-        # So BaseStorage.getSerial just works.  Note that this storage doesn't
-        # support versions.
+        # So BaseStorage.getSerial() just works.  Note that this storage
+        # doesn't support versions.
         return ''
-
-
-
-def _update(deltas, data, incdec):
-    refdoids = []
-    referencesf(data, refdoids)
-    for oid in refdoids:
-        rc = deltas.get(oid, 0) + incdec
-        if rc == 0:
-            # Save space in the dict by zapping zeroes
-            del deltas[oid]
-        else:
-            deltas[oid] = rc