comparison mercurial/localrepo.py @ 19202:0455fc94ae00

bundle-ng: move gengroup into bundler, pass repo object to bundler No semantic changes made.
author Sune Foldager <cryo@cyanite.org>
date Fri, 10 May 2013 21:35:49 +0200
parents 309c439cdbaa
children 627cd7842e5d
comparison
equal deleted inserted replaced
19201:309c439cdbaa 19202:0455fc94ae00
1842 bundlecaps = None 1842 bundlecaps = None
1843 # create a changegroup from local 1843 # create a changegroup from local
1844 if revs is None and not outgoing.excluded: 1844 if revs is None and not outgoing.excluded:
1845 # push everything, 1845 # push everything,
1846 # use the fast path, no race possible on push 1846 # use the fast path, no race possible on push
1847 bundler = changegroup.bundle10(bundlecaps) 1847 bundler = changegroup.bundle10(self, bundlecaps)
1848 cg = self._changegroup(outgoing.missing, bundler, 1848 cg = self._changegroup(outgoing.missing, bundler,
1849 'push') 1849 'push')
1850 else: 1850 else:
1851 cg = self.getlocalbundle('push', outgoing, bundlecaps) 1851 cg = self.getlocalbundle('push', outgoing, bundlecaps)
1852 1852
1990 if not bases: 1990 if not bases:
1991 bases = [nullid] 1991 bases = [nullid]
1992 csets, bases, heads = cl.nodesbetween(bases, heads) 1992 csets, bases, heads = cl.nodesbetween(bases, heads)
1993 # We assume that all ancestors of bases are known 1993 # We assume that all ancestors of bases are known
1994 common = cl.ancestors([cl.rev(n) for n in bases]) 1994 common = cl.ancestors([cl.rev(n) for n in bases])
1995 bundler = changegroup.bundle10() 1995 bundler = changegroup.bundle10(self)
1996 return self._changegroupsubset(common, csets, heads, bundler, source) 1996 return self._changegroupsubset(common, csets, heads, bundler, source)
1997 1997
1998 def getlocalbundle(self, source, outgoing, bundlecaps=None): 1998 def getlocalbundle(self, source, outgoing, bundlecaps=None):
1999 """Like getbundle, but taking a discovery.outgoing as an argument. 1999 """Like getbundle, but taking a discovery.outgoing as an argument.
2000 2000
2001 This is only implemented for local repos and reuses potentially 2001 This is only implemented for local repos and reuses potentially
2002 precomputed sets in outgoing.""" 2002 precomputed sets in outgoing."""
2003 if not outgoing.missing: 2003 if not outgoing.missing:
2004 return None 2004 return None
2005 bundler = changegroup.bundle10(bundlecaps) 2005 bundler = changegroup.bundle10(self, bundlecaps)
2006 return self._changegroupsubset(outgoing.common, 2006 return self._changegroupsubset(outgoing.common,
2007 outgoing.missing, 2007 outgoing.missing,
2008 outgoing.missingheads, 2008 outgoing.missingheads,
2009 bundler, 2009 bundler,
2010 source) 2010 source)
2031 bundlecaps=bundlecaps) 2031 bundlecaps=bundlecaps)
2032 2032
2033 @unfilteredmethod 2033 @unfilteredmethod
2034 def _changegroupsubset(self, commonrevs, csets, heads, bundler, source): 2034 def _changegroupsubset(self, commonrevs, csets, heads, bundler, source):
2035 2035
2036 cl = self.changelog 2036 cl = bundler._changelog
2037 mf = self.manifest 2037 mf = bundler._manifest
2038 mfs = {} # needed manifests 2038 mfs = {} # needed manifests
2039 fnodes = {} # needed file nodes 2039 fnodes = {} # needed file nodes
2040 changedfiles = set() 2040 changedfiles = set()
2041 fstate = ['', {}] 2041 fstate = ['', {}]
2042 count = [0, 0]
2043 2042
2044 # can we go through the fast path ? 2043 # can we go through the fast path ?
2045 heads.sort() 2044 heads.sort()
2046 if heads == sorted(self.heads()): 2045 if heads == sorted(self.heads()):
2047 return self._changegroup(csets, bundler, source) 2046 return self._changegroup(csets, bundler, source)
2061 _changesets = _('changesets') 2060 _changesets = _('changesets')
2062 _manifests = _('manifests') 2061 _manifests = _('manifests')
2063 _files = _('files') 2062 _files = _('files')
2064 2063
2065 def lookup(revlog, x): 2064 def lookup(revlog, x):
2065 count = bundler.count
2066 if revlog == cl: 2066 if revlog == cl:
2067 c = cl.read(x) 2067 c = cl.read(x)
2068 changedfiles.update(c[3]) 2068 changedfiles.update(c[3])
2069 mfs.setdefault(c[0], x) 2069 mfs.setdefault(c[0], x)
2070 count[0] += 1 2070 count[0] += 1
2085 progress(_bundling, count[0], item=fstate[0], 2085 progress(_bundling, count[0], item=fstate[0],
2086 unit=_files, total=count[1]) 2086 unit=_files, total=count[1])
2087 return fstate[1][x] 2087 return fstate[1][x]
2088 2088
2089 bundler.start(lookup) 2089 bundler.start(lookup)
2090 reorder = self.ui.config('bundle', 'reorder', 'auto') 2090
2091 if reorder == 'auto': 2091 def getmfnodes():
2092 reorder = None
2093 else:
2094 reorder = util.parsebool(reorder)
2095
2096 def gengroup():
2097 # Create a changenode group generator that will call our functions
2098 # back to lookup the owning changenode and collect information.
2099 count[:] = [0, len(csets)]
2100 for chunk in bundler.group(csets, cl, reorder=reorder):
2101 yield chunk
2102 progress(_bundling, None)
2103
2104 # Create a generator for the manifestnodes that calls our lookup
2105 # and data collection functions back.
2106 for f in changedfiles: 2092 for f in changedfiles:
2107 fnodes[f] = {} 2093 fnodes[f] = {}
2108 count[:] = [0, len(mfs)] 2094 bundler.count[:] = [0, len(mfs)]
2109 for chunk in bundler.group(prune(mf, mfs), mf, reorder=reorder): 2095 return prune(mf, mfs)
2110 yield chunk 2096 def getfiles():
2111 progress(_bundling, None)
2112
2113 mfs.clear() 2097 mfs.clear()
2114 2098 return changedfiles
2115 # Go through all our files in order sorted by name. 2099 def getfilenodes(fname, filerevlog):
2116 count[:] = [0, len(changedfiles)] 2100 fstate[0] = fname
2117 for fname in sorted(changedfiles): 2101 fstate[1] = fnodes.pop(fname, {})
2118 filerevlog = self.file(fname) 2102 return prune(filerevlog, fstate[1])
2119 if not len(filerevlog): 2103
2120 raise util.Abort(_("empty or missing revlog for %s") 2104 gengroup = bundler.generate(csets, getmfnodes, getfiles, getfilenodes,
2121 % fname) 2105 source)
2122 fstate[0] = fname 2106 return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN')
2123 fstate[1] = fnodes.pop(fname, {})
2124
2125 nodelist = prune(filerevlog, fstate[1])
2126 if nodelist:
2127 count[0] += 1
2128 yield bundler.fileheader(fname)
2129 for chunk in bundler.group(nodelist, filerevlog, reorder):
2130 yield chunk
2131
2132 # Signal that no more groups are left.
2133 yield bundler.close()
2134 progress(_bundling, None)
2135
2136 if csets:
2137 self.hook('outgoing', node=hex(csets[0]), source=source)
2138
2139 return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN')
2140 2107
2141 def changegroup(self, basenodes, source): 2108 def changegroup(self, basenodes, source):
2142 # to avoid a race we use changegroupsubset() (issue1320) 2109 # to avoid a race we use changegroupsubset() (issue1320)
2143 return self.changegroupsubset(basenodes, self.heads(), source) 2110 return self.changegroupsubset(basenodes, self.heads(), source)
2144 2111
2151 This is much easier than the previous function as we can assume that 2118 This is much easier than the previous function as we can assume that
2152 the recipient has any changenode we aren't sending them. 2119 the recipient has any changenode we aren't sending them.
2153 2120
2154 nodes is the set of nodes to send""" 2121 nodes is the set of nodes to send"""
2155 2122
2156 cl = self.changelog 2123 cl = bundler._changelog
2157 mf = self.manifest 2124 mf = bundler._manifest
2158 mfs = {} 2125 mfs = {}
2159 changedfiles = set() 2126 changedfiles = set()
2160 fstate = [''] 2127 fstate = ['']
2161 count = [0, 0]
2162 2128
2163 self.hook('preoutgoing', throw=True, source=source) 2129 self.hook('preoutgoing', throw=True, source=source)
2164 self.changegroupinfo(nodes, source) 2130 self.changegroupinfo(nodes, source)
2165 2131
2166 revset = set([cl.rev(n) for n in nodes]) 2132 revset = set([cl.rev(n) for n in nodes])
2174 _changesets = _('changesets') 2140 _changesets = _('changesets')
2175 _manifests = _('manifests') 2141 _manifests = _('manifests')
2176 _files = _('files') 2142 _files = _('files')
2177 2143
2178 def lookup(revlog, x): 2144 def lookup(revlog, x):
2145 count = bundler.count
2179 if revlog == cl: 2146 if revlog == cl:
2180 c = cl.read(x) 2147 c = cl.read(x)
2181 changedfiles.update(c[3]) 2148 changedfiles.update(c[3])
2182 mfs.setdefault(c[0], x) 2149 mfs.setdefault(c[0], x)
2183 count[0] += 1 2150 count[0] += 1
2193 progress(_bundling, count[0], item=fstate[0], 2160 progress(_bundling, count[0], item=fstate[0],
2194 total=count[1], unit=_files) 2161 total=count[1], unit=_files)
2195 return cl.node(revlog.linkrev(revlog.rev(x))) 2162 return cl.node(revlog.linkrev(revlog.rev(x)))
2196 2163
2197 bundler.start(lookup) 2164 bundler.start(lookup)
2198 reorder = self.ui.config('bundle', 'reorder', 'auto') 2165
2199 if reorder == 'auto': 2166 def getmfnodes():
2200 reorder = None 2167 bundler.count[:] = [0, len(mfs)]
2201 else: 2168 return gennodelst(mf)
2202 reorder = util.parsebool(reorder) 2169 def getfiles():
2203 2170 return changedfiles
2204 def gengroup(): 2171 def getfilenodes(fname, filerevlog):
2205 '''yield a sequence of changegroup chunks (strings)''' 2172 fstate[0] = fname
2206 # construct a list of all changed files 2173 return gennodelst(filerevlog)
2207 2174
2208 count[:] = [0, len(nodes)] 2175 gengroup = bundler.generate(nodes, getmfnodes, getfiles, getfilenodes,
2209 for chunk in bundler.group(nodes, cl, reorder=reorder): 2176 source)
2210 yield chunk 2177 return changegroup.unbundle10(util.chunkbuffer(gengroup), 'UN')
2211 progress(_bundling, None)
2212
2213 count[:] = [0, len(mfs)]
2214 for chunk in bundler.group(gennodelst(mf), mf, reorder=reorder):
2215 yield chunk
2216 progress(_bundling, None)
2217
2218 count[:] = [0, len(changedfiles)]
2219 for fname in sorted(changedfiles):
2220 filerevlog = self.file(fname)
2221 if not len(filerevlog):
2222 raise util.Abort(_("empty or missing revlog for %s")
2223 % fname)
2224 fstate[0] = fname
2225 nodelist = gennodelst(filerevlog)
2226 if nodelist:
2227 count[0] += 1
2228 yield bundler.fileheader(fname)
2229 for chunk in bundler.group(nodelist, filerevlog, reorder):
2230 yield chunk
2231 yield bundler.close()
2232 progress(_bundling, None)
2233
2234 if nodes:
2235 self.hook('outgoing', node=hex(nodes[0]), source=source)
2236
2237 return changegroup.unbundle10(util.chunkbuffer(gengroup()), 'UN')
2238 2178
2239 @unfilteredmethod 2179 @unfilteredmethod
2240 def addchangegroup(self, source, srctype, url, emptyok=False): 2180 def addchangegroup(self, source, srctype, url, emptyok=False):
2241 """Add the changegroup returned by source.read() to this repo. 2181 """Add the changegroup returned by source.read() to this repo.
2242 srctype is a string like 'push', 'pull', or 'unbundle'. url is 2182 srctype is a string like 'push', 'pull', or 'unbundle'. url is