Mercurial > hg
comparison mercurial/localrepo.py @ 1458:1033892bbb87
This changes the revlog.group and re-implements the localrepo.changeroup
function in terms of it.
revlog.group now takes a list of nodes, and some callback functions
instead of a linkmap.
author | Eric Hopper <hopper@omnifarious.org> |
---|---|
date | Fri, 07 Oct 2005 10:57:11 -0700 |
parents | 518da3c3b6ce |
children | 40d08cf1c544 |
comparison
equal
deleted
inserted
replaced
1457:518da3c3b6ce | 1458:1033892bbb87 |
---|---|
890 return 1 | 890 return 1 |
891 | 891 |
892 cg = self.changegroup(update) | 892 cg = self.changegroup(update) |
893 return remote.addchangegroup(cg) | 893 return remote.addchangegroup(cg) |
894 | 894 |
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 | |
980 | |
981 def gengroup(): | |
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) | |
1011 | |
1012 return util.chunkbuffer(gengroup()) | |
1013 | |
895 def changegroup(self, basenodes): | 1014 def changegroup(self, basenodes): |
896 genread = util.chunkbuffer | 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 | |
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 | |
897 | 1039 |
898 def gengroup(): | 1040 def gengroup(): |
899 nodes = self.changelog.nodesbetween(basenodes)[0] | |
900 | |
901 # construct the link map | |
902 linkmap = {} | |
903 for n in nodes: | |
904 linkmap[self.changelog.rev(n)] = n | |
905 | |
906 # construct a list of all changed files | 1041 # construct a list of all changed files |
907 changed = {} | 1042 changedfiles = {} |
908 for n in nodes: | 1043 |
909 c = self.changelog.read(n) | 1044 for chnk in cl.group(nodes, identity, |
910 for f in c[3]: | 1045 changed_file_collector(changedfiles)): |
911 changed[f] = 1 | 1046 yield chnk |
912 changed = changed.keys() | 1047 changedfiles = changedfiles.keys() |
913 changed.sort() | 1048 changedfiles.sort() |
914 | 1049 |
915 # the changegroup is changesets + manifests + all file revs | 1050 mnfst = self.manifest |
916 revs = [ self.changelog.rev(n) for n in nodes ] | 1051 def nodegen(revlog, reviter): |
917 | 1052 for r in reviter: |
918 for y in self.changelog.group(linkmap): yield y | 1053 yield revlog.node(r) |
919 for y in self.manifest.group(linkmap): yield y | 1054 nodeiter = gennodelst(mnfst) |
920 for f in changed: | 1055 for chnk in mnfst.group(nodeiter, lookuprevlink_func(mnfst)): |
921 yield struct.pack(">l", len(f) + 4) + f | 1056 yield chnk |
922 g = self.file(f).group(linkmap) | 1057 |
923 for y in g: | 1058 for fname in changedfiles: |
924 yield y | 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 yield struct.pack(">l", 0) | 1068 yield struct.pack(">l", 0) |
927 | 1069 |
928 return genread(gengroup()) | 1070 return util.chunkbuffer(gengroup()) |
929 | 1071 |
930 def addchangegroup(self, source): | 1072 def addchangegroup(self, source): |
931 | 1073 |
932 def getchunk(): | 1074 def getchunk(): |
933 d = source.read(4) | 1075 d = source.read(4) |