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

Jeremy Hylton jeremy@zope.com
Tue, 11 Mar 2003 18:38:46 -0500


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

Modified Files:
      Tag: opaque-pickles-branch
	file.py 
Log Message:
Partial fixes for pack() and commitVersion().

It looks like pack() is basically done, but commitVersion() has some
problems chasing backpointers.  The problem could actually be in undo.


=== Zope3/src/zodb/storage/file.py 1.8.4.7 => 1.8.4.8 ===
--- Zope3/src/zodb/storage/file.py:1.8.4.7	Tue Mar 11 15:17:47 2003
+++ Zope3/src/zodb/storage/file.py	Tue Mar 11 18:38:39 2003
@@ -200,15 +200,19 @@
 
 class CorruptedDataError(CorruptedFileStorageError):
 
-    def __init__(self, oid=None, buf=None):
+    def __init__(self, oid=None, buf=None, pos=None):
         self.oid = oid
         self.buf = buf
+        self.pos = pos
 
     def __str__(self):
         if self.oid:
-            return "Error reading oid %016x.  Found %r" % (self.oid, self.buf)
+            msg = "Error reading oid %016x.  Found %r" % (self.oid, self.buf)
         else:
-            return "Error reading unknown oid.  Found %r" % self.buf
+            msg = "Error reading unknown oid.  Found %r" % self.buf
+        if self.pos:
+            msg += " at %d" % self.pos
+        return msg
 
 class FileStorageQuotaError(FileStorageError, StorageSystemError):
     """File storage quota exceeded."""
@@ -427,10 +431,10 @@
         self._file.seek(pos)
         s = self._file.read(DATA_HDR_LEN)
         if len(s) != DATA_HDR_LEN:
-            raise CorruptedDataError(oid, s)
+            raise CorruptedDataError(oid, s, pos)
         h = DataHeader.fromString(s)
         if oid is not None and oid != h.oid:
-            raise CorruptedDataError(oid, s)
+            raise CorruptedDataError(oid, s, pos)
         if h.vlen:
             s = self._file.read(16 + h.vlen)
             h.parseVersion(s)
@@ -714,14 +718,15 @@
         #    always 0
         middle = struct.pack(">QHIQ", self._pos, len(dest), 0, 0)
 
+        # Argh!  what does heredelta mean?
         if dest:
             sd = p64(self._vindex.get(dest, 0))
             heredelta = 66 + len(dest)
         else:
             sd = ''
-            heredelta = 50
+            heredelta = 54
 
-        here = self._pos + (self._tfile.tell() + self._thl)
+        here = self._pos + self._tfile.tell() + self._thl
         oids = []
         current_oids = {}
         t = None
@@ -730,48 +735,40 @@
             newserial = self._serial
 
         while srcpos:
-            self._file.seek(srcpos)
-            h = self._file.read(DATA_VERSION_HDR_LEN)
-            # h -> oid, serial, prev(oid), tloc, vlen, plen, pnv, pv
-            oid = h[:8]
-            pnv = h[-16:-8]
+            h = self._read_data_header(srcpos)
             if abort:
                 # If we are aborting, the serialno in the new data
                 # record should be the same as the serialno in the last
                 # non-version data record.
                 # XXX This might be the only time that the serialno
                 # of a data record does not match the transaction id.
-                self._file.seek(u64(pnv))
-                h_pnv = self._file.read(DATA_VERSION_HDR_LEN)
-                newserial = h_pnv[8:16]
+                self._file.seek(h.pnv)
+                h_pnv = self._read_data_header(srcpos)
+                newserial = h_pnv.serial
 
-            if self._index.get(oid) == srcpos:
+            if self._index.get(h.oid) == srcpos:
                 # This is a current record!
-                self._tindex[oid] = here
-                oids.append(oid)
-                self._tfile.write(oid + newserial + spos + middle)
+                self._tindex[h.oid] = here
+                oids.append(h.oid)
+                self._tfile.write(h.oid + newserial + spos + middle)
                 if dest:
                     self._tvindex[dest] = here
-                    self._tfile.write(pnv + sd + dest)
+                    self._tfile.write(p64(h.pnv) + sd + dest)
                     sd = p64(here)
 
-                self._tfile.write(abort and pnv or spos)
+                self._tfile.write(abort and p64(h.pnv) or spos)
                 # data backpointer to src data
                 here += heredelta
 
-                current_oids[oid] = 1
-                # Once we've found the data we are looking for,
-                # we can stop chasing backpointers.
-                break
-
+                current_oids[h.oid] = 1
             else:
                 # Hm.  This is a non-current record.  Is there a
                 # current record for this oid?
-                if not current_oids.has_key(oid):
+                if not current_oids.has_key(h.oid):
                     break
 
-            spos = h[-8:]
-            srcpos = u64(spos)
+            srcpos = h.vprev
+            spos = p64(srcpos)
         return oids
 
     def load(self, oid, version):
@@ -1792,7 +1789,7 @@
                     else:
                         if pnv < packpos:
                             # we need to point to the packed non-version rec
-                            pnv = nvindex[h.oid]
+                            pnv = nvindex.get(h.oid, 0)
                         else:
                             # we just need to adjust the pointer with
                             # the offset