Commit acad480e authored by Jeremy Hylton's avatar Jeremy Hylton

Rewrite scan for clarity. Add doc string and comment.

parent 5bda3218
...@@ -84,7 +84,7 @@ except ImportError: ...@@ -84,7 +84,7 @@ except ImportError:
import getopt, ZODB.FileStorage, struct, time import getopt, ZODB.FileStorage, struct, time
from struct import unpack from struct import unpack
from ZODB.utils import t32, p64, U64 from ZODB.utils import t32, p64, u64
from ZODB.TimeStamp import TimeStamp from ZODB.TimeStamp import TimeStamp
from cPickle import loads from cPickle import loads
from ZODB.FileStorage import RecordIterator from ZODB.FileStorage import RecordIterator
...@@ -150,25 +150,37 @@ def read_transaction_header(file, pos, file_size): ...@@ -150,25 +150,37 @@ def read_transaction_header(file, pos, file_size):
return pos, result return pos, result
def scan(file, pos, file_size): def scan(file, pos):
seek=file.seek """Return a potential transaction location following pos in file.
read=file.read
This routine scans forward from pos looking for the last data
record in a transaction. A period '.' always occurs at the end of
a pickle, and an 8-byte transaction length follows the last
pickle. If a period is followed by a plausible 8-byte transaction
length, assume that we have found the end of a transaction.
The caller should try to verify that the returned location is
actually a transaction header.
"""
while 1: while 1:
seek(pos) file.seek(pos)
data=read(8096) data = file.read(8096)
if not data: return 0 if not data:
return 0
s=0 s = 0
while 1: while 1:
l=data.find('.', s) l = data.find('.', s)
if l < 0: if l < 0:
pos=pos+8096 pos += len(data)
break break
if l > 8080: # If we are less than 8 bytes from the end of the
pos = pos + l # string, we need to read more data.
if l > len(data) - 8:
pos += l
break break
s=l+1 s = l + 1
tl=U64(data[s:s+8]) tl = u64(data[s:s+8])
if tl < pos: if tl < pos:
return pos + s + 8 return pos + s + 8
...@@ -234,7 +246,7 @@ def recover(inp, outp, verbose=0, partial=0, force=0, pack=0): ...@@ -234,7 +246,7 @@ def recover(inp, outp, verbose=0, partial=0, force=0, pack=0):
print "\n%s: %s\n" % sys.exc_info()[:2] print "\n%s: %s\n" % sys.exc_info()[:2]
if not verbose: if not verbose:
progress(prog1) progress(prog1)
pos = scan(file, pos, file_size) pos = scan(file, pos)
continue continue
if transaction is None: if transaction is None:
...@@ -298,7 +310,7 @@ def recover(inp, outp, verbose=0, partial=0, force=0, pack=0): ...@@ -298,7 +310,7 @@ def recover(inp, outp, verbose=0, partial=0, force=0, pack=0):
print "\n%s: %s\n" % sys.exc_info()[:2] print "\n%s: %s\n" % sys.exc_info()[:2]
if not verbose: if not verbose:
progress(prog1) progress(prog1)
pos = scan(file, pos, file_size) pos = scan(file, pos)
else: else:
ofs.tpc_vote(transaction) ofs.tpc_vote(transaction)
ofs.tpc_finish(transaction) ofs.tpc_finish(transaction)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment