# HG changeset patch # User mason@suse.com # Date 1144183123 14400 # Node ID 343aeefb553bfa811e13f03c23e4751ac87a3da1 # Parent 01ee43dda68136e527d23ce9e88655961a4ed3ae 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 diff --git a/mercurial/appendfile.py b/mercurial/appendfile.py --- a/mercurial/appendfile.py +++ b/mercurial/appendfile.py @@ -42,9 +42,19 @@ class appendfile(object): # 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 @@ class sharedfile(object): 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 @@ class appendopener(object): '''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 @@ class appendchangelog(changelog.changelo 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 diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -168,6 +168,7 @@ class localrepository(object): try: return self.changelog.lookup(key) except: + raise raise repo.RepoError(_("unknown revision '%s'") % key) def dev(self): @@ -1456,6 +1457,8 @@ class localrepository(object): # 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 = "" diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -675,9 +675,11 @@ class revlog(object): 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 @@ class revlog(object): 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 @@ class revlog(object): 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")