Mercurial > hg
diff 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 |
line wrap: on
line diff
--- a/mercurial/wireproto.py Tue Jun 14 22:51:26 2011 +0200 +++ b/mercurial/wireproto.py Tue Jun 14 22:52:58 2011 +0200 @@ -126,9 +126,41 @@ def encodelist(l, sep=' '): return sep.join(map(hex, l)) +# batched call argument encoding + +def escapearg(plain): + return (plain + .replace(':', '::') + .replace(',', ':,') + .replace(';', ':;') + .replace('=', ':=')) + +def unescapearg(escaped): + return (escaped + .replace(':=', '=') + .replace(':;', ';') + .replace(':,', ',') + .replace('::', ':')) + # client side +def todict(**args): + return args + class wirerepository(repo.repository): + + def batch(self): + return remotebatch(self) + def _submitbatch(self, req): + cmds = [] + for op, argsdict in req: + args = ','.join('%s=%s' % p for p in argsdict.iteritems()) + cmds.append('%s %s' % (op, args)) + rsp = self._call("batch", cmds=';'.join(cmds)) + return rsp.split(';') + def _submitone(self, op, args): + return self._call(op, **args) + def lookup(self, key): self.requirecap('lookup', _('look up remote revision')) d = self._call("lookup", key=encoding.fromlocal(key)) @@ -302,6 +334,34 @@ % (cmd, ",".join(others))) return opts +def batch(repo, proto, cmds, others): + res = [] + for pair in cmds.split(';'): + op, args = pair.split(' ', 1) + vals = {} + for a in args.split(','): + if a: + n, v = a.split('=') + vals[n] = unescapearg(v) + func, spec = commands[op] + if spec: + keys = spec.split() + data = {} + for k in keys: + if k == '*': + star = {} + for key in vals.keys(): + if key not in keys: + star[key] = vals[key] + data['*'] = star + else: + data[k] = vals[k] + result = func(repo, proto, *[data[k] for k in keys]) + else: + result = func(repo, proto) + res.append(escapearg(result)) + return ';'.join(res) + def between(repo, proto, pairs): pairs = [decodelist(p, '-') for p in pairs.split(" ")] r = [] @@ -327,7 +387,7 @@ def capabilities(repo, proto): caps = ('lookup changegroupsubset branchmap pushkey known getbundle ' - 'unbundlehash').split() + 'unbundlehash batch').split() if _allowstream(repo.ui): requiredformats = repo.requirements & repo.supportedformats # if our local revlogs are just revlogv1, add 'stream' cap @@ -506,6 +566,7 @@ os.unlink(tempname) commands = { + 'batch': (batch, 'cmds *'), 'between': (between, 'pairs'), 'branchmap': (branchmap, ''), 'branches': (branches, 'nodes'),