mercurial/branchmap.py
author Pulkit Goyal <pulkit@yandex-team.ru>
Mon, 01 Apr 2019 13:56:47 +0300
changeset 42121 6578654916ae
parent 42120 2f8147521e59
child 42122 7c9d4cf23adf
permissions -rw-r--r--
branchcache: lazily validate nodes from the branchmap On my personal hg-repository with 365 entries in .hg/cache/branch2, following are the numbers for perfbranchmapload. Before this patch: ! wall 0.000866 comb 0.000000 user 0.000000 sys 0.000000 (best of 2680) ! wall 0.001525 comb 0.000000 user 0.000000 sys 0.000000 (max of 2680) ! wall 0.001107 comb 0.001097 user 0.001086 sys 0.000011 (avg of 2680) ! wall 0.001104 comb 0.000000 user 0.000000 sys 0.000000 (median of 2680) With this patch: ! wall 0.000530 comb 0.000000 user 0.000000 sys 0.000000 (best of 4240) ! wall 0.001078 comb 0.000000 user 0.000000 sys 0.000000 (max of 4240) ! wall 0.000696 comb 0.000693 user 0.000677 sys 0.000017 (avg of 4240) ! wall 0.000690 comb 0.000000 user 0.000000 sys 0.000000 (median of 4240) On our internal repository with ~20k entries in branchcache, I see improvement from 0.125 sec to 0.066 sec which is 47% speed up. The above are the numbers of perfbranchmapload which shows how much time we saved by not validating the nodes. But we need to validate some nodes. Following are timings of some mercurial operations which have speed up because of this lazy validation of nodes: No-op `hg update` on our internal repository (Avg on 4 runs): Before: 0.540 secs After: 0.430 secs Setting a branch name which already exists without --force (Avg of 4 runs): Before: 0.510 secs After: 0.250 secs I ran the ASV performance suite and was unable to see any improvements except there was improvement of perfdirstatewrite() on netbeans which I think was not related. I looked into the commit code, the command which I am trying to speedup, it looks like it uses revbranchcache to update the branchcache. Differential Revision: https://phab.mercurial-scm.org/D6208
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18116
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     1
# branchmap.py - logic to computes, maintain and stores branchmap for local repo
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     2
#
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     3
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     4
#
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
bcee63733aad branchmap: create a mercurial.branchmap module
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
18117
526e7ec5c96e branchmap: extract write logic from localrepo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18116
diff changeset
     7
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     8
from __future__ import absolute_import
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
     9
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    10
import struct
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    11
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    12
from .node import (
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    13
    bin,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    14
    hex,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    15
    nullid,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    16
    nullrev,
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    17
)
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    18
from . import (
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    19
    encoding,
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26460
diff changeset
    20
    error,
35831
a011e4140435 branchmap: make error messages consistent between Python 2 and 3
Augie Fackler <augie@google.com>
parents: 35495
diff changeset
    21
    pycompat,
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    22
    scmutil,
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
    23
    util,
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    24
)
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    25
from .utils import (
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    26
    stringutil,
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
    27
)
25918
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    28
47f36e050c2e branchmap: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25660
diff changeset
    29
calcsize = struct.calcsize
31370
906be86990c4 rbc: use struct unpack_from and pack_into instead of unpack and pack
Mads Kiilerich <madski@unity3d.com>
parents: 31360
diff changeset
    30
pack_into = struct.pack_into
906be86990c4 rbc: use struct unpack_from and pack_into instead of unpack and pack
Mads Kiilerich <madski@unity3d.com>
parents: 31360
diff changeset
    31
unpack_from = struct.unpack_from
18117
526e7ec5c96e branchmap: extract write logic from localrepo
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18116
diff changeset
    32
18118
e70ff1e599f4 branchmap: extract read logic from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18117
diff changeset
    33
20032
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    34
### Nearest subset relation
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    35
# Nearest subset of filter X is a filter Y so that:
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    36
# * Y is included in X,
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    37
# * X - Y is as small as possible.
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    38
# This create and ordering used for branchmap purpose.
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    39
# the ordering may be partial
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    40
subsettable = {None: 'visible',
35495
07fdac1d5c66 repoview: add a new filtername for accessing hidden commits
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34370
diff changeset
    41
               'visible-hidden': 'visible',
20032
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    42
               'visible': 'served',
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    43
               'served': 'immutable',
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    44
               'immutable': 'base'}
175c6fd8cacc subsettable: move from repoview to branchmap, the only place it's used
Augie Fackler <raf@durin42.com>
parents: 19839
diff changeset
    45
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    46
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    47
class BranchMapCache(object):
41718
a87ca1d7e61d branchmap: improve doc about BranchMapCache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41678
diff changeset
    48
    """mapping of filtered views of repo with their branchcache"""
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    49
    def __init__(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    50
        self._per_filter = {}
41567
c795c462b1d6 branchmap: add some clarifications and clean up flow
Martijn Pieters <mj@octobus.net>
parents: 41566
diff changeset
    51
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    52
    def __getitem__(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    53
        self.updatecache(repo)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    54
        return self._per_filter[repo.filtername]
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    55
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    56
    def updatecache(self, repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    57
        """Update the cache for the given filtered view on a repository"""
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    58
        # This can trigger updates for the caches for subsets of the filtered
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    59
        # view, e.g. when there is no cache for this filtered view or the cache
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    60
        # is stale.
18121
f8a13f061a8a branchmap: extract updatebranchcache from repo
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18120
diff changeset
    61
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    62
        cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    63
        filtername = repo.filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    64
        bcache = self._per_filter.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    65
        if bcache is None or not bcache.validfor(repo):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    66
            # cache object missing or cache object stale? Read from disk
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    67
            bcache = branchcache.fromfile(repo)
41567
c795c462b1d6 branchmap: add some clarifications and clean up flow
Martijn Pieters <mj@octobus.net>
parents: 41566
diff changeset
    68
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    69
        revs = []
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    70
        if bcache is None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    71
            # no (fresh) cache available anymore, perhaps we can re-use
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    72
            # the cache for a subset, then extend that to add info on missing
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    73
            # revisions.
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    74
            subsetname = subsettable.get(filtername)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    75
            if subsetname is not None:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    76
                subset = repo.filtered(subsetname)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    77
                bcache = self[subset].copy()
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    78
                extrarevs = subset.changelog.filteredrevs - cl.filteredrevs
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    79
                revs.extend(r for r in extrarevs if r <= bcache.tiprev)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    80
            else:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    81
                # nothing to fall back on, start empty.
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    82
                bcache = branchcache()
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
    83
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    84
        revs.extend(cl.revs(start=bcache.tiprev + 1))
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    85
        if revs:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    86
            bcache.update(repo, revs)
18124
79db6d40bced branchmap: store branchcache in a dedicated object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18121
diff changeset
    87
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    88
        assert bcache.validfor(repo), filtername
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    89
        self._per_filter[repo.filtername] = bcache
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    90
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    91
    def replace(self, repo, remotebranchmap):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    92
        """Replace the branchmap cache for a repo with a branch mapping.
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    93
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    94
        This is likely only called during clone with a branch map from a
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    95
        remote.
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
    96
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    97
        """
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    98
        cl = repo.changelog
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
    99
        clrev = cl.rev
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   100
        clbranchinfo = cl.branchinfo
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   101
        rbheads = []
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   102
        closed = []
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   103
        for bheads in remotebranchmap.itervalues():
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   104
            rbheads += bheads
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   105
            for h in bheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   106
                r = clrev(h)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   107
                b, c = clbranchinfo(r)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   108
                if c:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   109
                    closed.append(h)
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   110
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   111
        if rbheads:
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   112
            rtiprev = max((int(clrev(node)) for node in rbheads))
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   113
            cache = branchcache(
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   114
                remotebranchmap, repo[rtiprev].node(), rtiprev,
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   115
                closednodes=closed)
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   116
41615
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   117
            # Try to stick it as low as possible
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   118
            # filter above served are unlikely to be fetch from a clone
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   119
            for candidate in ('base', 'immutable', 'served'):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   120
                rview = repo.filtered(candidate)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   121
                if cache.validfor(rview):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   122
                    self._per_filter[candidate] = cache
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   123
                    cache.write(rview)
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   124
                    return
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   125
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   126
    def clear(self):
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   127
        self._per_filter.clear()
328ca3b9e545 branchmap: encapsulate cache updating in the map itself
Martijn Pieters <mj@octobus.net>
parents: 41567
diff changeset
   128
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   129
def _unknownnode(node):
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   130
    """ raises ValueError when branchcache found a node which does not exists
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   131
    """
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   132
    raise ValueError(r'node %s does not exist' % pycompat.sysstr(hex(node)))
26460
79ef867538ea branchmap: move branch cache code out of streamclone.py
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25918
diff changeset
   133
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   134
class branchcache(object):
20181
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   135
    """A dict like object that hold branches heads cache.
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   136
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   137
    This cache is used to avoid costly computations to determine all the
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   138
    branch heads of a repo.
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   139
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   140
    The cache is serialized on disk in the following format:
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   141
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   142
    <tip hex node> <tip rev number> [optional filtered repo hex hash]
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   143
    <branch head hex node> <open/closed state> <branch name>
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   144
    <branch head hex node> <open/closed state> <branch name>
20181
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   145
    ...
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   146
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   147
    The first line is used to check if the cache is still valid. If the
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   148
    branch cache is for a filtered repo view, an optional third hash is
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   149
    included that hashes the hashes of all filtered revisions.
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   150
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   151
    The open/closed state is represented by a single letter 'o' or 'c'.
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   152
    This field can be used to avoid changelog reads when determining if a
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   153
    branch head closes a branch or not.
20181
b9515fb9e72a branchmap: add documentation on the branchcache on-disk format
Brodie Rao <brodie@sf.io>
parents: 20032
diff changeset
   154
    """
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   155
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   156
    def __init__(self, entries=(), tipnode=nullid, tiprev=nullrev,
42007
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   157
                 filteredhash=None, closednodes=None, hasnode=None):
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   158
        """ hasnode is a function which can be used to verify whether changelog
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   159
        has a given node or not. If it's not provided, we assume that every node
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   160
        we have exists in changelog """
41677
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   161
        self.tipnode = tipnode
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   162
        self.tiprev = tiprev
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   163
        self.filteredhash = filteredhash
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   164
        # closednodes is a set of nodes that close their branch. If the branch
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   165
        # cache has been updated, it may contain nodes that are no longer
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   166
        # heads.
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   167
        if closednodes is None:
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   168
            self._closednodes = set()
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   169
        else:
bfc49f1df615 branchmap: move __init__ up in branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41615
diff changeset
   170
            self._closednodes = closednodes
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   171
        self._entries = dict(entries)
42006
111de135fc76 branchcache: add attributes to track which nodes are verified
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42005
diff changeset
   172
        # whether closed nodes are verified or not
111de135fc76 branchcache: add attributes to track which nodes are verified
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42005
diff changeset
   173
        self._closedverified = False
111de135fc76 branchcache: add attributes to track which nodes are verified
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42005
diff changeset
   174
        # branches for which nodes are verified
111de135fc76 branchcache: add attributes to track which nodes are verified
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42005
diff changeset
   175
        self._verifiedbranches = set()
42007
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   176
        self._hasnode = hasnode
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   177
        if self._hasnode is None:
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   178
            self._hasnode = lambda x: True
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   179
42120
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   180
    def _verifyclosed(self):
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   181
        """ verify the closed nodes we have """
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   182
        if self._closedverified:
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   183
            return
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   184
        for node in self._closednodes:
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   185
            if not self._hasnode(node):
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   186
                _unknownnode(node)
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   187
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   188
        self._closedverified = True
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   189
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   190
    def _verifybranch(self, branch):
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   191
        """ verify head nodes for the given branch. If branch is None, verify
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   192
        for all the branches """
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   193
        if branch not in self._entries or branch in self._verifiedbranches:
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   194
            return
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   195
        for n in self._entries[branch]:
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   196
            if not self._hasnode(n):
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   197
                _unknownnode(n)
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   198
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   199
        self._verifiedbranches.add(branch)
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   200
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   201
    def _verifyall(self):
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   202
        """ verifies nodes of all the branches """
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   203
        for b in self._entries:
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   204
            self._verifybranch(b)
2f8147521e59 branchcache: add functions to validate changelog nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42113
diff changeset
   205
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   206
    def __iter__(self):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   207
        return iter(self._entries)
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   208
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   209
    def __setitem__(self, key, value):
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   210
        self._entries[key] = value
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   211
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   212
    def __getitem__(self, key):
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   213
        self._verifybranch(key)
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   214
        return self._entries[key]
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   215
42113
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   216
    def __contains__(self, key):
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   217
        self._verifybranch(key)
42113
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   218
        return key in self._entries
f0def07fa82f branchmap: implement __contains__()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42112
diff changeset
   219
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   220
    def iteritems(self):
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   221
        self._verifyall()
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   222
        return self._entries.iteritems()
42001
624d6683c705 branchmap: remove the dict interface from the branchcache class (API)
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41839
diff changeset
   223
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   224
    def hasbranch(self, label):
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   225
        """ checks whether a branch of this name exists or not """
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   226
        self._verifybranch(label)
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   227
        return label in self._entries
42004
0bd730fbcc2b branchcache: introduce hasbranch()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42003
diff changeset
   228
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   229
    @classmethod
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   230
    def fromfile(cls, repo):
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   231
        f = None
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   232
        try:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   233
            f = repo.cachevfs(cls._filename(repo))
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   234
            lineiter = iter(f)
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   235
            cachekey = next(lineiter).rstrip('\n').split(" ", 2)
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   236
            last, lrev = cachekey[:2]
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   237
            last, lrev = bin(last), int(lrev)
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   238
            filteredhash = None
42007
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   239
            hasnode = repo.changelog.hasnode
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   240
            if len(cachekey) > 2:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   241
                filteredhash = bin(cachekey[2])
42007
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   242
            bcache = cls(tipnode=last, tiprev=lrev, filteredhash=filteredhash,
b5511845f9d5 branchcache: have a hasnode function to validate nodes
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42006
diff changeset
   243
                         hasnode=hasnode)
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   244
            if not bcache.validfor(repo):
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   245
                # invalidate the cache
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   246
                raise ValueError(r'tip differs')
41808
8ad46ac6728e branchmap: prevent reading the file twice through different iterators
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41797
diff changeset
   247
            bcache.load(repo, lineiter)
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   248
        except (IOError, OSError):
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   249
            return None
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   250
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   251
        except Exception as inst:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   252
            if repo.ui.debugflag:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   253
                msg = 'invalid branchheads cache'
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   254
                if repo.filtername is not None:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   255
                    msg += ' (%s)' % repo.filtername
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   256
                msg += ': %s\n'
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   257
                repo.ui.debug(msg % pycompat.bytestr(inst))
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   258
            bcache = None
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   259
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   260
        finally:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   261
            if f:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   262
                f.close()
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   263
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   264
        return bcache
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   265
41808
8ad46ac6728e branchmap: prevent reading the file twice through different iterators
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41797
diff changeset
   266
    def load(self, repo, lineiter):
8ad46ac6728e branchmap: prevent reading the file twice through different iterators
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41797
diff changeset
   267
        """ fully loads the branchcache by reading from the file using the line
8ad46ac6728e branchmap: prevent reading the file twice through different iterators
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41797
diff changeset
   268
        iterator passed"""
41797
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   269
        for line in lineiter:
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   270
            line = line.rstrip('\n')
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   271
            if not line:
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   272
                continue
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   273
            node, state, label = line.split(" ", 2)
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   274
            if state not in 'oc':
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   275
                raise ValueError(r'invalid branch state')
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   276
            label = encoding.tolocal(label.strip())
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   277
            node = bin(node)
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   278
            self._entries.setdefault(label, []).append(node)
41797
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   279
            if state == 'c':
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   280
                self._closednodes.add(node)
68bbcc70e274 branchcache: move loading of branch names and nodes into it's own function
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41759
diff changeset
   281
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   282
    @staticmethod
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   283
    def _filename(repo):
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   284
        """name of a branchcache file for a given repo or repoview"""
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   285
        filename = "branch2"
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   286
        if repo.filtername:
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   287
            filename = '%s-%s' % (filename, repo.filtername)
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   288
        return filename
18124
79db6d40bced branchmap: store branchcache in a dedicated object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18121
diff changeset
   289
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   290
    def validfor(self, repo):
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18451
diff changeset
   291
        """Is the cache content valid regarding a repo
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   292
18644
3e92772d5383 spelling: fix some minor issues found by spell checker
Mads Kiilerich <mads@kiilerich.com>
parents: 18451
diff changeset
   293
        - False when cached tipnode is unknown or if we detect a strip.
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   294
        - True when cache is up to date or a subset of current repo."""
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   295
        try:
18168
c351759ab0a0 branchmap: takes filtered revision in account for cache calculation
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18167
diff changeset
   296
            return ((self.tipnode == repo.changelog.node(self.tiprev))
41759
aaad36b88298 cleanup: use () to wrap long lines instead of \
Augie Fackler <augie@google.com>
parents: 41718
diff changeset
   297
                    and (self.filteredhash ==
24723
467a33142425 repoview: move function for computing filtered hash
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24378
diff changeset
   298
                         scmutil.filteredhash(repo, self.tiprev)))
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   299
        except IndexError:
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   300
            return False
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   301
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   302
    def _branchtip(self, heads):
20245
4edd179fefb8 help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents: 20190
diff changeset
   303
        '''Return tuple with last open head in heads and false,
4edd179fefb8 help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents: 20190
diff changeset
   304
        otherwise return last closed head and true.'''
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   305
        tip = heads[-1]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   306
        closed = True
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   307
        self._verifyclosed()
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   308
        for h in reversed(heads):
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   309
            if h not in self._closednodes:
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   310
                tip = h
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   311
                closed = False
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   312
                break
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   313
        return tip, closed
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   314
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   315
    def branchtip(self, branch):
20245
4edd179fefb8 help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents: 20190
diff changeset
   316
        '''Return the tipmost open head on branch head, otherwise return the
4edd179fefb8 help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents: 20190
diff changeset
   317
        tipmost closed head on branch.
4edd179fefb8 help: branch names primarily denote the tipmost unclosed branch head
Mads Kiilerich <madski@unity3d.com>
parents: 20190
diff changeset
   318
        Raise KeyError for unknown branch.'''
20186
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   319
        return self._branchtip(self[branch])[0]
f5b461a4bc55 branchmap: introduce branchtip() method
Brodie Rao <brodie@sf.io>
parents: 20185
diff changeset
   320
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   321
    def iteropen(self, nodes):
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   322
        self._verifyclosed()
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   323
        return (n for n in nodes if n not in self._closednodes)
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   324
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   325
    def branchheads(self, branch, closed=False):
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   326
        self._verifybranch(branch)
42112
29c22496dd97 branchmap: prevent using __getitem__() in branchheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42111
diff changeset
   327
        heads = self._entries[branch]
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   328
        if not closed:
34074
abf91c4f9608 branches: correctly show inactive multiheaded branches
the31k <the31k@thethirty.one>
parents: 33663
diff changeset
   329
            heads = list(self.iteropen(heads))
20188
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   330
        return heads
3a3727829607 branchmap: introduce branchheads() method
Brodie Rao <brodie@sf.io>
parents: 20186
diff changeset
   331
20190
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   332
    def iterbranches(self):
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   333
        for bn, heads in self.iteritems():
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   334
            yield (bn, heads) + self._branchtip(heads)
d5d25e541637 branchmap: introduce iterbranches() method
Brodie Rao <brodie@sf.io>
parents: 20188
diff changeset
   335
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   336
    def iterheads(self):
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   337
        """ returns all the heads """
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   338
        self._verifyall()
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   339
        return self._entries.itervalues()
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   340
18232
dd0b636b0b65 branchmap: add a copy method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18218
diff changeset
   341
    def copy(self):
dd0b636b0b65 branchmap: add a copy method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18218
diff changeset
   342
        """return an deep copy of the branchcache object"""
42121
6578654916ae branchcache: lazily validate nodes from the branchmap
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42120
diff changeset
   343
        self._verifyall()
42111
f0fa0fc4900a branchmap: dynamically resolve type of branchcache class
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42007
diff changeset
   344
        return type(self)(
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   345
            self._entries, self.tipnode, self.tiprev, self.filteredhash,
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   346
            self._closednodes)
18132
db25bf1dc828 branchmap: move validity logic in the object itself
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18131
diff changeset
   347
18128
f0d56efaa35a branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18127
diff changeset
   348
    def write(self, repo):
f0d56efaa35a branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18127
diff changeset
   349
        try:
41565
bf7fb97aecf1 branchmap: make branchcache responsible for reading
Martijn Pieters <mj@octobus.net>
parents: 41396
diff changeset
   350
            f = repo.cachevfs(self._filename(repo), "w", atomictemp=True)
31348
fc06c5260639 branchmap: stringify int in a portable way
Augie Fackler <augie@google.com>
parents: 31347
diff changeset
   351
            cachekey = [hex(self.tipnode), '%d' % self.tiprev]
18184
8d48af68e2ae branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18168
diff changeset
   352
            if self.filteredhash is not None:
8d48af68e2ae branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18168
diff changeset
   353
                cachekey.append(hex(self.filteredhash))
8d48af68e2ae branchmap: read and write key part related to filtered revision
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18168
diff changeset
   354
            f.write(" ".join(cachekey) + '\n')
21031
05cfcecb3aef branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20264
diff changeset
   355
            nodecount = 0
18357
a4ab37ca887b localrepo: store branchheads sorted
Mads Kiilerich <mads@kiilerich.com>
parents: 18307
diff changeset
   356
            for label, nodes in sorted(self.iteritems()):
41678
9d0d8793e847 branchmap: decode a label only once
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41677
diff changeset
   357
                label = encoding.fromlocal(label)
18128
f0d56efaa35a branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18127
diff changeset
   358
                for node in nodes:
21031
05cfcecb3aef branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20264
diff changeset
   359
                    nodecount += 1
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   360
                    if node in self._closednodes:
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   361
                        state = 'c'
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   362
                    else:
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   363
                        state = 'o'
41678
9d0d8793e847 branchmap: decode a label only once
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41677
diff changeset
   364
                    f.write("%s %s %s\n" % (hex(node), state, label))
18128
f0d56efaa35a branchmap: make write a method on the branchmap object
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18127
diff changeset
   365
            f.close()
21031
05cfcecb3aef branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20264
diff changeset
   366
            repo.ui.log('branchcache',
05cfcecb3aef branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20264
diff changeset
   367
                        'wrote %s branch cache with %d labels and %d nodes\n',
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   368
                        repo.filtername, len(self._entries), nodecount)
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26460
diff changeset
   369
        except (IOError, OSError, error.Abort) as inst:
34370
d0db41af73c0 branchmap: remove superfluous pass statements
Augie Fackler <augie@google.com>
parents: 34074
diff changeset
   370
            # Abort may be raised by read only opener, so log and continue
36396
743b293c3ca0 py3: use util.forcebytestr to convert error messages to bytes
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36201
diff changeset
   371
            repo.ui.debug("couldn't write branch cache: %s\n" %
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
   372
                          stringutil.forcebytestr(inst))
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   373
18305
2502a15e033d branchmap: pass revision insteads of changectx to the update function
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18234
diff changeset
   374
    def update(self, repo, revgen):
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   375
        """Given a branchhead cache, self, that may have extra nodes or be
20263
ea4996754d91 branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20262
diff changeset
   376
        missing heads, and a generator of nodes that are strictly a superset of
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   377
        heads missing, this function updates self to be correct.
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   378
        """
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
   379
        starttime = util.timer()
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   380
        cl = repo.changelog
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   381
        # collect new branch entries
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   382
        newbranches = {}
24373
59cc09240afb revbranchcache: move out of branchmap onto localrepo
Durham Goode <durham@fb.com>
parents: 24163
diff changeset
   383
        getbranchinfo = repo.revbranchcache().branchinfo
18307
0eed2546118a branchmap: Save changectx creation during update
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 18305
diff changeset
   384
        for r in revgen:
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   385
            branch, closesbranch = getbranchinfo(r)
20262
cf450ee3f8f7 branchmap: stop useless rev -> node -> rev round trip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20261
diff changeset
   386
            newbranches.setdefault(branch, []).append(r)
20185
7d4219512823 branchmap: cache open/closed branch head information
Brodie Rao <brodie@sf.io>
parents: 20181
diff changeset
   387
            if closesbranch:
20262
cf450ee3f8f7 branchmap: stop useless rev -> node -> rev round trip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20261
diff changeset
   388
                self._closednodes.add(cl.node(r))
22357
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   389
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   390
        # fetch current topological heads to speed up filtering
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   391
        topoheads = set(cl.headrevs())
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   392
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   393
        # if older branchheads are reachable from new ones, they aren't
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   394
        # really branchheads. Note checking parents is insufficient:
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   395
        # 1 (branch a) -> 2 (branch b) -> 3 (branch a)
20262
cf450ee3f8f7 branchmap: stop useless rev -> node -> rev round trip
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20261
diff changeset
   396
        for branch, newheadrevs in newbranches.iteritems():
42005
b137a6793c51 branchcache: make entries a private attribute
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42004
diff changeset
   397
            bheads = self._entries.setdefault(branch, [])
20264
d9e1c167943b branchmap: use set for update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20263
diff changeset
   398
            bheadset = set(cl.rev(node) for node in bheads)
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   399
20263
ea4996754d91 branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20262
diff changeset
   400
            # This have been tested True on all internal usage of this function.
ea4996754d91 branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20262
diff changeset
   401
            # run it again in case of doubt
ea4996754d91 branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20262
diff changeset
   402
            # assert not (set(bheadrevs) & set(newheadrevs))
20264
d9e1c167943b branchmap: use set for update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20263
diff changeset
   403
            bheadset.update(newheadrevs)
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   404
22356
3c8fb24334e9 branchmap: issue a single call to `ancestors` for all heads
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
   405
            # This prunes out two kinds of heads - heads that are superseded by
3c8fb24334e9 branchmap: issue a single call to `ancestors` for all heads
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
   406
            # a head in newheadrevs, and newheadrevs that are not heads because
3c8fb24334e9 branchmap: issue a single call to `ancestors` for all heads
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22059
diff changeset
   407
            # an existing head is their descendant.
22357
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   408
            uncertain = bheadset - topoheads
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   409
            if uncertain:
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   410
                floorrev = min(uncertain)
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   411
                ancestors = set(cl.ancestors(newheadrevs, floorrev))
9c3c3dc14a65 branchmap: pre-filter topological heads before ancestors based filtering
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22356
diff changeset
   412
                bheadset -= ancestors
20264
d9e1c167943b branchmap: use set for update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20263
diff changeset
   413
            bheadrevs = sorted(bheadset)
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   414
            self[branch] = [cl.node(rev) for rev in bheadrevs]
20263
ea4996754d91 branchmap: simplify update code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 20262
diff changeset
   415
            tiprev = bheadrevs[-1]
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   416
            if tiprev > self.tiprev:
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   417
                self.tipnode = cl.node(tiprev)
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   418
                self.tiprev = tiprev
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   419
19838
23386881abeb branchmap: remove the droppednodes logic
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 19837
diff changeset
   420
        if not self.validfor(repo):
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   421
            # cache key are not valid anymore
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   422
            self.tipnode = nullid
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   423
            self.tiprev = nullrev
42002
662ffdde5adf branchcache: rename itervalues() to iterheads()
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 42001
diff changeset
   424
            for heads in self.iterheads():
18131
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   425
                tiprev = max(cl.rev(node) for node in heads)
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   426
                if tiprev > self.tiprev:
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   427
                    self.tipnode = cl.node(tiprev)
f0eeb9b3444a branchmap: make update a method
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 18130
diff changeset
   428
                    self.tiprev = tiprev
24723
467a33142425 repoview: move function for computing filtered hash
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24378
diff changeset
   429
        self.filteredhash = scmutil.filteredhash(repo, self.tiprev)
21031
05cfcecb3aef branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20264
diff changeset
   430
30975
22fbca1d11ed mercurial: switch to util.timer for all interval timings
Simon Farnsworth <simonfar@fb.com>
parents: 29746
diff changeset
   431
        duration = util.timer() - starttime
21031
05cfcecb3aef branchmap: log events related to branch cache
Gregory Szorc <gregory.szorc@gmail.com>
parents: 20264
diff changeset
   432
        repo.ui.log('branchcache', 'updated %s branch cache in %.4f seconds\n',
41839
38de3300414f py3: convert filtername to str if it's None
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 41808
diff changeset
   433
                    repo.filtername or b'None', duration)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   434
41566
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   435
        self.write(repo)
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   436
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   437
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   438
class remotebranchcache(branchcache):
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   439
    """Branchmap info for a remote connection, should not write locally"""
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   440
    def write(self, repo):
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   441
        pass
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   442
eb7ce452e0fb branchmap: updating triggers a write
Martijn Pieters <mj@octobus.net>
parents: 41565
diff changeset
   443
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   444
# Revision branch info cache
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   445
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   446
_rbcversion = '-v1'
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   447
_rbcnames = 'rbc-names' + _rbcversion
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   448
_rbcrevs = 'rbc-revs' + _rbcversion
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   449
# [4 byte hash prefix][4 byte branch name number with sign bit indicating open]
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   450
_rbcrecfmt = '>4sI'
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   451
_rbcrecsize = calcsize(_rbcrecfmt)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   452
_rbcnodelen = 4
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   453
_rbcbranchidxmask = 0x7fffffff
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   454
_rbccloseflag = 0x80000000
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   455
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   456
class revbranchcache(object):
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   457
    """Persistent cache, mapping from revision number to branch name and close.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   458
    This is a low level cache, independent of filtering.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   459
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   460
    Branch names are stored in rbc-names in internal encoding separated by 0.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   461
    rbc-names is append-only, and each branch name is only stored once and will
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   462
    thus have a unique index.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   463
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   464
    The branch info for each revision is stored in rbc-revs as constant size
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   465
    records. The whole file is read into memory, but it is only 'parsed' on
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   466
    demand. The file is usually append-only but will be truncated if repo
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   467
    modification is detected.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   468
    The record for each revision contains the first 4 bytes of the
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   469
    corresponding node hash, and the record is only used if it still matches.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   470
    Even a completely trashed rbc-revs fill thus still give the right result
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   471
    while converging towards full recovery ... assuming no incorrectly matching
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   472
    node hashes.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   473
    The record also contains 4 bytes where 31 bits contains the index of the
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   474
    branch and the last bit indicate that it is a branch close commit.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   475
    The usage pattern for rbc-revs is thus somewhat similar to 00changelog.i
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   476
    and will grow with it but be 1/8th of its size.
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   477
    """
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   478
24159
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
   479
    def __init__(self, repo, readonly=True):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   480
        assert repo.filtername is None
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24373
diff changeset
   481
        self._repo = repo
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   482
        self._names = [] # branch names in local encoding with static index
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 30975
diff changeset
   483
        self._rbcrevs = bytearray()
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   484
        self._rbcsnameslen = 0 # length of names read at _rbcsnameslen
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   485
        try:
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   486
            bndata = repo.cachevfs.read(_rbcnames)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   487
            self._rbcsnameslen = len(bndata) # for verification before writing
31371
7dd2f51f38ac rbc: empty (and invalid) rbc-names file should give an empty name list
Mads Kiilerich <mads@kiilerich.com>
parents: 31370
diff changeset
   488
            if bndata:
7dd2f51f38ac rbc: empty (and invalid) rbc-names file should give an empty name list
Mads Kiilerich <mads@kiilerich.com>
parents: 31370
diff changeset
   489
                self._names = [encoding.tolocal(bn)
7dd2f51f38ac rbc: empty (and invalid) rbc-names file should give an empty name list
Mads Kiilerich <mads@kiilerich.com>
parents: 31370
diff changeset
   490
                               for bn in bndata.split('\0')]
29423
d2c6f3a948fa branchmap: remove unused exception variable
Gregory Szorc <gregory.szorc@gmail.com>
parents: 28558
diff changeset
   491
        except (IOError, OSError):
24159
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
   492
            if readonly:
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
   493
                # don't try to use cache - fall back to the slow path
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
   494
                self.branchinfo = self._branchinfo
5b4ed033390b revisionbranchcache: fall back to slow path if starting readonly (issue4531)
Mads Kiilerich <madski@unity3d.com>
parents: 23877
diff changeset
   495
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   496
        if self._names:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   497
            try:
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   498
                data = repo.cachevfs.read(_rbcrevs)
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 30975
diff changeset
   499
                self._rbcrevs[:] = data
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25266
diff changeset
   500
            except (IOError, OSError) as inst:
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   501
                repo.ui.debug("couldn't read revision branch cache: %s\n" %
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
   502
                              stringutil.forcebytestr(inst))
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   503
        # remember number of good records on disk
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   504
        self._rbcrevslen = min(len(self._rbcrevs) // _rbcrecsize,
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   505
                               len(repo.changelog))
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   506
        if self._rbcrevslen == 0:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   507
            self._names = []
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   508
        self._rbcnamescount = len(self._names) # number of names read at
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   509
                                               # _rbcsnameslen
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   510
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   511
    def _clear(self):
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   512
        self._rbcsnameslen = 0
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   513
        del self._names[:]
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   514
        self._rbcnamescount = 0
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   515
        self._rbcrevslen = len(self._repo.changelog)
31346
2a18e9e6ca43 py3: use bytearray() instead of array('c', ...) constructions
Augie Fackler <augie@google.com>
parents: 30975
diff changeset
   516
        self._rbcrevs = bytearray(self._rbcrevslen * _rbcrecsize)
40710
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
   517
        util.clearcachedproperty(self, '_namesreverse')
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
   518
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
   519
    @util.propertycache
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
   520
    def _namesreverse(self):
50a64c321c1e branchmap: build the revbranchcache._namesreverse() only when required
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 40425
diff changeset
   521
        return dict((b, r) for r, b in enumerate(self._names))
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   522
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   523
    def branchinfo(self, rev):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   524
        """Return branch name and close flag for rev, using and updating
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   525
        persistent cache."""
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   526
        changelog = self._repo.changelog
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   527
        rbcrevidx = rev * _rbcrecsize
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   528
25266
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
   529
        # avoid negative index, changelog.read(nullrev) is fast without cache
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
   530
        if rev == nullrev:
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
   531
            return changelog.branchinfo(rev)
38117278f295 revbranchcache: return uncached branchinfo for nullrev (issue4683)
Yuya Nishihara <yuya@tcha.org>
parents: 24728
diff changeset
   532
29604
db0095c83344 rbc: fix invalid rbc-revs entries caused by missing cache growth
Mads Kiilerich <madski@unity3d.com>
parents: 29423
diff changeset
   533
        # if requested rev isn't allocated, grow and cache the rev info
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   534
        if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   535
            return self._branchinfo(rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   536
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   537
        # fast path: extract data from cache, use it if node is matching
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   538
        reponode = changelog.node(rev)[:_rbcnodelen]
33663
1814ca418b30 branchmap: revert c34532365b38 for Python 2.7 compatibility
Mike Hommey <mh@glandium.org>
parents: 33535
diff changeset
   539
        cachenode, branchidx = unpack_from(
1814ca418b30 branchmap: revert c34532365b38 for Python 2.7 compatibility
Mike Hommey <mh@glandium.org>
parents: 33535
diff changeset
   540
            _rbcrecfmt, util.buffer(self._rbcrevs), rbcrevidx)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   541
        close = bool(branchidx & _rbccloseflag)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   542
        if close:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   543
            branchidx &= _rbcbranchidxmask
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   544
        if cachenode == '\0\0\0\0':
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   545
            pass
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   546
        elif cachenode == reponode:
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   547
            try:
28558
bcd106d456c4 cache: rebuild branch cache from scratch when inconsistencies are detected
Mads Kiilerich <madski@unity3d.com>
parents: 28557
diff changeset
   548
                return self._names[branchidx], close
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   549
            except IndexError:
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   550
                # recover from invalid reference to unknown branch
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   551
                self._repo.ui.debug("referenced branch names not found"
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   552
                    " - rebuilding revision branch cache from scratch\n")
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   553
                self._clear()
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   554
        else:
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   555
            # rev/node map has changed, invalidate the cache from here up
29615
a2a380e2750f rbc: fix superfluous rebuilding from scratch - don't abuse self._rbcnamescount
Mads Kiilerich <madski@unity3d.com>
parents: 29604
diff changeset
   556
            self._repo.ui.debug("history modification detected - truncating "
31497
a369482e9649 branchmap: be more careful about using %d on ints
Augie Fackler <augie@google.com>
parents: 31454
diff changeset
   557
                "revision branch cache to revision %d\n" % rev)
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   558
            truncate = rbcrevidx + _rbcrecsize
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   559
            del self._rbcrevs[truncate:]
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   560
            self._rbcrevslen = min(self._rbcrevslen, truncate)
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   561
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   562
        # fall back to slow path and make sure it will be written to disk
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   563
        return self._branchinfo(rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   564
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   565
    def _branchinfo(self, rev):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   566
        """Retrieve branch info from changelog and update _rbcrevs"""
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   567
        changelog = self._repo.changelog
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   568
        b, close = changelog.branchinfo(rev)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   569
        if b in self._namesreverse:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   570
            branchidx = self._namesreverse[b]
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   571
        else:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   572
            branchidx = len(self._names)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   573
            self._names.append(b)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   574
            self._namesreverse[b] = branchidx
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   575
        reponode = changelog.node(rev)
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   576
        if close:
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   577
            branchidx |= _rbccloseflag
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   578
        self._setcachedata(rev, reponode, branchidx)
24375
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
   579
        return b, close
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
   580
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   581
    def setdata(self, branch, rev, node, close):
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   582
        """add new data information to the cache"""
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   583
        if branch in self._namesreverse:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   584
            branchidx = self._namesreverse[branch]
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   585
        else:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   586
            branchidx = len(self._names)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   587
            self._names.append(branch)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   588
            self._namesreverse[branch] = branchidx
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   589
        if close:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   590
            branchidx |= _rbccloseflag
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   591
        self._setcachedata(rev, node, branchidx)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   592
        # If no cache data were readable (non exists, bad permission, etc)
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   593
        # the cache was bypassing itself by setting:
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   594
        #
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   595
        #   self.branchinfo = self._branchinfo
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   596
        #
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   597
        # Since we now have data in the cache, we need to drop this bypassing.
40232
d99a588d8515 py3: pass in system string to vars(branchmap).__contains__()
Yuya Nishihara <yuya@tcha.org>
parents: 39138
diff changeset
   598
        if r'branchinfo' in vars(self):
36962
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   599
            del self.branchinfo
95f4f1bfb650 revbranchcache: add a public function to update the data
Boris Feld <boris.feld@octobus.net>
parents: 36474
diff changeset
   600
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   601
    def _setcachedata(self, rev, node, branchidx):
24375
fe255b2525d5 revbranchcache: move entry writing to a separate function
Durham Goode <durham@fb.com>
parents: 24374
diff changeset
   602
        """Writes the node's branch data to the in-memory cache data."""
31454
a5bad127128d branchmap: handle nullrev in setcachedata
Durham Goode <durham@fb.com>
parents: 31381
diff changeset
   603
        if rev == nullrev:
a5bad127128d branchmap: handle nullrev in setcachedata
Durham Goode <durham@fb.com>
parents: 31381
diff changeset
   604
            return
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   605
        rbcrevidx = rev * _rbcrecsize
29604
db0095c83344 rbc: fix invalid rbc-revs entries caused by missing cache growth
Mads Kiilerich <madski@unity3d.com>
parents: 29423
diff changeset
   606
        if len(self._rbcrevs) < rbcrevidx + _rbcrecsize:
db0095c83344 rbc: fix invalid rbc-revs entries caused by missing cache growth
Mads Kiilerich <madski@unity3d.com>
parents: 29423
diff changeset
   607
            self._rbcrevs.extend('\0' *
40425
5e5c8f2a1eb5 branchmap: do not specify changelog as an argument
Yuya Nishihara <yuya@tcha.org>
parents: 40375
diff changeset
   608
                                 (len(self._repo.changelog) * _rbcrecsize -
29604
db0095c83344 rbc: fix invalid rbc-revs entries caused by missing cache growth
Mads Kiilerich <madski@unity3d.com>
parents: 29423
diff changeset
   609
                                  len(self._rbcrevs)))
31370
906be86990c4 rbc: use struct unpack_from and pack_into instead of unpack and pack
Mads Kiilerich <madski@unity3d.com>
parents: 31360
diff changeset
   610
        pack_into(_rbcrecfmt, self._rbcrevs, rbcrevidx, node, branchidx)
24376
203a078da052 revbranchcache: populate cache incrementally
Durham Goode <durham@fb.com>
parents: 24375
diff changeset
   611
        self._rbcrevslen = min(self._rbcrevslen, rev)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   612
24377
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
   613
        tr = self._repo.currenttransaction()
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
   614
        if tr:
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
   615
            tr.addfinalize('write-revbranchcache', self.write)
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
   616
656f93ce66d5 revbranchcache: move cache writing to the transaction finalizer
Durham Goode <durham@fb.com>
parents: 24376
diff changeset
   617
    def write(self, tr=None):
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   618
        """Save branch cache if it is dirty."""
24374
77fd1fb538cd revbranchcache: store repo on the object
Durham Goode <durham@fb.com>
parents: 24373
diff changeset
   619
        repo = self._repo
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   620
        wlock = None
29745
3b184adfb5be branchmap: simplify error handlind when writing rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29744
diff changeset
   621
        step = ''
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   622
        try:
29743
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
   623
            if self._rbcnamescount < len(self._names):
29745
3b184adfb5be branchmap: simplify error handlind when writing rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29744
diff changeset
   624
                step = ' names'
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   625
                wlock = repo.wlock(wait=False)
29746
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   626
                if self._rbcnamescount != 0:
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   627
                    f = repo.cachevfs.open(_rbcnames, 'ab')
29746
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   628
                    if f.tell() == self._rbcsnameslen:
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   629
                        f.write('\0')
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   630
                    else:
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   631
                        f.close()
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   632
                        repo.ui.debug("%s changed - rewriting it\n" % _rbcnames)
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   633
                        self._rbcnamescount = 0
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   634
                        self._rbcrevslen = 0
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   635
                if self._rbcnamescount == 0:
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   636
                    # before rewriting names, make sure references are removed
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   637
                    repo.cachevfs.unlinkpath(_rbcrevs, ignoremissing=True)
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   638
                    f = repo.cachevfs.open(_rbcnames, 'wb')
29746
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   639
                f.write('\0'.join(encoding.fromlocal(b)
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   640
                                  for b in self._names[self._rbcnamescount:]))
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   641
                self._rbcsnameslen = f.tell()
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   642
                f.close()
29743
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
   643
                self._rbcnamescount = len(self._names)
23785
cb99bacb9b4e branchcache: introduce revbranchcache for caching of revision branch names
Mads Kiilerich <madski@unity3d.com>
parents: 22357
diff changeset
   644
29743
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
   645
            start = self._rbcrevslen * _rbcrecsize
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
   646
            if start != len(self._rbcrevs):
29745
3b184adfb5be branchmap: simplify error handlind when writing rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29744
diff changeset
   647
                step = ''
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   648
                if wlock is None:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   649
                    wlock = repo.wlock(wait=False)
29743
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
   650
                revs = min(len(repo.changelog),
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
   651
                           len(self._rbcrevs) // _rbcrecsize)
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   652
                f = repo.cachevfs.open(_rbcrevs, 'ab')
29746
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   653
                if f.tell() != start:
33535
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   654
                    repo.ui.debug("truncating cache/%s to %d\n"
755e6532e81d cachevfs: migration the revbranchcache to 'cachevfs'
Boris Feld <boris.feld@octobus.net>
parents: 33534
diff changeset
   655
                                  % (_rbcrevs, start))
29746
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   656
                    f.seek(start)
28557
4b83507bfc91 cache: safer handling of failing seek when writing revision branch cache
Mads Kiilerich <madski@unity3d.com>
parents: 28556
diff changeset
   657
                    if f.tell() != start:
29746
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   658
                        start = 0
28557
4b83507bfc91 cache: safer handling of failing seek when writing revision branch cache
Mads Kiilerich <madski@unity3d.com>
parents: 28556
diff changeset
   659
                        f.seek(start)
29746
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   660
                    f.truncate()
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   661
                end = revs * _rbcrecsize
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   662
                f.write(self._rbcrevs[start:end])
3dbc95f3eb31 branchmap: remove extra indent
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29745
diff changeset
   663
                f.close()
29743
9f3c49ee4486 branchmap: preparatory indent of indent the branch rev writing code
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29615
diff changeset
   664
                self._rbcrevslen = revs
29745
3b184adfb5be branchmap: simplify error handlind when writing rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29744
diff changeset
   665
        except (IOError, OSError, error.Abort, error.LockError) as inst:
3b184adfb5be branchmap: simplify error handlind when writing rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29744
diff changeset
   666
            repo.ui.debug("couldn't write revision branch cache%s: %s\n"
37084
f0b6fbea00cf stringutil: bulk-replace call sites to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36962
diff changeset
   667
                          % (step, stringutil.forcebytestr(inst)))
29744
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   668
        finally:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   669
            if wlock is not None:
0d588332ad2c branchmap: acquires lock before writting the rev branch cache
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 29743
diff changeset
   670
                wlock.release()