Mercurial > public > mercurial-scm > hg
comparison mercurial/hg.py @ 56:ad2ea1185f04
Add getchangegroup code to efficiently calculate and request a changegroup
author | mpm@selenic.com |
---|---|
date | Wed, 11 May 2005 15:06:41 -0800 |
parents | 2add70d51441 |
children | e32fdbd97839 |
comparison
equal
deleted
inserted
replaced
55:2add70d51441 | 56:ad2ea1185f04 |
---|---|
558 def remove(self, list): | 558 def remove(self, list): |
559 dl = self.opener("to-remove", "a") | 559 dl = self.opener("to-remove", "a") |
560 for f in list: | 560 for f in list: |
561 dl.write(f + "\n") | 561 dl.write(f + "\n") |
562 | 562 |
563 def newer(self, node): | 563 def branches(self, nodes): |
564 nodes = [] | 564 if not nodes: nodes = [self.changelog.tip()] |
565 for i in xrange(self.changelog.rev(node) + 1, self.changelog.count()): | 565 b = [] |
566 nodes.append(self.changelog.node(i)) | 566 for n in nodes: |
567 | 567 t = n |
568 return nodes | 568 while n: |
569 | 569 p = self.changelog.parents(n) |
570 def changegroup(self, nodes): | 570 if p[1] != nullid or p[0] == nullid: |
571 b.append((t, n, p[0], p[1])) | |
572 break | |
573 n = p[0] | |
574 return b | |
575 | |
576 def between(self, pairs): | |
577 r = [] | |
578 | |
579 for top, bottom in pairs: | |
580 n, l, i = top, [], 0 | |
581 f = 1 | |
582 | |
583 while n != bottom: | |
584 p = self.changelog.parents(n)[0] | |
585 if i == f: | |
586 l.append(n) | |
587 f = f * 2 | |
588 n = p | |
589 i += 1 | |
590 | |
591 r.append(l) | |
592 | |
593 return r | |
594 | |
595 def newer(self, nodes): | |
596 m = {} | |
597 nl = [] | |
598 cl = self.changelog | |
599 t = l = cl.count() | |
600 for n in nodes: | |
601 l = min(l, cl.rev(n)) | |
602 for p in cl.parents(n): | |
603 m[p] = 1 | |
604 | |
605 for i in xrange(l, t): | |
606 n = cl.node(i) | |
607 for p in cl.parents(n): | |
608 if p in m and n not in m: | |
609 m[n] = 1 | |
610 nl.append(n) | |
611 | |
612 return nl | |
613 | |
614 def getchangegroup(self, remote): | |
615 tip = remote.branches([]) | |
616 cl = self.changelog | |
617 unknown = tip | |
618 search = [] | |
619 fetch = [] | |
620 | |
621 if tip[0] == self.changelog.tip(): | |
622 return "" | |
623 | |
624 while unknown: | |
625 n = unknown.pop(0) | |
626 if n == nullid: break | |
627 if n[1] and cl.nodemap.has_key(n[1]): # do we know the base? | |
628 search.append(n) # schedule branch range for scanning | |
629 else: | |
630 for b in remote.branches([n[2], n[3]]): | |
631 if cl.nodemap.has_key(b[0]): | |
632 fetch.append(n[1]) # earliest unknown | |
633 else: | |
634 unknown.append(b) | |
635 | |
636 while search: | |
637 n = search.pop(0) | |
638 l = remote.between([(n[0], n[1])])[0] | |
639 p = n[0] | |
640 f = 1 | |
641 for i in l + [n[1]]: | |
642 if self.changelog.nodemap.has_key(i): | |
643 if f == 1: | |
644 fetch.append(p) | |
645 else: | |
646 search.append((p, i)) | |
647 p, f = i, f * 2 | |
648 | |
649 return remote.changegroup(fetch) | |
650 | |
651 def changegroup(self, basenodes): | |
652 nodes = self.newer(basenodes) | |
653 | |
571 # construct the link map | 654 # construct the link map |
572 linkmap = {} | 655 linkmap = {} |
573 for n in nodes: | 656 for n in nodes: |
574 linkmap[self.changelog.rev(n)] = n | 657 linkmap[self.changelog.rev(n)] = n |
575 | 658 |
595 g = self.file(f).group(linkmap) | 678 g = self.file(f).group(linkmap) |
596 if not g: raise "couldn't find change to %s" % f | 679 if not g: raise "couldn't find change to %s" % f |
597 l = struct.pack(">l", len(f)) | 680 l = struct.pack(">l", len(f)) |
598 cg += [l, f, g] | 681 cg += [l, f, g] |
599 | 682 |
600 return compress("".join(cg)) | 683 return "".join(cg) |
601 | 684 |
602 def addchangegroup(self, data): | 685 def addchangegroup(self, data): |
603 data = decompress(data) | |
604 def getlen(data, pos): | 686 def getlen(data, pos): |
605 return struct.unpack(">l", data[pos:pos + 4])[0] | 687 return struct.unpack(">l", data[pos:pos + 4])[0] |
606 | 688 |
607 tr = self.transaction() | 689 tr = self.transaction() |
608 simple = True | 690 simple = True |