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, base |
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
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] + l |
|
|
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