hgext/schemes.py
author Gregory Szorc <gregory.szorc@gmail.com>
Sat, 26 Sep 2015 21:43:13 -0700
changeset 26380 56a640b0f656
parent 25186 80c5b2666a96
child 26587 56b2bcea2529
permissions -rw-r--r--
revlog: don't flush data file after every added revision The current behavior of revlogs is to flush the data file when writing data to it. Tracing system calls revealed that changegroup processing incurred numerous write(2) calls for values much smaller than the default buffer size (Python defaults to 4096, but it can be adjusted based on detected block size at run time by CPython). The reason we flush revlogs is so readers have all data available. For example, the current code in revlog.py will re-open the revlog file (instead of seeking an existing file handle) to read the text of a revision. This happens when starting a new delta chain when adding several revisions from changegroups, for example. Yes, this is likely sub-optimal (we should probably be sharing file descriptors between readers and writers to avoid the flushing and associated overhead of re-opening files). While flushing revlogs is necessary, it appears all callers are diligent about flushing files before a read is performed (see buildtext() in _addrevision()), making the flush in _writeentry() redundant and unncessary. So, we remove it. In practice, this means we incur a write(2) a) when the buffer is full (typically 4096 bytes) b) when a new delta chain is created rather than after every added revision. This applies to every revlog, but by volume it mostly impacts filelogs. Removing the redundant flush from _writeentry() significantly reduces the number of write(2) calls during changegroup processing on my Linux machine. When applying a changegroup of the hg repo based on my local repo, the total number of write(2) calls during application of the mercurial/localrepo.py revlogs dropped from 1,320 to 217 with this patch applied. Total I/O related system calls dropped from 1,577 to 474. When unbundling a mozilla-central gzipped bundle (264,403 changesets with 1,492,215 changes to 222,507 files), total write(2) calls dropped from 1,252,881 to 827,106 and total system calls dropped from 3,601,259 to 3,178,636 - a reduction of 425,775! While the system call reduction is significant, it appears to have no impact on wall time on my Linux and Windows machines. Still, fewer syscalls is fewer syscalls. Surely this can't hurt. If nothing else, it makes examining remaining system call usage simpler and opens the door to experimenting with the performance impact of different buffer sizes.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     1
# Copyright 2009, Alexander Solovyov <piranha@piranha.org.ua>
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     2
#
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     3
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10070
diff changeset
     4
# GNU General Public License version 2 or any later version.
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     5
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     6
"""extend schemes with shortcuts to repository swarms
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     7
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     8
This extension allows you to specify shortcuts for parent URLs with a
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
     9
lot of repositories to act like a scheme, for example::
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    10
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    11
  [schemes]
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    12
  py = http://code.python.org/hg/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    13
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    14
After that you can use it like::
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    15
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    16
  hg clone py://trunk/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    17
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    18
Additionally there is support for some more complex schemas, for
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    19
example used by Google Code::
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    20
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    21
  [schemes]
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    22
  gcode = http://{1}.googlecode.com/hg/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    23
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    24
The syntax is taken from Mercurial templates, and you have unlimited
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    25
number of variables, starting with ``{1}`` and continuing with
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    26
``{2}``, ``{3}`` and so on. This variables will receive parts of URL
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    27
supplied, split by ``/``. Anything not specified as ``{part}`` will be
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    28
just appended to an URL.
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    29
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    30
For convenience, the extension adds these schemes by default::
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    31
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    32
  [schemes]
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    33
  py = http://hg.python.org/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    34
  bb = https://bitbucket.org/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    35
  bb+ssh = ssh://hg@bitbucket.org/
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    36
  gcode = https://{1}.googlecode.com/hg/
10777
bdc3256a318e schemes: add Kiln On Demand to default schemes
Benjamin Pollack <benjamin@bitquabit.com>
parents: 10282
diff changeset
    37
  kiln = https://{1}.kilnhg.com/Repo/
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    38
9965
963ed04a8fde schemes: fixed typos in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 9964
diff changeset
    39
You can override a predefined scheme by defining a new scheme with the
963ed04a8fde schemes: fixed typos in module docstring
Martin Geisler <mg@lazybytes.net>
parents: 9964
diff changeset
    40
same name.
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    41
"""
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    42
13822
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
    43
import os, re
14076
924c82157d46 url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
    44
from mercurial import extensions, hg, templater, util
13822
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
    45
from mercurial.i18n import _
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    46
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 18910
diff changeset
    47
# Note for extension authors: ONLY specify testedwith = 'internal' for
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 18910
diff changeset
    48
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 18910
diff changeset
    49
# be specifying the version(s) of Mercurial they are tested with, or
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 18910
diff changeset
    50
# leave the attribute unspecified.
16743
38caf405d010 hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents: 15609
diff changeset
    51
testedwith = 'internal'
38caf405d010 hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents: 15609
diff changeset
    52
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    53
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    54
class ShortRepository(object):
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    55
    def __init__(self, url, scheme, templater):
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    56
        self.scheme = scheme
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    57
        self.templater = templater
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    58
        self.url = url
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    59
        try:
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    60
            self.parts = max(map(int, re.findall(r'\{(\d+)\}', self.url)))
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    61
        except ValueError:
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    62
            self.parts = 0
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    63
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    64
    def __repr__(self):
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    65
        return '<ShortRepository: %s>' % self.scheme
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    66
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    67
    def instance(self, ui, url, create):
17425
e95ec38f86b0 fix wording and not-completely-trivial spelling errors and bad docstrings
Mads Kiilerich <mads@kiilerich.com>
parents: 16743
diff changeset
    68
        # Should this use the util.url class, or is manual parsing better?
18910
b52404a914a9 scheme: don't crash on invalid URLs
Mads Kiilerich <madski@unity3d.com>
parents: 17425
diff changeset
    69
        try:
b52404a914a9 scheme: don't crash on invalid URLs
Mads Kiilerich <madski@unity3d.com>
parents: 17425
diff changeset
    70
            url = url.split('://', 1)[1]
b52404a914a9 scheme: don't crash on invalid URLs
Mads Kiilerich <madski@unity3d.com>
parents: 17425
diff changeset
    71
        except IndexError:
b52404a914a9 scheme: don't crash on invalid URLs
Mads Kiilerich <madski@unity3d.com>
parents: 17425
diff changeset
    72
            raise util.Abort(_("no '://' in scheme url '%s'") % url)
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    73
        parts = url.split('/', self.parts)
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    74
        if len(parts) > self.parts:
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    75
            tail = parts[-1]
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    76
            parts = parts[:-1]
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    77
        else:
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    78
            tail = ''
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
    79
        context = dict((str(i + 1), v) for i, v in enumerate(parts))
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    80
        url = ''.join(self.templater.process(self.url, context)) + tail
14568
5f002e3336ba hg: split peer and repo lookup tables
Matt Mackall <mpm@selenic.com>
parents: 14076
diff changeset
    81
        return hg._peerlookup(url).instance(ui, url, create)
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    82
13827
f1823b9f073b url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents: 13822
diff changeset
    83
def hasdriveletter(orig, path):
15609
8f4bad72d8b1 util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents: 14606
diff changeset
    84
    if path:
8f4bad72d8b1 util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents: 14606
diff changeset
    85
        for scheme in schemes:
8f4bad72d8b1 util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents: 14606
diff changeset
    86
            if path.startswith(scheme + ':'):
8f4bad72d8b1 util: fix url.__str__() for windows file URLs
Patrick Mezard <pmezard@gmail.com>
parents: 14606
diff changeset
    87
                return False
13822
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
    88
    return orig(path)
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
    89
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    90
schemes = {
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    91
    'py': 'http://hg.python.org/',
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    92
    'bb': 'https://bitbucket.org/',
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    93
    'bb+ssh': 'ssh://hg@bitbucket.org/',
10777
bdc3256a318e schemes: add Kiln On Demand to default schemes
Benjamin Pollack <benjamin@bitquabit.com>
parents: 10282
diff changeset
    94
    'gcode': 'https://{1}.googlecode.com/hg/',
bdc3256a318e schemes: add Kiln On Demand to default schemes
Benjamin Pollack <benjamin@bitquabit.com>
parents: 10282
diff changeset
    95
    'kiln': 'https://{1}.kilnhg.com/Repo/'
9964
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    96
    }
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    97
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    98
def extsetup(ui):
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
    99
    schemes.update(dict(ui.configitems('schemes')))
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   100
    t = templater.engine(lambda x: x)
e600ad9bc257 schemes extension
Alexander Solovyov <piranha@piranha.org.ua>
parents:
diff changeset
   101
    for scheme, url in schemes.items():
13822
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
   102
        if (os.name == 'nt' and len(scheme) == 1 and scheme.isalpha()
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
   103
            and os.path.exists('%s:\\' % scheme)):
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
   104
            raise util.Abort(_('custom scheme %s:// conflicts with drive '
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
   105
                               'letter %s:\\\n') % (scheme, scheme.upper()))
14606
6e631c24c6d9 hg: move peerschemes back to schemes
Matt Mackall <mpm@selenic.com>
parents: 14605
diff changeset
   106
        hg.schemes[scheme] = ShortRepository(url, scheme, t)
13822
fbf32a6c903e schemes: prevent one letter schemes from being interpreted as drive letters
Brodie Rao <brodie@bitheap.org>
parents: 10777
diff changeset
   107
14076
924c82157d46 url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
   108
    extensions.wrapfunction(util, 'hasdriveletter', hasdriveletter)