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)