Show More
@@ -6,6 +6,7 b'' | |||||
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | import collections |
|
8 | import collections | |
|
9 | import heapq | |||
9 | import os |
|
10 | import os | |
10 | import shutil |
|
11 | import shutil | |
11 |
|
12 | |||
@@ -198,6 +199,59 b' class progresssource:' | |||||
198 | self.progress.complete() |
|
199 | self.progress.complete() | |
199 |
|
200 | |||
200 |
|
201 | |||
|
202 | # Sorters are used by the `toposort` function to maintain a set of revisions | |||
|
203 | # which can be converted immediately and pick one | |||
|
204 | class branchsorter: | |||
|
205 | """If the previously converted revision has a child in the | |||
|
206 | eligible revisions list, pick it. Return the list head | |||
|
207 | otherwise. Branch sort attempts to minimize branch | |||
|
208 | switching, which is harmful for Mercurial backend | |||
|
209 | compression. | |||
|
210 | """ | |||
|
211 | ||||
|
212 | def __init__(self, parents): | |||
|
213 | self.nodes = [] | |||
|
214 | self.parents = parents | |||
|
215 | self.prev = None | |||
|
216 | ||||
|
217 | def picknext(self): | |||
|
218 | next = self.nodes[0] | |||
|
219 | for n in self.nodes: | |||
|
220 | if self.prev in self.parents[n]: | |||
|
221 | next = n | |||
|
222 | break | |||
|
223 | self.prev = next | |||
|
224 | self.nodes.remove(next) | |||
|
225 | return next | |||
|
226 | ||||
|
227 | def insert(self, node): | |||
|
228 | self.nodes.insert(0, node) | |||
|
229 | ||||
|
230 | def __len__(self): | |||
|
231 | return self.nodes.__len__() | |||
|
232 | ||||
|
233 | ||||
|
234 | class keysorter: | |||
|
235 | """Key-based sort, ties broken by insertion order""" | |||
|
236 | ||||
|
237 | def __init__(self, keyfn): | |||
|
238 | self.heap = [] | |||
|
239 | self.keyfn = keyfn | |||
|
240 | self.counter = 0 | |||
|
241 | ||||
|
242 | def picknext(self): | |||
|
243 | return heapq.heappop(self.heap)[2] | |||
|
244 | ||||
|
245 | def insert(self, node): | |||
|
246 | counter = self.counter | |||
|
247 | self.counter = counter + 1 | |||
|
248 | key = self.keyfn(node) | |||
|
249 | heapq.heappush(self.heap, (key, counter, node)) | |||
|
250 | ||||
|
251 | def __len__(self): | |||
|
252 | return self.heap.__len__() | |||
|
253 | ||||
|
254 | ||||
201 | class converter: |
|
255 | class converter: | |
202 | def __init__(self, ui, source, dest, revmapfile, opts): |
|
256 | def __init__(self, ui, source, dest, revmapfile, opts): | |
203 |
|
257 | |||
@@ -364,37 +418,10 b' class converter:' | |||||
364 |
|
418 | |||
365 | return children, roots |
|
419 | return children, roots | |
366 |
|
420 | |||
367 | # Sort functions are supposed to take a list of revisions which |
|
|||
368 | # can be converted immediately and pick one |
|
|||
369 |
|
||||
370 | def makebranchsorter(): |
|
|||
371 | """If the previously converted revision has a child in the |
|
|||
372 | eligible revisions list, pick it. Return the list head |
|
|||
373 | otherwise. Branch sort attempts to minimize branch |
|
|||
374 | switching, which is harmful for Mercurial backend |
|
|||
375 | compression. |
|
|||
376 | """ |
|
|||
377 | prev = [None] |
|
|||
378 |
|
||||
379 | def picknext(nodes): |
|
|||
380 | next = nodes[0] |
|
|||
381 | for n in nodes: |
|
|||
382 | if prev[0] in parents[n]: |
|
|||
383 | next = n |
|
|||
384 | break |
|
|||
385 | prev[0] = next |
|
|||
386 | return next |
|
|||
387 |
|
||||
388 | return picknext |
|
|||
389 |
|
||||
390 | def makesourcesorter(): |
|
421 | def makesourcesorter(): | |
391 | """Source specific sort.""" |
|
422 | """Source specific sort.""" | |
392 | keyfn = lambda n: self.commitcache[n].sortkey |
|
423 | keyfn = lambda n: self.commitcache[n].sortkey | |
393 |
|
424 | return keysorter(keyfn) | ||
394 | def picknext(nodes): |
|
|||
395 | return sorted(nodes, key=keyfn)[0] |
|
|||
396 |
|
||||
397 | return picknext |
|
|||
398 |
|
425 | |||
399 | def makeclosesorter(): |
|
426 | def makeclosesorter(): | |
400 | """Close order sort.""" |
|
427 | """Close order sort.""" | |
@@ -402,44 +429,36 b' class converter:' | |||||
402 | b'close' not in self.commitcache[n].extra, |
|
429 | b'close' not in self.commitcache[n].extra, | |
403 | self.commitcache[n].sortkey, |
|
430 | self.commitcache[n].sortkey, | |
404 | ) |
|
431 | ) | |
405 |
|
432 | return keysorter(keyfn) | ||
406 | def picknext(nodes): |
|
|||
407 | return sorted(nodes, key=keyfn)[0] |
|
|||
408 |
|
||||
409 | return picknext |
|
|||
410 |
|
433 | |||
411 | def makedatesorter(): |
|
434 | def makedatesorter(): | |
412 | """Sort revisions by date.""" |
|
435 | """Sort revisions by date.""" | |
413 | dates = {} |
|
|||
414 |
|
436 | |||
415 | def getdate(n): |
|
437 | def getdate(n): | |
416 | if n not in dates: |
|
438 | return dateutil.parsedate(self.commitcache[n].date) | |
417 | dates[n] = dateutil.parsedate(self.commitcache[n].date) |
|
|||
418 | return dates[n] |
|
|||
419 |
|
439 | |||
420 | def picknext(nodes): |
|
440 | return keysorter(getdate) | |
421 | return min([(getdate(n), n) for n in nodes])[1] |
|
|||
422 |
|
||||
423 | return picknext |
|
|||
424 |
|
441 | |||
425 | if sortmode == b'branchsort': |
|
442 | if sortmode == b'branchsort': | |
426 |
|
|
443 | sorter = branchsorter(parents) | |
427 | elif sortmode == b'datesort': |
|
444 | elif sortmode == b'datesort': | |
428 |
|
|
445 | sorter = makedatesorter() | |
429 | elif sortmode == b'sourcesort': |
|
446 | elif sortmode == b'sourcesort': | |
430 |
|
|
447 | sorter = makesourcesorter() | |
431 | elif sortmode == b'closesort': |
|
448 | elif sortmode == b'closesort': | |
432 |
|
|
449 | sorter = makeclosesorter() | |
433 | else: |
|
450 | else: | |
434 | raise error.Abort(_(b'unknown sort mode: %s') % sortmode) |
|
451 | raise error.Abort(_(b'unknown sort mode: %s') % sortmode) | |
435 |
|
452 | |||
436 |
children, |
|
453 | children, roots = mapchildren(parents) | |
|
454 | ||||
|
455 | for node in roots: | |||
|
456 | sorter.insert(node) | |||
437 |
|
457 | |||
438 | s = [] |
|
458 | s = [] | |
439 | pendings = {} |
|
459 | pendings = {} | |
440 |
while |
|
460 | while sorter: | |
441 |
n = picknext( |
|
461 | n = sorter.picknext() | |
442 | actives.remove(n) |
|
|||
443 | s.append(n) |
|
462 | s.append(n) | |
444 |
|
463 | |||
445 | # Update dependents list |
|
464 | # Update dependents list | |
@@ -455,7 +474,7 b' class converter:' | |||||
455 | ) |
|
474 | ) | |
456 | if not pendings[c]: |
|
475 | if not pendings[c]: | |
457 | # Parents are converted, node is eligible |
|
476 | # Parents are converted, node is eligible | |
458 |
|
|
477 | sorter.insert(c) | |
459 | pendings[c] = None |
|
478 | pendings[c] = None | |
460 |
|
479 | |||
461 | if len(s) != len(parents): |
|
480 | if len(s) != len(parents): |
General Comments 0
You need to be logged in to leave comments.
Login now