Mercurial > public > mercurial-scm > hg
comparison mercurial/bundlerepo.py @ 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 | cd403d6d96ef |
children | f0564402d059 |
comparison
equal
deleted
inserted
replaced
18642:a40d608e2a7b | 18643:cc28a84db8c9 |
---|---|
20 class bundlerevlog(revlog.revlog): | 20 class bundlerevlog(revlog.revlog): |
21 def __init__(self, opener, indexfile, bundle, linkmapper): | 21 def __init__(self, opener, indexfile, bundle, linkmapper): |
22 # How it works: | 22 # How it works: |
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). The base of the delta is stored in the base field. |
26 # | |
27 # basemap is indexed with revisions coming from the bundle, and it | |
28 # maps to the revision that is the base of the corresponding delta. | |
29 # | 26 # |
30 # To differentiate a rev in the bundle from a rev in the revlog, we | 27 # To differentiate a rev in the bundle from a rev in the revlog, we |
31 # check revision against basemap. | 28 # check revision against repotiprev. |
32 opener = scmutil.readonlyvfs(opener) | 29 opener = scmutil.readonlyvfs(opener) |
33 revlog.revlog.__init__(self, opener, indexfile) | 30 revlog.revlog.__init__(self, opener, indexfile) |
34 self.bundle = bundle | 31 self.bundle = bundle |
35 self.basemap = {} # mapping rev to delta base rev | |
36 n = len(self) | 32 n = len(self) |
33 self.repotiprev = n - 1 | |
37 chain = None | 34 chain = None |
38 self.bundlerevs = set() # used by 'bundle()' revset expression | 35 self.bundlerevs = set() # used by 'bundle()' revset expression |
39 while True: | 36 while True: |
40 chunkdata = bundle.deltachunk(chain) | 37 chunkdata = bundle.deltachunk(chain) |
41 if not chunkdata: | 38 if not chunkdata: |
66 raise LookupError(deltabase, self.indexfile, | 63 raise LookupError(deltabase, self.indexfile, |
67 _('unknown delta base')) | 64 _('unknown delta base')) |
68 | 65 |
69 baserev = self.rev(deltabase) | 66 baserev = self.rev(deltabase) |
70 # start, size, full unc. size, base (unused), link, p1, p2, node | 67 # start, size, full unc. size, base (unused), link, p1, p2, node |
71 e = (revlog.offset_type(start, 0), size, -1, -1, link, | 68 e = (revlog.offset_type(start, 0), size, -1, baserev, link, |
72 self.rev(p1), self.rev(p2), node) | 69 self.rev(p1), self.rev(p2), node) |
73 self.basemap[n] = baserev | |
74 self.index.insert(-1, e) | 70 self.index.insert(-1, e) |
75 self.nodemap[node] = n | 71 self.nodemap[node] = n |
76 self.bundlerevs.add(n) | 72 self.bundlerevs.add(n) |
77 chain = node | 73 chain = node |
78 n += 1 | 74 n += 1 |
79 | 75 |
80 def _chunk(self, rev): | 76 def _chunk(self, rev): |
81 # Warning: in case of bundle, the diff is against self.basemap, | 77 # Warning: in case of bundle, the diff is against what we stored as |
82 # not against rev - 1 | 78 # delta base, not against rev - 1 |
83 # XXX: could use some caching | 79 # XXX: could use some caching |
84 if rev not in self.basemap: | 80 if rev <= self.repotiprev: |
85 return revlog.revlog._chunk(self, rev) | 81 return revlog.revlog._chunk(self, rev) |
86 self.bundle.seek(self.start(rev)) | 82 self.bundle.seek(self.start(rev)) |
87 return self.bundle.read(self.length(rev)) | 83 return self.bundle.read(self.length(rev)) |
88 | 84 |
89 def revdiff(self, rev1, rev2): | 85 def revdiff(self, rev1, rev2): |
90 """return or calculate a delta between two revisions""" | 86 """return or calculate a delta between two revisions""" |
91 if rev1 in self.basemap and rev2 in self.basemap: | 87 if rev1 > self.repotiprev and rev2 > self.repotiprev: |
92 # hot path for bundle | 88 # hot path for bundle |
93 revb = self.basemap[rev2] | 89 revb = self.index[rev2][3] |
94 if revb == rev1: | 90 if revb == rev1: |
95 return self._chunk(rev2) | 91 return self._chunk(rev2) |
96 elif rev1 not in self.basemap and rev2 not in self.basemap: | 92 elif rev1 <= self.repotiprev and rev2 <= self.repotiprev: |
97 return revlog.revlog.revdiff(self, rev1, rev2) | 93 return revlog.revlog.revdiff(self, rev1, rev2) |
98 | 94 |
99 return mdiff.textdiff(self.revision(self.node(rev1)), | 95 return mdiff.textdiff(self.revision(self.node(rev1)), |
100 self.revision(self.node(rev2))) | 96 self.revision(self.node(rev2))) |
101 | 97 |
115 | 111 |
116 text = None | 112 text = None |
117 chain = [] | 113 chain = [] |
118 iterrev = rev | 114 iterrev = rev |
119 # reconstruct the revision if it is from a changegroup | 115 # reconstruct the revision if it is from a changegroup |
120 while iterrev in self.basemap: | 116 while iterrev > self.repotiprev: |
121 if self._cache and self._cache[1] == iterrev: | 117 if self._cache and self._cache[1] == iterrev: |
122 text = self._cache[2] | 118 text = self._cache[2] |
123 break | 119 break |
124 chain.append(iterrev) | 120 chain.append(iterrev) |
125 iterrev = self.basemap[iterrev] | 121 iterrev = self.index[iterrev][3] |
126 if text is None: | 122 if text is None: |
127 text = revlog.revlog.revision(self, iterrev) | 123 text = revlog.revlog.revision(self, iterrev) |
128 | 124 |
129 while chain: | 125 while chain: |
130 delta = self._chunk(chain.pop()) | 126 delta = self._chunk(chain.pop()) |