Mercurial > hg
view mercurial/pushkey.py @ 44182:9896a8d0d3d2
rust-node: handling binary Node prefix
Parallel to the inner signatures of the nodetree functions in
revlog.c, we'll have to handle prefixes of `Node` in binary
form.
Another motivation is that it allows to convert from full Node
references to `NodePrefixRef` without copy. This is expected to
be by far the most common case in practice.
There's a slight complication due to the fact that we'll be sometimes
interested in prefixes with an odd number of hexadecimal digits,
which translates in binary form by a last byte in which only the
highest weight 4 bits are considered. This is totally transparent for
callers and could be revised once we have proper means to measure
performance.
The C implementation does the same, passing the length in nybbles as
function arguments. Because Rust byte slices already have a length, we carry
the even/odd informaton as a boolean, to avoid introducing logical
redundancies and the related potential inconsistency bugs.
There are a few candidates for inlining here, but we refrain from
such premature optimizations, letting the compiler decide.
Differential Revision: https://phab.mercurial-scm.org/D7790
author | Georges Racinet <georges.racinet@octobus.net> |
---|---|
date | Fri, 27 Dec 2019 23:04:18 +0100 |
parents | 687b865b95ad |
children | d4ba4d51f85f |
line wrap: on
line source
# pushkey.py - dispatching for pushing and pulling keys # # Copyright 2010 Matt Mackall <mpm@selenic.com> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import from . import ( bookmarks, encoding, obsolete, phases, ) def _nslist(repo): n = {} for k in _namespaces: n[k] = b"" if not obsolete.isenabled(repo, obsolete.exchangeopt): n.pop(b'obsolete') return n _namespaces = { b"namespaces": (lambda *x: False, _nslist), b"bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks), b"phases": (phases.pushphase, phases.listphases), b"obsolete": (obsolete.pushmarker, obsolete.listmarkers), } def register(namespace, pushkey, listkeys): _namespaces[namespace] = (pushkey, listkeys) def _get(namespace): return _namespaces.get(namespace, (lambda *x: False, lambda *x: {})) def push(repo, namespace, key, old, new): '''should succeed iff value was old''' pk = _get(namespace)[0] return pk(repo, key, old, new) def list(repo, namespace): '''return a dict''' lk = _get(namespace)[1] return lk(repo) encode = encoding.fromlocal decode = encoding.tolocal def encodekeys(keys): """encode the content of a pushkey namespace for exchange over the wire""" return b'\n'.join([b'%s\t%s' % (encode(k), encode(v)) for k, v in keys]) def decodekeys(data): """decode the content of a pushkey namespace from exchange over the wire""" result = {} for l in data.splitlines(): k, v = l.split(b'\t') result[decode(k)] = decode(v) return result