[Zope3-checkins] CVS: Zope3/src/zodb/storage/file - pack.py:1.1.2.8

Jeremy Hylton jeremy@zope.com
Mon, 21 Apr 2003 15:11:51 -0400


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

Modified Files:
      Tag: jeremy-new-pack-branch
	pack.py 
Log Message:
Add error checking during pack.


=== Zope3/src/zodb/storage/file/pack.py 1.1.2.7 => 1.1.2.8 ===
--- Zope3/src/zodb/storage/file/pack.py:1.1.2.7	Mon Apr 21 13:18:31 2003
+++ Zope3/src/zodb/storage/file/pack.py	Mon Apr 21 15:11:50 2003
@@ -11,20 +11,25 @@
 a backpointer after that time.
 """
 
+import logging
 import os
 import stat
 
-from zodb.interfaces import ZERO
+from zodb.interfaces import ZERO, _fmt_oid
 from zodb.utils import p64, u64
 from zodb.storage.base import splitrefs
 from zodb.storage.file.copy import DataCopier
+from zodb.storage.file.errors import CorruptedError
 from zodb.storage.file.format import FileStorageFormatter
 from zodb.storage.file.index import fsIndex
 
+logger = logging.getLogger("zodb.storage.file")
+
 class GC(FileStorageFormatter):
 
     def __init__(self, file, eof, packtime):
         self._file = file
+        self._name = file.name
         self.eof = eof
         self.packtime = packtime
         # packpos: position of first txn header after pack time
@@ -45,6 +50,9 @@
         self.reachable = fsIndex()
         self.reach_ex = {}
 
+        # keep ltid for consistency checks during initial scan
+        self.ltid = ZERO
+
     def isReachable(self, oid, pos):
         """Return True if revision of `oid` at `pos` is reachable."""
 
@@ -66,12 +74,15 @@
             th = self._read_txn_header(pos)
             if th.tid > self.packtime:
                 break
+            self.checkTxn(th, pos)
 
+            tpos = pos
             end = pos + th.tlen
             pos += th.headerlen()
 
             while pos < end:
                 dh = self._read_data_header(pos)
+                self.checkData(th, tpos, dh, pos)
                 if dh.version:
                     self.oid2verpos[dh.oid] = pos
                 else:
@@ -79,7 +90,10 @@
                 pos += dh.recordlen()
 
             tlen = self._read_num(pos)
-            assert tlen == th.tlen
+            if tlen != th.tlen:
+                self.fail(pos, "redundant transaction length does not "
+                          "match initial transaction length: %d != %d",
+                          u64(s), th.tlen)
             pos += 8
 
         self.packpos = pos
@@ -123,11 +137,14 @@
         pos = self.packpos
         while pos < self.eof:
             th = self._read_txn_header(pos)
+            self.checkTxn(th, pos)
+            tpos = pos
             end = pos + th.tlen
             pos += th.headerlen()
 
             while pos < end:
                 dh = self._read_data_header(pos)
+                self.checkData(th, tpos, dh, pos)
 
                 if dh.back and dh.back < self.packpos:
                     if dh.oid in self.reachable:
@@ -150,7 +167,10 @@
                 pos += dh.recordlen()
 
             tlen = self._read_num(pos)
-            assert tlen == th.tlen
+            if tlen != th.tlen:
+                self.fail(pos, "redundant transaction length does not "
+                          "match initial transaction length: %d != %d",
+                          u64(s), th.tlen)
             pos += 8
 
         for pos in extra_roots:
@@ -298,7 +318,12 @@
                 self._tfile.seek(new_pos - 8)
                 self._tfile.write(p64(tlen))
 
-            # skip the end-of-transaction redundant length
+            
+            tlen = self._read_num(pos)
+            if tlen != th.tlen:
+                self.fail(pos, "redundant transaction length does not "
+                          "match initial transaction length: %d != %d",
+                          u64(s), th.tlen)
             pos += 8
 
         return pos, new_pos
@@ -429,3 +454,4 @@
             self.tindex.clear()
             self.vindex.update(self.tvindex)
             self.tvindex.clear()
+