comparison mercurial/bundlerepo.py @ 18416:87f370c5fef5

bundlerepo: store validated deltabase rev in basemap instead of node This avoids some lookups and aligns bundlerepo more with what revlog do.
author Mads Kiilerich <madski@unity3d.com>
date Wed, 16 Jan 2013 20:41:41 +0100
parents 95b8629fd2de
children 610706715778
comparison
equal deleted inserted replaced
18415:95b8629fd2de 18416:87f370c5fef5
23 # To retrieve a revision, we need to know the offset of the revision in 23 # To retrieve a revision, we need to know the offset of the revision in
24 # the bundle (an unbundle object). We store this offset in the index 24 # the bundle (an unbundle object). We store this offset in the index
25 # (start). 25 # (start).
26 # 26 #
27 # basemap is indexed with revisions coming from the bundle, and it 27 # basemap is indexed with revisions coming from the bundle, and it
28 # maps to the node that is the base of the corresponding delta. 28 # maps to the revision that is the base of the corresponding delta.
29 # 29 #
30 # To differentiate a rev in the bundle from a rev in the revlog, we 30 # To differentiate a rev in the bundle from a rev in the revlog, we
31 # check revision against basemap. 31 # check revision against basemap.
32 opener = scmutil.readonlyvfs(opener) 32 opener = scmutil.readonlyvfs(opener)
33 revlog.revlog.__init__(self, opener, indexfile) 33 revlog.revlog.__init__(self, opener, indexfile)
34 self.bundle = bundle 34 self.bundle = bundle
35 self.basemap = {} 35 self.basemap = {} # mapping rev to delta base rev
36 n = len(self) 36 n = len(self)
37 chain = None 37 chain = None
38 self.bundlerevs = set() # used by 'bundle()' revset expression 38 self.bundlerevs = set() # used by 'bundle()' revset expression
39 while True: 39 while True:
40 chunkdata = bundle.deltachunk(chain) 40 chunkdata = bundle.deltachunk(chain)
59 59
60 for p in (p1, p2): 60 for p in (p1, p2):
61 if p not in self.nodemap: 61 if p not in self.nodemap:
62 raise error.LookupError(p, self.indexfile, 62 raise error.LookupError(p, self.indexfile,
63 _("unknown parent")) 63 _("unknown parent"))
64
65 if deltabase not in self.nodemap:
66 raise LookupError(deltabase, self.indexfile,
67 _('unknown delta base'))
68
69 baserev = self.rev(deltabase)
64 # start, size, full unc. size, base (unused), link, p1, p2, node 70 # start, size, full unc. size, base (unused), link, p1, p2, node
65 e = (revlog.offset_type(start, 0), size, -1, -1, link, 71 e = (revlog.offset_type(start, 0), size, -1, -1, link,
66 self.rev(p1), self.rev(p2), node) 72 self.rev(p1), self.rev(p2), node)
67 self.basemap[n] = deltabase 73 self.basemap[n] = baserev
68 self.index.insert(-1, e) 74 self.index.insert(-1, e)
69 self.nodemap[node] = n 75 self.nodemap[node] = n
70 self.bundlerevs.add(n) 76 self.bundlerevs.add(n)
71 chain = node 77 chain = node
72 n += 1 78 n += 1
82 88
83 def revdiff(self, rev1, rev2): 89 def revdiff(self, rev1, rev2):
84 """return or calculate a delta between two revisions""" 90 """return or calculate a delta between two revisions"""
85 if rev1 in self.basemap and rev2 in self.basemap: 91 if rev1 in self.basemap and rev2 in self.basemap:
86 # hot path for bundle 92 # hot path for bundle
87 revb = self.rev(self.basemap[rev2]) 93 revb = self.basemap[rev2]
88 if revb == rev1: 94 if revb == rev1:
89 return self._chunk(rev2) 95 return self._chunk(rev2)
90 elif rev1 not in self.basemap and rev2 not in self.basemap: 96 elif rev1 not in self.basemap and rev2 not in self.basemap:
91 return revlog.revlog.revdiff(self, rev1, rev2) 97 return revlog.revlog.revdiff(self, rev1, rev2)
92 98
114 while iterrev in self.basemap: 120 while iterrev in self.basemap:
115 if self._cache and self._cache[1] == iterrev: 121 if self._cache and self._cache[1] == iterrev:
116 text = self._cache[2] 122 text = self._cache[2]
117 break 123 break
118 chain.append(iterrev) 124 chain.append(iterrev)
119 iterrev = self.rev(self.basemap[iterrev]) 125 iterrev = self.basemap[iterrev]
120 if text is None: 126 if text is None:
121 text = revlog.revlog.revision(self, iterrev) 127 text = revlog.revlog.revision(self, iterrev)
122 128
123 while chain: 129 while chain:
124 delta = self._chunk(chain.pop()) 130 delta = self._chunk(chain.pop())