Show More
@@ -11,6 +11,7 b' from revlog import *' | |||
|
11 | 11 | from demandload import * |
|
12 | 12 | demandload(globals(), "re lock urllib urllib2 transaction time socket") |
|
13 | 13 | demandload(globals(), "tempfile httprangereader bdiff") |
|
14 | demandload(globals(), "bisect") | |
|
14 | 15 | |
|
15 | 16 | class filelog(revlog): |
|
16 | 17 | def __init__(self, opener, path): |
@@ -124,16 +125,115 b' class manifest(revlog):' | |||
|
124 | 125 | else: |
|
125 | 126 | return mdiff.textdiff(a, b) |
|
126 | 127 | |
|
127 | def add(self, map, flags, transaction, link, p1=None, p2=None): | |
|
128 | files = map.keys() | |
|
129 | files.sort() | |
|
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 | |
|
130 | 177 | |
|
131 | self.addlist = ["%s\000%s%s\n" % | |
|
132 | (f, hex(map[f]), flags[f] and "x" or '') | |
|
133 | for f in files] | |
|
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: | |
|
181 | files = map.keys() | |
|
182 | files.sort() | |
|
183 | ||
|
184 | self.addlist = ["%s\000%s%s\n" % | |
|
185 | (f, hex(map[f]), flags[f] and "x" or '') | |
|
186 | for f in files] | |
|
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 | |
|
201 | ||
|
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 | ||
|
134 | 232 | text = "".join(self.addlist) |
|
135 | ||
|
136 | n = self.addrevision(text, transaction, link, p1, p2) | |
|
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 | 237 | self.mapcache = (n, map, flags) |
|
138 | 238 | self.listcache = (text, self.addlist) |
|
139 | 239 | self.addlist = None |
@@ -669,7 +769,7 b' class localrepository:' | |||
|
669 | 769 | for f in remove: |
|
670 | 770 | if f in m1: |
|
671 | 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 | 774 | # add changeset |
|
675 | 775 | new = new.keys() |
@@ -267,7 +267,7 b' class revlog:' | |||
|
267 | 267 | self.cache = (node, rev, text) |
|
268 | 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 | 271 | if text is None: text = "" |
|
272 | 272 | if p1 is None: p1 = self.tip() |
|
273 | 273 | if p2 is None: p2 = nullid |
@@ -284,8 +284,9 b' class revlog:' | |||
|
284 | 284 | base = self.base(t) |
|
285 | 285 | start = self.start(base) |
|
286 | 286 | end = self.end(t) |
|
287 | prev = self.revision(self.tip()) | |
|
288 | d = self.diff(prev, text) | |
|
287 | if not d: | |
|
288 | prev = self.revision(self.tip()) | |
|
289 | d = self.diff(prev, text) | |
|
289 | 290 | data = compress(d) |
|
290 | 291 | dist = end - start + len(data) |
|
291 | 292 |
General Comments 0
You need to be logged in to leave comments.
Login now