##// END OF EJS Templates
This changes the revlog.group and re-implements the localrepo.changeroup...
Eric Hopper -
r1458:1033892b default
parent child Browse files
Show More
@@ -892,40 +892,182 b' class localrepository:'
892 892 cg = self.changegroup(update)
893 893 return remote.addchangegroup(cg)
894 894
895 def changegroup(self, basenodes):
896 genread = util.chunkbuffer
895 def changegroupsubset(self, bases, heads):
896 cl = self.changelog
897 # msng = missing
898 msng_cl_lst, bases, heads = cl.nodesbetween(basenodes, headnodes)
899 junk = None
900 knownheads = {}
901 for n in basenodes:
902 for p in cl.parents(n):
903 if p != nullid:
904 knownheads[p] = 1
905 knownheads = knownheads.keys()
906 has_cl_set, junk, junk = cl.nodesbetween(None, knownheads)
907 has_cl_set = dict.fromkeys(hasnodeset)
908
909 mnfst = self.manifest
910 msng_mnfst_set = {}
911 msng_filenode_set = {}
912
913 def identity(x):
914 return x
915
916 def cmp_by_rev_func(revlog):
917 def cmpfunc(a, b):
918 return cmp(revlog.rev(a), revlog.rev(b))
919 return cmpfunc
920
921 def prune_parents(revlog, hasset, msngset):
922 haslst = hasset.keys()
923 haslst.sort(cmp_by_rev_func(revlog))
924 for node in haslst:
925 parentlst = [p for p in revlog.parents(node) if p != nullid]
926 while parentlst:
927 n = parentlst.pop()
928 if n not in hasset:
929 hasset[n] = 1
930 p = [p for p in revlog.parents(n) if p != nullid]
931 parentlst.extend(p)
932 for n in hasset:
933 msngset.pop(n, None)
934
935 def manifest_and_file_collector(changedfileset):
936 def collect_manifests_and_files(clnode):
937 c = cl.read(clnode)
938 for f in c[3]:
939 # This is to make sure we only have one instance of each
940 # filename string for each filename.
941 changedfileset.set_default(f, f)
942 msng_mnfst_set.set_default(c[0], clnode)
943 return collect_manifests_and_files
944
945 def prune_manifests():
946 has_mnfst_set = {}
947 for n in msng_mnfst_set:
948 linknode = cl.node(mnfst.linkrev(n))
949 if linknode in has_cl_set:
950 has_mnfst_set[n] = 1
951 prune_parents(mnfst, has_mnfst_set, msng_mnfst_set)
952
953 def lookup_manifest_link(mnfstnode):
954 return msng_mnfst_set[mnfstnode]
955
956 def filenode_collector(changedfiles):
957 def collect_msng_filenodes(mnfstnode):
958 m = mnfst.read(mnfstnode)
959 for f in changedfiles:
960 fnode = m.get(f, None)
961 if fnode is not None:
962 clnode = msng_mnfst_set[mnfstnode]
963 ndset = msng_filenode_set.setdefault(f, {})
964 ndset.set_default(fnode, clnode)
965
966 def prune_filenodes(f, filerevlog):
967 msngset = msng_filenode_set[f]
968 hasset = {}
969 for n in msngset:
970 clnode = cl.node(filerevlog.linkrev(n))
971 if clnode in has_cl_set:
972 hasset[n] = 1
973 prune_parents(filerevlog, hasset, msngset)
974
975 def lookup_filenode_link_func(fname):
976 msngset = msng_filenode_set[fname]
977 def lookup_filenode_link(fnode):
978 return msngset[fnode]
979 return lookup_filenode_link
897 980
898 981 def gengroup():
899 nodes = self.changelog.nodesbetween(basenodes)[0]
982 changedfiles = {}
983 group = cl.group(msng_cl_lst, identity,
984 manifest_and_file_collector(changedfiles))
985 for chnk in group:
986 yield chnk
987 prune_manifests()
988 msng_mnfst_lst = msng_mnfst_set.keys()
989 msng_mnfst_lst.sort(cmp_by_rev_func(mnfst))
990 changedfiles = changedfiles.keys()
991 changedfiles.sort()
992 group = mnfst.group(mnfst, lookup_manifest_link,
993 filenode_collector(changedfiles))
994 for chnk in group:
995 yield chnk
996 msng_mnfst_lst = None
997 msng_mnfst_set.clear()
998 for fname in changedfiles:
999 filerevlog = self.file(fname)
1000 prune_filenodes(fname, filerevlog)
1001 msng_filenode_lst = msng_filenode_set[fname].keys()
1002 if len(msng_filenode_lst) > 0:
1003 yield struct.pack(">l", len(f) + 4) + f
1004 msng_filenode_lst.sort(cmp_by_rev_func(filerevlog))
1005 group = filerevlog.group(msng_filenode_lst,
1006 lookup_filenode_link)
1007 for chnk in group:
1008 yield chnk
1009 del msng_filenode_set[fname]
1010 yield struct.pack(">l", 0)
900 1011
901 # construct the link map
902 linkmap = {}
903 for n in nodes:
904 linkmap[self.changelog.rev(n)] = n
1012 return util.chunkbuffer(gengroup())
1013
1014 def changegroup(self, basenodes):
1015 cl = self.changelog
1016 nodes = cl.nodesbetween(basenodes, None)[0]
1017 revset = dict.fromkeys([cl.rev(n) for n in nodes])
1018
1019 def identity(x):
1020 return x
905 1021
1022 def gennodelst(revlog):
1023 for r in xrange(0, revlog.count()):
1024 n = revlog.node(r)
1025 if revlog.linkrev(n) in revset:
1026 yield n
1027
1028 def changed_file_collector(changedfileset):
1029 def collect_changed_files(clnode):
1030 c = cl.read(clnode)
1031 for fname in c[3]:
1032 changedfileset[fname] = 1
1033 return collect_changed_files
1034
1035 def lookuprevlink_func(revlog):
1036 def lookuprevlink(n):
1037 return cl.node(revlog.linkrev(n))
1038 return lookuprevlink
1039
1040 def gengroup():
906 1041 # construct a list of all changed files
907 changed = {}
908 for n in nodes:
909 c = self.changelog.read(n)
910 for f in c[3]:
911 changed[f] = 1
912 changed = changed.keys()
913 changed.sort()
1042 changedfiles = {}
1043
1044 for chnk in cl.group(nodes, identity,
1045 changed_file_collector(changedfiles)):
1046 yield chnk
1047 changedfiles = changedfiles.keys()
1048 changedfiles.sort()
914 1049
915 # the changegroup is changesets + manifests + all file revs
916 revs = [ self.changelog.rev(n) for n in nodes ]
1050 mnfst = self.manifest
1051 def nodegen(revlog, reviter):
1052 for r in reviter:
1053 yield revlog.node(r)
1054 nodeiter = gennodelst(mnfst)
1055 for chnk in mnfst.group(nodeiter, lookuprevlink_func(mnfst)):
1056 yield chnk
917 1057
918 for y in self.changelog.group(linkmap): yield y
919 for y in self.manifest.group(linkmap): yield y
920 for f in changed:
921 yield struct.pack(">l", len(f) + 4) + f
922 g = self.file(f).group(linkmap)
923 for y in g:
924 yield y
1058 for fname in changedfiles:
1059 filerevlog = self.file(fname)
1060 nodeiter = gennodelst(filerevlog)
1061 nodeiter = list(nodeiter)
1062 if nodeiter:
1063 yield struct.pack(">l", len(fname) + 4) + fname
1064 lookup = lookuprevlink_func(filerevlog)
1065 for chnk in filerevlog.group(nodeiter, lookup):
1066 yield chnk
925 1067
926 1068 yield struct.pack(">l", 0)
927 1069
928 return genread(gengroup())
1070 return util.chunkbuffer(gengroup())
929 1071
930 1072 def addchangegroup(self, source):
931 1073
@@ -622,7 +622,7 b' class revlog:'
622 622 #print "next x"
623 623 gx = x.next()
624 624
625 def group(self, linkmap):
625 def group(self, nodelist, lookup, infocollect = None):
626 626 """calculate a delta group
627 627
628 628 Given a list of changeset revs, return a set of deltas and
@@ -631,14 +631,8 b' class revlog:'
631 631 have this parent as it has all history before these
632 632 changesets. parent is parent[0]
633 633 """
634 revs = []
635 needed = {}
636
637 # find file nodes/revs that match changeset revs
638 for i in xrange(0, self.count()):
639 if self.index[i][3] in linkmap:
640 revs.append(i)
641 needed[i] = 1
634 revs = [self.rev(n) for n in nodelist]
635 needed = dict.fromkeys(revs, 1)
642 636
643 637 # if we don't have any revisions touched by these changesets, bail
644 638 if not revs:
@@ -706,6 +700,9 b' class revlog:'
706 700 a, b = revs[d], revs[d + 1]
707 701 n = self.node(b)
708 702
703 if infocollect is not None:
704 infocollect(n)
705
709 706 # do we need to construct a new delta?
710 707 if a + 1 != b or self.base(b) == b:
711 708 if a >= 0:
@@ -727,7 +724,7 b' class revlog:'
727 724 d = chunks[b]
728 725
729 726 p = self.parents(n)
730 meta = n + p[0] + p[1] + linkmap[self.linkrev(n)]
727 meta = n + p[0] + p[1] + lookup(n)
731 728 l = struct.pack(">l", len(meta) + len(d) + 4)
732 729 yield l
733 730 yield meta
General Comments 0
You need to be logged in to leave comments. Login now