changeset 18643:cc28a84db8c9

bundlerepo: replace basemap with the base field in the index Bundle revisions had some info in their fake revlog intries and some info in a dict with all the bundle revisions. This dict was used to get the stored data and to distinguish repo revisions from bundle revisions. Real repo revisions and bundle revisions will now be distinguished by comparing with the tip revision of the original repo. This reintroduces something similar to disktiprev which was unused and removed in a928865b4a4f and let that replace the O(reposize) dict.
author Mads Kiilerich <mads@kiilerich.com>
date Fri, 08 Feb 2013 23:26:00 +0100
parents a40d608e2a7b
children 3e92772d5383
files mercurial/bundlerepo.py
diffstat 1 files changed, 12 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/bundlerepo.py	Fri Feb 08 22:54:48 2013 +0100
+++ b/mercurial/bundlerepo.py	Fri Feb 08 23:26:00 2013 +0100
@@ -22,18 +22,15 @@
         # How it works:
         # To retrieve a revision, we need to know the offset of the revision in
         # the bundle (an unbundle object). We store this offset in the index
-        # (start).
-        #
-        # basemap is indexed with revisions coming from the bundle, and it
-        # maps to the revision that is the base of the corresponding delta.
+        # (start). The base of the delta is stored in the base field.
         #
         # To differentiate a rev in the bundle from a rev in the revlog, we
-        # check revision against basemap.
+        # check revision against repotiprev.
         opener = scmutil.readonlyvfs(opener)
         revlog.revlog.__init__(self, opener, indexfile)
         self.bundle = bundle
-        self.basemap = {} # mapping rev to delta base rev
         n = len(self)
+        self.repotiprev = n - 1
         chain = None
         self.bundlerevs = set() # used by 'bundle()' revset expression
         while True:
@@ -68,9 +65,8 @@
 
             baserev = self.rev(deltabase)
             # start, size, full unc. size, base (unused), link, p1, p2, node
-            e = (revlog.offset_type(start, 0), size, -1, -1, link,
+            e = (revlog.offset_type(start, 0), size, -1, baserev, link,
                  self.rev(p1), self.rev(p2), node)
-            self.basemap[n] = baserev
             self.index.insert(-1, e)
             self.nodemap[node] = n
             self.bundlerevs.add(n)
@@ -78,22 +74,22 @@
             n += 1
 
     def _chunk(self, rev):
-        # Warning: in case of bundle, the diff is against self.basemap,
-        # not against rev - 1
+        # Warning: in case of bundle, the diff is against what we stored as
+        # delta base, not against rev - 1
         # XXX: could use some caching
-        if rev not in self.basemap:
+        if rev <= self.repotiprev:
             return revlog.revlog._chunk(self, rev)
         self.bundle.seek(self.start(rev))
         return self.bundle.read(self.length(rev))
 
     def revdiff(self, rev1, rev2):
         """return or calculate a delta between two revisions"""
-        if rev1 in self.basemap and rev2 in self.basemap:
+        if rev1 > self.repotiprev and rev2 > self.repotiprev:
             # hot path for bundle
-            revb = self.basemap[rev2]
+            revb = self.index[rev2][3]
             if revb == rev1:
                 return self._chunk(rev2)
-        elif rev1 not in self.basemap and rev2 not in self.basemap:
+        elif rev1 <= self.repotiprev and rev2 <= self.repotiprev:
             return revlog.revlog.revdiff(self, rev1, rev2)
 
         return mdiff.textdiff(self.revision(self.node(rev1)),
@@ -117,12 +113,12 @@
         chain = []
         iterrev = rev
         # reconstruct the revision if it is from a changegroup
-        while iterrev in self.basemap:
+        while iterrev > self.repotiprev:
             if self._cache and self._cache[1] == iterrev:
                 text = self._cache[2]
                 break
             chain.append(iterrev)
-            iterrev = self.basemap[iterrev]
+            iterrev = self.index[iterrev][3]
         if text is None:
             text = revlog.revlog.revision(self, iterrev)