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