mercurial/pushkey.py
author Gregory Szorc <gregory.szorc@gmail.com>
Fri, 06 Apr 2018 22:39:58 -0700
changeset 37497 1541e1a8e87d
parent 25969 7b200566e474
child 43075 57875cf423c9
permissions -rw-r--r--
filelog: wrap revlog instead of inheriting it (API) The revlog base class exposes a ton of methods. Inheriting the revlog class for filelog will make it difficult to expose a clean interface. There will be abstraction violations. This commit breaks the inheritance of revlog by the filelog class. Filelog instances now contain a reference to a revlog instance. Various properties and methods are now proxied to that instance. There is precedence for doing this: manifestlog does something similar. Although, manifestlog has a cleaner interface than filelog. We'll get there with filelog... The new filelog class exposes a handful of extra properties and methods that aren't part of the declared filelog interface. Every extra item was added in order to get a test to pass. The set of tests that failed without these extra proxies has significant overlap with the set of tests that don't work with the simple store repo. There should be no surprise there. Hopefully the hardest part about this commit to review are the changes to bundlerepo and unionrepo. Both repository types define a custom revlog or revlog-like class and then have a custom filelog that inherits from both filelog and their custom revlog. This code has been changed so the filelog types don't inherit from revlog. Instead, they replace the revlog instance on the created filelog. This is super hacky. I plan to fix this in a future commit by parameterizing filelog.__init__. Because Python function call overhead is a thing, this change could impact performance by introducing a nearly empty proxy function for various methods and properties. I would gladly measure the performance impact of it, but I'm not sure what operations have tight loops over filelog attribute lookups or function calls. I know some of the DAG traversal code can be sensitive about the performance of e.g. parentrevs(). However, many of these functions are implemented on the revlog class and therefore have direct access to self.parentrevs() and aren't going through a proxy. .. api:: filelog.filelog is now a standalone class and doesn't inherit from revlog. Instead, it wraps a revlog instance at self._revlog. This change was made in an attempt to formalize storage APIs and prevent revlog implementation details leaking through to callers. Differential Revision: https://phab.mercurial-scm.org/D3154
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
# pushkey.py - dispatching for pushing and pulling keys
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
#
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
# Copyright 2010 Matt Mackall <mpm@selenic.com>
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
#
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
25969
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
     8
from __future__ import absolute_import
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
     9
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    10
from . import (
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    11
    bookmarks,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    12
    encoding,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    13
    obsolete,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    14
    phases,
7b200566e474 pushkey: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22953
diff changeset
    15
)
13353
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 11367
diff changeset
    16
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
def _nslist(repo):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
    n = {}
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
    for k in _namespaces:
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
        n[k] = ""
22953
b1d694d3975e obsolete: add exchange option
Durham Goode <durham@fb.com>
parents: 21661
diff changeset
    21
    if not obsolete.isenabled(repo, obsolete.exchangeopt):
17298
59c14bf5a48c pushkey: do not exchange obsole markers if feature is disabled
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17075
diff changeset
    22
        n.pop('obsolete')
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
    return n
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
13353
689bf32b3bbd bookmarks: move pushkey functions into core
Matt Mackall <mpm@selenic.com>
parents: 11367
diff changeset
    25
_namespaces = {"namespaces": (lambda *x: False, _nslist),
15648
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 13353
diff changeset
    26
               "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks),
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 13353
diff changeset
    27
               "phases": (phases.pushphase, phases.listphases),
17075
28ed1c4511ce obsolete: exchange obsolete marker over pushkey
Pierre-Yves.David@ens-lyon.org
parents: 15648
diff changeset
    28
               "obsolete": (obsolete.pushmarker, obsolete.listmarkers),
15648
79cc89de5be1 phases: add basic pushkey support
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 13353
diff changeset
    29
              }
11367
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
def register(namespace, pushkey, listkeys):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
    _namespaces[namespace] = (pushkey, listkeys)
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
def _get(namespace):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
    return _namespaces.get(namespace, (lambda *x: False, lambda *x: {}))
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
def push(repo, namespace, key, old, new):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
    '''should succeed iff value was old'''
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
    pk = _get(namespace)[0]
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
    return pk(repo, key, old, new)
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    41
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
def list(repo, namespace):
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
    '''return a dict'''
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
    lk = _get(namespace)[1]
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
    return lk(repo)
ca4fc993087c pushkey: add pushkey core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
21661
2f52a16f2bee pushkey: add an ``encode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21659
diff changeset
    47
encode = encoding.fromlocal
2f52a16f2bee pushkey: add an ``encode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21659
diff changeset
    48
21659
a319842539f5 pushkey: add a ``decode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21652
diff changeset
    49
decode = encoding.tolocal
a319842539f5 pushkey: add a ``decode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21652
diff changeset
    50
21650
a2c7ae21e8f4 pushkey: introduce an ``encodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 17298
diff changeset
    51
def encodekeys(keys):
a2c7ae21e8f4 pushkey: introduce an ``encodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 17298
diff changeset
    52
    """encode the content of a pushkey namespace for exchange over the wire"""
21661
2f52a16f2bee pushkey: add an ``encode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21659
diff changeset
    53
    return '\n'.join(['%s\t%s' % (encode(k), encode(v)) for k, v in keys])
21652
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    54
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    55
def decodekeys(data):
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    56
    """decode the content of a pushkey namespace from exchange over the wire"""
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    57
    result = {}
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    58
    for l in data.splitlines():
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    59
        k, v = l.split('\t')
21659
a319842539f5 pushkey: add a ``decode`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21652
diff changeset
    60
        result[decode(k)] = decode(v)
21652
ed6e61eaebc0 pushkey: introduce an ``decodekeys`` function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 21650
diff changeset
    61
    return result