[Zodb-checkins] CVS: ZODB3/ZODB - fsdump.py:1.3.72.1 FileStorage.py:1.105.2.4 BaseStorage.py:1.24.2.1
Jeremy Hylton
jeremy@zope.com
Mon, 21 Oct 2002 11:15:56 -0400
Update of /cvs-repository/ZODB3/ZODB
In directory cvs.zope.org:/tmp/cvs-serv7174/ZODB
Modified Files:
Tag: ZODB3-3_1-branch
fsdump.py FileStorage.py BaseStorage.py
Log Message:
Backport from trunk: restore() / backpointer fixes
FileStorage.py: A version of restore() that writes backpointers...
BaseStorage.py: sync up with new restore() signature.
fsdump.py: Print backpointer if it exists.
=== ZODB3/ZODB/fsdump.py 1.3 => 1.3.72.1 ===
--- ZODB3/ZODB/fsdump.py:1.3 Mon Feb 11 14:38:09 2002
+++ ZODB3/ZODB/fsdump.py Mon Oct 21 11:15:55 2002
@@ -64,8 +64,14 @@
version = "version=%s " % rec.version
else:
version = ''
- print >> file, " data #%05d oid=%016x %sclass=%s" % \
- (j, U64(rec.oid), version, fullclass)
+ if rec.data_txn:
+ # XXX It would be nice to print the transaction number
+ # (i) but it would be too expensive to keep track of.
+ bp = "bp=%016x" % U64(rec.data_txn)
+ else:
+ bp = ""
+ print >> file, " data #%05d oid=%016x %sclass=%s %s" % \
+ (j, U64(rec.oid), version, fullclass, bp)
j += 1
print >> file
i += 1
=== ZODB3/ZODB/FileStorage.py 1.105.2.3 => 1.105.2.4 ===
--- ZODB3/ZODB/FileStorage.py:1.105.2.3 Fri Oct 18 15:39:58 2002
+++ ZODB3/ZODB/FileStorage.py Mon Oct 21 11:15:55 2002
@@ -742,7 +742,40 @@
finally:
self._lock_release()
- def restore(self, oid, serial, data, version, transaction):
+ def _data_find(self, tpos, oid, data):
+ # Return backpointer to oid in data record for in transaction at tpos.
+ # It should contain a pickle identical to data. Returns 0 on failure.
+ # Must call with lock held.
+ self._file.seek(tpos)
+ h = self._file.read(TRANS_HDR_LEN)
+ tid, stl, status, ul, dl, el = struct.unpack(TRANS_HDR, h)
+ self._file.read(ul + dl + el)
+ tend = tpos + U64(stl) + 8
+ pos = self._file.tell()
+ while pos < tend:
+ h = self._file.read(DATA_HDR_LEN)
+ _oid, serial, sprev, stpos, vl, sdl = struct.unpack(DATA_HDR, h)
+ dl = U64(sdl)
+ reclen = DATA_HDR_LEN + vl + dl
+ if vl:
+ reclen += 16
+ if _oid == oid:
+ if vl:
+ self._file.read(vl + 16)
+ # Make sure this looks like the right data record
+ if dl != len(data):
+ # XXX what if this data record also has a backpointer?
+ # I don't think that's possible, but I'm not sure.
+ return 0
+ _data = self._file.read(dl)
+ if data != _data:
+ return 0
+ return pos
+ pos += reclen
+ self._file.seek(pos)
+ return 0
+
+ def restore(self, oid, serial, data, version, prev_txn, transaction):
# A lot like store() but without all the consistency checks. This
# should only be used when we /know/ the data is good, hence the
# method name. While the signature looks like store() there are some
@@ -756,6 +789,9 @@
#
# - data can be None, which indicates a George Bailey object
# (i.e. one who's creation has been transactionally undone).
+ #
+ # If prev_txn is not None, it should contain the same data as
+ # the argument data. If it does, write a backpointer to it.
if self._is_read_only:
raise POSException.ReadOnlyError()
if transaction is not self._transaction:
@@ -763,17 +799,25 @@
self._lock_acquire()
try:
+ prev_pos = 0
+ if prev_txn is not None:
+ prev_txn_pos = self._txn_find(prev_txn)
+ if prev_txn_pos:
+ prev_pos = self._data_find(prev_txn_pos, oid, data)
old = self._index_get(oid, 0)
# Calculate the file position in the temporary file
here = self._pos + self._tfile.tell() + self._thl
# And update the temp file index
self._tindex[oid] = here
- # Write the recovery data record
+ if prev_pos:
+ # If there is a valid prev_pos, don't write data.
+ data = None
if data is None:
dlen = 0
else:
dlen = len(data)
- self._tfile.write(pack('>8s8s8s8sH8s',
+ # Write the recovery data record
+ self._tfile.write(pack(DATA_HDR,
oid, serial, p64(old), p64(self._pos),
len(version), p64(dlen)))
# We need to write some version information if this revision is
@@ -806,9 +850,13 @@
self._tfile.write(version)
# And finally, write the data
if data is None:
- # Write a zero backpointer, which indicates an
- # un-creation transaction.
- self._tfile.write(z64)
+ if prev_pos:
+ self._tfile.write(p64(prev_pos))
+ else:
+ # Write a zero backpointer, which indicates an
+ # un-creation transaction.
+ # write a backpointer instead of data
+ self._tfile.write(z64)
else:
self._tfile.write(data)
finally:
=== ZODB3/ZODB/BaseStorage.py 1.24 => 1.24.2.1 ===
--- ZODB3/ZODB/BaseStorage.py:1.24 Sat Sep 28 05:16:46 2002
+++ ZODB3/ZODB/BaseStorage.py Mon Oct 21 11:15:55 2002
@@ -281,7 +281,8 @@
oid=r.oid
if verbose: print `oid`, r.version, len(r.data)
if restoring:
- self.restore(oid, r.serial, r.data, r.version, transaction)
+ self.restore(oid, r.serial, r.data, r.version,
+ r.data_txn, transaction)
else:
pre=preget(oid, None)
s=self.store(oid, pre, r.data, r.version, transaction)