Show More
@@ -11,6 +11,7 b' from revlog import *' | |||||
11 | from demandload import * |
|
11 | from demandload import * | |
12 | demandload(globals(), "re lock urllib urllib2 transaction time socket") |
|
12 | demandload(globals(), "re lock urllib urllib2 transaction time socket") | |
13 | demandload(globals(), "tempfile httprangereader bdiff") |
|
13 | demandload(globals(), "tempfile httprangereader bdiff") | |
|
14 | demandload(globals(), "bisect") | |||
14 |
|
15 | |||
15 | class filelog(revlog): |
|
16 | class filelog(revlog): | |
16 | def __init__(self, opener, path): |
|
17 | def __init__(self, opener, path): | |
@@ -124,16 +125,115 b' class manifest(revlog):' | |||||
124 | else: |
|
125 | else: | |
125 | return mdiff.textdiff(a, b) |
|
126 | return mdiff.textdiff(a, b) | |
126 |
|
127 | |||
127 | def add(self, map, flags, transaction, link, p1=None, p2=None): |
|
128 | def add(self, map, flags, transaction, link, p1=None, p2=None,changed=None): | |
|
129 | # directly generate the mdiff delta from the data collected during | |||
|
130 | # the bisect loop below | |||
|
131 | def gendelta(delta): | |||
|
132 | i = 0 | |||
|
133 | result = [] | |||
|
134 | while i < len(delta): | |||
|
135 | start = delta[i][2] | |||
|
136 | end = delta[i][3] | |||
|
137 | l = delta[i][4] | |||
|
138 | if l == None: | |||
|
139 | l = "" | |||
|
140 | while i < len(delta) - 1 and start <= delta[i+1][2] and end >= delta[i+1][2]: | |||
|
141 | if delta[i+1][3] > end: | |||
|
142 | end = delta[i+1][3] | |||
|
143 | if delta[i+1][4]: | |||
|
144 | l += delta[i+1][4] | |||
|
145 | i += 1 | |||
|
146 | result.append(struct.pack(">lll", start, end, len(l)) + l) | |||
|
147 | i += 1 | |||
|
148 | return result | |||
|
149 | ||||
|
150 | # apply the changes collected during the bisect loop to our addlist | |||
|
151 | def addlistdelta(addlist, delta): | |||
|
152 | # apply the deltas to the addlist. start from the bottom up | |||
|
153 | # so changes to the offsets don't mess things up. | |||
|
154 | i = len(delta) | |||
|
155 | while i > 0: | |||
|
156 | i -= 1 | |||
|
157 | start = delta[i][0] | |||
|
158 | end = delta[i][1] | |||
|
159 | if delta[i][4]: | |||
|
160 | addlist[start:end] = [delta[i][4]] | |||
|
161 | else: | |||
|
162 | del addlist[start:end] | |||
|
163 | return addlist | |||
|
164 | ||||
|
165 | # calculate the byte offset of the start of each line in the | |||
|
166 | # manifest | |||
|
167 | def calcoffsets(addlist): | |||
|
168 | offsets = [0] * (len(addlist) + 1) | |||
|
169 | offset = 0 | |||
|
170 | i = 0 | |||
|
171 | while i < len(addlist): | |||
|
172 | offsets[i] = offset | |||
|
173 | offset += len(addlist[i]) | |||
|
174 | i += 1 | |||
|
175 | offsets[i] = offset | |||
|
176 | return offsets | |||
|
177 | ||||
|
178 | # if we're using the listcache, make sure it is valid and | |||
|
179 | # parented by the same node we're diffing against | |||
|
180 | if not changed or not self.listcache or not p1 or self.mapcache[0] != p1: | |||
128 | files = map.keys() |
|
181 | files = map.keys() | |
129 | files.sort() |
|
182 | files.sort() | |
130 |
|
183 | |||
131 | self.addlist = ["%s\000%s%s\n" % |
|
184 | self.addlist = ["%s\000%s%s\n" % | |
132 | (f, hex(map[f]), flags[f] and "x" or '') |
|
185 | (f, hex(map[f]), flags[f] and "x" or '') | |
133 | for f in files] |
|
186 | for f in files] | |
134 | text = "".join(self.addlist) |
|
187 | cachedelta = None | |
|
188 | else: | |||
|
189 | addlist = self.listcache[1] | |||
|
190 | ||||
|
191 | # find the starting offset for each line in the add list | |||
|
192 | offsets = calcoffsets(addlist) | |||
|
193 | ||||
|
194 | # combine the changed lists into one list for sorting | |||
|
195 | work = [[x, 0] for x in changed[0]] | |||
|
196 | work[len(work):] = [[x, 1] for x in changed[1]] | |||
|
197 | work.sort() | |||
|
198 | ||||
|
199 | delta = [] | |||
|
200 | bs = 0 | |||
135 |
|
201 | |||
136 | n = self.addrevision(text, transaction, link, p1, p2) |
|
202 | for w in work: | |
|
203 | f = w[0] | |||
|
204 | # bs will either be the index of the item or the insertion point | |||
|
205 | bs = bisect.bisect(addlist, f, bs) | |||
|
206 | if bs < len(addlist): | |||
|
207 | fn = addlist[bs][:addlist[bs].index('\0')] | |||
|
208 | else: | |||
|
209 | fn = None | |||
|
210 | if w[1] == 0: | |||
|
211 | l = "%s\000%s%s\n" % (f, hex(map[f]), flags[f] and "x" or '') | |||
|
212 | else: | |||
|
213 | l = None | |||
|
214 | start = bs | |||
|
215 | if fn != f: | |||
|
216 | # item not found, insert a new one | |||
|
217 | end = bs | |||
|
218 | if w[1] == 1: | |||
|
219 | sys.stderr.write("failed to remove %s from manifest" % f) | |||
|
220 | sys.exit(1) | |||
|
221 | else: | |||
|
222 | # item is found, replace/delete the existing line | |||
|
223 | end = bs + 1 | |||
|
224 | delta.append([start, end, offsets[start], offsets[end], l]) | |||
|
225 | ||||
|
226 | self.addlist = addlistdelta(addlist, delta) | |||
|
227 | if self.mapcache[0] == self.tip(): | |||
|
228 | cachedelta = "".join(gendelta(delta)) | |||
|
229 | else: | |||
|
230 | cachedelta = None | |||
|
231 | ||||
|
232 | text = "".join(self.addlist) | |||
|
233 | if cachedelta and mdiff.patch(self.listcache[0], cachedelta) != text: | |||
|
234 | sys.stderr.write("manifest delta failure") | |||
|
235 | sys.exit(1) | |||
|
236 | n = self.addrevision(text, transaction, link, p1, p2, cachedelta) | |||
137 | self.mapcache = (n, map, flags) |
|
237 | self.mapcache = (n, map, flags) | |
138 | self.listcache = (text, self.addlist) |
|
238 | self.listcache = (text, self.addlist) | |
139 | self.addlist = None |
|
239 | self.addlist = None | |
@@ -669,7 +769,7 b' class localrepository:' | |||||
669 | for f in remove: |
|
769 | for f in remove: | |
670 | if f in m1: |
|
770 | if f in m1: | |
671 | del m1[f] |
|
771 | del m1[f] | |
672 | mn = self.manifest.add(m1, mf1, tr, linkrev, c1[0], c2[0]) |
|
772 | mn = self.manifest.add(m1, mf1, tr, linkrev, c1[0], c2[0], (new,remove)) | |
673 |
|
773 | |||
674 | # add changeset |
|
774 | # add changeset | |
675 | new = new.keys() |
|
775 | new = new.keys() |
@@ -267,7 +267,7 b' class revlog:' | |||||
267 | self.cache = (node, rev, text) |
|
267 | self.cache = (node, rev, text) | |
268 | return text |
|
268 | return text | |
269 |
|
269 | |||
270 | def addrevision(self, text, transaction, link, p1=None, p2=None): |
|
270 | def addrevision(self, text, transaction, link, p1=None, p2=None, d=None): | |
271 | if text is None: text = "" |
|
271 | if text is None: text = "" | |
272 | if p1 is None: p1 = self.tip() |
|
272 | if p1 is None: p1 = self.tip() | |
273 | if p2 is None: p2 = nullid |
|
273 | if p2 is None: p2 = nullid | |
@@ -284,6 +284,7 b' class revlog:' | |||||
284 | base = self.base(t) |
|
284 | base = self.base(t) | |
285 | start = self.start(base) |
|
285 | start = self.start(base) | |
286 | end = self.end(t) |
|
286 | end = self.end(t) | |
|
287 | if not d: | |||
287 | prev = self.revision(self.tip()) |
|
288 | prev = self.revision(self.tip()) | |
288 | d = self.diff(prev, text) |
|
289 | d = self.diff(prev, text) | |
289 | data = compress(d) |
|
290 | data = compress(d) |
General Comments 0
You need to be logged in to leave comments.
Login now