Mercurial > hg
comparison mercurial/wireproto.py @ 14622:bd88561afb4b
wireproto: add batching support to wirerepository
Adds the plumbing and wire call for batched execution, but does not
batch-enable any methods yet.
author | Peter Arrenbrecht <peter.arrenbrecht@gmail.com> |
---|---|
date | Tue, 14 Jun 2011 22:52:58 +0200 |
parents | 84094c0d2724 |
children | e7c9fdbbb902 |
comparison
equal
deleted
inserted
replaced
14621:84094c0d2724 | 14622:bd88561afb4b |
---|---|
124 return [] | 124 return [] |
125 | 125 |
126 def encodelist(l, sep=' '): | 126 def encodelist(l, sep=' '): |
127 return sep.join(map(hex, l)) | 127 return sep.join(map(hex, l)) |
128 | 128 |
129 # batched call argument encoding | |
130 | |
131 def escapearg(plain): | |
132 return (plain | |
133 .replace(':', '::') | |
134 .replace(',', ':,') | |
135 .replace(';', ':;') | |
136 .replace('=', ':=')) | |
137 | |
138 def unescapearg(escaped): | |
139 return (escaped | |
140 .replace(':=', '=') | |
141 .replace(':;', ';') | |
142 .replace(':,', ',') | |
143 .replace('::', ':')) | |
144 | |
129 # client side | 145 # client side |
130 | 146 |
147 def todict(**args): | |
148 return args | |
149 | |
131 class wirerepository(repo.repository): | 150 class wirerepository(repo.repository): |
151 | |
152 def batch(self): | |
153 return remotebatch(self) | |
154 def _submitbatch(self, req): | |
155 cmds = [] | |
156 for op, argsdict in req: | |
157 args = ','.join('%s=%s' % p for p in argsdict.iteritems()) | |
158 cmds.append('%s %s' % (op, args)) | |
159 rsp = self._call("batch", cmds=';'.join(cmds)) | |
160 return rsp.split(';') | |
161 def _submitone(self, op, args): | |
162 return self._call(op, **args) | |
163 | |
132 def lookup(self, key): | 164 def lookup(self, key): |
133 self.requirecap('lookup', _('look up remote revision')) | 165 self.requirecap('lookup', _('look up remote revision')) |
134 d = self._call("lookup", key=encoding.fromlocal(key)) | 166 d = self._call("lookup", key=encoding.fromlocal(key)) |
135 success, data = d[:-1].split(" ", 1) | 167 success, data = d[:-1].split(" ", 1) |
136 if int(success): | 168 if int(success): |
300 if others: | 332 if others: |
301 sys.stderr.write("abort: %s got unexpected arguments %s\n" | 333 sys.stderr.write("abort: %s got unexpected arguments %s\n" |
302 % (cmd, ",".join(others))) | 334 % (cmd, ",".join(others))) |
303 return opts | 335 return opts |
304 | 336 |
337 def batch(repo, proto, cmds, others): | |
338 res = [] | |
339 for pair in cmds.split(';'): | |
340 op, args = pair.split(' ', 1) | |
341 vals = {} | |
342 for a in args.split(','): | |
343 if a: | |
344 n, v = a.split('=') | |
345 vals[n] = unescapearg(v) | |
346 func, spec = commands[op] | |
347 if spec: | |
348 keys = spec.split() | |
349 data = {} | |
350 for k in keys: | |
351 if k == '*': | |
352 star = {} | |
353 for key in vals.keys(): | |
354 if key not in keys: | |
355 star[key] = vals[key] | |
356 data['*'] = star | |
357 else: | |
358 data[k] = vals[k] | |
359 result = func(repo, proto, *[data[k] for k in keys]) | |
360 else: | |
361 result = func(repo, proto) | |
362 res.append(escapearg(result)) | |
363 return ';'.join(res) | |
364 | |
305 def between(repo, proto, pairs): | 365 def between(repo, proto, pairs): |
306 pairs = [decodelist(p, '-') for p in pairs.split(" ")] | 366 pairs = [decodelist(p, '-') for p in pairs.split(" ")] |
307 r = [] | 367 r = [] |
308 for b in repo.between(pairs): | 368 for b in repo.between(pairs): |
309 r.append(encodelist(b) + "\n") | 369 r.append(encodelist(b) + "\n") |
325 r.append(encodelist(b) + "\n") | 385 r.append(encodelist(b) + "\n") |
326 return "".join(r) | 386 return "".join(r) |
327 | 387 |
328 def capabilities(repo, proto): | 388 def capabilities(repo, proto): |
329 caps = ('lookup changegroupsubset branchmap pushkey known getbundle ' | 389 caps = ('lookup changegroupsubset branchmap pushkey known getbundle ' |
330 'unbundlehash').split() | 390 'unbundlehash batch').split() |
331 if _allowstream(repo.ui): | 391 if _allowstream(repo.ui): |
332 requiredformats = repo.requirements & repo.supportedformats | 392 requiredformats = repo.requirements & repo.supportedformats |
333 # if our local revlogs are just revlogv1, add 'stream' cap | 393 # if our local revlogs are just revlogv1, add 'stream' cap |
334 if not requiredformats - set(('revlogv1',)): | 394 if not requiredformats - set(('revlogv1',)): |
335 caps.append('stream') | 395 caps.append('stream') |
504 finally: | 564 finally: |
505 fp.close() | 565 fp.close() |
506 os.unlink(tempname) | 566 os.unlink(tempname) |
507 | 567 |
508 commands = { | 568 commands = { |
569 'batch': (batch, 'cmds *'), | |
509 'between': (between, 'pairs'), | 570 'between': (between, 'pairs'), |
510 'branchmap': (branchmap, ''), | 571 'branchmap': (branchmap, ''), |
511 'branches': (branches, 'nodes'), | 572 'branches': (branches, 'nodes'), |
512 'capabilities': (capabilities, ''), | 573 'capabilities': (capabilities, ''), |
513 'changegroup': (changegroup, 'roots'), | 574 'changegroup': (changegroup, 'roots'), |