[Zodb-checkins] CVS: Zope/lib/python/ZODB - BaseStorage.py:1.20.4.4 Connection.py:1.72.4.2 DemoStorage.py:1.12.4.3 FileStorage.py:1.95.4.3 POSException.py:1.12.4.5 Transaction.py:1.37.4.1 __init__.py:1.13.4.2

Chris McDonough chrism@zope.com
Mon, 16 Sep 2002 02:01:25 -0400


Update of /cvs-repository/Zope/lib/python/ZODB
In directory cvs.zope.org:/tmp/cvs-serv9237/lib/python/ZODB

Modified Files:
      Tag: chrism-install-branch
	BaseStorage.py Connection.py DemoStorage.py FileStorage.py 
	POSException.py Transaction.py __init__.py 
Log Message:
Merging with HEAD.


=== Zope/lib/python/ZODB/BaseStorage.py 1.20.4.3 => 1.20.4.4 ===
--- Zope/lib/python/ZODB/BaseStorage.py:1.20.4.3	Tue Sep 10 23:36:38 2002
+++ Zope/lib/python/ZODB/BaseStorage.py	Mon Sep 16 02:00:53 2002
@@ -122,6 +122,8 @@
         pass
 
     def tpc_begin(self, transaction, tid=None, status=' '):
+        if self._is_read_only:
+            raise POSException.ReadOnlyError()
         self._lock_acquire()
         try:
             if self._transaction is transaction:


=== Zope/lib/python/ZODB/Connection.py 1.72.4.1 => 1.72.4.2 ===


=== Zope/lib/python/ZODB/DemoStorage.py 1.12.4.2 => 1.12.4.3 ===


=== Zope/lib/python/ZODB/FileStorage.py 1.95.4.2 => 1.95.4.3 ===
--- Zope/lib/python/ZODB/FileStorage.py:1.95.4.2	Tue Sep  3 03:43:47 2002
+++ Zope/lib/python/ZODB/FileStorage.py	Mon Sep 16 02:00:53 2002
@@ -1088,41 +1088,20 @@
             if self._packt is None:
                 raise UndoError(
                     'Undo is currently disabled for database maintenance.<p>')
-            pos = self._pos
-            r = []
-            i = 0
-            # BAW: Why 39 please?  This makes no sense (see also below).
-            while i < last and pos > 39:
-                self._file.seek(pos - 8)
-                pos = pos - U64(self._file.read(8)) - 8
-                self._file.seek(pos)
-                h = self._file.read(TRANS_HDR_LEN)
-                tid, tl, status, ul, dl, el = struct.unpack(">8s8scHHH", h)
-                if tid < self._packt or status == 'p':
-                    break
-                if status != ' ':
-                    continue
-                d = u = ''
-                if ul:
-                    u = self._file.read(ul)
-                if dl:
-                    d = self._file.read(dl)
-                e = {}
-                if el:
-                    try:
-                        e = loads(read(el))
-                    except:
-                        pass
-                d = {'id': base64.encodestring(tid).rstrip(),
-                     'time': TimeStamp(tid).timeTime(),
-                     'user_name': u,
-                     'description': d}
-                d.update(e)
-                if filter is None or filter(d):
-                    if i >= first:
-                        r.append(d)
-                    i += 1
-            return r
+            us = UndoSearch(self._file, self._pos, self._packt,
+                            first, last, filter)
+            while not us.finished():
+                # Hold lock for batches of 20 searches, so default search
+                # parameters will finish without letting another thread run.
+                for i in range(20):
+                    if us.finished():
+                        break
+                    us.search()
+                # Give another thread a chance, so that a long undoLog()
+                # operation doesn't block all other activity.
+                self._lock_release()
+                self._lock_acquire()
+            return us.results
         finally:
             self._lock_release()
 
@@ -2245,7 +2224,6 @@
         read=file.read
         pos=self._pos
 
-        LOG("ZODB FS", BLATHER, "next(%d)" % index)
         while 1:
             # Read the transaction record
             seek(pos)
@@ -2296,10 +2274,6 @@
                          self._file.name, pos)
                     break
 
-            if self._stop is not None:
-                LOG("ZODB FS", BLATHER,
-                    ("tid %x > stop %x ? %d" %
-                     (U64(tid), U64(self._stop), tid > self._stop)))
             if self._stop is not None and tid > self._stop:
                 raise IndexError, index
 
@@ -2413,3 +2387,59 @@
     """
     def __init__(self, *args):
         self.oid, self.serial, self.version, self.data = args
+
+class UndoSearch:
+
+    def __init__(self, file, pos, packt, first, last, filter=None):
+        self.file = file
+        self.pos = pos
+        self.packt = packt
+        self.first = first
+        self.last = last
+        self.filter = filter
+        self.i = 0
+        self.results = []
+        self.stop = 0
+
+    def finished(self):
+        """Return True if UndoSearch has found enough records."""
+        # BAW: Why 39 please?  This makes no sense (see also below).
+        return self.i >= self.last or self.pos < 39 or self.stop
+
+    def search(self):
+        """Search for another record."""
+        dict = self._readnext()
+        if self.filter is None or self.filter(dict):
+            if self.i >= self.first:
+                self.results.append(dict)
+            self.i += 1
+
+    def _readnext(self):
+        """Read the next record from the storage."""
+        self.file.seek(self.pos - 8)
+        self.pos -= U64(self.file.read(8)) + 8
+        self.file.seek(self.pos)
+        h = self.file.read(TRANS_HDR_LEN)
+        tid, tl, status, ul, dl, el = struct.unpack(">8s8scHHH", h)
+        if tid < self.packt or status == 'p':
+            self.stop = 1
+            return None
+        if status != ' ':
+            return None
+        d = u = ''
+        if ul:
+            u = self.file.read(ul)
+        if dl:
+            d = self.file.read(dl)
+        e = {}
+        if el:
+            try:
+                e = loads(self.file.read(el))
+            except:
+                pass
+        d = {'id': base64.encodestring(tid).rstrip(),
+             'time': TimeStamp(tid).timeTime(),
+             'user_name': u,
+             'description': d}
+        d.update(e)
+        return d


=== Zope/lib/python/ZODB/POSException.py 1.12.4.4 => 1.12.4.5 ===


=== Zope/lib/python/ZODB/Transaction.py 1.37 => 1.37.4.1 ===
--- Zope/lib/python/ZODB/Transaction.py:1.37	Wed Aug 14 18:07:09 2002
+++ Zope/lib/python/ZODB/Transaction.py	Mon Sep 16 02:00:54 2002
@@ -206,12 +206,13 @@
                         else:
                             vote(self) # last chance to bail
 
-                # Try to finish one jar, since we may be able to
-                # recover if the first one fails.
-                self._finish_one(jarsv)
-                # Once a single jar has finished, it's a fatal (hosed)
-                # error if another jar fails.
-                self._finish_rest(jarsv)
+                # Handle multiple jars separately.  If there are
+                # multiple jars and one fails during the finish, we
+                # mark this transaction manager as hosed.
+                if len(jarsv) == 1:
+                    self._finish_one(jarsv[0])
+                else:
+                    self._finish_many(jarsv)
             except:
                 # Ugh, we got an got an error during commit, so we
                 # have to clean up.
@@ -266,11 +267,9 @@
                 jars[i] = j
             j.commit_sub(self)
 
-    def _finish_one(self, jarsv):
+    def _finish_one(self, jar):
         try:
-            if jarsv:
-                jarsv[-1].tpc_finish(self) # This should never fail
-                jarsv.pop() # It didn't, so it's taken care of.
+            jar.tpc_finish(self) # This should never fail
         except:
             # Bug if it does, we need to keep track of it
             LOG('ZODB', ERROR,
@@ -279,7 +278,7 @@
                 error=sys.exc_info())
             raise
 
-    def _finish_rest(self, jarsv):
+    def _finish_many(self, jarsv):
         global hosed
         try:
             while jarsv:


=== Zope/lib/python/ZODB/__init__.py 1.13.4.1 => 1.13.4.2 ===
--- Zope/lib/python/ZODB/__init__.py:1.13.4.1	Mon Aug 26 02:22:38 2002
+++ Zope/lib/python/ZODB/__init__.py	Mon Sep 16 02:00:54 2002
@@ -13,6 +13,9 @@
 ##############################################################################
 import sys
 import cPersistence, Persistence
+
+__version__ = '3.1b1+'
+
 from zLOG import register_subsystem
 register_subsystem('ZODB')