Make the appendfile class inline-data index friendly
The appendfile class needs a few changes to make it work with interleaved
index files. It needs to support the tell() method, opening in a+ mode,
and it needs to delay the checkinlinesize call until after the
append file is written.
Given that open(file, "a+") doesn't always seek to the end of the file,
this adds seek operations to appendfile that understand whence args
--- a/mercurial/appendfile.py Tue Apr 04 16:38:43 2006 -0400
+++ b/mercurial/appendfile.py Tue Apr 04 16:38:43 2006 -0400
@@ -42,9 +42,19 @@
# seek and read can be fast.
self.fpsize = os.fstat(fp.fileno()).st_size
- def seek(self, offset):
+ def end(self):
+ self.tmpfp.flush() # make sure the stat is correct
+ return self.fpsize + os.fstat(self.tmpfp.fileno()).st_size
+
+ def seek(self, offset, whence=0):
'''virtual file offset spans real file and temp file.'''
- self.offset = offset
+ if whence == 0:
+ self.offset = offset
+ elif whence == 1:
+ self.offset += offset
+ elif whence == 2:
+ self.offset = self.end() + offset
+
if self.offset < self.fpsize:
self.realfp.seek(self.offset)
else:
@@ -103,8 +113,16 @@
self.fp = fp
self.offset = 0
- def seek(self, offset):
- self.offset = offset
+ def tell(self):
+ return self.offset
+
+ def seek(self, offset, whence=0):
+ if whence == 0:
+ self.offset = offset
+ elif whence == 1:
+ self.offset += offset
+ elif whence == 2:
+ self.offset = self.fp.end() + offset
def read(self, count=-1):
try:
@@ -143,7 +161,7 @@
'''open file. return same cached appendfile object for every
later call.'''
- assert mode in 'ra'
+ assert mode in 'ra+'
fp = self.fps.get(name)
if fp is None:
fp = appendfile(self.realopener(name, 'a+'))
@@ -165,8 +183,12 @@
def __init__(self, opener):
appendopener.__init__(self, opener)
changelog.changelog.__init__(self, self)
+ def checkinlinesize(self, fp, tr):
+ return
class appendmanifest(manifest.manifest, appendopener):
def __init__(self, opener):
appendopener.__init__(self, opener)
manifest.manifest.__init__(self, self)
+ def checkinlinesize(self, fp, tr):
+ return
--- a/mercurial/localrepo.py Tue Apr 04 16:38:43 2006 -0400
+++ b/mercurial/localrepo.py Tue Apr 04 16:38:43 2006 -0400
@@ -168,6 +168,7 @@
try:
return self.changelog.lookup(key)
except:
+ raise
raise repo.RepoError(_("unknown revision '%s'") % key)
def dev(self):
@@ -1456,6 +1457,8 @@
# make changelog and manifest see real files again
self.changelog = changelog.changelog(self.opener)
self.manifest = manifest.manifest(self.opener)
+ self.changelog.checkinlinesize(tr)
+ self.changelog.checkinlinesize(tr)
newheads = len(self.changelog.heads())
heads = ""
--- a/mercurial/revlog.py Tue Apr 04 16:38:43 2006 -0400
+++ b/mercurial/revlog.py Tue Apr 04 16:38:43 2006 -0400
@@ -675,9 +675,11 @@
self.cache = (node, rev, text)
return text
- def checkinlinesize(self, fp, tr):
+ def checkinlinesize(self, tr, fp=None):
if not self.inlinedata():
return
+ if not fp:
+ fp = self.opener(self.indexfile, 'r')
size = fp.tell()
if size < 131072:
return
@@ -786,7 +788,7 @@
if self.inlinedata():
f.write(data[0])
f.write(data[1])
- self.checkinlinesize(f, transaction)
+ self.checkinlinesize(transaction, f)
self.cache = (node, n, text)
return node
@@ -966,7 +968,7 @@
if self.inlinedata():
ifh.write(struct.pack(self.indexformat, *e))
ifh.write(cdelta)
- self.checkinlinesize(ifh, transaction)
+ self.checkinlinesize(transaction, ifh)
if not self.inlinedata():
dfh = self.opener(self.datafile, "a")
ifh = self.opener(self.indexfile, "a")